Grabing RigidBody2D like Target Joint in Unity

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By websterek
:warning: Old Version Published before Godot 3 was released.

Hi
How can I achieve something like TargetJoint in Unity: https://www.youtube.com/watch?v=uG7doV7pT4I ?

There are some example at QA (I can’t find it right now) but the problem with that method is grabing object only at origin point.

Best!

:bust_in_silhouette: Reply From: mollusca

Maybe this can be done with a DampedSpringJoint2D somehow but here’s a version using impulses applied to the RigidBody2D.

extends RigidBody2D

const DRAG_DIST = 64
const SPRING_FACTOR = 0.1
const DAMP_FACTOR = 0.01
var drag_point = Vector2()
var dragging = false

func _ready():
    set_process_input(true)
    set_fixed_process(true)
    set_pickable(true)

func _input(event):
    if event.type == InputEvent.MOUSE_BUTTON and !event.pressed and event.button_index == BUTTON_LEFT and dragging:
        dragging = false

func _input_event(viewport, event, shape_idx):
    if event.type == InputEvent.MOUSE_BUTTON and event.pressed and event.button_index == BUTTON_LEFT:
        drag_point = get_global_transform().xform_inv(event.pos)
        dragging = true

func _fixed_process(delta):
    if dragging:
        var tf = get_global_transform()
        var mouse_pos = tf.xform_inv(get_global_mouse_pos())
        var dist = drag_point.distance_to(mouse_pos)
        if dist > DRAG_DIST:
            var dir = mouse_pos - drag_point
            var dir_impulse = tf.basis_xform(dir.normalized())
            var impulse = dir_impulse * (dist - DRAG_DIST) * SPRING_FACTOR - get_linear_velocity() * DAMP_FACTOR
            apply_impulse(tf.basis_xform(drag_point), impulse)

You’ll have to adjust the spring and damping factors and the dragging distance to your liking.

Which method seems to works pretty well, thanks!

websterek | 2018-01-11 13:45