How would I make a model face the nearest player?

I’m attempting to make a model look at the nearest player, I’ve skimmed through a couple pages / tutorials but it doesn’t seem to work, It doesn’t have a humanoid just a humanoidrootpart, Could it work in a serverscript within the model?
Help would be appreicated!

1 Like

LocalScript, Put in StarterCharacter scripts

local player = game.Players.LocalPlayer
local char = player.Character
local hum = char:WaitForChild("Humanoid")
local hrp = char:WaitForChild("HumanoidRootPart")

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 task.wait(0.15) 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
          hrp.CFrame = hrp.CFrame + closestHrp.Position
    end
end

no comments in your code or explanations in your post?

1 Like

What would this do exactly? Since i dont want it to find other players models i want one particular model to look at the players

I read it wrong, i thought you said “Make Player see Nearest NPC” , Sorry

local player = game.Players.LocalPlayer
local char = player.Character
local hum = char:WaitForChild("Humanoid")
local hrp = char:WaitForChild("HumanoidRootPart")

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 task.wait(0.15) 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
          hrp.CFrame = hrp.CFrame + closestHrp.Position
    end
end

you can put a script inside the npc , his head will look at the nearest player

Where does it define the model since it doesn’t seem to work when I put it in the model

This

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