I am making a horse using body gyro, but now it just stays the same on the floor and on the slope. I am trying to manipulate it Angles using RaycastResult.Normal, but I don’t know where to go next.
Here is the code i use to detect Surface Normal
local ray = Ray.new(driverSeat.Position, Vector3.new(0, -20, 0))
local target, position, surfaceNormal = workspace:FindPartOnRay(ray)
bodyGyro.CFrame = -- what should I do with surface Normal
‘lookvector’ would be the general direction the horse is facing.
the ‘red’ vector is the lookvector crossed with the normal vector.
the ‘yellow’ vector is the normal vector crossed with the ‘red’ vector, it should point in the same X-Z direction as ‘lookvector’ while being aligned with the ground.
So you want your bodygyro to be a CFrame that points along the yellow vector.
local ray = Ray.new(driverSeat.Position, Vector3.new(0, -20, 0))
local target, position, surfaceNormal = workspace:FindPartOnRay(ray)
local p1 = driverSeat.CFrame.LookVector:Cross(surfaceNormal)
local p2 = surfaceNormal:Cross(p1)
bodyGyro.CFrame = CFrame.new(Vector3.new(0, 0, 0), p2)
Also the old ray casting method is apparently being deprecated; Roblox wants us to use workspace:Raycast now.
I would apply the Angles calculation after calculating the orientation relative to the ground, then you would only need to update the bodygyro once instead of twice:
Also I found a case in my code where it might not align with the ground if you are sideways on a slope.
You would want to construct a cframe whose lookVector is pointing along the yellow, and whose upVector is pointing along the surface normal:
local p1 = driverSeat.CFrame.LookVector:Cross(surfaceNormal)
--fromMatrix calculates the new lookvector for us so all we need is the rightVector and upVector
bodyGyro.CFrame = CFrame.fromMatrix(Vector3.new(0, 0, 0), p1, surfaceNormal)
TestRig.rbxl (145.0 KB)
(Hit Play, not run Or hit F5 to demo)
An alternate and much better way (in my opinion) is to raycast down at 3 points around the horse and then define a plane which all three points lie on.
Orient the horse so that it is level with the plane.
Each leg should now roughly appear to be standing on each of the positions directly below it.
The result is a muchsmoother transition.
The demo above also has physics code for handling a max slope angle which I thought was nice to include. The legs also move a bit more freely to allow for more smoothness and less jumpiness.
Enjoy.
One thing I wanted to add for those who see this when searching same problem,
the reason the above is better than acquiring the surface normal is because:
Imagine a flat plane and a ramp.
Surface normal method abruptly changes orientation when moving from flat plane to ramp (and can make it jumpy / glitchy).
Whereas
Method above changes orientation smoothly. I.e. if your animal puts half its body on the ramp and half on the flat plane, it will orient sort-of halfway between them placing the legs appropiately. The freely moving legs also help with smoother transitions.
As an example, The Wild West uses something similar to 3-point plane method.