I'm losing my mind. I've been trying to figure this out for two weeks now, and I'm not making any progress at all.
I have a system where I can pick up an object via a dynamic handle connected to a parent object with a pin joint.
You can click inside the parent object to establish the point of click, a signal gets emitted to the world scene for the sake of delegation, and the child handle can be dragged around the screen. The parent's physics remains intact. I use a little bit of trig to make sure where you click on the parent object is where you pick it up.
I want that click to update the position of my pin joint in the child to change the center of gravity of the selection. I've tried adding a handle scene, setting the pin location, then adding an instance as a child. I've tried to integrate forces on the handle to update the position, and nothing happens.
The pin joint is always at the center of the scene. I know the position can be changed. I can set the position to something other than the center in the editor, but I can't make it budge dynamically.
The code:
The parent senses the click and delegates the handle to the world scene.
extends RigidBody2D
signal clicked
signal dropped
var held = false
var local_offset = Vector2.ZERO
var rotated_offset = Vector2.ZERO
func _input_event(viewport, event, shape_idx):
if event.is_action_pressed("click"):
local_offset = get_local_mouse_position()
rotated_offset = rotate(local_offset)
emit_signal("clicked", $Pin)
func _input(event):
if event.is_action_released("click"):
emit_signal("dropped", $Pin)
func rotate(coords):
var x2 = cos(rotation)*coords.x - sin(rotation)*coords.y
var y2 = sin(rotation)*coords.x + cos(rotation)*coords.y
return Vector2(x2,y2)
Delegates to the world scene which communicates back to the "handle" child.
extends Node2D
var held_object = null
func _ready():
for node in get_tree().get_nodes_in_group("pickable"):
node.connect("clicked", self, "_on_pickable_clicked")
node.connect("dropped", self, "_on_pickable_released")
func _on_pickable_clicked(object):
if !held_object:
held_object = object
held_object.pickup()
func _on_pickable_released(object):
if held_object:
held_object.drop(Input.get_last_mouse_speed())
held_object = null
My current child code. Trying to update the position of itself and hoping the PinJoint2D position will follow. _integrate_forces(state) isn't making it move.
extends RigidBody2D
var held = false
onready var parent = get_parent()
var reset_state = false
var location = Vector2.ZERO
func _physics_process(delta):
if held:
global_transform.origin = compute_offset_vector()
func _integrate_forces(state):
if reset_state:
var xform = state.get_transform()
xform.origin = parent.local_offset
state.set_transform(xform)
reset_state = false
func pickup():
if held:
return
mode = RigidBody2D.MODE_STATIC
held = true
reset_state = true
func drop(impulse=Vector2.ZERO):
if held:
mode = RigidBody2D.MODE_RIGID
apply_central_impulse(impulse)
held = false
location = Vector2.ZERO
reset_state = true
func compute_offset_vector():
return Vector2(get_global_mouse_position().x - parent.rotated_offset.x, get_global_mouse_position().y - parent.rotated_offset.y)
This code drags the parent around correctly (as the gif above indicates). I'm happy with that. I want the to move the center of gravity, but I'm so incredibly lost. I would love any insight anyone could provide.