hi all!! im not really great at coding so im already using this code How to get angle of platform player standing on - #12 by MrNicNac however the movement is very janky/snappy and it seems to lock forward to where the slope is going upwards, not being able to face downwards without turning, id like to fix the turning issue as well as make the transition from the group to the slope smoother ( / look more natural)
ive tried looking + implementing other code in the forum but as linked, its the only one thats been able to work with my custom model since
again i know like little to nothing about coding but am hoping to learn :] any help / explanation would be greatly appreciated
local char = script.Parent
local rootPart = char:WaitForChild("HumanoidRootPart")
local xzGyro = Instance.new("BodyGyro")
local yGyro = Instance.new("BodyGyro")
yGyro.MaxTorque = Vector3.new(0,3e5,0)
yGyro.P = 5e5
xzGyro.MaxTorque = Vector3.new(3e5,0,3e5)
xzGyro.P = 5e5
xzGyro.Parent = rootPart
while wait(0.5) do
local params = RaycastParams.new()
params.FilterDescendantsInstances = {char}
params.FilterType = Enum.RaycastFilterType.Blacklist
local result = workspace:Raycast(rootPart.Position, Vector3.new(0,-10,0), params)
yGyro.CFrame = CFrame.new(rootPart.Position, rootPart.Position + char.Humanoid.MoveDirection*10)
if (result) then
print(result.Normal)
local currentRightVector = rootPart.CFrame.RightVector
local upVector = result.Normal
local newFacialVector = currentRightVector:Cross(upVector)
xzGyro.CFrame = CFrame.fromMatrix(rootPart.Position, currentRightVector, upVector, newFacialVector)
end
end
The code attaches a part of custom type “BodyGyros” ( ? this must be using AngularVelocity type as well ) that rotate the Parent character. It uses a Raycast to check if there is a surface within 10 units below and if there is it assumes it must be walking on it. It does this every 0.5s, which is a very low rate if want a real time responsiveness, should be the reason for “jankiness”
yGyro applies angular force to the character to be parallel with the MoveDirection vector, which means when they’re on a slope they will be rotated forward or backward so character looks up or down
xzGyro does the same thing but uses a bit more math, for the X and Z axis alignments. They’re getting the up and right directions from the perspective of the object coordinate space only. For example, an object facing directly west, to their right is north, left is south. These are only relative to the object’s rotation. If the object was aligned with the world axis perfectly then these directions would match the global coordinate system.
They use the raycast result to determine the upVector, which is the normal of the surface it detected. A normal is a vector perpendicular to a surface, meaning it comes straight out of the wall, floor, or whatever surface.
They then do another math thing called a “cross product” of the right and up vectors. A cross product results in another vector perpendicular to the two vectors involved in the calculation. Because it used the X (right) and Y (up) components for calculation, the vector will be the Z (forward, backward) component. The object Z axis is the object’s forward and backward direction and it’s the last component needed, in the code it’s called newFacialVector. They then use all the components to construct the xzGyro CFrame which applies angular force to the attached character so that it aligns correctly.
The character forcefully turning one direction is due to the way it’s using the xzGyro. It seems implemented that way on purpose because when you tap a key in Roblox you don’t instantly change direction to match your movement direction. Without it, a person could do a 180 degree turn with a key tap and only rotate halfway around. The character’s rotation could look quite strange in these cases.
Anyway remove the loop, make it a function and do
local RunService = game:GetService("RunService")
RunService.RenderStepped:Connect(thatfunction)