Making sure an NPC is facing forwards

I’m currently working on an AI for enemies in an RPG (generic, I know) but since I’m scripting everything from scratch, I don’t know how to fix this issue. I won’t post the full script because it is fairly complex and the issue is only related to how Humanoid:MoveTo() functions.

Basically when I use Humanoid:MoveTo() to move an NPC to a position 15 studs in front of the player, the NPC is not guaranteed to face the player for insert variety of reasons here.

Is there some way to make sure when using Humanoid:MoveTo() that the NPC will face the player?

3 Likes

A easy way to do this would be to manually set the CFrame of the CPU’s HumanoidRootPart.

Position = Player.Character.HumanoidRootPart.Position + Player.Character.HumanoidRootPart.CFrame.LookVector * 15
Look = Player.Character.HumanoidRootPart.Position
CPU.HumanoidRootPart.CFrame = CFrame.new(Position, Look)

This code would move the CPU 15 studs in front of the Player, and force it to look towards the Player. You could of course set the Orientation after moving, if you wanted to use MoveTo(), or use SetPrimaryPartCFrame.

1 Like

That is unfortunately exactly what I’m currently doing.

entity.Hostile:MoveTo(player.Character.HumanoidRootPart.Position + (CFrame.new(entity.HumanoidRootPart.Position, player.Character.HumanoidRootPart.Position).LookVector * entity.Attributes.Near.Value))

It doesn’t quite work since the NPC will rotate itself away from the player if the player is moving towards the NPC.

The next best solution I tried was to use BodyGyro in the Humanoid’s root to make sure the root is facing towards the player, but for some reason it has zero effect on the NPC.

if entity.HumanoidRootPart:FindFirstChild("BodyGyro") ~= nil then
    local gyro = entity.HumanoidRootPart:FindFirstChild("BodyGyro")
    gyro.CFrame = CFrame.new(entity.HumanoidRootPart.Position, player.Character.HumanoidRootPart.Position)
else
    local gyro = Instance.new("BodyGyro")
    gyro.CFrame = CFrame.new(entity.HumanoidRootPart.Position, player.Character.HumanoidRootPart.Position)
    gyro.P = 5000 --already tried many different values along with changing the maxtorque, nothing works.
    gyro.Parent = entity.HumanoidRootPart
end

So currently I’m kinda at a loss. Not sure what to do if a BodyGyro doesn’t work. If you have any ideas to fix the bodygyro/solutions in general, do reply.

1 Like

If you are attempting to make the NPC constantly menacingly face towards the Player, you could use a loop, or better a RunService connection.

RunService = game:GetService("RunService")

RunService.Stepped:Connect(function()
entity.HumanoidRootPart.CFrame = CFrame.new(entity.HumanoidRootPart.Position, player.Character.HumanoidRootPart.Position)
end)
1 Like

Turns out BodyGyro does work! I just tried every MaxTorque except the right one.

entity.Hostile:MoveTo(player.Character.HumanoidRootPart.Position + (CFrame.new(entity.HumanoidRootPart.Position, player.Character.HumanoidRootPart.Position).LookVector * entity.Attributes.Near.Value))
entity.Hostile.AutoRotate = false --[[this removes jankiness from the re-orientation, don't forget to set it back to true when done.]]

if entity.HumanoidRootPart:FindFirstChild("BodyGyro") ~= nil then
    local gyro = entity.HumanoidRootPart:FindFirstChild("BodyGyro")
    gyro.CFrame = CFrame.new(entity.HumanoidRootPart.Position, player.Character.HumanoidRootPart.Position)
else
    local gyro = Instance.new("BodyGyro")
    gyro.CFrame = CFrame.new(entity.HumanoidRootPart.Position, player.Character.HumanoidRootPart.Position)
    gyro.MaxTorque = Vector3.new(0,500000,0)
    gyro.P = 5000 --5000 looks the most natural, but increasing this improves accuracy of reorientation
    gyro.Parent = entity.HumanoidRootPart
end

I’ll leave this here for anyone who encounters a similar issue.

2 Likes