Godot Version
Godot 4.6
Question
I’ve been trying to get a wire working that wraps and unwraps around objects. Solutions involving physics based ropes don’t work for my case. I’ve gotten wrapping to work, but the unwrapping side has been giving me trouble for awhile. Here is what I’ve got so far:
extends Node3D
@onready var tip: Node3D = $Tip
@onready var segments: Node3D = $Segments
const ROPE_SEGMENT = preload("uid://d4h861jbj5jt3")
@export var end_node: Node3D
var points: Array = [Vector3.ZERO]
var angles: Array = [[]]
var previous_points: Array = [Vector3.ZERO]
func _ready() -> void:
points[0] = global_position
func _physics_process(delta: float) -> void:
tip.position.x -= 4.0*delta if Input.is_action_pressed("ui_left") else 0.0
tip.position.x += 4.0*delta if Input.is_action_pressed("ui_right") else 0.0
tip.position.z -= 4.0*delta if Input.is_action_pressed("ui_up") else 0.0
tip.position.z += 4.0*delta if Input.is_action_pressed("ui_down") else 0.0
points[points.size()-1] = global_position
for i in segments.get_child_count():
var child: Node3D = segments.get_child(i)
var ray: RayCast3D = child.get_node("RayCast3D")
var child_count = segments.get_child_count()
child.visible = true
child.get_node("MeshInstance3D").visible = true #TEMPORARY
if i == 0:
child.global_position = end_node.global_position
if not child.global_position.is_equal_approx(points[i]): child.look_at(points[i])
child.scale.z = child.global_position.distance_to(points[i])/2.0
previous_points[i] = child.global_position
else:
child.global_position = points[i-1]
if not child.global_position.is_equal_approx(points[i]): child.look_at(points[i])
child.scale.z = child.global_position.distance_to(points[i])/2.0
previous_points[i] = child.global_position
continue
if child_count>1:
#INSERT UNWRAP LOGIC
pass
if ray.is_colliding():
var wrap: bool = true
var collision_point: Vector3 = ray.get_collision_point()
for p in points.size(): if points[p].distance_to(collision_point) < 0.02: wrap = false
if wrap:
var new_seg = ROPE_SEGMENT.instantiate()
#new_seg.hide()
segments.add_child(new_seg)
segments.move_child(new_seg, 1)
points.insert(0, collision_point)
angles.insert(0, [global_position, previous_points[i], collision_point])
previous_points.insert(0, collision_point)
return
previous_points[i] = child.global_position
Heres my setup for the node with the script:

Here’s the actual wire segments:

I can’t upload a video showing what it looks like right now since I’m a new user.
Is anyone able to help get this working? I’ve already looked at the few posts from people trying to do similar things, though none of that helped me ![]()