How to fix a conflict of two instances of my rope scene

Godot Version

4.3

Question

I’ve built a cable physical simulation scene. Scene gets two links of RigidBody2D anchors and 1 link of Line2D. If parent scene has just one instance of cable scene everything works well. But if I add another one both cable shapes become same and chaotic.

Cable scene tree

Cable scene code

extends Node2D

@export_group("line_settings")
@export var chain_length: float = 500
@export var link_count: int = 10
@export var smoothness: float = 0.3

@export_group("physical_settings")
@export var mass: float = 0.1
@export var inertia: float = 100
@export var softness: float = 0.1
@export var resilience: float = 3000
@export var link_linear_damp: float = 0.1
@export var link_angular_damp: float = 10

@export_group("outer_nodes")
@export var anchor1: PhysicsBody2D
@export var anchor2: PhysicsBody2D
@export var line: Line2D
@export_flags_2d_physics var layers
@export_flags_2d_physics var mask

var links: Array[RigidBody2D]
var joints: Array[PinJoint2D]

func _ready() -> void:
	var length = chain_length/link_count
	generate_chain(length)

func get_self_position(body:Node2D) -> Vector2:
	return ((body.global_position - self.global_position).rotated(-self.global_rotation)/self.global_scale)
func get_self_rotation(body:Node2D) -> float:
	return (body.global_rotation - self.global_rotation)

func generate_chain(length) -> void:
	#clear existing chain
	for link in links:
		if is_instance_valid(link):
			link.queue_free()
	links.clear()
	joints.clear()
	for child in $Chain.get_children():
		child.queue_free()
	
	#generate links
	for i in range(link_count):
		var link = add_link(length)
		link.position = Vector2(get_self_position(anchor1).x + length*i, get_self_position(anchor1).y)
		link.inertia = inertia
		$Chain.add_child(link)
		links.append(link)
	
	await get_tree().process_frame
	
	#generate joints
	$Path2D.curve.clear_points()
	for i in range(link_count):
		var body_a = anchor1 if i == 0 else links[i-1]
		var body_b = links[i]
		var joint = add_joint(body_a, body_b)
		body_b.add_child(joint)
		joints.append(joint)
	if anchor2 != null:
		var body_a = links[-1]
		body_a.position = Vector2(get_self_position(anchor2).x-length, get_self_position(anchor2).y)
		var joint = add_joint(body_a, anchor2)
		joint.position = Vector2(length*self.global_scale.x, 0)
		body_a.add_child(joint)
		joints.append(joint)
		
	await get_tree().process_frame
	
	#generate points
	for joint in joints:
		$Path2D.curve.add_point(get_self_position(joint))
			
func add_link(length) -> RigidBody2D:
	var link = RigidBody2D.new()
	link.mass = mass/link_count
	link.linear_damp = link_linear_damp
	link.angular_damp = link_angular_damp
	link.center_of_mass_mode = 1
	link.center_of_mass = Vector2(length/2, 0)
	
	link.collision_layer = layers
	link.collision_mask = mask
	var collider = CollisionShape2D.new()
	collider.disabled = true
	var shape = SegmentShape2D.new()
	
	shape.a = Vector2(0, 0)
	shape.b = Vector2(length*self.global_scale.x, 0)
	collider.shape = shape
	link.add_child(collider)
	
	return link

func add_joint(body_a: PhysicsBody2D, body_b: PhysicsBody2D) -> PinJoint2D:
	var joint = PinJoint2D.new()
	joint.softness = softness
	joint.ready.connect(func():
		joint.node_a = joint.get_path_to(body_a)
		joint.node_b = joint.get_path_to(body_b)
	)
	return joint

func _process(_delta: float) -> void:
	# prevent index is out of bounds error on start
	while $Path2D.curve.point_count < len(joints): return
	
	var length = chain_length/link_count
	for i in range(len(links)):
		var link = links[i]
		var depending_body = anchor1 if i == 0 else links[i-1]
		var torqe = resilience*(get_self_rotation(depending_body)-get_self_rotation(link))
		link.apply_torque(torqe)
	
	for i in range(len(joints)):
		$Path2D.curve.set_point_position(i, get_self_position(joints[i]))
		
		if i==0:
			joints[i].global_position = anchor1.global_position
		elif i==len(joints)-1:
			joints[i].global_position = anchor2.global_position
		else:
			var prev_joint = joints[i-1]
			var next_joint = joints[i+1]
			var vector = get_self_position(next_joint)-get_self_position(prev_joint)
			vector = length*smoothness*vector.normalized()
			$Path2D.curve.set_point_in(i, -vector)
			$Path2D.curve.set_point_out(i, vector)

Path2D code

extends Path2D

#Wire up signals on enter tree, since they are removed in exit tree
func _ready() -> void:
	var line = $"..".line
	line.points = curve.tessellate()
	#lock_node(line)
	if not curve.changed.is_connected(curve_changed):
		curve.changed.connect(curve_changed)
		
func lock_node(node:Node):
	node.set_meta("_edit_lock_", true)

func _enter_tree():
	if not curve.changed.is_connected(curve_changed):
		curve.changed.connect(curve_changed)

#Clean up signals (ie. when closing scene) to prevent error messages in the editor
func _exit_tree():
	if curve.changed.is_connected(curve_changed):
		curve.changed.disconnect(curve_changed)

func curve_changed():
	var line = $"..".line
	line.points = curve.tessellate()

Тестовая сцена

I fixed this with turning on "local to scene " flag for curve’s resource of the Path2D node in cable scene