So I want to make a movement system which i have total control over using assemblyLinearVelocity for the HumanoidRootPart.
I want to make it as accurate as possible to the normal movement, except for climbing and adding spinting, sliding etc.
There are 4 problems to be exact
- Falling down near a platform causes the HumanoidRootPart to get stuck for a bit (kinda solved)
- The same thing for jumping up and getting stuck between the gap of 2 parts on top of each other
- when im walking against the wall, the character is shaking a bit
- Climbing up the stairs sideways, causes the HumanoidRootPart to hit the elevated part
This is the part of the script that runs on every frame that controls the jump and move function in the PlayerModule with RenderStepped()
function ControlModule:JumpHandler(Jump: boolean, dt)
if not self.humanoid or self.humanoid.Health <= 0 then return end
local HumanoidRootPart = self.humanoid.RootPart
local currentVel = HumanoidRootPart.AssemblyLinearVelocity
local isGrounded = false
if self.humanoid.FloorMaterial ~= Enum.Material.Air and self:CheckGrounded() then
isGrounded = true
end
if isGrounded and self.VerticalVelocity <= 0 then
self.JumpEnabled = true
self.VerticalVelocity = 0
self.WallKickAmount = 0
else
self.JumpEnabled = false
if self.VerticalVelocity > 0 then -- If head hit a roof
local HitHead = false
local corners = getTopCorners(HumanoidRootPart)
local rayCastDir = Vector3.new(0, 10, 0)
local rayCastParams = RaycastParams.new()
rayCastParams.FilterDescendantsInstances = {HumanoidRootPart.Parent}
rayCastParams.FilterType = Enum.RaycastFilterType.Exclude
local raycastResults = {}
raycastResults[1] = workspace:Raycast(corners.TopFrontRight, rayCastDir, rayCastParams)
raycastResults[2] = workspace:Raycast(corners.TopFrontLeft, rayCastDir, rayCastParams)
raycastResults[3] = workspace:Raycast(corners.TopBackRight, rayCastDir, rayCastParams)
raycastResults[4] = workspace:Raycast(corners.TopBackLeft, rayCastDir, rayCastParams)
for i = 1, 4 do
if raycastResults[i] ~= nil and raycastResults[i].Distance < 1.1 then
HitHead = true
end
end
if HitHead then
self.VerticalVelocity = self.VerticalVelocity * -1
end
end
local gravityToApply = 200
self.VerticalVelocity -= gravityToApply * dt
--Velocity cap
if self.VerticalVelocity < -150 then
self.VerticalVelocity = -150
end
end
-- Jump
if self.activeController:GetIsJumping() and self.JumpEnabled then
self.JumpEnabled = false
local power = (self.humanoid.JumpPower > 0) and self.humanoid.JumpPower or 50
self.humanoid:ChangeState(Enum.HumanoidStateType.Jumping)
self.VerticalVelocity = power
end
local finalY = self.VerticalVelocity
HumanoidRootPart.AssemblyLinearVelocity = Vector3.new(currentVel.X, finalY, currentVel.Z)
end
function ControlModule:Move(direction: Vector3, relativeToCam: boolean, dt)
if not self.humanoid or self.humanoid.Health <= 0 then return end
local HumanoidRootPart : Part = self.humanoid.RootPart
if relativeToCam then
if direction.Magnitude > 0 then
HumanoidRootPart.AssemblyLinearVelocity = direction.Unit * self.humanoid.WalkSpeed
local targetLook = HumanoidRootPart.Position + Vector3.new(direction.X, 0, direction.Z)
-- 2. Create the target CFrame
local targetCFrame = CFrame.lookAt(HumanoidRootPart.Position, targetLook)
HumanoidRootPart.CFrame = HumanoidRootPart.CFrame:Lerp(targetCFrame, dt * 10)
else
HumanoidRootPart.AssemblyLinearVelocity = Vector3.new(0,0,0)
end
end