using Godot; public partial class DragMover : Node { [Export] public Node2D Parent; // The node that will move [Export] public Area2D DragArea; // Click detection [Export] public Area2D CheckArea; // Overlap validation [Export] public Area2D ShootArea; // This gets disabled while dragging private bool _tresholdReached = false; private bool _dragging; private Vector2 _dragOffset; private Vector2 _originalPosition; private bool _canMove = true; public override void _Ready() { if (Parent == null || DragArea == null || CheckArea == null) { GD.PushError("DragMover exports are not assigned."); return; } DragArea.InputEvent += OnDragAreaInputEvent; _originalPosition = Parent.GlobalPosition; } private void OnDragAreaInputEvent(Node viewport, InputEvent @event, long shapeIdx) { if (!_canMove) return; if (@event is not InputEventMouseButton mb) return; if (mb.ButtonIndex != MouseButton.Left) return; if (mb.Pressed) { _dragging = true; ShootArea.Monitoring = false; _originalPosition = Parent.GlobalPosition; Parent.SetModulate(Color.FromHtml("ffffff20")); _dragOffset = Parent.GlobalPosition - Parent.GetGlobalMousePosition(); } else { ShootArea.Monitoring = true; if (CheckArea.HasOverlappingAreas() || CheckArea.HasOverlappingBodies() || !_tresholdReached) { Parent.GlobalPosition = _originalPosition; Parent.SetModulate(Color.FromHtml("ffffffff")); } else { MovementDelay(); } _tresholdReached = false; _dragging = false; } } public override void _Process(double delta) { if ((Parent.GetGlobalMousePosition() + _dragOffset).DistanceTo(_originalPosition) >= 10f && _dragging) { _tresholdReached = true; } if ((Parent.GetGlobalMousePosition() + _dragOffset).DistanceTo(_originalPosition) <= 10f && !_tresholdReached) return; if (!_dragging) return; if (CheckArea.HasOverlappingAreas() || CheckArea.HasOverlappingBodies()) { Parent.SetModulate(Color.FromHtml("ff000020")); } else { Parent.SetModulate(Color.FromHtml("ffffff20")); } Parent.GlobalPosition = Parent.GetGlobalMousePosition() + _dragOffset; } private async void MovementDelay() { ShootArea.Monitoring = false; _canMove = false; Parent.SetModulate(Color.FromHtml("ffffff20")); await ToSignal(GetTree().CreateTimer(1.5), SceneTreeTimer.SignalName.Timeout); Parent.SetModulate(Color.FromHtml("ffffffff")); ShootArea.Monitoring = true; _canMove = true; } }