How to make an npc turn to the nearest player?

Hello. I’m making a bot system like in shooters and I ran into a problem. When the bot shoots, it is sometimes turned in the opposite direction and may not look at the player at all. To make it clearer, I will attach a video.

3 Likes

Provide code please! We can not help without code.

local function BotLogic()
Target = FindNearestPlayer(BRootPart.Position)

if not Target then
	MoveToClosestPoint()
else
	local TCharacter = Target.Character
	local THumanoid = TCharacter and TCharacter:FindFirstChild("Humanoid")
	local TRootPart = TCharacter and TCharacter:FindFirstChild("HumanoidRootPart")

	if not (TRootPart and THumanoid and THumanoid.Health > 0) then
		Target = nil
	else
		local TDistance = (BRootPart.Position - TRootPart.Position).Magnitude

		if TDistance <= AttackDistance then
			if BPath.Status == "Active" then
				BPath:Stop()
			end

			if THumanoid and tick() - LastAttack > AttackWait then
				LastAttack = tick()
				THumanoid:TakeDamage(Damage)
				AttackTrack:Play()
				CreateFireEffect()
			end
		else
			local SDistance = (BRootPart.Position - BStartPosition).Magnitude

			if TDistance > TargetDistance or SDistance >= StopDistance then
				Target = nil
			else
				BPath:Run(TRootPart.Position)
			end
		end
	end
	Moving = nil
end

end

local function FindNearestPlayer(Position)
local NearestPlayer = nil
local Dist = TargetDistance
MostDrive()
for _, Player in pairs(Players:GetChildren()) do
local TCharacter = Player.Character
local TRootPart = TCharacter and TCharacter:FindFirstChild(“HumanoidRootPart”)

	if TRootPart then
		local TDistance = (Position - TRootPart.Position).Magnitude
		local SDistance = (TRootPart.Position - BStartPosition).Magnitude
		
		if TDistance < Dist and SDistance < StopDistance then
			NearestPlayer = Player
			Dist = TDistance
		end
	end
end
return NearestPlayer

end

This is the nearest player detection feature if needed.

So will you help me with my problem?

Use CFrame:LookAt() (CFrame | Documentation - Roblox Creator Hub) with the current bot CFrame and the CFrame of the nearest player. Then, every time the FindNearestPlayer() function runs, reupdate this CFrame value, and set the bot’s HumanoidRootPart CFrame to match that of CFrame:LookAt().

Okay, now I’ll try and write it solved my problem

And how can I arrange it approximately?

local function FindNearestPlayer(Position)
local NearestPlayer = nil
local Dist = TargetDistance
MostDrive()
for _, Player in pairs(Players:GetChildren()) do
local TCharacter = Player.Character
local TRootPart = TCharacter and TCharacter:FindFirstChild(“HumanoidRootPart”)
	if TRootPart then
		local TDistance = (Position - TRootPart.Position).Magnitude
		local SDistance = (TRootPart.Position - BStartPosition).Magnitude
		
		if TDistance < Dist and SDistance < StopDistance then
			NearestPlayer = Player
			Dist = TDistance
		end

        --find the cframe:lookat
        local lookat = CFrame:lookAt([POSITION OF DUMMY], TRootPart.Position) --replace position of dummy with the pointer to the position
        [DUMMY].CFrame = lookat --you can do this or you can use TweenService or Lerp to smoothly move between angles.
        --replace dummy with your dummy variable
	end
end
return NearestPlayer

This is the alternate FindNearestPlayer() function.

Hope this helped!

1 Like

It constantly throws the same error invalid argument #1 to ‘lookAt’ (Vector3 expected, got table).

Replace [POSITION OF DUMMY] with the actual position of the dummy, don’t just write [POSITION OF DUMMY]

attempt to call missing method ‘LoockAt’ of table

I have a BHumanoidRootPart. I’ll attach a photo if I can.
Снимок экрана 2024-06-19 184822

You misspelled “LookAt”. You have it as “LoockAt”.

I did it! You just need to write like this local lookat = CFrame.lookAt. Separated by a dot, not a colon. Thanks for the help!!

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