Rigidbody Won't Move Position Specifically when Triggered By Enter_Body

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Limisios

I’m trying to create a script where, when a rigid body cube touches a podium, they are teleported to a set location. But I’m experiencing a weird problem. The script will seem to teleport the cube for a moment and then the cube will revert to its original location. Weirdly, this only seems to happen when using the enter_body signal.

So, in this example, I’m dropping the cube onto the trigger as shown in this example. (The script is attached to the Area node of the post. (Sorry for my bad diagram.)

A cube hovers in the air above a black and yellow post. There is an arrow leading from the cube, pointing towards the post.

func _ready():
	var cube = get_node("../../Cube")
	print(cube.translation)
	cube.translation = Vector3(100, 100, 100)
	print(cube.translation)

func _on_body_entered(body):
	if body.name == "Cube":
		print("body entered!")
		print(body.translation)
		body.translation = Vector3(100, 100, 100)
		print(body.translation)

Terminal output:

(0, 19.3706, -10.0313)
(100, 100, 100)

When I run this code, the cube is immediately transported to (100, 100, 100) Seems fine. Now look what happens when I comment out the ready function as shown:

func _ready():
#	var cube = get_node("../../Cube")
#	print(cube.translation)
#	cube.translation = Vector3(100, 100, 100)
#	print(cube.translation)
	pass

func _on_body_entered(body):
	if body.name == "Cube":
		print("body entered!")
		print(body.translation)
		body.translation = Vector3(100, 100, 100)
		print(body.translation)

Terminal output:

body entered!
(0, 15.007609, -10.0313)
(100, 100, 100)

The print functions all get called and the second translate option, even displays the translation at the correct location, however, the cube doesn’t move anywhere, and in the inspector, it still shows the translation to be the cube’s original position. (Adding a breakpoint just after the translate shows the translation at all 100s in inspector but when you unpause the game the inspector shows the old location.)

:bust_in_silhouette: Reply From: Inces

I have never used translation for changing position of 3d object, proper way to do it is to use transform.origin, however I am not sure if this is the case here.

Other issue I can think of is, that You may have weird scene tree structure of cubic object, where body and mesh are siblings instead of parent/child and only the body is translated, while mesh stays in place ?

Thank you for the tip on using transform.origin, that was good to know. I did look to see if the body and mesh were siblings but they seem to be parent/child. (Rigidbody > CollisionShape > MeshInstance) But while I was trying things, I managed to work out the problem but I don’t know why this is happening. It seems the script only works correctly if the cube is placed above the teleporters in the scene hierarchy. Here’s another bad diagram. Two Godot hierarchies. First has 'Cube' above 'Teleporters', second is the opposite.

Is there some quirk of Godot that I’m missing? Keep in mind the trigger script is displaying the print statements in either situation. (Also, just for clarity, the teleporter dropdown list being up or down does not make a difference, sorry that was a small error on my part.)

Limisios | 2022-09-04 19:28

Hierarchy on the tree indicated which nodes have their ready called first, so there must be some commotion in teleporters or Cubes ready
did You try replacing translation with transform.origin ?

Inces | 2022-09-05 14:52

I did replace translation with transform.origin. It didn’t make a difference but it’s still good to know. The only other stuff in the teleporters ready function is this:

extends Area

var exitnode;

func _ready():
	connect("body_entered", self, "_on_body_entered")
	if self.name == "Point_1":
		exitnode = get_node("../Point_2/ExitPoint")
	elif self.name == "Point_2":
		exitnode = get_node("../Point_1/ExitPoint")

This is to just get the coordinates where the cube should go when it touches the teleporter. (I wasn’t using these coordinates while solving this problem, I used (100, 100, 100) to simplify things.) The cube itself doesn’t have a script.

Limisios | 2022-09-06 18:20

your debugging shows clearly, that cube is teleported to 100s correctly, and very next frame is teleported back. So this is exactly the line, that must be causing this. Conflicting code is resolved in almost the same frame, it wants cube at different locations. This is why swapping order of ready fixes the problem, desired teleport to 100s happens after 1-frame teleport to original position

This calls for more questions :
the first script posted by You, the one that teleports cube on ready. What node is using it ?? I can see double parent reference to cube, but I can’t see anything with that relation in your scene tree.

Inces | 2022-09-06 20:03