Advertisement
memecreater

bhop

Oct 10th, 2022
31
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.49 KB | None | 0 0
  1. local mv = {}
  2. local player
  3. local character
  4. local collider
  5. local camera
  6. local input
  7. local collider
  8. local playerGrounded
  9. local playerVelocity
  10. local jumping
  11. local moveInputSum
  12. local dt = 1/60
  13. local partYRatio
  14. local partZRatio
  15. local cameraYaw
  16. local cameraLook
  17. local movementPosition
  18. local movementVelocity
  19. local gravityForce
  20.  
  21. local airAccelerate
  22. local airMaxSpeed --only limits projection of velocity onto acceleration
  23. local groundAccelerate
  24. local groundMaxVelocity --only limits projection of velocity onto acceleration
  25. local friction
  26. local playerTorsoToGround
  27. local movementStickDistance
  28. local jumpVelocity
  29. local movementPositionForce
  30. local movementVelocityForce
  31. local maxMovementPitch
  32. local rayYLength
  33. local movementPositionD
  34. local movementPositionP
  35. local movementVelocityP
  36. local gravity
  37.  
  38.  
  39.  
  40. function mv.init(Player, Camera, Input)
  41. player = Player
  42. character = player.Character
  43. collider = character.Torso
  44. camera = Camera
  45. input = Input
  46. playerVelocity = 0
  47. playerGrounded = false
  48. moveInputSum = {
  49. ["forward"] = 0,
  50. ["side"] = 0 --left is positive
  51. }
  52.  
  53. airAccelerate = 5000
  54. airMaxSpeed = 20
  55. groundAccelerate = 25
  56. groundMaxVelocity = 400
  57. friction = 10
  58. playerTorsoToGround = 3
  59. movementStickDistance = 0.5
  60. jumpVelocity = 80
  61. movementPositionForce = 400000
  62. movementVelocityForce = 3000000
  63. maxMovementPitch = 0.6
  64. rayYLength = playerTorsoToGround + movementStickDistance
  65. movementPositionD = 125
  66. movementPositionP = 14000
  67. movementVelocityP = 15000
  68. gravity = 0.4
  69.  
  70. end
  71.  
  72. function mv.initBodyMovers()
  73. movementPosition = Instance.new("BodyPosition", collider)
  74. movementPosition.Name = "movementPosition"
  75. movementPosition.D = movementPositionD
  76. movementPosition.P = movementPositionP
  77. movementPosition.maxForce = Vector3.new()
  78. movementPosition.position = Vector3.new()
  79.  
  80. movementVelocity = Instance.new("BodyVelocity", collider)
  81. movementVelocity.Name = "movementVelocity"
  82. movementVelocity.P = movementVelocityP
  83. movementVelocity.maxForce = Vector3.new()
  84. movementVelocity.velocity = Vector3.new()
  85.  
  86. gravityForce = Instance.new("BodyForce", collider)
  87. gravityForce.Name = "gravityForce"
  88. gravityForce.force = Vector3.new(0, (1-gravity)*196.2, 0) * getCharacterMass()
  89. end
  90.  
  91. function mv.update(deltaTime)
  92. dt = deltaTime
  93. updateMoveInputSum()
  94. cameraYaw = getYaw()
  95. cameraLook = cameraYaw.lookVector
  96. if cameraLook == nil then
  97. return
  98. end
  99. local hitPart, hitPosition, hitNormal, yRatio, zRatio = findCollisionRay()
  100. partYRatio = yRatio
  101. partZRatio = zRatio
  102.  
  103. playerGrounded = hitPart ~= nil and true or false
  104. playerVelocity = collider.Velocity - Vector3.new(0, collider.Velocity.y, 0)
  105. if playerGrounded and (input["Space"] or jumping) then
  106. jumping = true
  107. else
  108. jumping = false
  109. end
  110.  
  111. setCharacterRotation()
  112. if jumping then
  113. jump()
  114. print(math.random())
  115. elseif playerGrounded then
  116. run(hitPosition)
  117. else
  118. air()
  119. end
  120.  
  121. end
  122.  
  123. function updateMoveInputSum()
  124. moveInputSum["forward"] = input["W"] == true and 1 or 0
  125. moveInputSum["forward"] = input["S"] == true and moveInputSum["forward"] - 1 or moveInputSum["forward"]
  126. moveInputSum["side"] = input["A"] == true and 1 or 0
  127. moveInputSum["side"] = input["D"] == true and moveInputSum["side"] - 1 or moveInputSum["side"]
  128. end
  129.  
  130. function findCollisionRay()
  131. local torsoCFrame = character.Torso.CFrame
  132. local ignoreList = {character, camera}
  133. local rays = {
  134. Ray.new(character.Torso.Position, Vector3.new(0, -rayYLength, 0)),
  135. Ray.new((torsoCFrame * CFrame.new(-0.8,0,0)).p, Vector3.new(0, -rayYLength, 0)),
  136. Ray.new((torsoCFrame * CFrame.new(0.8,0,0)).p, Vector3.new(0, -rayYLength, 0)),
  137. Ray.new((torsoCFrame * CFrame.new(0,0,0.8)).p, Vector3.new(0, -rayYLength, 0)),
  138. Ray.new((torsoCFrame * CFrame.new(0,0,-0.8)).p, Vector3.new(0, -rayYLength, 0))
  139. }
  140. local rayReturns = {}
  141.  
  142. local i
  143. for i = 1, #rays do
  144. local part, position, normal = game.Workspace:FindPartOnRayWithIgnoreList(rays[i],ignoreList)
  145. if part == nil then
  146. position = Vector3.new(0,-3000000,0)
  147. end
  148. if i == 1 then
  149. table.insert(rayReturns, {part, position, normal})
  150. else
  151. local yPos = position.y
  152. if yPos <= rayReturns[#rayReturns][2].y then
  153. table.insert(rayReturns, {part, position, normal})
  154. else
  155. local j
  156. for j = 1, #rayReturns do
  157. if yPos >= rayReturns[j][2].y then
  158. table.insert(rayReturns, j, {part, position, normal})
  159. end
  160. end
  161. end
  162. end
  163. end
  164.  
  165. i = 1
  166. local yRatio, zRatio = getPartYRatio(rayReturns[i][3])
  167. while magnitude2D(yRatio, zRatio) > maxMovementPitch and i<#rayReturns do
  168. i = i + 1
  169. if rayReturns[i][1] then
  170. yRatio, zRatio = getPartYRatio(rayReturns[i][3])
  171. end
  172. end
  173.  
  174. return rayReturns[i][1], rayReturns[i][2], rayReturns[i][3], yRatio, zRatio
  175. end
  176.  
  177. function setCharacterRotation()
  178. local rotationLook = collider.Position + camera.CoordinateFrame.lookVector
  179. collider.CFrame = CFrame.new(collider.Position, Vector3.new(rotationLook.x, collider.Position.y, rotationLook.z))
  180. collider.RotVelocity = Vector3.new()
  181. end
  182.  
  183. function jump()
  184. collider.Velocity = Vector3.new(collider.Velocity.x, jumpVelocity, collider.Velocity.z)
  185. air()
  186. end
  187.  
  188. function air()
  189. movementPosition.maxForce = Vector3.new()
  190. movementVelocity.velocity = getMovementVelocity(collider.Velocity, airAccelerate, airMaxSpeed)
  191. movementVelocity.maxForce = getMovementVelocityAirForce()
  192. end
  193.  
  194. function run(hitPosition)
  195. local playerSpeed = collider.Velocity.magnitude
  196. local mVelocity = collider.Velocity
  197.  
  198. if playerSpeed ~= 0 then
  199. local drop = playerSpeed * friction * dt;
  200. mVelocity = mVelocity * math.max(playerSpeed - drop, 0) / playerSpeed;
  201. end
  202.  
  203. movementPosition.position = hitPosition + Vector3.new(0,playerTorsoToGround,0)
  204. movementPosition.maxForce = Vector3.new(0,movementPositionForce,0)
  205. movementVelocity.velocity = getMovementVelocity(mVelocity, groundAccelerate, groundMaxVelocity)
  206. local VelocityForce = getMovementVelocityForce()
  207. movementVelocity.maxForce = VelocityForce
  208. movementVelocity.P = movementVelocityP
  209. end
  210.  
  211. function getMovementVelocity(prevVelocity, accelerate, maxVelocity)
  212. local accelForward = cameraLook * moveInputSum["forward"]
  213. local accelSide = (cameraYaw * CFrame.Angles(0,math.rad(90),0)).lookVector * moveInputSum["side"];
  214. local accelDir = (accelForward+accelSide).unit;
  215. if moveInputSum["forward"] == 0 and moveInputSum["side"] == 0 then --avoids divide 0 errors
  216. accelDir = Vector3.new(0,0,0);
  217. end
  218.  
  219. local projVel = prevVelocity:Dot(accelDir);
  220. local accelVel = accelerate * dt;
  221.  
  222. if (projVel + accelVel > maxVelocity) then
  223. accelVel = math.max(maxVelocity - projVel, 0);
  224. end
  225.  
  226. return prevVelocity + accelDir * accelVel;
  227. end
  228.  
  229. function getMovementVelocityForce()
  230.  
  231. return Vector3.new(movementVelocityForce,0,movementVelocityForce)
  232. end
  233.  
  234. function getMovementVelocityAirForce()
  235. local accelForward = cameraLook * moveInputSum["forward"];
  236. local accelSide = (cameraYaw * CFrame.Angles(0,math.rad(90),0)).lookVector * moveInputSum["side"]
  237. local accelDir = (accelForward+accelSide).unit
  238. if moveInputSum["forward"] == 0 and moveInputSum["side"] == 0 then
  239. accelDir = Vector3.new(0,0,0);
  240. end
  241.  
  242. local xp = math.abs(accelDir.x)
  243. local zp = math.abs(accelDir.z)
  244.  
  245. return Vector3.new(movementVelocityForce*xp,0,movementVelocityForce*zp)
  246. end
  247.  
  248. function getPartYRatio(normal)
  249. local partYawVector = Vector3.new(-normal.x, 0, -normal.z)
  250. if partYawVector.magnitude == 0 then
  251. return 0,0
  252. else
  253. local partPitch = math.atan2(partYawVector.magnitude,normal.y)/(math.pi/2)
  254. local vector = Vector3.new(cameraLook.x, 0, cameraLook.z)*partPitch
  255. return vector:Dot(partYawVector), -partYawVector:Cross(vector).y
  256. end
  257. end
  258.  
  259. function getYaw() --returns CFrame
  260. return camera.CoordinateFrame*CFrame.Angles(-getPitch(),0,0)
  261. end
  262.  
  263. function getPitch() --returns number
  264. return math.pi/2 - math.acos(camera.CoordinateFrame.lookVector:Dot(Vector3.new(0,1,0)))
  265. end
  266.  
  267. function getCharacterMass()
  268. return character.Torso:GetMass() + character.Head:GetMass()
  269. end
  270.  
  271. function magnitude2D(x,z)
  272. return math.sqrt(x*x+z*z)
  273. end
  274.  
  275. --note: this only works with filtering enabled
  276.  
  277. local player = game.Players.LocalPlayer
  278. local camera = game.Workspace.CurrentCamera
  279. local UserInputService = game:GetService("UserInputService")
  280.  
  281. local prevUpdateTime = nil
  282. local updateDT = 1/60
  283. local inputKeys = {
  284. ["W"] = false,
  285. ["S"] = false,
  286. ["A"] = false,
  287. ["D"] = false,
  288. ["Space"] = false,
  289. ["LMB"] = false,
  290. ["RMB"] = false
  291. }
  292.  
  293. function main()
  294. -- character spawning bs
  295. if player:FindFirstChild("customCharacterSpawned") == nil then
  296. local newval = Instance.new("BoolValue", player);
  297. newval.Name = "customCharacterSpawned";
  298. newval.Value = false;
  299. end
  300.  
  301. if not player.customCharacterSpawned.Value then
  302. player.customCharacterSpawned.Value = true;
  303. return;
  304. end
  305.  
  306. player.Character:WaitForChild("Humanoid");
  307. --remove hats for physics sake
  308. huckFats();
  309. spawn(function()
  310. while player.Character do
  311. wait(1)
  312. huckFats();
  313. end
  314. end)
  315.  
  316. --init movement
  317. mv.init(player, camera, inputKeys);
  318. mv.initBodyMovers();
  319.  
  320. --display poop
  321.  
  322.  
  323. --connect input
  324. UserInputService.InputBegan:connect(onInput);
  325. UserInputService.InputEnded:connect(onInput);
  326.  
  327. --connect updateloop
  328. game:GetService("RunService"):BindToRenderStep("updateLoop", 1, updateLoop);
  329.  
  330. --rip
  331. player.Character.Humanoid.Died:connect(onDeath)
  332. end
  333.  
  334. function updateLoop()
  335. setDeltaTime();
  336. mv.update(updateDT);
  337. end
  338.  
  339. function huckFats()
  340. for _,v in pairs (player.Character:GetChildren()) do
  341. if v:IsA("Hat") then
  342. v:Destroy()
  343. end
  344. end
  345. end
  346.  
  347. function setDeltaTime() --seconds
  348. local UpdateTime = tick()
  349. if prevUpdateTime ~= nil then
  350. updateDT = (UpdateTime - prevUpdateTime)
  351. else
  352. updateDT = 1/60
  353. end
  354. prevUpdateTime = UpdateTime
  355. end
  356.  
  357. function onInput(input, gameProcessedEvent)
  358. local inputState
  359. --print(input.KeyCode)
  360. if input.UserInputState == Enum.UserInputState.Begin then
  361. inputState = true
  362. elseif input.UserInputState == Enum.UserInputState.End then
  363. inputState = false
  364. else
  365. return
  366. end
  367.  
  368. if input.UserInputType == Enum.UserInputType.Keyboard then
  369. local key = input.KeyCode.Name
  370. if inputKeys[key] ~= nil then
  371. inputKeys[key] = inputState
  372. end
  373. elseif input.UserInputType == Enum.UserInputType.MouseButton1 then --LMB down
  374. inputKeys.LMB = inputState
  375. elseif input.UserInputType == Enum.UserInputType.MouseButton2 then --RMB down
  376. inputKeys.RMB = inputState
  377. end
  378. end
  379.  
  380. function onDeath()
  381. player.customCharacterSpawned = false
  382. end
  383.  
  384. main()
  385. end)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement