CFrame rotation matrix being lost over network?

I am creating a system where a player can place a beartrap and a preview is shown. A CFrame created by the offset of the CFrame compared to the object’s CFrame it’s being placed on is sent to the the server. However, when printing the same value on the client and then when it’s sent to the server, they appear to be different.



You can see in the video that the rotation is being changed.
I don’t understand why this is happening, it’s like the rotation matrix of the CFrame is being reset in a way. I am not modifying them either, I am printing right before it’s sent, and right after it’s received. Are CFrames compressed over the network in a way that I’m not aware of?

3 Likes

Are you sending the CFrame of the beartrap over the network? Also, it doesn’t look like there’s any change, so why do you need this preciseness?

2 Likes

You can see in the video and print statements that the rotation snaps back to facing only forward no matter how it’s being rotated on the client. I don’t know what is causing this so I’m probably just going to run the calculations for placing on the server instead anyway.

1 Like

They should still maintain the same rotation. I have programmed many placement systems where the client calculates the CFrame before, but the rotation is always kept regardless. It really seems like a problem with your code, and without it, there aren’t really any good suggestions we can give.

2 Likes

Okay, here.

--CLIENT (runs when being placed)
print(raycastData.Instance.CFrame:Inverse() * beartrapPreview.CFrame)
RemoteEvent:FireServer(1, raycastData.Instance.CFrame:Inverse() * beartrapPreview.CFrame, raycastData.Instance)
--SERVER
local Events = {
	[1] = function(player, offsetCFrame, object)
		print(offsetCFrame)
	end,
	--...other events not related to this
}

RemoteEvent.OnServerEvent:Connect(function(player, eventId, ...)
	local Event = Events[eventId]
	if not Event then
		warn("Event " .. eventId .. " not found. " .. tool.Name .. "/" .. script.Name)
		return
	end
	Event(player, ...)
end)

I didn’t send my code beforehand because the CFrame is immediately being printed on both ends without any modification so I thought it must’ve been something else.

Okay, scratch all of this. I just found this staff post:

So, it looks like the :Inverse might be breaking the rotation somehow?

Original post:


I’m having a hard time reproducing this:

The green is another SpawnLocation that is updated locally by the client, and the grey is the SpawnLocation the server is updating through a RemoteEvent. I even tried to set it up in the same way as you:

-- CLIENT
local ReplicatedStorage = game:GetService("ReplicatedStorage")

local RemoteEvent = ReplicatedStorage.RemoteEvent

local Rotation = 0

while true do
	local Delta = wait(0.1)
	
	Rotation += Delta * 25
	
	local RotationRad = math.rad(Rotation)
	local SpawnCF = workspace.Baseplate.CFrame:Inverse() * CFrame.new(0, 5, 0) * CFrame.Angles(RotationRad, RotationRad, RotationRad)
	RemoteEvent:FireServer(1, SpawnCF)
	
	workspace.SpawnLocClient.CFrame = SpawnCF
end
-- SERVER
local ReplicatedStorage = game:GetService("ReplicatedStorage")

local RemoteEvent = ReplicatedStorage.RemoteEvent

local SpawnLocation = workspace.SpawnLocation

local Events = {
	[1] = function(Plr, CF)
		SpawnLocation.CFrame = CF
	end
}

RemoteEvent.OnServerEvent:Connect(function(Player, EventId, ...)
	Events[EventId](Player, ...)
end)

Try it out for yourself:
RotationKeptInTransit.rbxl (54.8 KB)

The only idea I have is beartrapPreview somehow resetting. Did you add the print before you found out the beartrap wasn’t rotating correctly, or after? Maybe putting it into a variable before doing a print will fix it if this is what’s happening?

I do know that CFrames are compressed in some way when they are sent over the network, but, given that it’s working for me, I’m not sure if that’s what’s happening here.

1 Like

Thank you for the reply!

I’ve already tried putting it into a variable then printing and sending the same variable and nothing changed. I’ll check out your code and that post and try and work out a solution later on today.

1 Like

I fixed it! Utilizing the code from the post you sent, I set this up:

--...initial beartrap cframe code here
beartrapPreview.CFrame = CFrame.fromMatrix(beartrapPreview.CFrame.Position, beartrapPreview.CFrame.XVector, beartrapPreview.CFrame.YVector)

Somehow, running CFrame.fromMatrix() on the CFrame after it’s set up allows it to be sent to the server without the rotation matrix being reset. I can probably guess that the problem was that, stated in the post you sent, the CFrame was invalid because it was inverted.

Thank you for your help and finding that post, I would’ve still been stuck on this without it!

1 Like

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