Created
June 25, 2021 22:24
-
-
Save evan-boissonnot/5402aa38b37b330b5a2b565ec80c98c2 to your computer and use it in GitHub Desktop.
Godot - Drag and drop example in GDScript and C#
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Handle input events on the current slot. | |
* | |
* @param InputEvent @event The input event to handle | |
* | |
* @return void | |
*/ | |
public override void _GuiInput(InputEvent @event) | |
{ | |
// If right click, then equip item | |
if (@event.IsActionReleased("right_click")) { | |
this.AcceptEvent(); | |
var item = this.getItem(); | |
if (item != null) { | |
this.unsetItem(); | |
var parent = (BagContent) this.GetParent(); | |
parent.emitEquip(item); | |
} | |
} | |
// If left click, force drag and drop | |
if (@event.IsActionReleased("left_click")) { | |
GD.print("ACTION RELEASED!"); | |
this.AcceptEvent(); | |
var item = this.getItem(); | |
if (item != null) { | |
this.unsetItem(); | |
var preview = this.getDragPreview(item); | |
this.ForceDrag(item, preview); | |
} | |
} | |
} | |
/** | |
* Returns the drag-and-drop preview for an item. | |
* | |
* @return Control | null | |
*/ | |
public Control getDragPreview(Item item = null) | |
{ | |
if (item == null) { | |
item = this.getItem(); | |
} | |
if (item != null) { | |
var preview = new Control(); | |
var sprite = new Sprite(); | |
sprite.SetTexture(item.getIcon()); | |
preview.AddChild(sprite); | |
return preview; | |
} | |
return null; | |
} | |
/** | |
* Unsets the current item and starts the drag-and-drop flow. | |
* | |
* @param Vector2 _pos The position clicked | |
* | |
* @return Item The item we want to drag | |
*/ | |
public override Godot.Object GetDragData(Vector2 position) | |
{ | |
var item = this.getItem(); | |
var preview = this.getDragPreview(); | |
this.SetDragPreview(preview); | |
this.unsetItem(); | |
return item; | |
} | |
/** | |
* Checks whether we can drop the item on the current slot. | |
* If the item is of class Item, then return true. Else return false | |
* | |
* @param Vector2 position The position clicked | |
* @param Variant data The dropped data | |
* | |
* @return bool True if we can drop the item here, false otherwise | |
*/ | |
public override bool CanDropData(Vector2 position, object item) | |
{ | |
if (item is Item) { | |
return true; | |
} | |
return false; | |
} | |
/** | |
* Drop an item on the current slot. If the slot is already occupied, swap them. | |
* | |
* @param Vector2 position The click/drop position | |
* @param Item item The item to drop | |
* | |
* @return void | |
*/ | |
public override void DropData(Vector2 position, object item) | |
{ | |
if (Input.IsActionPressed("left_click")) { | |
this.CallDeferred("force_drag", (Item)item, this.getDragPreview((Item)item)); | |
} else { | |
var oldItem = this.getItem(); | |
if (oldItem == null) { | |
this.setItem((Item)item); | |
} else { | |
this.EmitSignal("swapItem", item); | |
} | |
} | |
} | |
/** | |
* Swaps the item currently occupying the slot with another one, and forces drag-and-drop on the current one | |
* | |
* @param Item item The item which to swap with the one currently on the slot | |
* | |
* @return void | |
*/ | |
public void swapItem(Item item) | |
{ | |
var oldItem = this.getItem(); | |
this.unsetItem(); | |
this.setItem(item); | |
var preview = this.getDragPreview(oldItem); | |
this.CallDeferred("force_drag", oldItem, preview); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
Handle input events on the current slot. | |
@param InputEvent ev The input event to handle | |
""" | |
func _gui_input(ev): | |
""" | |
If right click, then equip item | |
""" | |
if (ev.is_action_pressed("right_click")): | |
self.accept_event() | |
var item = self.getItem() | |
if(item != null): | |
self.unsetItem() | |
get_parent().emitEquip(item) | |
""" | |
if left click RELEASED, force drag and drop | |
""" | |
if (ev.is_action_released("left_click")): | |
self.accept_event() | |
var item = self.getItem() | |
if (item != null): | |
self.unsetItem() | |
var preview = self.getDragPreview(item) | |
self.call_deferred("force_drag", item, preview) | |
""" | |
Returns a new Sprite with an item's icon, so we can se what we are dragging. | |
@param Item _item The item we need to generate the preview for. If it's null, | |
get the current item. | |
@return Control A control node with a Sprite child, containing the preview. | |
Control is used because the drag preview needs to be a Control node (or a child of Control) | |
""" | |
func getDragPreview(item = null): | |
if (item == null): | |
item = self.getItem() | |
if (item != null): | |
var preview = Control.new() | |
var sprite = Sprite.new() | |
sprite.set_texture(item.icon) | |
preview.add_child(sprite) | |
return preview | |
return null | |
""" | |
Unsets the current item and starts the drag-and-drop flow. | |
@param Vector2 _pos The position clicked | |
@return Item The item we want to drag | |
""" | |
func get_drag_data(pos): | |
var item = self.getItem() | |
var preview = self.getDragPreview() | |
self.set_drag_preview(preview) | |
self.unsetItem() | |
return item | |
""" | |
Checks whether we can drop the item on the current slot. | |
If the item is of class Item, then return true. Else return false | |
@param Vector2 _pos The position clicked | |
@param Variant _item The dropped data | |
@return book True if we can drop the item here, false otherwise | |
""" | |
func can_drop_data(pos, data): | |
if (data is Item): | |
return true | |
return false | |
""" | |
Drop an item on the current slot. If the slot is already occupied, swap them. | |
@param Vector2 _pos The click/drop position | |
@param Item _item The item to drop | |
@return void | |
""" | |
func drop_data(_pos, _item): | |
if(Input.is_action_pressed("left_click")): | |
self.call_deferred("force_drag", _item, self.getDragPreview(_item)) | |
else: | |
var oldItem = self.getItem() | |
if (oldItem == null): | |
self.setItem(_item) | |
else: | |
emit_signal("swapItem", _item) | |
""" | |
Swaps the item currently occupying the slot with another one, and forces drag-and-drop on the current one | |
@param Item item The item which to swap with the one currently on the slot | |
@return void | |
""" | |
func swapItem(item): | |
var oldItem = getItem() | |
self.unsetItem() | |
self.setItem(item) | |
var preview = self.getDragPreview(oldItem) | |
self.force_drag(oldItem, preview) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment