Advertisement
Guest User

Untitled

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