Hello reader! I am trying to make an NPC body look at the player at all times. Like if you walk around them, the will rotate like you. There are some post that also have this but none seem to work. If you need more info or know how to do this, please let me know!
You can use CFrame to do this basically do:
while wait() do
script.Parent.HumanoidRootPart.CFrame = CFrame.new(script.Parent.HumanoidRootPart.Position,Player.Character.HumanoidRootPart.Position)
end
Does not seem to be working. Do I need a certain script or does the script need to be in a certain part of the humanoid’s body?
You basically want to get the players look vector and the npcs look vector. From there compare the difference of the npcs look vector to the players look vector. From there apply an angular difference with i think its the cross product? It’s this cool cframe trick, egomoose explained it better than me
This is completely useless to do when you can literally just use CFrame.lookAt
. No need to make this overcomplicated. @CoderHusk
Hello reader! I am trying to make an NPC body look at the player at all times. Like if you walk around them, the will rotate like you. There are some post that also have this but none seem to work. If you need more info or know how to do this, please let me know!
Use CFrame.lookAt(eye, target)
where eye is the NPC’s primary part (you want to maintain it’s position) and target being the player.
Are you trying to make it locally (per each player) or the NPC to look at the nearest player?
local Player = game.Players.LocalPlayer
local NPC = workspace.Dummy -- Replace with with your NPC location
local HuamnoidRootPart = NPC.PrimaryPart
local Target = Player.Character or Player.CharacterAdded:Wait()
Target = Target:WaitForChild("HumanoidRootPart")
while wait() do
NPC:SetPrimaryPartCFrame(CFrame.lookAt(HuamnoidRootPart.Position, Target.Position * Vector3.new(1, 0, 1) + HuamnoidRootPart.Position * Vector3.new(0, 1, 0)))
end
Place this code in a local script, inside PlayerGui or StarterCharacterScripts. Make sure your NPC has “HumanoidRootPart” set as PrimaryPart.
Thanks! I’ll see what I can do
I think you can use game:GetService("RunService").RenderStepped
instead of while wait() do
Ik this is 11 months ago. Maybe put the Animate script in the NPC, could be localscript or normal script I think. Here is a random video, Making NPC look at player - Roblox Studio NPC Tutorial [READ THE DESCRIPTION OR THE PINNED COMMENT] This video makes the NPC look at you only when you are close. ONLY ON R15 so if you are using R6 you’re gonna have to change the script a bit. Make sure you NPC is named Dummy.
it doesn’t work at all, no matter what model it is. what were you trying to imply?
Hey sorry for being extremely late. But recently I made a headlook system that was designed to work very efficiently and for both players and npcs.
Here is the module source:
-- HashCollision 04/25/23
local module = {}
local tweenService = game:GetService("TweenService")
local players = game:GetService("Players")
local camera = workspace.CurrentCamera
local neck_tween_info = TweenInfo.new(1.3, Enum.EasingStyle.Exponential, Enum.EasingDirection.Out)
local neck_offset = Vector3.new(-0, 0.976, 0.061)
local poll_rate = (1 / 12)
local controller = {}
controller.__index = controller
function controller:LookTowards(direction)
local angle = CFrame.fromOrientation(math.asin(direction.Y) * 1.1, -math.asin(direction.X) * 1.1, 0) + neck_offset
if self._tween then
self._tween:Cancel()
self._tween:Destroy()
end
local tween = tweenService:Create(self._neck, neck_tween_info, {C0 = angle})
tween:Play()
self._tween = tween
self.direction = direction
end
function controller:_IdleLoop()
local lastDirection = self.direction
while self.active do
local direction = self._root.CFrame:ToObjectSpace(camera.CFrame).LookVector
if (direction - lastDirection).Magnitude > 0.05 then
lastDirection = direction
self.idle = false
self:LookTowards(direction)
else
self.idle = true
end
task.wait(poll_rate)
end
end
function module.new(character)
local newController = setmetatable({}, controller)
newController._root = character:WaitForChild("HumanoidRootPart")
newController._neck = character:WaitForChild("Head").Neck
newController.direction = Vector3.new(0, 0, 0)
newController.isLocal = players:GetPlayerFromCharacter(character) == players.LocalPlayer
newController.active = true
task.defer(function()
newController:LookTowards(Vector3.zero)
if newController.isLocal then
newController:_IdleLoop()
end
end)
return newController
end
function controller:Destroy()
table.clear(self)
setmetatable(self, nil)
end
return module
Put this code into a ModuleScript
somewhere, probably in ReplicatedStorage.
Using this module, you can create a headlook object and instruct it to look in a certain direction, which means we can write a very short script that instructs npcs to look in the players direction.
A very basic one is as follows, feel free to change it to your needs:
local controllers = require(<module here>)
-- ^ Make sure this points to the module script.
local npcFolder = workspace.NPCs
-- Folder or model or whatever of where all your npcs are.
local playerHead = script.Parent:WaitForChild("Head")
-- This variable assumes this script is under StarterCharacterScripts, you can replace this line and obtain the character your own way.
for _, npc in npcFolder:GetChildren() do
local controller = controllers.new(npc)
local head = npc.Head
-- construct an object for later use
task.spawn(function()
while task.wait(0.5) do
local direction = CFrame.lookAt(head.Position, playerHead.Position).LookVector
-- basic cframe math to compute a direction for the npc to use.
controller:LookTowards(direction)
end
end)
end
unfortunately, i am having no luck on getting this to work, I’m assuming its made for a specific model instead of any r15 character?
This is made and works for an r15 character. Are you having a specific error? I can help you track it down.
does this only work for r15? I tried doing it on a r6 model and it errored out.