Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

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

Discussion in 'UGUI & TextMesh Pro' started by Nervly, Jul 2, 2017.

  1. Nervly

    Nervly

    Joined:
    Mar 15, 2016
    Posts:
    19
    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
    Code (csharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.UI;
    5. using UnityEngine.EventSystems;
    6.  
    7. public class Drag : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler {
    8.  
    9.     public Transform parentToReturnTo = null;
    10.     public Transform placeholderParent = null;
    11.  
    12.     public enum Slot {Monster, Item, Spell, Impact, Set};
    13.     public Slot CardType = Slot.Monster;
    14.  
    15.     GameObject placeholder = null;
    16.  
    17.     public void OnBeginDrag(PointerEventData eventData) {
    18.         Debug.Log ("OnBeginDrag");
    19.  
    20.  
    21.  
    22.         placeholder = new GameObject ();
    23.         placeholder.transform.SetParent (this.transform.parent);
    24.  
    25.         LayoutElement le = placeholder.AddComponent<LayoutElement> ();
    26.  
    27.         le.preferredWidth = this.GetComponent<LayoutElement> ().preferredWidth;
    28.         le.preferredHeight = this.GetComponent<LayoutElement> ().preferredHeight;
    29.         le.flexibleWidth = 0;
    30.         le.flexibleHeight = 0;
    31.  
    32.         placeholder.transform.SetSiblingIndex (this.transform.GetSiblingIndex());
    33.  
    34.         parentToReturnTo = this.transform.parent;
    35.         placeholderParent = parentToReturnTo;
    36.  
    37.         this.transform.SetParent (this.transform.parent.parent);
    38.  
    39.         GetComponent<CanvasGroup> ().blocksRaycasts = false;
    40.     }
    41.  
    42.     public void OnDrag(PointerEventData eventData) {
    43.         //Debug.Log ("OnDrag");
    44.  
    45.         this.transform.position = eventData.position;
    46.  
    47.         if (placeholder.transform.parent != placeholderParent)
    48.             placeholder.transform.SetParent (placeholderParent);
    49.  
    50.         int newSiblingIndex = placeholderParent.childCount;
    51.  
    52.         for(int i=0; i < placeholderParent.childCount; i++){
    53.             if (this.transform.position.x < placeholderParent.GetChild (i).position.x){
    54.  
    55.                 newSiblingIndex = i;
    56.  
    57.                 if (placeholder.transform.GetSiblingIndex () < newSiblingIndex)
    58.                     newSiblingIndex--;
    59.  
    60.                 break;
    61.             }
    62.         }
    63.  
    64.         placeholder.transform.SetSiblingIndex (newSiblingIndex);
    65.     }
    66.  
    67.     public void OnEndDrag(PointerEventData eventData) {
    68.         Debug.Log ("OnEndDrag");
    69.  
    70.         this.transform.SetParent (parentToReturnTo);
    71.         this.transform.SetSiblingIndex (placeholder.transform.GetSiblingIndex());
    72.  
    73.         GetComponent<CanvasGroup> ().blocksRaycasts = true;
    74.         Destroy (placeholder);
    75.     }
    76. }

    Field.cs
    Code (csharp):
    1.  
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5. using UnityEngine.EventSystems;
    6.  
    7. public class Field : MonoBehaviour, IPointerEnterHandler, IDropHandler, IPointerExitHandler{
    8.  
    9.     public Drag.Slot CardType = Drag.Slot.Monster;
    10.  
    11.     public void OnPointerEnter(PointerEventData eventData) {
    12.         //Debug.Log ("OnPointerEnter");
    13.         if (eventData.pointerDrag == null)
    14.             return;
    15.  
    16.         Drag d = eventData.pointerDrag.GetComponent<Drag> ();
    17.  
    18.         if (d != null) {
    19.             d.placeholderParent = this.transform;
    20.         }
    21.     }
    22.  
    23.     public void OnPointerExit(PointerEventData eventData) {
    24.         //Debug.Log ("OnPointerExit");
    25.         if (eventData.pointerDrag == null)
    26.             return;
    27.      
    28.         Drag d = eventData.pointerDrag.GetComponent<Drag> ();
    29.  
    30.         if (d != null && d.placeholderParent == this.transform) {
    31.             d.placeholderParent = d.parentToReturnTo;
    32.         }
    33.     }
    34.  
    35.     public void OnDrop(PointerEventData eventData) {
    36.      
    37.         Drag d = eventData.pointerDrag.GetComponent<Drag> ();
    38.  
    39.         if (d != null) {
    40.             if (CardType == d.CardType) {
    41.                 d.parentToReturnTo = this.transform;
    42.                 Debug.Log (eventData.pointerDrag.name + " was dropped on the " + gameObject.name + " as a " + CardType);
    43.  
    44.             } else {
    45.                 Debug.Log (eventData.pointerDrag.name + " can't be dropped on the " + gameObject.name + " as a " + d.CardType);
    46.                 return;
    47.             }
    48.         }
    49.     }
    50. }

    Thank you in advance,
    - Nervly
     
  2. SimonDarksideJ

    SimonDarksideJ

    Joined:
    Jul 3, 2012
    Posts:
    1,685
    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.
     
  3. Nervly

    Nervly

    Joined:
    Mar 15, 2016
    Posts:
    19
    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!