Help with NPC 2D Turning

I have a LocalScript that makes the npc SnapTurn/2D turn, but it requires the npc’s MoveDirection.
What would I replace the MoveDirection with to make this work?

wait(2)
local char = script.Parent
local Humanoid = char:WaitForChild("Humanoid")
local HRP = char:WaitForChild("HumanoidRootPart")
Humanoid:GetPropertyChangedSignal('MoveDirection'):Connect(function()
	if Humanoid.MoveDirection.X > .1 then
		HRP.CFrame = CFrame.new(HRP.CFrame.p, Vector3.new(HRP.CFrame.p.X + 2, HRP.CFrame.p.Y, HRP.CFrame.p.Z))
	elseif Humanoid.MoveDirection.X < -.1 then
		HRP.CFrame = CFrame.new(HRP.CFrame.p, Vector3.new(HRP.CFrame.p.X - 2, HRP.CFrame.p.Y, HRP.CFrame.p.Z))
	end 
end)
3 Likes

I didn’t get it, what are trying to make exactly can you clear you idea a little bit more?

You can use Velocity property. As far as i know, it is deprecated but it will help you to get direction of the NPC.

Instead of the normal turning I want it to turn 90 degrees every time the npc turns around.
Like this:
robloxapp-20230707-1711491.wmv (1.1 MB)

Well this is not easy how it looks but it’s not impossible :sweat_smile:, to achive this you will have to edit the PlayerModule script itself to make the player move only on the axis, here is a few steps how to do that:

  1. Run the game and copy the PlayerModule script inside of PlayerScripts.
  2. Stop the game and paste the script inside of StarterPlayerScripts.
  3. Expand the PlayerModule and look for ControlModule.
  4. Open ControlModule and go to the line 412 and add this code:
local function SnapToAxis(vec)
	local lx = math.abs(vec.X)
	local ly = math.abs(vec.Y)
	local lz = math.abs(vec.Z)

	if (lx > ly and lx > lz) then
		return Vector3.new(math.sign(vec.X), 0, 0);
	elseif (ly > lx and ly > lz) then
		return Vector3.new(0, math.sign(vec.Y), 0);
	else
		return Vector3.new(0, 0, math.sign(vec.Z));
	end
end

moveVector = SnapToAxis(moveVector)

or you can skip all of this steps and download this already edited model
PlayerModule.rbxm (123.9 KB) and add it to your game by:

  1. Right click on the StarterPlayerScripts.
  2. Click Insert from File…
  3. Choose the PlayerModule.rbxm that you download.

that’s should be it, by the way if you don’t want your character to trun smoothly you can add this script to the StarterCharacterScripts:

local char = script.Parent
local hum = char:WaitForChild("Humanoid")
local hrp = char:WaitForChild("HumanoidRootPart")

hum.AutoRotate = false -- Disable the automatic rotation of the humanoid

hum:GetPropertyChangedSignal('MoveDirection'):Connect(function()
	if hum.MoveDirection.X > .1 then
		hrp.CFrame = CFrame.new(hrp.CFrame.p, Vector3.new(hrp.CFrame.p.X + 2, hrp.CFrame.p.Y, hrp.CFrame.p.Z))
	elseif hum.MoveDirection.X < -.1 then
		hrp.CFrame = CFrame.new(hrp.CFrame.p, Vector3.new(hrp.CFrame.p.X - 2, hrp.CFrame.p.Y, hrp.CFrame.p.Z))
	elseif hum.MoveDirection.Z > .1 then
		hrp.CFrame = CFrame.new(hrp.CFrame.p, Vector3.new(hrp.CFrame.p.X, hrp.CFrame.p.Y, hrp.CFrame.p.Z + 2))
	elseif hum.MoveDirection.Z < -.1 then
		hrp.CFrame = CFrame.new(hrp.CFrame.p, Vector3.new(hrp.CFrame.p.X, hrp.CFrame.p.Y, hrp.CFrame.p.Z - 2))
	end 
end)

that will disable the default rotation of the character and make it rotate as the video you sent, hope that helps you and sorry for the detailed steps.

2 Likes

It works but, how would i do this to an npc?

1 Like

NPC’s are not like players, you move them using scripts so you can easily move them on the axis, here is a simple function that can help you do that:

function MoveToDirection(npc:Model,direction:Vector3)
	
	local Humanoid = npc:FindFirstChild("Humanoid")
	local HumanoidRootPart = npc:FindFirstChild("HumanoidRootPart")
	
	if Humanoid and HumanoidRootPart then
		
		local lx = math.abs(direction.X)
		local ly = math.abs(direction.Y)
		local lz = math.abs(direction.Z)
		
		local distination
		
		if (lx > ly and lx > lz) then
			distination = HumanoidRootPart.CFrame.Position + Vector3.new(direction.X, 0, 0);
		elseif (ly > lx and ly > lz) then
			distination = HumanoidRootPart.CFrame.Position + Vector3.new(0, direction.Y, 0);
		else
			distination = HumanoidRootPart.CFrame.Position + Vector3.new(0, 0, direction.Z);
		end
		Humanoid:MoveTo(distination)
		return Humanoid.MoveToFinished
	end

