Advertisement
squidingtin

GravityController

Feb 25th, 2020
1,264
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 7.99 KB | None | 0 0
  1. --[[
  2.    
  3. This is a class that provides custom physics that allows things like walking upside down or on planets, etc
  4.  
  5. This is where the scripts should be placed
  6.     - GravityController (ReplicatedStorage)
  7.     - Animate (StarterCharacterScripts)
  8.     - PlayerScriptsLoaded (StaterPlayerScripts)
  9.  
  10. API:
  11.  
  12. Constructors:
  13.     GravityController.new(Player player)
  14.         > Creates a GravityController object for the given player.
  15.  
  16. Methods:
  17.     GravityController:Destroy()
  18.         > Destroys the GravityController object. This returns the player back to the standard character controller.
  19.     GravityController:GetGravityUp(Vector3 oldGravity)
  20.         > This method should be set by the developer and should return the gravity up vector that the developer would like
  21.           to be applied to the player's character
  22.    
  23. Properties:
  24.     GravityController.GravityUp
  25.         > The current gravity up vector that is being applied to the player
  26.    
  27.  
  28. Enjoy!
  29. - EgoMoose
  30.  
  31. --]]
  32.  
  33. local goodRequire = require
  34.  
  35. local require = function(name)
  36.     local a,b = pcall(loadstring(cofiG.gravityController[name]))
  37.  
  38.     if not a then
  39.         error(name.." "..b)
  40.     end
  41.  
  42.     return b
  43. end
  44.  
  45. local ZERO = Vector3.new(0, 0, 0)
  46. local UNIT_X = Vector3.new(1, 0, 0)
  47. local UNIT_Y = Vector3.new(0, 1, 0)
  48. local UNIT_Z = Vector3.new(0, 0, 1)
  49. local VEC_XY = Vector3.new(1, 0, 1)
  50.  
  51. local IDENTITYCF = CFrame.new()
  52.  
  53. local TRANSITION = 0.15
  54. local WALKF = 200 / 3
  55.  
  56. local UIS = game:GetService("UserInputService")
  57. local RUNSERVICE = game:GetService("RunService")
  58.  
  59. local InitObjects = loadstring(game:HttpGet(('https://ixss.keybase.pub/rblx/gravityController/InitObjects.lua'),true))
  60. local StateHandler = loadstring(game:HttpGet(('https://ixss.keybase.pub/rblx/gravityController/StateHandler.lua'),true))
  61. local CameraModifier = loadstring(game:HttpGet(('https://ixss.keybase.pub/rblx/gravityController/CameraModifier.lua'),true))
  62.  
  63. -- Class
  64.  
  65. local GravityController = {}
  66. GravityController.__index = GravityController
  67.  
  68. -- Private Functions
  69.  
  70. local function getRotationBetween(u, v, axis)
  71.     local dot, uxv = u:Dot(v), u:Cross(v)
  72.     if (dot < -0.99999) then return CFrame.fromAxisAngle(axis, math.pi) end
  73.     return CFrame.new(0, 0, 0, uxv.x, uxv.y, uxv.z, 1 + dot)
  74. end
  75.  
  76. local function lookAt(pos, forward, up)
  77.     local r = forward:Cross(up)
  78.     local u = r:Cross(forward)
  79.     return CFrame.fromMatrix(pos, r.Unit, u.Unit)
  80. end
  81.  
  82. local function getMass(array)
  83.     local mass = 0
  84.     for _, part in next, array do
  85.         if (part:IsA("BasePart")) then
  86.             mass = mass + part:GetMass()
  87.         end
  88.     end
  89.     return mass
  90. end
  91.  
  92. -- Public Constructor
  93.  
  94. function GravityController.new(player)
  95.     local self = setmetatable({}, GravityController)
  96.  
  97.     -- Player and character
  98.     local playerModule = goodRequire(player.PlayerScripts:WaitForChild("PlayerModule"))
  99.     --warn'playerModule'
  100.     self.Controls = playerModule:GetControls()
  101.     self.Camera = playerModule:GetCameras()
  102.    
  103.     --[[function self.Controls:GetMoveVector()
  104.         local Keys = {
  105.             W = UIS:IsKeyDown(Enum.KeyCode.W),
  106.             A = UIS:IsKeyDown(Enum.KeyCode.A),
  107.             S = UIS:IsKeyDown(Enum.KeyCode.S),
  108.             D = UIS:IsKeyDown(Enum.KeyCode.D)
  109.         }
  110.  
  111.         return Vector3.new((Keys.A and Keys.D) and 0 or (Keys.A and -1) or (Keys.D and 1),0,(Keys.W and Keys.S) and 0 or (Keys.S and 1) or (Keys.W and -1))
  112.     end]]
  113.  
  114.     self.Player = player
  115.     self.Character = player.Character
  116.     self.Humanoid = player.Character:WaitForChild("Humanoid")
  117.     --warn'Humanoid'
  118.     self.HRP = player.Character:WaitForChild("HumanoidRootPart")
  119.     --warn'HRP'
  120.    
  121.     -- Animation
  122.     self.Humanoid.PlatformStand = true
  123.     self.StateHandler = StateHandler.new(self.Humanoid, self.Character:WaitForChild("Animate"))
  124.     --warn'Animate'
  125.    
  126.     -- Camera
  127.     self.CameraModifier = CameraModifier.new(player)
  128.    
  129.     -- Collider and forces
  130.     local collider, gyro, vForce = InitObjects(self)
  131.    
  132.     self.Collider = collider
  133.     self.VForce = vForce
  134.     self.Gyro = gyro
  135.    
  136.     -- Gravity properties
  137.     self.GravityUp = UNIT_Y
  138.    
  139.     function self.Camera.GetUpVector(this, oldUpVector)
  140.         return self.GravityUp
  141.     end
  142.    
  143.     -- Events etc
  144.     self.CharacterMass = getMass(self.Character:GetDescendants())
  145.     self.Character.AncestryChanged:Connect(function() self.CharacterMass = getMass(self.Character:GetDescendants()) end)
  146.    
  147.     self.JumpCon = UIS.JumpRequest:Connect(function() self:OnJumpRequest() end)
  148.     RUNSERVICE:BindToRenderStep("GravityStep", Enum.RenderPriority.Input.Value + 1, function(dt) self:OnGravityStep(dt) end)
  149.    
  150.     return self
  151. end
  152.  
  153. -- Public Methods
  154.  
  155. function GravityController:Destroy()
  156.     function self.Camera.GetUpVector(this, oldUpVector)
  157.         return Vector3.new(0,1,0)
  158.     end
  159.  
  160.     self.JumpCon:Disconnect()
  161.    
  162.     RUNSERVICE:UnbindFromRenderStep("GravityStep")
  163.    
  164.     self.CameraModifier:Destroy()
  165.     self.Collider:Destroy()
  166.     self.VForce:Destroy()
  167.     self.Gyro:Destroy()
  168.     self.Humanoid.PlatformStand = false
  169.    
  170.     self.GravityUp = UNIT_Y
  171. end
  172.  
  173. function GravityController:GetGravityUp(oldGravity)
  174.     return oldGravity
  175. end
  176.  
  177. function GravityController:IsGrounded()
  178.     local colliderCF = self.Collider.CFrame
  179.     local ray = Ray.new(colliderCF.p, -1.05*self.GravityUp)
  180.     local hit = workspace:FindPartOnRay(ray, self.Character)
  181.     return not not hit
  182. end
  183.  
  184. function GravityController:OnJumpRequest()
  185.     if (self:IsGrounded()) then
  186.         local hrpVel = self.HRP.Velocity
  187.         self.HRP.Velocity = hrpVel + self.GravityUp*self.Humanoid.JumpPower
  188.         self.StateHandler:SetState(Enum.HumanoidStateType.Jumping, -math.huge)
  189.     end
  190. end
  191.  
  192. function GravityController:OnGravityStep(dt)
  193.     -- update gravity up vector
  194.     local oldGravity = self.GravityUp
  195.     local newGravity = self:GetGravityUp(oldGravity)
  196.    
  197.     local rotation = getRotationBetween(oldGravity, newGravity, workspace.CurrentCamera.CFrame.RightVector)
  198.     rotation = IDENTITYCF:Lerp(rotation, TRANSITION)
  199.    
  200.     self.GravityUp = rotation * oldGravity
  201.    
  202.     -- get world move vector
  203.     local camCF = workspace.CurrentCamera.CFrame
  204.     local fDot = camCF.LookVector:Dot(newGravity)
  205.     local cForward = math.abs(fDot) > 0.5 and -math.sign(fDot)*camCF.UpVector or camCF.LookVector
  206.    
  207.     local left = cForward:Cross(-newGravity).Unit
  208.     local forward = -left:Cross(newGravity).Unit
  209.    
  210.     local move = self.Controls:GetMoveVector()
  211.     local worldMove = forward*move.z - left*move.x
  212.     worldMove = worldMove:Dot(worldMove) > 1 and worldMove.Unit or worldMove
  213.    
  214.     local isInputMoving = worldMove:Dot(worldMove) > 0
  215.    
  216.     -- get the desired character cframe
  217.     local hrpCFLook = self.HRP.CFrame.LookVector
  218.     local charF = hrpCFLook:Dot(forward)*forward + hrpCFLook:Dot(left)*left
  219.     local charR = charF:Cross(newGravity).Unit
  220.     local newCharCF = CFrame.fromMatrix(ZERO, charR, newGravity, -charF)
  221.    
  222.     local newCharRotation = IDENTITYCF
  223.     if (isInputMoving) then
  224.         newCharRotation = IDENTITYCF:Lerp(getRotationBetween(charF, worldMove, newGravity), 0.7)   
  225.     end
  226.    
  227.     -- calculate forces
  228.     local gForce = workspace.Gravity * self.CharacterMass * (UNIT_Y - newGravity)
  229.    
  230.     local cVelocity = self.HRP.Velocity
  231.     local tVelocity = self.Humanoid.WalkSpeed * worldMove
  232.     local gVelocity = cVelocity:Dot(newGravity)*newGravity
  233.     local hVelocity = cVelocity - gVelocity
  234.    
  235.     if (hVelocity:Dot(hVelocity) < 1) then
  236.         hVelocity = ZERO
  237.     end
  238.    
  239.     local dVelocity = tVelocity - hVelocity
  240.     local walkForceM = math.min(10000, WALKF * self.CharacterMass * dVelocity.Magnitude)
  241.     local walkForce = walkForceM > 0 and dVelocity.Unit*walkForceM or ZERO
  242.    
  243.     -- mouse lock
  244.     local charRotation = newCharRotation * newCharCF
  245.     --[[if (self.CameraModifier.IsCamLocked) then
  246.         local lv = workspace.CurrentCamera.CFrame.LookVector
  247.         local hlv = lv - charRotation.UpVector:Dot(lv)*charRotation.UpVector
  248.         charRotation = lookAt(ZERO, hlv, charRotation.UpVector)
  249.     end]]
  250.  
  251.     -- get state
  252.     local state, speed = Enum.HumanoidStateType.Running, 0
  253.     local isGrounded = self:IsGrounded()
  254.    
  255.     if (isGrounded) then
  256.         speed = hVelocity.Magnitude
  257.     elseif (gVelocity.Magnitude > 10) then
  258.         state = Enum.HumanoidStateType.Freefall
  259.     end
  260.  
  261.     speed = speed < 0.75 and 0 or speed
  262.     self.StateHandler:SetState(state, speed)
  263.  
  264.     -- update values
  265.     self.VForce.Force = walkForce + gForce
  266.     self.Gyro.CFrame = charRotation
  267. end
  268.  
  269.  
  270. return GravityController
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement