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)
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!
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. Best of luck!
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!
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