Drag and Drop in Unity Part Two

After getting a basic system of moving Items between different Containers, I needed to extend this slightly. First of all, I need some feedback of which container an item is going to, and also of restricting items to only some containers. In most games, only some containers are valid locations to drop an item.

Feedback

What I want is for the containers to highlight when an item is hovering over them and they can be dropped. To detect when an item is hovering, I gave all the Containers a BoxCollider2D component and all of the Items both a RigidBody2D component and a BoxCollider2D. Now apparently, the collider should size its mesh to the shape of the GameObject but since I am only using Panels, not sprites, this doesn’t seem to be the case. It’s not a problem, since the collider mesh can be edited manually.

The RigidBody2D components need to be set to Kinematic for the Body Type, so that the Unity engine doesn’t try to push them with gravity all over the place.

The BoxCollider2D elements on the Containers need to have Is Trigger set to true, so that the trigger methods fire.

Then on the DropHandler script I added the following methods (which are overrides of methods on the MonoBehavior base object so they don’t need any more interfaces):

private Color? _startingColour;
 
private void OnTriggerEnter2D(Collider2D collision)
{     var image = GetComponent<Image>();     _startingColour = _startingColour ?? image.color;     if (collision.transform.parent.gameObject != gameObject)     {         image.color = Color.red;     }
}
 
private void OnTriggerExit2D(Collider2D collision)
{     if (collision.transform.parent.gameObject != gameObject)         GetComponent<Image>().color = _startingColour.Value;
}

This will make the Container red when something is hovering, and white otherwise, but only if the container is not it’s original parent container. The _startingColour field is to be able to return to whatever it was before. The last part of the puzzle is to add the following to the OnDrop method in the DropHandler script:

GetComponent<Image>().color =

_startingColour ?? GetComponent<Image>().color;

So that after an item has been dropped, the container will return to it’s original colour.

Restrictions

Restrictions were surprisingly easy. First of all, everything got renamed either ContainerAA, ContainerBB, ItemAA and ItemBB so I could check conditionals without having to go through added a custom editor pane. Then, I added the CanDrop method to the DropHandler script:

public bool CanDrop()
{     return (DragHandler.ItemBeingDragged.name.Contains("AA") && gameObject.name.Contains("AA"))         || (DragHandler.ItemBeingDragged.name.Contains("BB") && gameObject.name.Contains("BB"));
}

And called it as part of the conditional checks on OnDrop, OnTriggerEnter2D and OnTriggerExit2D.

Et voila! Only some targets highlighted on hover, and those were the only ones that would accept the drop. Different items had different targets.

In further developing this, I can see that CanDrop will really be looking for a specific MonoBehavior type (for example, by calling ItemBeingDragged.GetComponent<Card>()) and then interrogating the properties against specific logic – different for each container. So in Solitaire, the CanDrop method would get the Card component out of the item being dragged and then check it’s suit and value against the current suit and value on it’s own stack to determine if the card can be dropped or not.

Leave a Reply

Your email address will not be published. Required fields are marked *