Rotating parent node and its children

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By DodoIta
:warning: Old Version Published before Godot 3 was released.

Hello!
So, imagine I have a background seen from a top-down perspective and that I rotate that background around its center.
On this background there are some characters moving towards the center, I want them to rotate with the background while they keep going towards the center.
I tried this using the KinematicBody node for these characters (so I use move for their movement) and instanced them as children of the background node. When I rotate the parent node, what happens is that the characters rotate, but this changes their direction in a way I can’t predict.
Am I thinking wrong or is there a better way to implement this?

are you doing it with 3D?

volzhs | 2017-04-11 15:46

show code :slight_smile:

Nuno Donato | 2017-04-11 17:47

Are your characters children of the background? If they are, they will rotate too using the same referential. If you do that you will also have to use a local direction rather than global coordinates.
If you didn’t make your characters children of the background… then I don’t know, because the way you did it might change the answer.
Note that you could also rotate the camera instead of the world, perhaps? (unless only a part of the world rotates)

Zylann | 2017-04-11 18:07

I’m doing this 2D (top-down perspective :D).

Basically the ‘main’ scene is a StaticBody with a script which allows me to rotate it and the following children:

  • a Sprite node;
  • an instance of another scene (the moving character).

The code for the child scene is the following, currently attached to an Area2D node (since the move function stops the sprite while I’m rotating its parent):

extends Area2D

var speed = 50.0
onready var start_pos = get_viewport().get_rect().size / 2
var movement = Vector2()
var direction = Vector2()

func _ready():
	set_global_pos(start_pos)
	set_fixed_process(true)


func _fixed_process(delta):
	var cur_pos = get_global_pos()
	direction = start_pos - cur_pos
	movement += direction.normalized() * speed * delta
	set_global_pos(movement)

What happens is that the child node rotates around its pivot (not around the parent’s) and just keeps going to the center.
What I want is to change the child’s position according to the rotation (just imagine you put a rubber on a rotating DVD :p), while it’s still moving towards the center of the screen.

Am I overthinking this? Should I change approach?

DodoIta | 2017-04-12 16:20

When you have a setup with Node2Ds children of a parent Node2D, then you should avoid using global_* stuff unless you really know what you are doing.

For example, you should not use set_global_pos, but set_pos, and the target position should be expressed as local coordinates too (which might simply be (0,0) if the pivot of your background is centered).

Also, how exactly did you rotate this? I don’t see any set_rot. Also, I’m not sure StaticBodies can be rotated, since they are static.

Zylann | 2017-04-12 21:19

what about adding Camera2D to the background?
current flag should be on(true) of course.

volzhs | 2017-04-13 03:04

I’ve never tried using a Camera2D, I could but it’s important that the characters rotate because I’d use rotation to make them collide with static objects (which are not affected with rotation).

I’ll try using local coordinates; I also thought StaticBodies could not be rotated, but I tried the following code:

extends StaticBody2D

var rot_speed = 10.0
var rotating = false
var rot = 0

func _ready():
	set_global_pos(get_viewport().get_rect().size / 2)
	set_fixed_process(true)


func _fixed_process(delta):
	if(Input.is_action_pressed("ui_up")):
		rot += rot_speed * delta
	if(Input.is_action_pressed("ui_down")):
		rot -= rot_speed * delta
		
	set_rot(rot)

And they actually rotate! I was messing around, I don’t know if it’s a good way to do this.

DodoIta | 2017-04-13 17:14