Topic was automatically imported from the old Question2Answer platform.
Asked By
Footurist
When connecting PinJoint2Ds before runtime everything works fine. But when I do the EXACT same thing at runtime, everything just explodes. I even looked a thousand times at the remote tree and it’s EXACTLY the same structure as when connected before runtime with editor.
Node RopeLink:
RigidBody2D
Sprite
CollisionShape2D
PinJoint2D
Node Rope:
func _ready():
_spawn(3)
pass
func _spawn(link_num):
var link_pos = []
for i in range(link_num):
var link = RopeLink.instance()
if i == 0:link.set_mode(RigidBody2D.MODE_STATIC)
link_pos.append(link.get_position())
add_child(link)
link.set_position(Vector2(link_pos[i].x, link_pos[i].y + i * 200))
for i in range(link_num - 1):
var link = get_child(i)
var next_link = get_child(i + 1)
var joint = link.get_child(2)
joint.position.y += 0
joint.node_a = "../../" + link.name
joint.node_b = "../../" + next_link.name
pass
Solved this myself. Turns out using _init() gets rid of the problem, since spawning links in _ready() causes the joints to mess up due to gravity being applied while spawning them.
add_child(link)
link.set_position(Vector2(link_pos[i].x, link_pos[i].y + i * 200))
You add the link to the scenetree and this leads to the effect that the physics engine is taking control of its position. You have to set the position first. So just swap the lines.
link.set_position(Vector2(link_pos[i].x, link_pos[i].y + i * 200))
add_child(link)
By the way, your code can be refactored:
Remove meaningless pass
Remove meaningless joint.position.y += 0
Add some comments so it’s not hard to understand what is going on
Use godots function API to make your code more readable:
I tried to rewrite your code the way I would like to read it. You don’t have to agree because everyone has their own style. It’s just a suggestion:
var RopeLink = preload("res://RopeLink.tscn")
func _ready():
_spawn(3)
func _spawn(link_num):
# Keep a list of creating links
var links = []
# Create those links
for i in range(link_num):
# Instance and set a relative position
var link = RopeLink.instance()
link.set_position(link.position + i * Vector2(0, 200))
# First link should be fixed
if i == 0:
link.set_mode(RigidBody2D.MODE_STATIC)
add_child(link)
links.append(link)
# Set their PinJoint2Ds
for i in range(links.size() - 1):
var joint = links[i].get_node("PinJoint2D") # The node can be found by its name
joint.node_a = joint.get_path_to(links[i]) # Relative paths are way easier to maintain
joint.node_b = joint.get_path_to(links[i+1])
Thanks alot! What you said makes sense. And now I also understand better why my approach with doing the spawning in the _init(): function works.
Footurist | 2018-02-13 21:12
You are welcome. Using the _init function is also a valid way of implementing this. It depends on your needs and you should always consider every way possible.