How Does This Script Work?

So i was trying to dissect this script to see how it works and I just dont understand how LookAtPlayerDistance is incorporated. If I change the distance’s number it changes to that number but I dont see the script take it into effect but it somehow does? can someone explain?

local Players = game:GetService("Players")


local LookAtPlayerDistance = 30 -- Studs between player and dummy that dummy can look.

local HeadHorFactor = 0.8
local HeadVertFactor = 0.4
local BodyHorFactor = 0.4
local BodyVertFactor = 0.2

local UpdateSpeed = 0.2 -- How fast the body rotates.


local NPC = script.Parent
local Head = NPC.Head
local Neck = Head.Neck
local Trso = NPC.UpperTorso
local Waist = Trso.Waist


local Ang = CFrame.Angles
local aTan = math.atan

local NeckOrgnC0 = Neck.C0
local WaistOrgnC0 = Waist.C0

function getClosestPlayer()
	local closest_player, closest_distance = nil, LookAtPlayerDistance
	for i, player in pairs(workspace:GetChildren()) do
		if player:FindFirstChild("Humanoid") and player ~= NPC and Players:GetPlayerFromCharacter(player) then
			local distance = (NPC.PrimaryPart.Position - player.PrimaryPart.Position).Magnitude
			if distance < closest_distance then
				closest_player = player
				closest_distance = distance
			end
		end
	end
	return closest_player
end

function rWait(n)
	n = n or 0.05
	local startTime = os.clock()

	while os.clock() - startTime < n do
		game:GetService("RunService").Heartbeat:Wait()
	end
end

game:GetService("RunService").Heartbeat:Connect(function()
	rWait()
	local TrsoLV = Trso.CFrame.lookVector
	local HdPos = Head.CFrame.p
	local player = getClosestPlayer()
	if player then
		local is_in_front = NPC.PrimaryPart.CFrame:ToObjectSpace(player.Head.CFrame).Z < 0
		print(player)
		if is_in_front then
			local Dist = (Head.CFrame.p-player.Head.CFrame.p).magnitude
			local Diff = Head.CFrame.Y-player.Head.CFrame.Y
			
			local unit = -(NPC.PrimaryPart.CFrame.p - player.Head.Position).unit
			
			Neck.C0 = Neck.C0:lerp(NeckOrgnC0*Ang(-(aTan(Diff/Dist)*HeadVertFactor), (((HdPos-player.Head.CFrame.p).Unit):Cross(TrsoLV)).Y*HeadHorFactor, 0), UpdateSpeed/2)
			Waist.C0 = Waist.C0:lerp(WaistOrgnC0*Ang(-(aTan(Diff/Dist)*BodyVertFactor), (((HdPos-player.Head.CFrame.p).Unit):Cross(TrsoLV)).Y*BodyHorFactor, 0), UpdateSpeed/2)
		else
			Neck.C0 = Neck.C0:lerp(NeckOrgnC0, UpdateSpeed/2)
			Waist.C0 = Waist.C0:lerp(WaistOrgnC0, UpdateSpeed/2)
		end
	else
		Neck.C0 = Neck.C0:lerp(NeckOrgnC0, UpdateSpeed/2)
		Waist.C0 = Waist.C0:lerp(WaistOrgnC0, UpdateSpeed/2)
	end
end)

As far as I can tell, LookAtPlayerDistance is defined as 30, then declared again in the getClosestPlayer() function, and never referenced again.
Perhaps the programmer forgot to take it out, as it seems to have no real usage.

I would say its useless but if its deleted it gives this

LookAtPlayerDistance variable in your script is used as a threshold to determine the maximum distance at which the NPC will react to a player. It is currently set to 30 studs.

In the getClosestPlayer function, closest_distance is initially set to the value of LookAtPlayerDistance . This means that any player farther away than this distance will be ignored.

So closest_distance basically turns into LookAtPlayerDistance which is 30 studs? Do you know why they wrote it like this? Because I had never seen this before.

It’s common practice actually, it sets it as LookAtPlayerDistance to reset the variable.

As it iterates through players, if it finds a player closer than this radius, it updates closest_distance to this new smaller distance. This way, the script only considers players within the set radius and efficiently finds the closest one.

The script appears to define a humanoid NPC (Non-Player Character) that looks at the closest player within a specified distance (LookAtPlayerDistance). The getClosestPlayer function calculates the distance between the NPC and each player in the workspace, selecting the closest one.

If a player is found within the defined distance, the script adjusts the orientation (C0 values) of the NPC’s neck and waist to face the player. The adjustment is based on the relative positions of the NPC’s head and the player’s head.

The is_in_front variable checks if the player is in front of the NPC, and if true, it calculates the angles (Diff and Dist) and adjusts the orientation accordingly using the lerp function. The HeadHorFactor, HeadVertFactor, BodyHorFactor, and BodyVertFactor are factors that determine how much the NPC should rotate its head and waist.

If no player is within the specified distance, or if the closest player is not in front of the NPC, the script gradually resets the orientation to the original position.

If changing LookAtPlayerDistance seems to have an effect but you’re having trouble understanding how it works precisely, you might want to focus on how the angles and orientation adjustments are calculated based on the player’s position relative to the NPC. Pay attention to the trigonometric functions (aTan) and how they affect the rotation angles.

This really helps with other stuff, and thanks I will search about aTan. Is it true that the way he wrote it resets the closest_distance variable tho? Thanks btw!

ohhh if this is true then Thank You! This is what was bothering me. Im going to try and test this to see if it works for me!

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.