Is there a way to lock my NPC into only one alignment/orientation?

I’m probably typing/wording this poorly.

Anyway, I’m working on an NPC that follows the orientation of your character, as long as you are within range of its ProximityPrompt. Works pretty well, as seen here.

Only issue, it always follows the orientation of the character, even when I jump, as seen here. Used to be a lot worse before I used HumanoidRootPart to base the positions/orientation.

How do I lock my NPC’s movement to just the Y-axis and not allow it to move on the X-axis/other axes? I have tried using AlignOrientation, but that has not worked.

Here’s the code I use, for reference:

local npcPosition = dummy.HumanoidRootPart.Position
local playerPosition = char.HumanoidRootPart.Position
dummy.HumanoidRootPart.CFrame = CFrame.new(npcPosition, playerPosition)

This is a little tough, but maybe you could lock it to the X-axis/Z-axis by just plugging in those coordinates… as seen below! :wink:

Let me know if it errors or you need any more help!

Revised alignPosition Function
local npcPosition = dummy.HumanoidRootPart.Position
local playerPosition = char.HumanoidRootPart.Position
dummy.HumanoidRootPart.CFrame = CFrame.new(npcPosition, (Vector3.new(playerPosition.X, 0, playerPosition.Z)))```

Unfortunately, that made the issue worse, as seen here.

If you check my now quoted(and revised!) code, I have added a solution I just tested in studio.

Now, all I did was add a 4 in place for the component of a Y-axis position, which I think is inefficient and overall lazy coding on my end… However! It does provide a solution to the problem at hand.

Let me know if you need any help or there are any errors on your end! :wink:

1 Like

Now it works!

Only issue is, the closer you get to the NPC, and even standing on said NPC, his orientation gets out of whack. Not sure what I can do about that

Maybe calculate the magnitude between the player and the NPC since you already have both positions, and then make the Y-axis component in the snippet I sent earlier scale based on the distance between them?

For example, the NPC will stand straight up if it’s farther than 4 studs away, otherwise the Y-axis component will gradually fall off or rise to compensate for the players distance.

That is, if I’m identifying the problem correctly (which if I’m not, sorry!).

Let me know how it goes and if you need any other help, and I’ll be sure to respond if I figure out any other solutions in the meantime. :wink: Best of luck!

Can you send me exactly what code is running, though? In my studio the NPC stood straight up no matter where the character was…

The following code is running in a LocalScript on the client.

local animation = script:WaitForChild("Wave",2)
local player = game.Players.LocalPlayer
local char = player.Character or player.CharacterAdded:Wait()

for _,child in next,workspace:GetChildren() do
	if child.Name == "Dummy" then
		local near = false
		local function moveIt()
			local dummy = child
			while near == true do
				local npcPosition = dummy.HumanoidRootPart.Position
				local playerPosition = char.HumanoidRootPart.Position
				dummy.HumanoidRootPart.CFrame = CFrame.new(npcPosition, (Vector3.new(playerPosition.X, 4, playerPosition.Z)))
				task.wait(0.1)
			end	
		end
		local prox = child.Head:WaitForChild("ProximityPrompt",3)
		if prox ~= nil then
			local playIt = child.Humanoid:LoadAnimation(animation)
			prox.PromptShown:Connect(function()
				near = true
				task.spawn(moveIt)
				playIt:Play()
				playIt.Looped = true
				prox.PromptHidden:Wait()
				near = false
				playIt:Stop()
			end)
		end
	end
end

I know it isn’t the greatest, especially the while do loop, which I will be converting to RunService soon, I just quickly made this script and ran with it as it worked. In either case, the loop is constantly adjusting the position/orientation of the NPC to the player’s position.

So I had used the moveIt() function on an R6 Model and not an R15 Model, so that could possibly be causing issues on my end. Don’t see why, though.

Honestly, I’m a bit stumped given it’s working just fine for me in studio, however, what I would recommend is that you experiment a lot-- move around values, change your methods, take new approaches, etc.!

It is getting a bit late for me but let me know if anything new pops up or if you have any new ideas, I’d love to help you flesh them out. Best of luck, though, John! :wink:

1 Like

I appreciate the help!

I asked a developer friend of mine, and the code/edits he gave worked. Here’s the code:

local animation = script:WaitForChild("Wave",2)
local player = game.Players.LocalPlayer
local char = player.Character or player.CharacterAdded:Wait()
local rs = game:GetService("RunService")
local chars = {}

rs.Stepped:Connect(function(Time, deltaTime)
	
end)

for _,child in next,workspace:GetChildren() do
	if child.Name == "Dummy" then
		local near = false
		local _,Y = child.HumanoidRootPart.CFrame:ToOrientation();
		local Align = CFrame.Angles(0,Y,0);
		local function moveIt()
			local dummy = child
			while near == true do
				local npcPosition = dummy.HumanoidRootPart.Position
				local playerPosition = char.HumanoidRootPart.Position
				local _,Y = CFrame.new(npcPosition,playerPosition):ToOrientation();
				dummy.HumanoidRootPart.CFrame = CFrame.Angles(0,Y,0)+npcPosition;
				task.wait(0.1)
			end	
		end
		local prox = child.Head:WaitForChild("ProximityPrompt",3)
		if prox ~= nil then
			local playIt = child.Humanoid:LoadAnimation(animation)
			prox.PromptShown:Connect(function()
				near = true
				task.spawn(moveIt)
				playIt:Play()
				playIt.Looped = true
				prox.PromptHidden:Wait()
				near = false
				playIt:Stop()
			end)
		end
	end
end

Have a good night!

1 Like

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