• 2D
  • Rotation property

Firstly, I would like to say hello to the GODOT community. This is my first post on these forums A few days ago, I decided to install the GODOT engine (3.2.3) and give it a try, since I read so many good comments for this engine. I am a newcomer to the world of GDScript and I try to learn the basics. After the first steps, I decided to create a node tree and play with the properties of each node. The tree has a simple root node and 3 KinematicBody2D nodes with a parent-child relationship among them.

If I rotate the first KinematicBody2D(segment0) by setting the rotationproperty with a new value, everything works as I expected. But if I rotate any of the rest KinematicBody2D (segment1, segment2,...) then the node is turning but it is positioned on the position of the first KinematicBody2D Please watch the video below: https://youtu.be/UCF_lcU20i4

Project attached Any help will be appreciated

Welcome to the forums @george2868!

I downloaded the project and I think I found the issue. The issue is that you are offsetting the position of each segment by 32 * i, where i is the number of segments. The position property is the position of the node relative to its parent scene, and since you are parenting each node to the next segment in the chain, you don't need to multiply by i since the position is only relative to its parent. Changing line 22 in node2d.gd to copy.set_position(Vector2(0, 32)) fixed the issue in my testing.

If you were using global_position though, which is relative to the scene origin, then you would want to multiply by i.

Hi TwistedTwigle, Thank you for taking the time to look at the code snippet of a newbie! :)

The position property is the position of the node relative to its parent scene, and since you are parenting each node to the next segment in the chain, you don't need to multiply by i since the position is only relative to its parent Yes you are right, but if I change to copy.set_position(Vector2(0, 32)) and set the length variable to 3 or greater then the segments are not placed beneath each other (please see the attached project)

@george2868 said: Hi TwistedTwigle, Thank you for taking the time to look at the code snippet of a newbie! :)

The position property is the position of the node relative to its parent scene, and since you are parenting each node to the next segment in the chain, you don't need to multiply by i since the position is only relative to its parent Yes you are right, but if I change to copy.set_position(Vector2(0, 32)) and set the length variable to 3 or greater then the segments are not placed beneath each other (please see the attached project)

Yup, you're right! I totally missed that when testing. After debugging and some head scratching, I found out the issue though and thankfully its simple to fix. The issue is that you are using KinematicBody2D nodes and they ignore having their position changed for a single frame as they setup their physics, so you have to yield for a single frame and then set the position, and then it will work as expected. Here's the code I used:

extends Node2D

export var length = 2

onready var segment_current = get_node("segment0")

func _ready():
	length = abs(length) - 1
	for i in range(length):
		segment_current = create_segment(segment_current, i+1)
		yield(get_tree(), "idle_frame")
		segment_current.position = Vector2(0, 32);
	
	segment_current = get_node("segment0")
	segment_current = segment_current.get_node("segment1")


func _physics_process(delta):
	segment_current.rotation += -1 * delta
	pass


func create_segment(seg, i):
	var copy = seg.duplicate()
	copy.name = "segment" + str(i)
	segment_current.add_child(copy)
	#copy.set_position(Vector2(0, i*32))
	copy.set_position(Vector2(0, 32))
	
	return copy

Then it should work as expected!

Side note: the only reason I figured out it was a KinematicBody2D node quirk that causes the issue is because if you use a Node2D node, the yield is not necessary and it works without any issue. It did take me a bit to figure out that was the issue though, as I thought it was something with the code for setting the position initially until I did a long chain of print statements for debugging.

Well, I have a long road to walk on the GODOT path. I could never imagine a function like yield (I am an old fashioned and hobbyist programmer) I read the documentation about it and I understood what it does. Thank you for pointing this out. But your code snippet does not run as I expected. I removed the copy.set_position(Vector2(0, 32)) in the create_segment(sef, i) function, since I don't think that it is necessary and set the length to 4

The segments are not placed beneath each other:

here is the code:

     extends Node2D
     
     var length = 4
     
     onready var segment_current = get_node("segment0")
     
     func _ready():
     	length = abs(length) - 1
     	for i in range(length):
     		segment_current = create_segment(segment_current, i+1)
     		yield(get_tree(), "idle_frame")
     		segment_current.position = Vector2(0, 32);
     	
     func _physics_process(delta):
     	pass
     	
     func create_segment(seg, i):
     	var copy = seg.duplicate()
     	copy.name = "segment" + str(i)
     	segment_current.add_child(copy)
     	return copy

Huh, strange. I not getting that result on my machine. I've attached the project I'm using. Currently I"m using Godot 3.2.3 stable mono-version on Linux, but I don't think that should make a difference.

Hmm... That's very strange I've installed GODOT 3.2.3 (I don't remember if it is the mono-version) in my Windows 10 system. I downloaded your project and its runs fine. I copy your source code to my project and it does not run the way like yours. On the left side it is your project

At first, I thought that it may be the V-sync setting but this is not the case... - I checked all the project parameters on both projects and are exactly the same. - I check the properties of the node2D and are the same Could you please run the attached project on your system and let me now if it runs like yours?

I downloaded the project and it seems to be working fine on my machine. I'm not sure why it wouldn't be working on your machine then...