I'm currently using two rays, one for the right leg and one for the left leg, to detect if an NPC is over an edge. This code is functional. Because of Roblox physics, one leg can be over the edge of a cliff and the NPC still stay on top of the cliff.
The problem is, however, that the way the rest of my code is set up, moving away from the cliff is not instantaneous. Therefore, although the NPC tries to correct itself, it still falls. It's even worse when the Torso is parallel to the cliff edge.
I suppose I could take the coordinates of the brick and detect if the NPC is nearing the edge, but this is messy and I don't want to have to edit my code every time I change the location or size of the brick.
This is not a request, since I'm only asking for a good method, not for code.
Use my raycasting code for reference, but it's really not needed, as my method is flawed.
function script.Parent.OnInvoke(left,right) --Left leg local ray = Ray.new(left.Position, Vector3.new(0,-1,0) * 50) local hitLeft,positionLeft = workspace:FindPartOnRay(ray) --Right leg local ray = Ray.new(right.Position, Vector3.new(0,-1,0) * 50) local hitRight,positionRight = workspace:FindPartOnRay(ray) if not hitLeft or not hitRight then return true end end
I would recommend adding a third ray that originates from a few studs in front of the torso and looks down. That way, you can detect if there's a sudden drop off before the NPC is too close to the drop off to stop.
Here's the edited code:
function script.Parent.OnInvoke(Left, Right, Torso) --Left leg local LRay = Ray.new(Left.Position, Vector3.new(0, -50, 0)) local LRayHit, _ = game.Workspace:FindPartOnRay(LRay) --Right leg local RRay = Ray.new(Right.Position, Vector3.new(0, -50, 0)) local RRayHit, _ = game.Workspace:FindPartOnRay(RRay) --Torso local TRay = Ray.new(Torso.Position + (Torso.CFrame.lookVector * 3), Vector3.new(0, -50, 0)) --This creates a ray that originates from 3 studs in front of the center of the torso local TRayHit, _ = game.Workspace:FindPartOnRay(TRay) if (not LRayHit) or (not RRayHit) or (not TRayHit) then return true end end
Hope this helped!