Having trouble using CFrame to rotate a part

I want to make a part that always, but only, points it’s front face at the Y level of a random player. For example, if the player jumped, the part would only move up and down to follow the jumping movement. but if you moved left to right it would not follow.

The problem is that when the part does move up and down, it doesn’t seem to be following the character’s head like its supposed to. And I’m not sure how I would get the part to continue looking at the player when the player is behind it.

The blue face represents the front of the part. This is what’s happening

and this is the code im using on a local script. I’m not worried about replicating the movement, ill do that later

local playerService = game:GetService("Players")

local part = script.Parent

local lookOffset = part.CFrame:ToWorldSpace(CFrame.new(0,0,-1))

local char = playerService.LocalPlayer.Character
game:GetService("RunService").Heartbeat:Connect(function()
	if not char then
	else
		part.CFrame = CFrame.lookAt(part.Position, Vector3.new(lookOffset.X, char.Head.Position.Y, lookOffset.Z))
	end
end)

The Issue seems to come from setting the lookOffset as the X and Z values of the Vector3 in the new cframe. This is what keeps the part from turning left and right. When I replace the x and z values with those of the head, the part follows the head’s Y value perfectly fine. I Don’t know any way to limit the left and right movement of the part without using this method though.

1 Like

I’m assuming it’s a Script and not a LocalScript, this is the reason for the delay. You should generally do stuff like this on the client since it’s expensive for the server (with a lot of parts like these the server will lag) to do it.
It also has this delay that you noticed because the server sees the player’s character a short time behind where they actually are due to ping.
You basically need to move the rotating part of the script to a LocalScript.

Also why are you choosing a new player for the part to follow every HeartBeat? This will cause the part to keep rotating very fast.

If you want to chose one player for the part to follow do it outside the HeartBeat and to make it so that every player sees the same thing fire a RemoteEvent to every client (:FireAllClients()) and handle the following there

Choosing a new player each heartbeat was an accident.
While switching to a local script does fix the lag, that wasn’t really the issue i was addressing. More so how the part doesn’t seem to be actually pointing at the head of the player.

after messing around with everything for a while, i noticed that the farther away the look offset is from the part the more accurate the part is
changing the part.Cframe:ToWorldSpace(CFrame.new(0,0,-1)) to (CFrame.new(0,0,-5)) solved the issue, although i’m still not sure why

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