#How to make an npc head follow the player
1 messages · Page 1 of 1 (latest)
Send your code
also... just don't use chat gpt. Learn to code.
(easier) https://www.khanacademy.org/computing/computer-programming/programming
(harder) https://cs50.harvard.edu/x/2024/
I just hopped off lemme hop on again ill dend you the code
-- Get references to necessary objects
local npc = game.Workspace:WaitForChild("Quest Rig")
local npcHead = npc:WaitForChild("Head") -- Assuming the head is named "Head"
local players = game:GetService("Players")
-- Function to make NPC head look at player without moving the body
local function lookAtPlayer(player)
-- Ensure the player's character and head exist
if player.Character and player.Character:FindFirstChild("Head") then
local playerHead = player.Character.Head
-- Calculate the direction from the NPC's head to the player's head
local direction = (playerHead.Position - npcHead.Position).unit
-- Create a CFrame that only modifies the head's rotation
local lookAtCFrame = CFrame.new(npcHead.Position, playerHead.Position)
-- Only update the head's orientation (rotation), not its position
npcHead.CFrame = CFrame.new(npcHead.Position, npcHead.Position + direction)
end
end
-- Continuously update NPC's head to look at the closest player
while true do
local closestPlayer = nil
local shortestDistance = math.huge
-- Find the closest player to the NPC
for _, player in ipairs(players:GetPlayers()) do
if player.Character and player.Character:FindFirstChild("HumanoidRootPart") then
local distance = (npcHead.Position - player.Character.HumanoidRootPart.Position).Magnitude
if distance < shortestDistance then
shortestDistance = distance
closestPlayer = player
end
end
end
-- If there is a closest player, make the NPC head look at them
if closestPlayer then
lookAtPlayer(closestPlayer)
end
-- Update every 0.1 seconds
wait(0.1)
end
it gave me this
So the issue is the head is always looking away from you?
Then you need to swap the direction value in lookAtPlayer
Heres the revised code
-- Get references to necessary objects
local npc = game.Workspace:WaitForChild("Quest Rig")
local npcHead = npc:WaitForChild("Head") -- Assuming the head is named "Head"
local players = game:GetService("Players")
-- Function to make NPC head look at player without moving the body
local function lookAtPlayer(player)
-- Ensure the player's character and head exist
if player.Character and player.Character:FindFirstChild("Head") then
local playerHead = player.Character.Head
-- Calculate the direction from the NPC's head to the player's head
local direction = (npcHead.Position - playerHead.Position).unit
-- Create a CFrame that only modifies the head's rotation
local lookAtCFrame = CFrame.new(npcHead.Position, playerHead.Position)
-- Only update the head's orientation (rotation), not its position
npcHead.CFrame = CFrame.new(npcHead.Position, npcHead.Position + direction)
end
end
-- Continuously update NPC's head to look at the closest player
while true do
local closestPlayer = nil
local shortestDistance = math.huge
-- Find the closest player to the NPC
for _, player in ipairs(players:GetPlayers()) do
if player.Character and player.Character:FindFirstChild("HumanoidRootPart") then
local distance = (npcHead.Position - player.Character.HumanoidRootPart.Position).Magnitude
if distance < shortestDistance then
shortestDistance = distance
closestPlayer = player
end
end
end
-- If there is a closest player, make the NPC head look at them
if closestPlayer then
lookAtPlayer(closestPlayer)
end
-- Update every 0.1 seconds
wait(0.1)
end
Thats unusual, can you record a clip of this? My first thought is directly setting the head cframe might be doing silly things to the physics
And if you disable the script that issue still occurs?
Try setting the neck's motor 6D's C0 or C1 instead of the Head's CFrame
how do i do that im pretty new to scripting sorry
** You are now Level 3! **
i only animate and do vfx
i fixed it with this script
local char = script.Parent
local head = char:WaitForChild("Head")
local hrp = char:WaitForChild("HumanoidRootPart")
local neck = head:WaitForChild("Neck")
local xOffSet = neck.C0.X
local yOffSet = neck.C0.Y
local zOffSet = neck.C0.Z
local function getClosestPlayerHrp(dist)
local closestHrp = nil
for i, v in pairs(game.Players:GetChildren()) do
local tmpChar = v.Character or v.CharacterAdded:Wait()
local tmpHrp = tmpChar:FindFirstChild("HumanoidRootPart")
local tmpDist = (tmpHrp.Position - hrp.Position).Magnitude
if tmpHrp and tmpDist < dist then
closestHrp = tmpHrp
dist = tmpDist
end
end
return closestHrp, dist
end
while wait() do
local closestHrp, dist = getClosestPlayerHrp(50)
if closestHrp then
local dir = (closestHrp.Position - hrp.Position).Unit
local vecA = Vector2.new(hrp.CFrame.LookVector.X, hrp.CFrame.LookVector.Z)
local vecB = Vector2.new(dir.X, dir.Z)
local dotValue = vecA:Dot(vecB)
local crossValue = vecA:Cross(vecB)
local ht = hrp.Position.Y - closestHrp.Position.Y
local upAngle = math.atan(ht/dist)
local angle = math.atan2(crossValue, dotValue)
if angle > math.pi/3 then
angle = math.pi/3
elseif angle < -math.pi/3 then
angle = -math.pi/3
end
neck.C0 = CFrame.new(xOffSet, yOffSet, zOffSet)*CFrame.Angles(0, -angle, 0) *
CFrame.Angles(-upAngle, 0, 0)
end
end