end

--We can now move the npc to any direction using this function like this:
local NPC = game.Workspace.Rig

--To make the NPC move left 15 std.
local leftDirection = Vector3.new(15,0,0)
MoveToDirection(NPC,leftDirection):Wait()

--To make the NPC move forward 50 std.
local forwardDirection = Vector3.new(0,0,50)
MoveToDirection(NPC,leftDirection):Wait()

--To make the NPC move right 20 std.
local rightDirection = Vector3.new(-20,0,0)
MoveToDirection(NPC,leftDirection):Wait()

--To make the NPC move backward 70 std.
local backwardDirection = Vector3.new(0,0,-70)
MoveToDirection(NPC,leftDirection):Wait()

again, if you don’t want the NPC to turn smoothly you can use this function instead:

function MoveToDirection(npc:Model,direction:Vector3)
	
	local Humanoid = npc:FindFirstChild("Humanoid")
	local HumanoidRootPart = npc:FindFirstChild("HumanoidRootPart")
	
	if Humanoid and HumanoidRootPart then
		
		local lx = math.abs(direction.X)
		local ly = math.abs(direction.Y)
		local lz = math.abs(direction.Z)
		
		local distination
		
		if (lx > ly and lx > lz) then
			distination = HumanoidRootPart.CFrame.Position + Vector3.new(direction.X, 0, 0);
		elseif (ly > lx and ly > lz) then
			distination = HumanoidRootPart.CFrame.Position + Vector3.new(0, direction.Y, 0);
		else
			distination = HumanoidRootPart.CFrame.Position + Vector3.new(0, 0, direction.Z);
		end
		
		if direction.X > .1 then
			HumanoidRootPart.CFrame = CFrame.new(HumanoidRootPart.CFrame.p, distination)
		elseif direction.X < -.1 then
			HumanoidRootPart.CFrame = CFrame.new(HumanoidRootPart.CFrame.p, distination)
		elseif direction.Z > .1 then
			HumanoidRootPart.CFrame = CFrame.new(HumanoidRootPart.CFrame.p, distination)
		elseif direction.Z < -.1 then
			HumanoidRootPart.CFrame = CFrame.new(HumanoidRootPart.CFrame.p, distination)
		end 
		
		Humanoid:MoveTo(distination)
		return Humanoid.MoveToFinished
	end

end

please if this does not solve your problem do not close this topic, I will be happy to help.

1 Like

Where would I put this script in?

1 Like

that’s the script you should use to move the NPC, how you are moving it?

2 Likes

This is the script that moves the NPC, It make the npc chase the player:

local NPC = workspace.Enemy
NPC.PrimaryPart:SetNetworkOwner(nil)

local pfs = game:GetService("PathfindingService") -- Pathfinding service
local runService = game:GetService("RunService")

local hum = script.Parent:WaitForChild("Humanoid") -- npc humanoid
local torso = script.Parent:WaitForChild("HumanoidRootPart") -- npc torso


local players = game:GetService("Players")
local distance
local closestPlayer, closestDistance = nil, math.huge


function checkPlayerDistance() -- Function will loop through the players and get the nearest player
	local children = players:GetChildren()

	for i,v in pairs(children) do
		if v then
			distance = (v.Character:FindFirstChild("HumanoidRootPart").Position - torso.Position).magnitude

			if distance <= closestDistance then
				closestDistance = distance
				closestPlayer = v
			end
		end
	end

	return closestPlayer 
end

runService.Heartbeat:Connect(function() -- NPC will follow the nearest player

	local returnedPlayer = checkPlayerDistance()

	local path = pfs:CreatePath()
	path:ComputeAsync(torso.Position, returnedPlayer.Character.HumanoidRootPart.Position)

	local waypoints = path:GetWaypoints()

	local function npcStuck()
		local pos1 = torso.Position
		wait(1)
		local pos2 = torso.Position

		if (pos1 - pos2).magnitude < 1 then

		end
	end

	if waypoints and waypoints[2] then
		local pos = waypoints[2]	
		hum:MoveTo(pos.Position)
	end

	closestDistance = math.huge
end)

How would I combine the 2 scripts? Anyone’s help is appreciated

cant you use cframe to rotate the npc?

yea, but idk how I would do that

Idk if this works but this is what I would do:

Blockquote
Local x,y,z = Rootpart.CFrame:ToOrientation()
Rootpart.CFrame = Rootpart.CFrame * CFrame:FromOrientation(x, -y, z)

There are no errors but it doesn’t work

Sorry I’m not home and I just sent this from my phone, I could help when I get home

Anyone else’s help is appreciated, I’ll leave this post open until there is a solution :+1:

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.