function CharacterRealism.UpdateLookAngles(T,F)local r,u=T:ComputeLookAngle()T:OnLookReceive(T.Player,r,u)local V=T.LastUpdate or 0 local J=os.clock()if J-V>.5 then r=Util:RoundNearestInterval(r,.05)u=Util:RoundNearestInterval(u,.05)if r~=T.Pitch then T.Pitch=r T.Dirty=true end if u~=T.Yaw then T.Yaw=u T.Dirty=true end if T.Dirty then T.Dirty=false T.LastUpdate=J T.SetLookAngles:FireServer(r,u)end end local n=workspace.CurrentCamera local D=n.CFrame.Position local m=T.Player local N for F,r in pairs(T.Rotators)do if not F.Parent then if not N then N={}end N[F]=true continue end local u=Players:GetPlayerFromCharacter(F)local V=u and u:DistanceFromCharacter(D)or 0 if u~=m and V>30 then continue end local n=r.LastStep or 0 local Z=J-n local M=F:FindFirstChildOfClass("\072\117\109\097\110\111\105\100")local b=M and M.RootPart if not b then continue end local L=r.Pitch T:StepValue(L,Z)local c=r.Yaw T:StepValue(c,Z)local a=r.Motors r.LastStep=J if not a then continue end for T,u in pairs(T.RotationFactors)do local V=a and a[T]if not V then continue end local J=V.Motor local n=V.Origin if n then local F=J.Part0 local T=n.Parent if F and F~=T then local T=F:FindFirstChild(n.Name)if T and T:IsA("\065\116\116\097\099\104\109\101\110\116")then n=T V.Origin=T end end n=n.CFrame elseif V.C0 then n=V.C0 else continue end local D=L.Current or 0 local m=c.Current or 0 if r.SnapFirstPerson and T=="\072\101\097\100"then if FpsCamera:IsInFirstPerson()then D=L.Goal m=c.Goal end end local N=D*u.Pitch local Z=m*u.Yaw if T:sub(-4)==" \065\114\109"or T:sub(-8)=="\085\112\112\101\114\065\114\109"then local r=F:FindFirstChildOfClass("\084\111\111\108")if r and not CollectionService:HasTag(r,"\078\111\065\114\109\082\111\116\097\116\105\111\110")then if T:sub(1,5)=="\082\105\103\104\116"and b:GetRootPart()~=b then N=D*1.3 Z=m*1.3 elseif T:sub(1,4)=="\076\101\102\116"and b:GetRootPart()~=b then N=D*1 Z=m*1.5 else Z=m*.8 end end end local M=false if N~=L.Value then L.Value=N M=true end if Z~=c.Value then c.Value=Z M=true end if M then local F=n-n.Position local T=CFrame.Angles(0,N,0)*CFrame.Angles(Z,0,0)J.C0=((n*F:Inverse())*T)*F end end end if N then for F in pairs(N)do local r=T.Rotators[F]local u=r and r.Listener if u then u:Disconnect()end T.Rotators[F]=nil end end end
-- Called to update all of the look-angles being tracked
-- on the client, as well as our own client look-angles.
-- This is called during every RunService Heartbeat.

function CharacterRealism:UpdateLookAngles(delta)
	-- Update our own look-angles with no latency
	local pitch, yaw = self:ComputeLookAngle()
	self:OnLookReceive(self.Player, pitch, yaw)

	-- Submit our look-angles if they have changed enough.
	local lastUpdate = self.LastUpdate or 0
	local now = os.clock()

	if (now - lastUpdate) > 0.5 then
		pitch = Util:RoundNearestInterval(pitch, 0.05)
		yaw = Util:RoundNearestInterval(yaw, 0.05)

		if pitch ~= self.Pitch then
			self.Pitch = pitch
			self.Dirty = true
		end

		if yaw ~= self.Yaw then
			self.Yaw = yaw
			self.Dirty = true
		end

		if self.Dirty then
			self.Dirty = false
			self.LastUpdate = now
			self.SetLookAngles:FireServer(pitch, yaw)
		end
	end

	-- Update all of the character look-angles
	local camera = workspace.CurrentCamera
	local camPos = camera.CFrame.Position

	local player = self.Player
	local dropList

	for character, rotator in pairs(self.Rotators) do
		if not character.Parent then
			if not dropList then
				dropList = {}
			end

			dropList[character] = true
			continue
		end

		local owner = Players:GetPlayerFromCharacter(character)
		local dist = owner and owner:DistanceFromCharacter(camPos) or 0

		if owner ~= player and dist > 30 then
			continue
		end

		local lastStep = rotator.LastStep or 0
		local stepDelta = now - lastStep

		local humanoid = character:FindFirstChildOfClass("Humanoid")
		local rootPart = humanoid and humanoid.RootPart

		if not rootPart then
			continue
		end

		local pitchState = rotator.Pitch
		self:StepValue(pitchState, stepDelta)

		local yawState = rotator.Yaw
		self:StepValue(yawState, stepDelta)

		local motors = rotator.Motors
		rotator.LastStep = now

		if not motors then
			continue
		end

		for name, factors in pairs(self.RotationFactors) do
			local data = motors and motors[name]

			if not data then
				continue
			end

			local motor = data.Motor
			local origin = data.Origin

			if origin then
				local part0 = motor.Part0
				local setPart0 = origin.Parent

				if part0 and part0 ~= setPart0 then
					local newOrigin = part0:FindFirstChild(origin.Name)

					if newOrigin and newOrigin:IsA("Attachment") then
						origin = newOrigin
						data.Origin = newOrigin
					end
				end

				origin = origin.CFrame
			elseif data.C0 then
				origin = data.C0
			else
				continue
			end

			local pitch = pitchState.Current or 0
			local yaw = yawState.Current or 0

			if rotator.SnapFirstPerson and name == "Head" then
				if FpsCamera:IsInFirstPerson() then
					pitch = pitchState.Goal
					yaw = yawState.Goal
				end
			end

			local fPitch = pitch * factors.Pitch
			local fYaw = yaw * factors.Yaw

			-- HACK: Make the arms rotate with a tool.
			if name:sub(-4) == " Arm" or name:sub(-8) == "UpperArm" then
				local tool = character:FindFirstChildOfClass("Tool")

				if tool and not CollectionService:HasTag(tool, "NoArmRotation") then
					if name:sub(1, 5) == "Right" and rootPart:GetRootPart() ~= rootPart then
						fPitch = pitch * 1.3
						fYaw = yaw * 1.3
					elseif name:sub(1, 4) == "Left" and rootPart:GetRootPart() ~= rootPart then
						fPitch = pitch * 1
						fYaw = yaw * 1.5
					else
						fYaw = yaw * 0.8
					end
				end
			end

			local dirty = false

			if fPitch ~= pitchState.Value then
				pitchState.Value = fPitch
				dirty = true
			end

			if fYaw ~= yawState.Value then
				yawState.Value = fYaw
				dirty = true
			end

			if dirty then
				local rot = origin - origin.Position

				local cf = CFrame.Angles(0, fPitch, 0) * CFrame.Angles(fYaw, 0, 0)

				motor.C0 = origin * rot:Inverse() * cf * rot
			end
		end
	end

	-- If the dropList is declared, remove any characters that
	-- were indexed into it. This is done after iterating over
	-- the rotators to avoid problems with removing data from
	-- a table while iterating over said table.

	if dropList then
		for character in pairs(dropList) do
			local rotator = self.Rotators[character]
			local listener = rotator and rotator.Listener

			if listener then
				listener:Disconnect()
			end

			self.Rotators[character] = nil
		end
	end
end
