Currently I’m trying to make it so an NPC will always look at a player, even while moving.
How I’m trying to do it now is having a part constantly teleport and look at the player and use allignorientation between the NPC and the block, however this is what has ended up happening to the block that is supposed to be following and looking at the player.
It doesn’t move from this position.
If I remove the CFrame.LookAt part of the code, it’ll teleport to me fine.
I have both the block and the script that teleports the block parented to the player.
Here is the script that teleports, it is disabled be default and parented to the script under this one.
local following = script.Parent.HumanoidRootPart
local block = script.Parent:FindFirstChild("TheGuy")
while true do
block.Position = following.Position
wait(.5)
end
Here is the relevant part of the script that gives the script and block, note that it is parented to the NPC.
if blockfollowing == false then
blockfollowing = true
local block = Instance.new("Part")
block.Transparency = 0
block.CanCollide = false
block.Name = ("TheGuy")
block.Parent = target.Parent
block.Anchored = true
local scr = script.childscript:Clone()
scr.Parent = target.Parent
scr.Enabled = true
end
And here is the full NPC script.
local larm = script.Parent:FindFirstChild("HumanoidRootPart")
local rarm = script.Parent:FindFirstChild("HumanoidRootPart")
function findNearestTorso(pos)
local list = game.Workspace:children()
local torso = nil
local dist = 10000
local temp = nil
local human = nil
local temp2 = nil
for x = 1, #list do
temp2 = list[x]
if (temp2.className == "Model") and (temp2 ~= script.Parent) then
temp = temp2:findFirstChild("HumanoidRootPart")
human = temp2:findFirstChild("Humanoid")
if (temp ~= nil) and (human ~= nil) and (human.Health > 0) and game.Players:GetPlayerFromCharacter(human.Parent) then
if (temp.Position - pos).magnitude < dist then
torso = temp
dist = (temp.Position - pos).magnitude
end
end
end
end
return torso
end
local blockfollowing = false
while true do
wait(.5)
local target = findNearestTorso(script.Parent.HumanoidRootPart.Position)
if target ~= nil then
if blockfollowing == false then
blockfollowing = true
local block = Instance.new("Part")
block.Transparency = 0
block.CanCollide = false
block.Name = ("TheGuy")
block.Parent = target.Parent
block.Anchored = true
local scr = script.childscript:Clone()
scr.Parent = target.Parent
scr.Enabled = true
end
script.Parent.Humanoid:MoveTo(target.Position - Vector3.new(5,5,5))
script.Parent.HumanoidRootPart.AlignOrientation.Enabled = true
end
end
Whats happening is when setting cf.lookat it sets the cf to be its current cf with new angles, this means when teleporting you have 2 lots of cf positions which buggs out your script. Ideally you need a way of stopping the lookat while its teleporting, this would have no effect at stopping the lookat effect as you can still teleport and make it face where you want
Note that both the Position and LookAt parameters are the same exact location. When this happens the position usually sets to what your screenshots show. To fix this, you must make sure you are passing two different vector positions. What I recommend is adding the LookVector of the player being followed to the position parameter as shown below:
local following = script.Parent.HumanoidRootPart
local block = script.Parent:FindFirstChild("TheGuy")
while true do
local look = following.CFrame.LookVector
block.CFrame = CFrame.LookAt(following.Position + look, following.Position)
wait(.5)
end
I believe there are simpler options to create what you are hoping for, but this should fix the problem you were having setting the CFrame of the part.
I typed this outside of studio so let me know if there are any bugs!
I might have misspoken when I said simpler. It’s more complicated math wise, but in the end is more efficient and easier to handle.
I would get rid of the whole concept of using a teleporting part to align the NPC and instead get the direction from the NPC to the player using vector math.
NOTE before removing any of your code I would first make sure that what i suggest works
But I would recomend replacing your while true loop within the main script with this:
while true do
wait(.5)
local target = findNearestTorso(script.Parent.HumanoidRootPart.Position)
if target ~= nil then
local targetCFrame = target.CFrame
local NPCRoot = script.Parent.HumanoidRootPart
local NPCFrame = NPCRoot.CFrame
local direction = targetCFrame.Position - NPCFrame.Position -- getting direction from npc to player
local xzDirectionUnit = Vector3.new(direction.X, 0, direction.Z).Unit
script.Parent.Humanoid:MoveTo(target.Position - (xzDirectionUnit * 5))
NPCRoot.CFrame = CFrame.lookAt(NPCFrame.Position, NPCFrame.Position + xzDirectionUnit)
end
end
I think this should work the way you intended it to without the need of a block. However, I am not able to test it myself. If it doesn’t work, I would ignore this for now and continue with your method.
This is what I tried and it worked, however the NPC won’t move after moving a single time it’s the same issue I had when I tried it, thank you for the help though!