How to make an enemy NPC face me using CFrame

Having an enemy monster facing my character with CFrame is easy enough.

(this is how I did it):

enemy.CFrame = CFrame.lookAt(enemy.Position, character.HumanoidRootPart.Position);

However, I need the monster to face me only on the X and Z axis. I don’t want it to face my Y vector, because then this happens:

(I don’t have permissions to paste images onto DevForum, I’m not sure how to get perms but whatever. Here’s a link to the images):

https://docs.google.com/document/d/1o7YyCxJ9_HlitIBbs8k7i_n6Mmvsihghv97ux1rvuS8/edit?usp=sharing

How do I get it to not face me on the Y axis? I’ve been struggling with this for a while now and can’t seem to figure it out.

So I’m gonna assume your using the lookAt function, in that case all you need too do is change the 2nd argument which is the target, create a new vector3 without the Y position of your character

Vector3.new(character.HumanoidRoortPart.Position.X,0,character.HumanoidRootPart.Position.Z)

Nope. That doesn’t work because the closer you get to it, the more the character looks downwards.

Can I see your replaced code because that definitely should be working

Even if I do this (also, I should mention this is in a while true do loop):

enemy.CFrame = CFrame.lookAt(enemy.Position, Vector3.new(character.HumanoidRootPart.Position.X, 0, character.HumanoidRootPart.Position.Z));

It still doesn’t work. To see what I mean, look here:
https://docs.google.com/document/d/161K_w1D8wsV2vnLvPKVBdPNTdzP5UHWDq0tWnBScxZc/edit?usp=sharing

1 Like

Usually you would not set the CFrame directly every frame as you will loose physics. Humanoids automatically apply a force to stand upright.

To get around this I recommend using a constraint you want to use the new align orientation constraint. Make sure that it has enough force to rotate the character.

You can use basic trigonometry to solve for the angle that your NPC needs to look.
math.atan2(dX,dZ)
Where dX is difference in X axis and dX is difference in Z axis.

you can apply a rotation to a CFrame using CFrame.Angles or CFrame.FromOrientation. You will need to convert to radians if using the former.

SideNote: if you want the very very simple fix you can set the Y value to Humanoid.HipHeight + 1 for the NPC. If you are not on flat ground you can put th Humanoid.RootPart.Position.Y for the Y axis look at.:

enemy.CFrame = CFrame.lookAt(enemy.Position, Vector3.new(character.HumanoidRootPart.Position.X, enemy.Position.Y, character.HumanoidRootPart.Position.Z))
4 Likes

Thank you, I appreciate the answer. While I would normally be willing to do the extra work to get optimal results, I actually do need CFrame for this so the simple fix you stated worked beautifully.

Also, just curious, How’d you get the “Composer” label on your account? I see people with tags like that all the time and always wondered how they got 'em.

For information like that in the future you can refer to #forum-help

They are called flairs. To get one simply navigate to your Profile then go to Preferences. Under Account you will see a dropdown for the flairs for all groups that you have joined. If you do not see the option dropdown, you will need to join a group. On mobile you can view and join groups using the hamburger menu button in the top right.

Happy coding.