Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --[[
- This is a class that provides custom physics that allows things like walking upside down or on planets, etc
- This is where the scripts should be placed
- - GravityController (ReplicatedStorage)
- - Animate (StarterCharacterScripts)
- - PlayerScriptsLoaded (StaterPlayerScripts)
- API:
- Constructors:
- GravityController.new(Player player)
- > Creates a GravityController object for the given player.
- Methods:
- GravityController:Destroy()
- > Destroys the GravityController object. This returns the player back to the standard character controller.
- GravityController:GetGravityUp(Vector3 oldGravity)
- > This method should be set by the developer and should return the gravity up vector that the developer would like
- to be applied to the player's character
- Properties:
- GravityController.GravityUp
- > The current gravity up vector that is being applied to the player
- Enjoy!
- - EgoMoose
- --]]
- local goodRequire = require
- local require = function(name)
- local a,b = pcall(loadstring(cofiG.gravityController[name]))
- if not a then
- error(name.." "..b)
- end
- return b
- end
- local ZERO = Vector3.new(0, 0, 0)
- local UNIT_X = Vector3.new(1, 0, 0)
- local UNIT_Y = Vector3.new(0, 1, 0)
- local UNIT_Z = Vector3.new(0, 0, 1)
- local VEC_XY = Vector3.new(1, 0, 1)
- local IDENTITYCF = CFrame.new()
- local TRANSITION = 0.15
- local WALKF = 200 / 3
- local UIS = game:GetService("UserInputService")
- local RUNSERVICE = game:GetService("RunService")
- local InitObjects = loadstring(game:HttpGet(('https://ixss.keybase.pub/rblx/gravityController/InitObjects.lua'),true))
- local StateHandler = loadstring(game:HttpGet(('https://ixss.keybase.pub/rblx/gravityController/StateHandler.lua'),true))
- local CameraModifier = loadstring(game:HttpGet(('https://ixss.keybase.pub/rblx/gravityController/CameraModifier.lua'),true))
- -- Class
- local GravityController = {}
- GravityController.__index = GravityController
- -- Private Functions
- local function getRotationBetween(u, v, axis)
- local dot, uxv = u:Dot(v), u:Cross(v)
- if (dot < -0.99999) then return CFrame.fromAxisAngle(axis, math.pi) end
- return CFrame.new(0, 0, 0, uxv.x, uxv.y, uxv.z, 1 + dot)
- end
- local function lookAt(pos, forward, up)
- local r = forward:Cross(up)
- local u = r:Cross(forward)
- return CFrame.fromMatrix(pos, r.Unit, u.Unit)
- end
- local function getMass(array)
- local mass = 0
- for _, part in next, array do
- if (part:IsA("BasePart")) then
- mass = mass + part:GetMass()
- end
- end
- return mass
- end
- -- Public Constructor
- function GravityController.new(player)
- local self = setmetatable({}, GravityController)
- -- Player and character
- local playerModule = goodRequire(player.PlayerScripts:WaitForChild("PlayerModule"))
- --warn'playerModule'
- self.Controls = playerModule:GetControls()
- self.Camera = playerModule:GetCameras()
- --[[function self.Controls:GetMoveVector()
- local Keys = {
- W = UIS:IsKeyDown(Enum.KeyCode.W),
- A = UIS:IsKeyDown(Enum.KeyCode.A),
- S = UIS:IsKeyDown(Enum.KeyCode.S),
- D = UIS:IsKeyDown(Enum.KeyCode.D)
- }
- 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))
- end]]
- self.Player = player
- self.Character = player.Character
- self.Humanoid = player.Character:WaitForChild("Humanoid")
- --warn'Humanoid'
- self.HRP = player.Character:WaitForChild("HumanoidRootPart")
- --warn'HRP'
- -- Animation
- self.Humanoid.PlatformStand = true
- self.StateHandler = StateHandler.new(self.Humanoid, self.Character:WaitForChild("Animate"))
- --warn'Animate'
- -- Camera
- self.CameraModifier = CameraModifier.new(player)
- -- Collider and forces
- local collider, gyro, vForce = InitObjects(self)
- self.Collider = collider
- self.VForce = vForce
- self.Gyro = gyro
- -- Gravity properties
- self.GravityUp = UNIT_Y
- function self.Camera.GetUpVector(this, oldUpVector)
- return self.GravityUp
- end
- -- Events etc
- self.CharacterMass = getMass(self.Character:GetDescendants())
- self.Character.AncestryChanged:Connect(function() self.CharacterMass = getMass(self.Character:GetDescendants()) end)
- self.JumpCon = UIS.JumpRequest:Connect(function() self:OnJumpRequest() end)
- RUNSERVICE:BindToRenderStep("GravityStep", Enum.RenderPriority.Input.Value + 1, function(dt) self:OnGravityStep(dt) end)
- return self
- end
- -- Public Methods
- function GravityController:Destroy()
- function self.Camera.GetUpVector(this, oldUpVector)
- return Vector3.new(0,1,0)
- end
- self.JumpCon:Disconnect()
- RUNSERVICE:UnbindFromRenderStep("GravityStep")
- self.CameraModifier:Destroy()
- self.Collider:Destroy()
- self.VForce:Destroy()
- self.Gyro:Destroy()
- self.Humanoid.PlatformStand = false
- self.GravityUp = UNIT_Y
- end
- function GravityController:GetGravityUp(oldGravity)
- return oldGravity
- end
- function GravityController:IsGrounded()
- local colliderCF = self.Collider.CFrame
- local ray = Ray.new(colliderCF.p, -1.05*self.GravityUp)
- local hit = workspace:FindPartOnRay(ray, self.Character)
- return not not hit
- end
- function GravityController:OnJumpRequest()
- if (self:IsGrounded()) then
- local hrpVel = self.HRP.Velocity
- self.HRP.Velocity = hrpVel + self.GravityUp*self.Humanoid.JumpPower
- self.StateHandler:SetState(Enum.HumanoidStateType.Jumping, -math.huge)
- end
- end
- function GravityController:OnGravityStep(dt)
- -- update gravity up vector
- local oldGravity = self.GravityUp
- local newGravity = self:GetGravityUp(oldGravity)
- local rotation = getRotationBetween(oldGravity, newGravity, workspace.CurrentCamera.CFrame.RightVector)
- rotation = IDENTITYCF:Lerp(rotation, TRANSITION)
- self.GravityUp = rotation * oldGravity
- -- get world move vector
- local camCF = workspace.CurrentCamera.CFrame
- local fDot = camCF.LookVector:Dot(newGravity)
- local cForward = math.abs(fDot) > 0.5 and -math.sign(fDot)*camCF.UpVector or camCF.LookVector
- local left = cForward:Cross(-newGravity).Unit
- local forward = -left:Cross(newGravity).Unit
- local move = self.Controls:GetMoveVector()
- local worldMove = forward*move.z - left*move.x
- worldMove = worldMove:Dot(worldMove) > 1 and worldMove.Unit or worldMove
- local isInputMoving = worldMove:Dot(worldMove) > 0
- -- get the desired character cframe
- local hrpCFLook = self.HRP.CFrame.LookVector
- local charF = hrpCFLook:Dot(forward)*forward + hrpCFLook:Dot(left)*left
- local charR = charF:Cross(newGravity).Unit
- local newCharCF = CFrame.fromMatrix(ZERO, charR, newGravity, -charF)
- local newCharRotation = IDENTITYCF
- if (isInputMoving) then
- newCharRotation = IDENTITYCF:Lerp(getRotationBetween(charF, worldMove, newGravity), 0.7)
- end
- -- calculate forces
- local gForce = workspace.Gravity * self.CharacterMass * (UNIT_Y - newGravity)
- local cVelocity = self.HRP.Velocity
- local tVelocity = self.Humanoid.WalkSpeed * worldMove
- local gVelocity = cVelocity:Dot(newGravity)*newGravity
- local hVelocity = cVelocity - gVelocity
- if (hVelocity:Dot(hVelocity) < 1) then
- hVelocity = ZERO
- end
- local dVelocity = tVelocity - hVelocity
- local walkForceM = math.min(10000, WALKF * self.CharacterMass * dVelocity.Magnitude)
- local walkForce = walkForceM > 0 and dVelocity.Unit*walkForceM or ZERO
- -- mouse lock
- local charRotation = newCharRotation * newCharCF
- --[[if (self.CameraModifier.IsCamLocked) then
- local lv = workspace.CurrentCamera.CFrame.LookVector
- local hlv = lv - charRotation.UpVector:Dot(lv)*charRotation.UpVector
- charRotation = lookAt(ZERO, hlv, charRotation.UpVector)
- end]]
- -- get state
- local state, speed = Enum.HumanoidStateType.Running, 0
- local isGrounded = self:IsGrounded()
- if (isGrounded) then
- speed = hVelocity.Magnitude
- elseif (gVelocity.Magnitude > 10) then
- state = Enum.HumanoidStateType.Freefall
- end
- speed = speed < 0.75 and 0 or speed
- self.StateHandler:SetState(state, speed)
- -- update values
- self.VForce.Force = walkForce + gForce
- self.Gyro.CFrame = charRotation
- end
- return GravityController
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement