I’ve been working on a competitive obby race game that utilizes several platforming mechanics, one of which includes rail grinding. The mechanic works by using Blockcasts to see if a valid part can be found and aligning the character’s position accordingly via an AlignPosition instance. It works well for the most part, but some issues come up when handling certain character rotations.
Due to the way the engine handles rotations, I made it so the character’s orientation on the Z axis is either 0 or 180 depending on the Normal vector of the Blockcast result (better explained below). As seen above, this approach works fine on the circular rail, but the other one produces very inconsistent results. Even the rotation is successful, there is still a noticeable jitter. Other times, it does not properly set the rotation, so the Blockcast is always unsuccessful, leaving the character floating in place.
Here’s the relevant code:
LocalScript:
function action.perform(controller, last_action)
heartbeat = run_s.Heartbeat:Connect(function(dt)
local root_cframe = root.CFrame --root is a HumanoidRootPart of the character
local result = controller:rail_blockcast(Vector3.zero, Vector3.new(3, 3, 1))
if result and result.Instance:HasTag("GrindRail") then
local new_cframe = CFrame.lookAlong(root.Position,
result.Instance.CFrame.RightVector * 100)
local x, y, z = new_cframe:ToOrientation()
--Below is the real important part (and what I'm having trouble fixing)
if result.Normal.Y < 0 then
z = math.rad(180)
end
new_cframe *= CFrame.fromOrientation(0, 0, z)
root.CFrame = new_cframe
local part = result.Instance
--align_p referenced below is an AlignPosition
align_p.Position = ((part.Position + part.CFrame.RightVector)
+ part.CFrame:VectorToWorldSpace(Vector3.new(0, 2.5, 0)))
+ root.CFrame.LookVector
end
end)
end
ModuleScript function that the LocalScript references:
function module:rail_blockcast(offset, size)
local root = self.root
local cframe = root.CFrame
local result = workspace:Blockcast(cframe + offset,
size,
-root.CFrame.UpVector * (2.6 + offset.Y),
raycast_p2)
return result
end
I have tried also using various unit vectors of the character’s HumanoidRootPart to fix this, but no implementations have worked. Feel free to ask for clarification if need be. Any help is appreciated!