Quick answer: Enable update_rotation on the RemoteTransform node. It has separate boolean flags for position, rotation, and scale syncing. Also verify use_global_coordinates is set correctly — if the source rotates in world space, the target must use global coordinates to match.

Here is how to fix Godot RemoteTransform not syncing rotation. You attach a RemoteTransform3D to your player to drive a camera. The camera follows the player’s position perfectly, but when the player turns, the camera stays facing the original direction. Position syncs, rotation does not. You assume RemoteTransform copies the full transform, but it has granular flags that control what gets synced.

The Symptom

A RemoteTransform2D or RemoteTransform3D drives a target node’s position correctly, but the target’s rotation remains at its initial value. The player rotates, the camera (or weapon, or UI element) does not rotate with it. The remote_path is set, the target node updates its position each frame, but rotation is stuck at zero.

What Causes This

update_rotation is disabled. RemoteTransform nodes have three independent flags: update_position, update_rotation, and update_scale. If update_rotation is false, rotation is never pushed to the target regardless of the source node’s rotation.

use_global_coordinates mismatch. When use_global_coordinates is true, the target receives the RemoteTransform’s global transform. When false, it receives local transform. If your player rotates in global space but the RemoteTransform passes local coordinates, the target gets the wrong rotation (relative to the parent, not the world).

Target node overriding its own rotation. If the target node has a script that sets its rotation every frame (e.g., a camera script with look_at), it overwrites whatever RemoteTransform pushes. The RemoteTransform sets rotation, then the target’s own _process sets it again.

remote_path pointing to wrong node. If the path points to a parent of the intended target, the wrong node receives the transform. Position might appear correct due to hierarchy, but rotation on the parent does not affect the child the way you expect.

The Fix

Step 1: Enable update_rotation in the Inspector.

# RemoteTransform3D properties:
# remote_path: ../Camera3D (or absolute path)
# update_position: true
# update_rotation: true   <-- Enable this
# update_scale: false     (usually not needed for cameras)
# use_global_coordinates: true

In the Inspector, find the RemoteTransform node and check update_rotation. This is the most common fix.

Step 2: Set use_global_coordinates appropriately.

extends Node3D

@onready var remote: RemoteTransform3D = $RemoteTransform3D

func _ready():
    remote.update_position = true
    remote.update_rotation = true
    remote.update_scale = false
    remote.use_global_coordinates = true
    remote.remote_path = get_node("/root/Main/Camera3D").get_path()

Use use_global_coordinates = true when the target is not a sibling or child of the RemoteTransform. This ensures world-space rotation is transferred correctly.

Step 3: Remove conflicting scripts on the target. If the camera has its own rotation logic, it fights with RemoteTransform:

# Bad: Camera script overrides RemoteTransform rotation
extends Camera3D

func _process(_delta):
    look_at(target.global_position)  # This overwrites RemoteTransform

# Fix: Remove look_at or disable RemoteTransform rotation sync
# Choose ONE source of rotation, not both

Either let RemoteTransform control rotation entirely, or disable update_rotation and handle rotation in the camera script. Never both.

Step 4: Verify remote_path targets the correct node.

# Debug: Print what RemoteTransform is actually targeting
func _ready():
    var target = remote.get_node(remote.remote_path)
    print("Remote target: ", target.name, " at ", target.get_path())

Confirm the path resolves to the node you intend. A stale NodePath after scene restructuring is a common source of silent failure.

2D vs 3D Differences

RemoteTransform2D and RemoteTransform3D share the same API for update flags. In 2D, rotation is a single float (angle). In 3D, it is a full basis rotation. Both respect the same update_rotation flag. The fix is identical for both.

# RemoteTransform2D for a top-down camera
@onready var remote: RemoteTransform2D = $RemoteTransform2D

func _ready():
    remote.update_position = true
    remote.update_rotation = true
    remote.use_global_coordinates = true

“RemoteTransform is granular by design. Position, rotation, scale are independent channels. Enable what you need explicitly.”

Related Issues

For autoload access patterns used with global camera managers, see Autoload Not Accessible. For tween-based camera animations, see Tween Chain Stopping Midway.

Enable update_rotation, set global coordinates, remove competing scripts. One source of rotation truth.