Hello everyone, I created an NPC and I want his head to follow the player at a certain distance(I tried to find how to do this, but either these options were outdated or they were not the same at all.). And I don’t know how to do it. I will be very grateful for your help!
I have a script saved up (from some video I watched), it should also work for your npc if you change some things
local char = script.Parent
local hrp = char:WaitForChild("HumanoidRootPart")
local head = char:WaitForChild("Head")
local neck = head:WaitForChild("Neck")
local function findClosestsPlayerHrp(dist)
local closestHrp = nil
for i, v in pairs(game.Players:GetChildren()) do
local tChar = v.Character or v.CharacterAdded:Wait()
local tHrp = tChar:FindFirstChild("HumanoidRootPart")
if tHrp then
local tmpDist = (tHrp.Position - hrp.Position).Magnitude
if tmpDist < dist then
closestHrp = tHrp
dist = tmpDist
end
end
end
return closestHrp, dist
end
while wait() do
local closestHrp, dist = findClosestsPlayerHrp(100)
if closestHrp then
local dir = (closestHrp.Position - hrp.Position).Unit
local vecA = Vector2.new(dir.X, dir.Z)
local vecB = Vector2.new(hrp.CFrame.LookVector.X, hrp.CFrame.LookVector.Z)
local dotProd = vecA:Dot(vecB)
local crossProd = vecA:Cross(vecB)
local angle = math.atan2(crossProd, dotProd)
local ht = closestHrp.Position.Y - hrp.Position.Y
local UpDwnAngle = math.atan(ht/dist)
neck.C0 = CFrame.new(neck.C0.Position) * CFrame.Angles(0, angle, 0)
* CFrame.Angles(UpDwnAngle, 0, 0)
end
end
O, it’s you again, good to see you. Infinite yield possible on ‘Workspace.Mark.Head:WaitForChild(“Neck”)’ writes this warning
Is your NPC a R6 or R15 Character? (Using the Roblox Rig Builder)
I can’t send a short message. And my NPC in R6
Oh that’s because R6 Rigs don’t contain the Neck Motor6d, you either change it to a R15 Character or you could try add a Motor6D to the Head and make Part0 be the torso and Part1 the Head
That’s the properties of R15:
what should it look like in the script?
Nevermind, it doesn’t really work on a R6 Character, I recommend you to use R15. I will experience it to make it possible for R6, but just for now make the character R15
By the way, I have a script for moving the character’s head depending on the camera. I have a game in R6 and this script works:
local mouse = plr:GetMouse()
local char = plr.Character or plr.CharacterAdded:wait()
local hum = char:WaitForChild("Humanoid")
local isR6 = hum.RigType == Enum.HumanoidRigType.R6
local head = char:WaitForChild("Head")
local root = char.HumanoidRootPart
local torso = isR6 and char.Torso or char.UpperTorso
local neck = isR6 and torso.Neck or head.Neck
local waist = not isR6 and torso.Waist
local neckC0 = neck.C0
local waistC0 = not isR6 and waist.C0
neck.MaxVelocity = 1/3
runService.RenderStepped:Connect(function ()
if torso and head and ((isR6 and neck) or (neck and waist)) and cam.CameraSubject == hum then
local camCF = cam.CFrame
local headCF = head.CFrame
local torsoLV = torso.CFrame.lookVector
local dist = (headCF.p - camCF.p).magnitude
local diff = headCF.Y - camCF.Y
local asinDiffDist = math.asin(diff / dist)
local whateverThisDoes = ((headCF.p - camCF.p).Unit:Cross(torsoLV)).Y
if isR6 then
neck.C0 = neck.C0:lerp(neckC0 * CFrame.Angles(-1 * asinDiffDist * headVerFactor, 0, -1 * whateverThisDoes * headHorFactor), updateSpeed)
else
neck.C0 = neck.C0:lerp(neckC0 * CFrame.Angles(asinDiffDist * headVerFactor, -1 * whateverThisDoes * headHorFactor, 0), updateSpeed)
waist.C0 = waist.C0:lerp(waistC0 * CFrame.Angles(asinDiffDist * bodyVerFactor, -1 * whateverThisDoes * bodyHorFactor, 0), updateSpeed)
end
end
end)
I think this should be ok? No Motor 6d is needed and should be compatible with R6
local char = script.Parent
local hrp = char:WaitForChild("HumanoidRootPart")
local head = char:WaitForChild("Head")
local function findClosestsPlayerHrp(dist)
local closestHrp = nil
for i, v in pairs(game.Players:GetChildren()) do
local tChar = v.Character or v.CharacterAdded:Wait()
local tHrp = tChar:FindFirstChild("HumanoidRootPart")
if tHrp then
local tmpDist = (tHrp.Position - hrp.Position).Magnitude
if tmpDist < dist then
closestHrp = tHrp
dist = tmpDist
end
end
end
return closestHrp, dist
end
while wait() do
local closestHrp, dist = findClosestsPlayerHrp(100)
if closestHrp then
local dir = (closestHrp.Position - hrp.Position).Unit
local vecA = Vector2.new(dir.X, dir.Z)
local vecB = Vector2.new(hrp.CFrame.LookVector.X, hrp.CFrame.LookVector.Z)
local dotProd = vecA:Dot(vecB)
local crossProd = vecA:Cross(vecB)
local angle = math.atan2(crossProd, dotProd)
local ht = closestHrp.Position.Y - hrp.Position.Y
local UpDwnAngle = math.atan(ht/dist)
head.CFrame = CFrame.new(head.Position) * CFrame.Angles(0, angle, 0)
* CFrame.Angles(UpDwnAngle, 0, 0)
if head.Orientation.Y >= 101 or head.Orientation.Y <= -101 then
head.Orientation = Vector3.new(0,0,0) -- this returns to the front, so it doesn't turn 360°
end
end
end
Sorry for the late answer. I couldn’t insert the video due to an error, but I can explain. The NPC’s body twitches very much, so he goes somewhere (He has animation if anything)
Could you upload the model and send it into here? So I can investigate it
Sorry for the stupid question, but how to export a model to rbxm format? Otherwise, the model is exported in obj format
You could send the model via the roblox page.
That link, paste that over here
Wait no I am stupid, uhm basically do this that how you can do .rbxm
And just make a name and paste it onto here
Sorry for the confusion
So you said you made an animation for the guy, right?
That’s right. I made this animation.
If you have any type of Head movement, it always tries to continue the animation but since the script is running it twitches weirdly. I suggest you go into animation editor and remove all head keyframes and insert the new animation. Hopefully this helps!