Make NPCS Turn While Walking (Path Finding Service)

Currently making a tower defense game where units can move. Units have a mode called “Anchored” mode which makes units move around in a small area. How i do it is i clone a part and position it on the humanoid root part. Then a script gets the random x and y value of the parts position and moves the unit to that position every few seconds. The moving is completely fine, except that units dont turn.

Anyone know how to fix this?

3 Likes

Forgot to give the script.

module.ChangeMovementMode = function(unit, movementValue, mode, defaultWalkSpeed)
	if unit and unit.Parent ~= nil then
		print(mode)
		if mode ~= "Anchored" and mode ~= "Explorer" and mode ~= "Patrol" and mode ~= "Sentinel" and mode ~= "Command" then return warn("Anti Cheat started") end
		
		if mode == "Sentinel" then
		end
		
		
		
		
		if mode == "Anchored" then
			local AreaPart = RS.UnitHandler.AnchoredModeArea:Clone()
			
			local height = (unit.PrimaryPart.Size.Y / 2) + unit["Left Leg"].Size.Y 
			local unitPosition = unit.PrimaryPart.Position
			
			AreaPart.Parent = workspace.Areas
			AreaPart.CFrame = CFrame.new(Vector3.new(unitPosition.X, unitPosition.Y - height, unitPosition.Z))


			local boundaryCFrame = AreaPart.CFrame
			local boundarySize = AreaPart.Size

			local boundaryMin = boundaryCFrame.Position - (boundarySize / 2)
			local boundaryMax = boundaryCFrame.Position + (boundarySize / 2)
			
			repeat
				local targetPosition = Vector3.new(math.random(boundaryMin.X,boundaryMax.X), unit.PrimaryPart.Position.Y, math.random(boundaryMin.Z, boundaryMax.Z))
				
				local path = PFS:CreatePath()
				
				path:ComputeAsync(unit.PrimaryPart.Position, targetPosition)
				local wayPoints = path:GetWaypoints()
				
				for _, waypoint in wayPoints do
					if movementValue.Value == "Anchored" then
						
						unit.Humanoid:MoveTo(waypoint.Position)
						unit.Humanoid.MoveToFinished:Wait()
					else
						return
					end
				end
				local waitTime = math.random(1, 4)
				
				task.wait(waitTime)
				
			until movementValue.Value ~= "Anchored"
		end
			
		
		
	end
end
1 Like

the commented line i gave you should make the humanoid look at the current waypoint

for _, waypoint in wayPoints do
					if movementValue.Value == "Anchored" then
						
						unit.Humanoid:MoveTo(waypoint.Position)
--unit.HumanoidRootPart.CFrame = CFrame.lookAt(unit.HumanoidRootPart.CFrame, CFrame.new(waypoint.Position))
						unit.Humanoid.MoveToFinished:Wait()
					else
						return
					end
				end
1 Like

I’ve tried this already, since the way point is on the ground the NPC will turn its body and will just fall over.

2 Likes

hmm, maybe use the waypoints position, but set the Y position of it to the unit’s humanoidrootpart?

and THEN make it look at it?

sometihng like this

-- the math i'm doing here very likely won't work, i'm just giving you an idea
local pointToLookAt = waypoint.Position + Vector3.new(0, rootPart.Position.Y, 0)

rootPart.CFrame = CFrame.lookAt(rootPart.Position, pointToLookAt)
1 Like

Instead of looking down it looks up for some reason. Really thought this would work but now I’m confused.

1 Like

i assume you just CnP’d the codei gave you, i’m not sure ifthat’ll work
i think something like this should work:

for _, waypoint in ipairs(wayPoints) do
    if movementValue.Value == "Anchored" then
        local rootPart = unit.HumanoidRootPart
-- create a targetPosition variable, that uses the waypoint's X and Z positions, but the Y of the root parts
        local targetPosition = Vector3.new(waypoint.Position.X, rootPart.Position.Y, waypoint.Position.Z)
        
-- then just simply make it look at that target position and walk towards it
        rootPart.CFrame = CFrame.lookAt(rootPart.Position, targetPosition)
        
        unit.Humanoid:MoveTo(waypoint.Position)
        unit.Humanoid.MoveToFinished:Wait()
    else
        return
    end
end

but also, just a question

since the movement value is “Anchored”, is the actual unit anchored aswell?

i assume it is, since the unit is just kinda sliding across the ground and not even rotating (unless .AutoRotate is off)

1 Like

No I didn’t CnP the code and no the unit isn’t anchored, i just thought it was a cool way to call the movement mode where the unit only has a small space to walk around.

After trying out your code again it got a bit more confusing, the rootPart was nil. Idk what happened but when it enters the for loop the unit.PrimaryPart just becomes nil.

weird… the unit should be turning around if it’s not anchored

whar???
possessed code :sob:
i actually have no idea why that is

On the first loop the rootPart is fine but after the second loop it just completely breaks.

Yeah im confused

image

i added the index so its clearer

damn, honestly i have no idea

ask ai, but at the same time, what error does it give out?

I just somehow fixed it by moving the root part out of the for loop. That problem is solved but the main problem is still not fixed, the NPC just gets teleported to 0, -1000000, 0

DAMN

okay i seriously have no idea D:
i TRIED

try playing around with the rootPart.CFrame, maybe the first parameter somehow breaks it
i’ll be lurking in here incase you get a revelation, will try to help

instead of doing the cframe thingy EXACTLY like that you just have to have the y value in the cframe positioning be the same as the waypoint’s y value

the most convenient method im looking at it here would be
also make sure cframe.lookat has 2 vector3s as inputs because thats what it expects (to my knowledge)

unit.HumanoidRootPart.CFrame = CFrame.lookAt(unit.HumanoidRootPart.Position, CFrame.new((waypoint.Position*Vector3.new(1,0,1))+Vector3.New(0,unit.HumanoidRootPart.Position.Y,0))

edit: made a mistake, corrected it

shouldn’t you be adding only the Y position of the root part, rather than the entire cframe of it?

i like the approach you took with the multiplication, wouldn’t think of that

no, because if the y axis of the hrp and the y axis of the waypoint were both 100, it would add to 200

1 Like

Tried and still no. The unit just dissapears and goes to 0, -100000, 0

what do you mean you removed the root part out of the loop