Child node that doesn't follow rotation?

Godot Version

4.3.stable

Question

Hey, so I’d like for a child to accompany the Transform3D of the parent, having the same global position, but keeping it at the Identity Basis globally.

I need the child node there because I do want the parent node script to control the behavior of the child in the scene, and keep it organized.

image
This does not work, as I ignore the rotation, it will keep being transformed by the parent naturally, which is not what I want.

I tried this and it does not work either. I thought that doing a gray Node in between would “stop the transform hierarchy” as every Node3D child of a gray node behaves like the tree root for those. But mysteriously the RemoteTransform3D keeps on pos (0,0,0), doing nothing.

Am I doing something wrong? Should I write my own RemoteTransform3D instead? Thanks!

What node are you trying to remote transform? I don’t think you want the “Laser Pivot” to be a child of the RemoteTransform3D if that’s the node you set to it’s remote_path, maybe you could set the Laser Pivot top_level and keep it a child.

RemoteTransform works best as a child of the object you want copy from, then set the remote_path to the object to apply the copied transform to. But if you are applying to a child of the copied object, and/or the transform, then it’s already having it’s transform modified through the hierarchy.

2 Likes

I ended up solving this by doing my own custom code like this:

class_name CustomRemoteTransform3D extends Node3D

@export var who:NodePath;
@export var follow_position:bool = true;
@export var follow_rotation:bool = true;
@export var follow_scale:bool = true;
@export var global_get:bool;
@export var global_set:bool;

var follow:Node3D;

func _ready() -> void:
	follow = get_node(who);

func _process(delta: float) -> void:
	var tr:Transform3D;
	if global_get:
		tr = follow.global_transform;
	else:
		tr = follow.transform;
		
	if !follow_position: tr.origin = Vector3.ZERO;
	if !follow_rotation: tr.basis = Basis.IDENTITY;
	if !follow_scale: tr = tr.orthonormalized()
	
	if global_set:
		global_transform = tr;
	else:
		transform = tr;

This worked fine on the second hierarchy, but it felt like doing something that the engine already implemented again.

1 Like

@gertkeno is right, but also

Remote transforms disable themselves when the target is an ancestor of the remote transform, or the remote transform is an ancestor of the target. I.e., they would get the same source transforms anyway (in a typical case), and should not feedback on itself.

It can be fixed like this, by breaking the ancestry chain and making the remote transform a sibling to the “cleansing” Node. (Btw you can also just make the node top level, if that cleansing node is solely for that purpose). If the Node is by design, just make the remote transform a sibling to the target branch but a still child of the source.

Node3d is the source

Meshinstance3d is the target