You can write your topic however you want, but you need to answer these questions:
What do you want to achieve? Keep it simple and clear!
I would like to make a NPC rotate his head to face the player whenever it’s nearby.
What is the issue? Include screenshots / videos if possible!
I’m unable to figure out how to do this. I have tried a script I previously made however it doesn’t function.
What solutions have you tried so far? Did you look for solutions on the Developer Hub?
Using Old Scripts.
After that, you should include more details if you have any. Try to make your topic as descriptive as possible, so that it’s easier for people to help you!
--
local ShopCharacter = game.Workspace.ShopGuy
local function GetDistance()
local Character = game.Players.LocalPlayer.Character
local magnitude_distance = (Character.PrimaryPart.Position - game.Workspace.ShopGuy.PrimaryPart.Position).Magnitude
return magnitude_distance
end
while true do
if GetDistance() <= 6 then
local is_in_front = game.Workspace.ShopGuy.PrimaryPart.CFrame:ToObjectSpace(game.Players.LocalPlayer.Character.PrimaryPart.CFrame).Z < 0
if is_in_front then
local unit = (game.Workspace.ShopGuy.PrimaryPart.CFrame.Position - game.Players.LocalPlayer.Character.PrimaryPart.Position).unit
game.Workspace.ShopGuy.Head.Neck.C0 = game.Workspace.ShopGuy.Head.Neck.C0 * CFrame.new(Vector3.new(0, 0, 0), unit) * CFrame.Angles(0, -math.rad(game.Workspace.ShopGuy.PrimaryPart.Orientation.Y), 0)
end
end
wait()
I would like to be local and only activate if they are nearby and within 6 studs.
You could either use a hitbox that represents its distance, have some raycasts at the character’s eye-level. OR, you could just simply do some mathematics to get the right values for the CFrame angles. In this case, I do just that.
I know you’d like the script to be local. But, if you’re wanting the ShopGuy’s head to be seen by the rest of the players, then you’d want the script to be server-sided.
local RunService = game:GetService("RunService")
local Player = game.Players.LocalPlayer
local ShopGuy = workspace.ShopGuy
local Character = Player.Character or Player.CharacterAdded:Wait()
local IsR15 = ShopGuy.Humanoid.RigType == Enum.HumanoidRigType.R15
local SG_Head = ShopGuy.Head
local SG_HRP = ShopGuy.HumanoidRootPart
local SG_Torso = ShopGuy:WaitForChild("Torso") or ShopGuy:WaitForChild("UpperTorso")
local SG_Neck = SG_Torso.Neck::Motor6D
local SG_Waist = IsR15 and SG_Torso:WaitForChild("Waist")::Motor6D
local HumanoidRootPart = Character.PrimaryPart
local Head = Character:WaitForChild("Head")::BasePart
local SG_OGNeckC0 = SG_Neck.C0
local SG_OGWaistC0 = IsR15 and SG_Waist.C0
local SG_OGHeadCFrame = SG_Head.CFrame
local sightDistance = 6 -- Maximum bertical sight distance.
local LimitFactors = { -- Head limitations, giving it a realistic feel. Anything above 1 will make the movement realistically impossible
Horizontal = 0.7,
Vertical = 0.6
}
local lookLerpTime = 0.4
local restLerpTime = 0.15
--while task.wait() do <- actually, instead, use RunService.Heartbeat:Wait()
while true do
local HeadPos = SG_Head.CFrame.Position
local HRP_Pos = SG_HRP.CFrame.Position
local TorsoLV = ShopGuy.Torso.CFrame.LookVector
local Distance = (SG_Head.CFrame.Position - Head.CFrame.Position).Magnitude
local inFrontOf = SG_HRP.CFrame:PointToObjectSpace(Head.CFrame.Position).Z < 0
and Distance <= sightDistance
if inFrontOf then
local Difference = SG_Head.CFrame.Position.Y - Head.CFrame.Position.Y
local calcX = math.atan(Difference/Distance) * LimitFactors.Vertical
local calcZ = (HRP_Pos - Head.CFrame.Position).Unit:Cross(TorsoLV).Y * LimitFactors.Horizontal
if IsR15 then
SG_Neck.C0 = SG_Neck.C0:Lerp(SG_OGNeckC0 * CFrame.Angles(-calcX, calcZ, 0), lookLerpTime)
SG_Waist.C0 = SG_Waist.C0:Lerp(SG_OGWaistC0 * CFrame.Angles(-calcX, calcZ, 0), lookLerpTime)
else
SG_Neck.C0 = SG_Neck.C0:Lerp(SG_OGNeckC0 * CFrame.Angles(calcX, 0, calcZ), lookLerpTime)
end
else
if IsR15 then
SG_Neck.C0 = SG_Neck.C0:Lerp(SG_OGNeckC0, lookLerpTime/2)
SG_Waist.C0 = SG_Waist.C0:Lerp(SG_OGWaistC0, lookLerpTime/2)
else
SG_Neck.C0 = SG_Neck.C0:Lerp(SG_OGNeckC0, lookLerpTime/2)
end
end
RunService.Heartbeat:Wait()
end