CFrame.new() does not work when the Z axis on lookAt parameter is 0

Hi, I’m trying to rotate a dummy to look at the character’s head. I’m using CFrame.new() to rotate it, but it’s not working for some reason, Here’s my code:

RunService.RenderStepped:Connect(function()
    if dummy:FindFirstChild("HumanoidRootPart") then
        dummy.HumanoidRootPart.CFrame = CFrame.new(dummy.HumanoidRootPart.Position, Vector3.new(head.Position.X, head.Position.Y, 0))
    end

end)

A video of the dummy when I try to rotate it and with CFrame.new(dummy.HumanoidRootPart.Position, head.Position)
https://streamable.com/gfujoz

It floats when you go near it

Thanks for any help!

3 Likes

It appears to float when you get near it because the angle of attack gets exponentially tighter

1 Like

This cframe constructer has been deprecated try using CFrame.lookat

1 Like

Is there any way to fix it? If, so then please help me.

1 Like

I tried using CFrame.lookAt as well, but same result.

1 Like

This is an issue with the impossibility of having uniformly smooth tangents on a sphere.

Hairy ball theorem - Wikipedia

There is no fix for this problem and you will most likely simply need to avoid having it look directly on the Y axis. This is because .lookAt using the “up” vector to cross vectors (V3:Cross(Up)) to get the resulting matrix.

When I only do it on the Y axis, it doesn’t work:

CFrame.new(dummy.HumanoidRootPart.Position, Vector3.new(0, head.Position.Y, 0))
1 Like

Sorry, that isn’t what I said. I said avoid having the resulting CFrame face directly on the y-axis.

This is your code (which I have 0 idea why you’re not using the Z axis)

dummy.HumanoidRootPart.CFrame = CFrame.new(dummy.HumanoidRootPart.Position, Vector3.new(head.Position.X, head.Position.Y, 0))

You need to check if the direction to the target is close to parallel with the Y axis.

local target = head.Position
local dir = (target - dummy.HumanoidRootPart.Position).unit
local dot = dir:Dot(Vector3.new(0,1,0))

if (dot >= 0.9) then
	target -= Vector3.new(0,2.5,0)
elseif (dot <= 0.9) then
	target += Vector3.new(0,2.5,0)
end

dummy.HumanoidRootPart.CFrame = CFrame.lookAt(dummy.HumanoidRootPart.Position, target)
1 Like

Oh, sorry. I misunderstood your post. I’m sorry for that. Thanks for helping me, I’m trying that right now…

It’s the same result when going near the dummy.

Okay let me ask you this instead. What do you expect to happen when you get under it like this…?

Video above

I don’t want the rotation to happen like this. It’s just looking at my character right away. My code was doing the exact some job, I want something to happen like this:

I mean just Y rotation, not anything else to directly look at it.

I have 0 idea what you are trying to say and what you mean with just “Y rotation.” Also you just showed me a picture so I don’t know what I’m supposed to take from that. Do you mean just rotation around the Y axis like shown below?

This is exactly what I’m trying to say. Thanks for understanding

Change that in your code to be

Vector3.new(head.Position.X, dummy.HumanoidRootPart.Position.Y, head.Position.Z)

Trying it. Thanks for your help!!!

It is because you welded the other BodyParts to the head, or the Motor6Ds are all towards the head.
Try to apply all welds to the HumanoidRootPart, or all Motor6Ds.

(I am unsure what you are using, that is why I say both)