How do I limit numbers of slots in Horizontal Layout Groups?

Greetings!

I watched a tutorial on how to do Drag&Drops a few days ago and have now a question. I have several cards in my hand and three different fields, all of them are Horizontal Layout Groups. However, I want to make it so once there’s a card inside one of those Groups, you can’t put anymore cards in that group until it is empty again. So basically, limit these groups to hold only one card at a time. I’ve already tried a few things but I can’t seem to make it work. How can this be done?

Here’s all the code I have at the moment:

Drag.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;

public class Drag : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler {

    public Transform parentToReturnTo = null;
    public Transform placeholderParent = null;

    public enum Slot {Monster, Item, Spell, Impact, Set};
    public Slot CardType = Slot.Monster;

    GameObject placeholder = null;

    public void OnBeginDrag(PointerEventData eventData) {
        Debug.Log ("OnBeginDrag");



        placeholder = new GameObject ();
        placeholder.transform.SetParent (this.transform.parent);

        LayoutElement le = placeholder.AddComponent<LayoutElement> ();

        le.preferredWidth = this.GetComponent<LayoutElement> ().preferredWidth;
        le.preferredHeight = this.GetComponent<LayoutElement> ().preferredHeight;
        le.flexibleWidth = 0;
        le.flexibleHeight = 0;

        placeholder.transform.SetSiblingIndex (this.transform.GetSiblingIndex());

        parentToReturnTo = this.transform.parent;
        placeholderParent = parentToReturnTo;

        this.transform.SetParent (this.transform.parent.parent);

        GetComponent<CanvasGroup> ().blocksRaycasts = false;
    }

    public void OnDrag(PointerEventData eventData) {
        //Debug.Log ("OnDrag");

        this.transform.position = eventData.position;

        if (placeholder.transform.parent != placeholderParent)
            placeholder.transform.SetParent (placeholderParent);

        int newSiblingIndex = placeholderParent.childCount;

        for(int i=0; i < placeholderParent.childCount; i++){
            if (this.transform.position.x < placeholderParent.GetChild (i).position.x){

                newSiblingIndex = i;

                if (placeholder.transform.GetSiblingIndex () < newSiblingIndex)
                    newSiblingIndex--;

                break;
            }
        }

        placeholder.transform.SetSiblingIndex (newSiblingIndex);
    }

    public void OnEndDrag(PointerEventData eventData) {
        Debug.Log ("OnEndDrag");

        this.transform.SetParent (parentToReturnTo);
        this.transform.SetSiblingIndex (placeholder.transform.GetSiblingIndex());

        GetComponent<CanvasGroup> ().blocksRaycasts = true;
        Destroy (placeholder);
    }
}

Field.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;

public class Field : MonoBehaviour, IPointerEnterHandler, IDropHandler, IPointerExitHandler{

    public Drag.Slot CardType = Drag.Slot.Monster;

    public void OnPointerEnter(PointerEventData eventData) {
        //Debug.Log ("OnPointerEnter");
        if (eventData.pointerDrag == null)
            return;

        Drag d = eventData.pointerDrag.GetComponent<Drag> ();

        if (d != null) {
            d.placeholderParent = this.transform;
        }
    }

    public void OnPointerExit(PointerEventData eventData) {
        //Debug.Log ("OnPointerExit");
        if (eventData.pointerDrag == null)
            return;
     
        Drag d = eventData.pointerDrag.GetComponent<Drag> ();

        if (d != null && d.placeholderParent == this.transform) {
            d.placeholderParent = d.parentToReturnTo;
        }
    }

    public void OnDrop(PointerEventData eventData) {
     
        Drag d = eventData.pointerDrag.GetComponent<Drag> ();

        if (d != null) {
            if (CardType == d.CardType) {
                d.parentToReturnTo = this.transform;
                Debug.Log (eventData.pointerDrag.name + " was dropped on the " + gameObject.name + " as a " + CardType);

            } else {
                Debug.Log (eventData.pointerDrag.name + " can't be dropped on the " + gameObject.name + " as a " + d.CardType);
                return; 
            }
        }
    }
}

Thank you in advance,

  • Nervly

I’d recommend using the Reorderable List control from the Unity UI Extensions project (link in sig)

But ultimately, you want to restrict the controls ability to accept “drops” when the container is full. Just use the child count of the drop container to inform the child to be dropped.

Thank you for your reply. I ended up using a bool in the code that detects when the field is full and thus disallowing the placement of the card. Appreciate the help regardless!