You can ignore certain axis of rotation by changing the lookvector of the CFrame. For example, you could multiply that last vector by Vector3.new(1,0,1) and that would cause the part to ignore changes on the Y axis as it moves. Though since you are using position rather than look direction here, you may also need to add back the vector as a constant + Vector3.new(0,Eye.Position.Y,0)
You have to make sure one particular axis is exactly the same(in this case, the blue axis, which I think is the z axis). Make sure both values are the same, this should theoretically not make it flip.
Another option is to use math.clamp to clap the axis.
So the reason this happens is because that CFrame constructor has to make some assumptions in order to properly function.
The biggest of those assumptions is that the unit direction vector between your eye and goal is not Vector3.new(0, 1, 0). If it is, then it snaps to a default rotation and I can assure you that looks worse/more abrupt than what you’re showing in your video. You can see if you are able to get the goal postion EXACTLY above the eye position.
If you want to have it work as described you’re going to need to do some math.
The trick is to adjust by the rotational delta of the current look vector and the desired look vector. I have discussed how to do this before as found in this post. I have purposefully not included the function in the code snippet below because I want you to actually read the post I just linked.
local UNIT_X = Vector3.new(1, 0, 0)
local UNIT_Z = Vector3.new(0, 0, 1)
local eyePart = workspace.EyePart
local goalPart = workspace.GoalPart
eyePart.CFrame = CFrame.new(eyePart.Position, goalPart.Position)
game:GetService("RunService").Heartbeat:Connect(function(dt)
local eyeCF = eyePart.CFrame
local delta = getRotationBetween(-UNIT_Z, eyeCF:PointToObjectSpace(goalPart.Position).Unit, UNIT_X)
eyePart.CFrame = eyeCF * delta
end)
Big thanks. Im currently reading ur POST. Btw is there a way to prevent the eye from rotating in Z (blue) at all? It eye perfectly rotates to the goal, but that angle is screwed up after some moving.