• Projects
  • Godot 3.4 Rigid Body 2D Design - Extending the Rope

I have made use of others' rigid body designs for rope for some time now but cannot find a good method to add links to the rope or chain. For a game I am designing (2D platformer) I need to be able to lengthen a hose as the player vehicle moves away from a starting position. The code for the most part is working - as the Player moves away a comparison is done in code and when the hose is stretched too far a segment is duplicated and attached to the previous segment.

Now the trouble and question: I modeled my code after how I would duplicate the segments in the editor, then move the segment and attach node_b. That seemed to work but each successive segment seems to be attached at one corner where the entire length of rope (initially 20 segments) are all aligned on center. I am uncertain why the offset.

Key Part of the Code: "link_players()", "calc_length()", and "add_segments()".

func link_players():
	
	#prevents the rope from freaking out, when relocated
	yield(get_tree(), "idle_frame")
	
	pjoint = get_parent().get_node("RescueSub/Player_pinjoint")
	ppos = pjoint.global_position 
	pjoint.node_a = $Segments.get_child(19).get_path()
	
	player2 = get_parent().get_node("VOO")
	p2pos = player2.get_node("Position2D").global_position
	var p2seg = $Segments.get_child(0)
	var p2joint = p2seg.get_node("PinJoint2D")
	p2joint.node_b = player2.get_path()

	linked = true

func calc_length():
	hose_length = num_segs*9.7

func add_segments():
	for chld in $Segments.get_children():
		chld.mode = 1
		chld.set_physics_process(false)

	player = get_parent().get_node("RescueSub")
	var init_vel = player.velocity
	player.set_process_input(false)
	player.set_physics_process(false)
	player.velocity = Vector2.ZERO
	
	var segs_list = $Segments.get_children()
	var last_seg = segs_list[num_segs-1]
	var seg_dup = last_seg.duplicate(15)
	print("did we pause")
	seg_dup.rotate(180)
	seg_dup.set_physics_process(false)
	$Segments.add_child(seg_dup, true)

	yield(get_tree(), "idle_frame")
	var dupjoint = seg_dup.get_node("PinJoint2D")
	dupjoint.node_b = last_seg.get_path()
	num_segs = $Segments.get_child_count()

	ppos = pjoint.global_position 
	seg_dup.get_node("North_Pole").global_position = ppos
	pjoint.node_a = seg_dup.get_path()
	
	player.velocity = init_vel
	player.set_process_input(true)
	player.set_physics_process(true)
	
	for chld in $Segments.get_children():
		chld.mode = 0
		chld.set_physics_process(true)

While I stop physics processing during the add_segment code, my problem must be the original position of the 'Segment' that I am duplicating. The 'hose' is aligned from the player to the base at about a 20 degree up angle. When the segments are duplicated it is duplicating this original copy vice the current hose segment by the player. Note lines 7 through 13 in the Add_segments() function above. this is attempting to duplicate, invert the new segment add as a child and then connect the pinjoint to the old segment.

I guess a solution is to not 'duplicate' but find the current segment node and copy that?

Guess I am answering my question here but the lines 7 to 13 are working. I think my problem must be where the "rotate()" function applies the rotation to each segment.

The origin of the segment scene is center at (0,0). Anyone understand why my origin may be wrong or why rotate gives an offset rotation??

Folks, my code works for the most part. I would say 95% right. I used DEGREES instead of RADIANS. I changed "180" to "PI" and it rotates and attaches the next segment as expected.

When I have a more complete game to demo I will post a video.

2 months later

@joedad said: Folks, my code works for the most part. I would say 95% right. I used DEGREES instead of RADIANS. I changed "180" to "PI" and it rotates and attaches the next segment as expected.

When I have a more complete game to demo I will post a video.

All, I stated above I would post a video after getting the extending and shortening code to work. The code to grow the rope works - the code to shorten proved to be too much trouble. My solution is a separate pin joint 2d node that serves as a reel system. I code a constant set torque value on the reel which keeps the full length of hose under tension. This allows the player to unreel during game play and when returning close to the reel the reel automatically reels the hose back up. Works great!

I am going to post no further discussions on this thread.

6 months later

To solve the hose effect for my game I had to manually create the length I wanted in the editor and then write some code to reverse the deck reel when the Rescue Vessel is descending. As the rescue sub comes back shallow the reel has more torque in the positive. Coding extending the hose/rope did work. Coding the retracting part did not work. Or I could not get it to work. Has to do with moving the links and reconnecting the pin joints.

My game which uses the hose discussed here can be played at my itch.io site; https://joehubdad.itch.io/submarine-rescue-ops.