[Unity3D] UGUI Implementing Hierarchical Menu

I. Preface

Hierarchical menus are not used much in Unity. They are mainly used in classifying. Today, I will share some hierarchical codes with you. It is also good to expand them and write plug-ins.

Let's look at the effect first.
1.

2.

3.


4.

5.

II. Resource Download

Source files:
https://download.csdn.net/download/q764424567/11644500

III. Text

The first realization effect


Realization Principle: This is a script that uses UGUI Scroll View component that comes with the system. The script controls the creation of the parent object, and the parent object is loaded with the script that initializes the child object.
Advantages and disadvantages:
The advantage is that it is simple to implement, does not need many plug-ins, the amount of code is not large, and the control is more convenient.
The disadvantage is that only two levels of display can be achieved.
Implementation process:
1. Create a new Scrpll View

2. Prefabrication
That's the way the interface is designed:

Change the name
Content: parent node container
ParentMenu: parent node
TextParent: parent node text
ChildMenu: child node container
item: child node
TextChild: Subnode Text

Then the parent node is renamed parentMenu, which is prefabricated:

Prefabricated objects are placed in the Resources folder:

Subobjects are also fabricated into prefabricated bodies:

3. Writing script ParentMenu.cs
The main purpose of this script is to create sub-objects:

using System.Collections;
using UnityEngine;
using UnityEngine.UI;

public class ParentMenu : MonoBehaviour
{
    private GameObject childMenu;//parent of Submenu
    private RectTransform[] childs;//rect for all submenus
    private RectTransform itemRect;//prefab of submenu
    private Vector3 offset;//Height of a single submenu
    private int count;//Number of submenus
    public bool isOpening { get; private set; }//Does the parent menu expand
    public bool isCanClick { get; set; }//Is the parent menu clickable

    public void Init(RectTransform rect, int count)
    {
        //Find the child node
        childMenu = transform.Find("childMenu").gameObject;
        itemRect = rect;
        this.count = count;
        childs = new RectTransform[this.count];
        offset = new Vector3(0, itemRect.rect.height);
        for (int i = 0; i < this.count; i++)
        {
            childs[i] = Instantiate(itemRect, childMenu.transform);
        }
        childMenu.gameObject.SetActive(false);
        isOpening = false;
        isCanClick = true;
        GetComponent<Button>().onClick.AddListener(OnButtonClick);
    }

    void OnButtonClick()
    {
        if (!isCanClick) return;
        if (!isOpening)
            StartCoroutine(ShowChildMenu());
        else
            StartCoroutine(HideChildMenu());
    }

    IEnumerator ShowChildMenu()
    {
        childMenu.gameObject.SetActive(true);
        for (int i = 0; i < count; i++)
        {
            childs[i].localPosition -= i * offset;
            yield return new WaitForSeconds(0.1f);
        }
        isCanClick = true;
        isOpening = true;
    }

    IEnumerator HideChildMenu()
    {
        for (int i = count - 1; i >= 0; i--)
        {
            childs[i].localPosition += i * offset;
            yield return new WaitForSeconds(0.1f);
        }
        childMenu.gameObject.SetActive(false);
        isCanClick = true;
        isOpening = false;
    }
}

4. Writing script Foldable Menu.cs
This script is mainly for creating parent objects and controlling folding menus.

using System.Collections;
using UnityEngine;
using UnityEngine.UI;

public class FoldableMenu : MonoBehaviour
{
    private RectTransform content;//Parent of parent object
    private TextAsset textAsset;//All menu information
    private RectTransform parentRect;//prefab of the parent menu
    private RectTransform[] parentArr;//Array of all parent menus
    private RectTransform childRect;//prefab of submenu
    private Vector3 parentOffset;//Height of a single parent menu
    private Vector3 childOffset;//Height of a single parent menu
    private int[] cntArr;//Number of sub-menus owned by all parent menus

    void Awake()
    {
        Init();
    }

    void Init()
    {
        //Get to the parent node
        content = transform.Find("Viewport/Content").GetComponent<RectTransform>();
        //Access to information in menuinfo 334 455
        textAsset = Resources.Load<TextAsset>("menuInfo");
        //Gets the height of the parent object set by the parent object
        parentRect = Resources.Load<RectTransform>("parentMenu");
        parentOffset = new Vector3(0, parentRect.rect.height);
        //Get the height of the child object to set the child object
        childRect = Resources.Load<RectTransform>("item");
        childOffset = new Vector3(0, childRect.rect.height);
        //Split string info = 3 344 555
        var info = textAsset.text.Split(',');//Get information about the number of submenus
        //The length of the array
        cntArr = new int[info.Length];
        //Array of parent menu
        parentArr = new RectTransform[info.Length];
        //Initialize content height width invariant height is the total length of all parent objects
        content.sizeDelta = new Vector2(content.rect.width, parentArr.Length * parentRect.rect.height);
        //i = 6
        for (int i = 0; i < cntArr.Length; i++)
        {
            //Create a server
            parentArr[i] = Instantiate(parentRect, content.transform);
            //The width of the parent object in coordinates
            parentArr[i].localPosition -= i * parentOffset;
            //assignment
            cntArr[i] = int.Parse(info[i]);
            //The number of child objects loaded on the parent object is 334 455
            parentArr[i].GetComponent<ParentMenu>().Init(childRect, cntArr[i]);
            int j = i;
            //button Binding Event on the Parent Object
            parentArr[i].GetComponent<Button>().onClick.AddListener(() => { OnButtonClick(j); });
        }
    }

    void OnButtonClick(int i)
    {
        //If iscanclick is false, return cannot be clicked again because it has been clicked, unless it is true when it rises.
        if (!parentArr[i].GetComponent<ParentMenu>().isCanClick)
            return;
        parentArr[i].GetComponent<ParentMenu>().isCanClick = false;
        //isopening executes menuup for true and menuDown for flase
        if (!parentArr[i].GetComponent<ParentMenu>().isOpening)
            StartCoroutine(MenuDown(i));
        else
            StartCoroutine(MenuUp(i));
    }

    IEnumerator MenuDown(int index)
    {       
        for (int i = 0; i < cntArr[index]; i++)
        {
            //Update content height
            content.sizeDelta = new Vector2(content.rect.width,
                content.rect.height + childOffset.y);
            for (int j = index + 1; j < parentArr.Length; j++)
            {
                parentArr[j].localPosition -= childOffset;
            }
            yield return new WaitForSeconds(0.1f);
        }     
    }

    IEnumerator MenuUp(int index)
    {
        for (int i = 0; i < cntArr[index]; i++)
        {
            //Update content height
            content.sizeDelta = new Vector2(content.rect.width,
                content.rect.height - childOffset.y);
            for (int j = index + 1; j < parentArr.Length; j++)
            {
                parentArr[j].localPosition += childOffset;
            }
            yield return new WaitForSeconds(0.1f);
        }
    }
}

Mount this script on Scroll View:

Run, get it done!

The second effect


Realization Principle: This is also done with UGUI. The difference is that no container component is needed. It is mainly to find the parent node, then save the information of the parent node. The next node is offset with the parent node as the target, or the parent node as the target child node.
Advantages and disadvantages:
The advantages are clear code, strong scalability, and no need to design UGUI.
The disadvantage is that the structure is simple and the multi-level function is not realized.
Implementation process:
1. Create prefabrication

Simple structure, two images, arrow images with Button components (can be pulled down and merged)
Then place the prefabricated body in the Resources folder:

2. Writing PublicData.cs script
A Data Class

using UnityEngine;

public class PublicData
{
    public static Transform parent;
    public static Vector2 currentPosition;
}

3. Write the script Options_Triangle.cs
Functions to initialize subnodes

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

public class Options_Triangle : MonoBehaviour
{
    public Button triangle;
    public Image content;
    public List<Transform> children = new List<Transform>();
    void Start()
    {
        triangle.onClick.AddListener(() =>
        {
            if (triangle.transform.eulerAngles.z == 270)
            {
                triangle.transform.eulerAngles = Vector3.zero;
                for (int i = 0; i < children.Count; i++)
                {
                    children[i].gameObject.SetActive(false);
                }
            }
            else
            {
                triangle.transform.eulerAngles = new Vector3(0, 0, -90);
                for (int i = 0; i < children.Count; i++)
                {
                    children[i].gameObject.SetActive(true);
                }
            }
        });

    }
}

4. Writing ClickEvent.cs
This is a script for editing functions of a hierarchical menu

using UnityEngine;
using UnityEngine.UI;

public class ClickEvent : MonoBehaviour
{
    public Button add_options_t;
    public Button add_options;
    public Transform canvasParent;

    void Start()
    {
        add_options_t.onClick.AddListener(() =>
        {
            if (PublicData.parent == null)
            {
                PublicData.parent = Instantiate(Resources.Load<Transform>("Options_triangle"));
                PublicData.parent.transform.SetParent(canvasParent, false);
                PublicData.currentPosition = new Vector2(PublicData.parent.position.x, PublicData.parent.position.y);
            }
            else
            {
                Transform option = Instantiate(Resources.Load<Transform>("Options_triangle"));
                option.transform.SetParent(PublicData.parent, false);
                option.transform.position = new Vector3(PublicData.currentPosition.x + 30, PublicData.currentPosition.y - 32, 0);
                PublicData.parent.GetComponent<Options_Triangle>().triangle.transform.eulerAngles = new Vector3(0, 0, -90);
                PublicData.parent.GetComponent<Options_Triangle>().children.Add(option);
                PublicData.parent = option;
                PublicData.currentPosition = new Vector2(PublicData.parent.position.x, PublicData.parent.position.y);
            }

        });
        add_options.onClick.AddListener(() =>
        {
            if (PublicData.parent == null)
            {
                return;
            }
            PublicData.parent.GetComponent<Options_Triangle>().triangle.transform.eulerAngles = new Vector3(0, 0, -90);
            Transform content = Instantiate(Resources.Load<Transform>("Options"));
            content.transform.SetParent(PublicData.parent, false);
            content.transform.position = new Vector3(PublicData.currentPosition.x + 16, PublicData.currentPosition.y - 32, 0);
            PublicData.parent.GetComponent<Options_Triangle>().children.Add(content);
            PublicData.currentPosition = new Vector2(content.position.x - 16, content.position.y);

        });
    }
}

OK. Just mount the ClickEvent script on any object in the scene.

The third effect


Realization Principle: This is also done with UGUI, which is characterized by the use of Vertical Layout Group and Content Size Fitter components'automatic sorting function and Button's OnClick component to control the display and hiding of sub-objects to achieve the function of hierarchical menu.
Advantages and disadvantages:
The advantage is that it does not require code control and is easy to use.
The disadvantage is that the UI needs to be built in advance, the workload is relatively large, and then the time to change is time-consuming and energy-consuming.
Implementation process:
1. New Scroll View

2. Parent node


The parent node has a Button and a hidden Image

Button

There are two functions

The first one is to display BtnSelecteStyle, which is a child of Button, because BtnSelecteStyle is a child of Button, so BtnSelecteStyle will block Button, why do you want to block it, because it also needs OnClick of BtnSelecteStyle to collect the child nodes.
The OnClick mounting function of BtnSelecteStyle:

The second is the container that displays the child nodes, which is ImgBtnParentLayout.

This ImgBtnParentLayout is the container for the child node

Here are a few child nodes

OK. All right

The fourth realization effect


Realization Principle: This is generated dynamically by code. One script is mainly used to create parent and child objects, and parent-level relationship. The other script is to set location, change arrow, initialize button function.
Advantages and disadvantages:
The advantages are clear code and clear structure, which can realize hierarchical multi-level display, multi-level directory settings, tree-level menu and so on.
The disadvantage is that there is no code to judge the last node, the last node can not set pictures, and the function of the last node has not been added.
Implementation process:
1. Prefabrication is also the first step.







Arrow Button and Arrow Button 2 are designed to control the closure and display of sub-nodes. The difference is that Arrow Button is a small button on the left, and there is a picture display function. Arrow Button 2 is a button on the whole, but not on the whole, but clicking on the whole can realize the function of displaying and hiding sub-nodes.

Resources:



The picture is white, look carefully or you can see it - - then save and download it and put it in the project

2. Writing script ItemPanelBase.cs
This script is the script that sets the location of the node and the arrow switch.

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

public enum NameSort
{
    Default,
    Active,
    Passive
}
public class ItemPanelBase : MonoBehaviour
{
    private List<ItemPanelBase> childList;//Subobject set
    [HideInInspector]
    public Button downArrow;//Down arrow button
    public Button downArrow2;//Down arrow button
    public Sprite down, right, dot;
    public bool isOpen { get; set; }//Opening state of child object
    private Vector2 startSize;//Initial size

    NameSort m_NameSore = NameSort.Default;
    string m_Name;

    private void Awake()
    {
        childList = new List<ItemPanelBase>();
        downArrow = this.transform.Find("ContentPanel/ArrowButton").GetComponent<Button>();
        downArrow.onClick.AddListener(() =>
        {
            if (isOpen)
            {
                CloseChild();
                isOpen = false;
            }
            else
            {
                OpenChild();
                isOpen = true;
            }
        });
        downArrow2 = this.transform.Find("ContentPanel/ArrowButton2").GetComponent<Button>();
        downArrow2.onClick.AddListener(() =>
        {
            if (isOpen)
            {
                CloseChild();
                isOpen = false;
            }
            else
            {
                OpenChild();
                isOpen = true;
            }
        });
        startSize = this.GetComponent<RectTransform>().sizeDelta;
        isOpen = false;
    }

    //Add subobjects to collections
    private void AddChild(ItemPanelBase parentItemPanelBase)
    {
        childList.Add(parentItemPanelBase);
        if (childList.Count >= 1)
        {
            downArrow.GetComponent<Image>().sprite = right;
        }
    }

    //Set the name value of the current object
    public void SetName(string _name,NameSort m_sort)
    {
        m_Name = _name;
        m_NameSore = m_sort;
    }

    /// <summary>
    /// Set the parent object, the parent object is not a first-level menu
    /// </summary>
    /// <param name="parentItemPanelBase"></param>
    public void SetItemParent(ItemPanelBase parentItemPanelBase)
    {
        this.transform.parent = parentItemPanelBase.transform;
        parentItemPanelBase.AddChild(this);
        this.GetComponent<VerticalLayoutGroup>().padding = new RectOffset((int)parentItemPanelBase.downArrow.GetComponent<RectTransform>().sizeDelta.x, 0, 0, 0);
        if (parentItemPanelBase.isOpen)
        {

            this.GetComponent<ItemPanelBase>().AddParentSize((int)this.gameObject.GetComponent<RectTransform>().sizeDelta.y);
        }
        else
        {
            this.transform.gameObject.SetActive(false);
        }
    }

    /// <summary>
    /// Set the parent object as a first-level menu
    /// </summary>
    /// <param name="tran"></param>
    public void SetBaseParent(Transform tran)
    {
        this.transform.parent = tran;
    }

    /// <summary>
    /// Fill in Item data
    /// </summary>
    /// <param name="_name">name</param>
    public void InitPanelContent(string _name)
    {
        transform.Find("ContentPanel/Text").GetComponent<Text>().text = _name;
    }

    /// <summary>
    /// Update Panel size after adding a child object
    /// </summary>
    /// <param name="change"></param>
    public void UpdateRectTranSize(int change)
    {
        this.gameObject.GetComponent<RectTransform>().sizeDelta = new Vector2(startSize.x, this.gameObject.GetComponent<RectTransform>().sizeDelta.y + change);
    }
    /// <summary>
    /// Increase the height of the parent object
    /// </summary>
    /// <param name="parentItem"></param>
    /// <param name="change"></param>
    public void AddParentSize(int change)
    {
        if (this.transform.parent.GetComponent<ItemPanelBase>() != null)
        {
            this.transform.parent.GetComponent<ItemPanelBase>().UpdateRectTranSize(change);
            this.transform.parent.GetComponent<ItemPanelBase>().AddParentSize(change);
        }
    }

    /// <summary>
    /// Close the list of child objects
    /// </summary>
    public void CloseChild()
    {
        if (childList.Count == 0) return;
        foreach (ItemPanelBase child in childList)
        {
            child.gameObject.SetActive(false);
            child.GetComponent<ItemPanelBase>().AddParentSize(-(int)child.gameObject.GetComponent<RectTransform>().sizeDelta.y);
        }
        downArrow.GetComponent<Image>().sprite = right;
    }

    /// <summary>
    /// Open the list of child objects
    /// </summary>
    public void OpenChild()
    {
        if (childList.Count == 0)
        {
            if (m_Name == "125K Card reader" && m_NameSore == NameSort.Active)
            {
                Debug.Log("125k equipment");
            }
            return;
        }

        foreach (ItemPanelBase child in childList)
        {
            child.gameObject.SetActive(true);
            child.GetComponent<ItemPanelBase>().AddParentSize((int)child.gameObject.GetComponent<RectTransform>().sizeDelta.y);
        }
        downArrow.GetComponent<Image>().sprite = down;

    }
}

3. Write the script PullDownList.cs
This is the script for creating hierarchical menus:
Comparatively tedious

using System.Collections.Generic;
using UnityEngine;

public class PullDownList : MonoBehaviour
{
    private List<GameObject> itemPanelList;
    public GameObject itemPanel;

    private void Awake()
    {
        itemPanelList = new List<GameObject>();
    }

    void Start()
    {
        for (int i = 0; i < 27; i++)
        {
            //Level 1 menu
            if(i == 0)
            {
                GameObject newItemPanel = Instantiate(itemPanel);
                itemPanelList.Add(newItemPanel);
                newItemPanel.GetComponent<ItemPanelBase>().SetBaseParent(this.transform);
                newItemPanel.GetComponent<ItemPanelBase>().InitPanelContent("Level I");
            }
            //Level 2 menu
            if (i == 1)
            {
                GameObject newItemPanel2 = Instantiate(itemPanel);
                itemPanelList.Add(newItemPanel2);
                newItemPanel2.GetComponent<ItemPanelBase>().SetItemParent(itemPanelList[0].GetComponent<ItemPanelBase>());
                newItemPanel2.GetComponent<ItemPanelBase>().InitPanelContent("Level II");
            }
            else if (i == 2)
            {
                GameObject newItemPanel2 = Instantiate(itemPanel);
                itemPanelList.Add(newItemPanel2);
                newItemPanel2.GetComponent<ItemPanelBase>().SetItemParent(itemPanelList[0].GetComponent<ItemPanelBase>());
                newItemPanel2.GetComponent<ItemPanelBase>().InitPanelContent("Level II");
            }
            //Level 3 menu
            else if (i == 3)
            {
                GameObject newItemPanel2 = Instantiate(itemPanel);
                itemPanelList.Add(newItemPanel2);
                newItemPanel2.GetComponent<ItemPanelBase>().SetItemParent(itemPanelList[1].GetComponent<ItemPanelBase>());
                newItemPanel2.GetComponent<ItemPanelBase>().InitPanelContent("Level III");
            }
            else if (i == 4)
            {
                GameObject newItemPanel2 = Instantiate(itemPanel);
                itemPanelList.Add(newItemPanel2);
                newItemPanel2.GetComponent<ItemPanelBase>().SetItemParent(itemPanelList[1].GetComponent<ItemPanelBase>());
                newItemPanel2.GetComponent<ItemPanelBase>().InitPanelContent("Level III");
            }
            else if (i == 5)
            {
                GameObject newItemPanel2 = Instantiate(itemPanel);
                itemPanelList.Add(newItemPanel2);
                newItemPanel2.GetComponent<ItemPanelBase>().SetItemParent(itemPanelList[1].GetComponent<ItemPanelBase>());
                newItemPanel2.GetComponent<ItemPanelBase>().InitPanelContent("Level III");
            }
            else if (i == 6)
            {
                GameObject newItemPanel2 = Instantiate(itemPanel);
                itemPanelList.Add(newItemPanel2);
                newItemPanel2.GetComponent<ItemPanelBase>().SetItemParent(itemPanelList[1].GetComponent<ItemPanelBase>());
                newItemPanel2.GetComponent<ItemPanelBase>().InitPanelContent("Level III");
            }
            else if (i == 7)
            {
                GameObject newItemPanel2 = Instantiate(itemPanel);
                itemPanelList.Add(newItemPanel2);
                newItemPanel2.GetComponent<ItemPanelBase>().SetItemParent(itemPanelList[2].GetComponent<ItemPanelBase>());
                newItemPanel2.GetComponent<ItemPanelBase>().InitPanelContent("Level III");
            }
            else if (i == 8)
            {
                GameObject newItemPanel2 = Instantiate(itemPanel);
                itemPanelList.Add(newItemPanel2);
                newItemPanel2.GetComponent<ItemPanelBase>().SetItemParent(itemPanelList[2].GetComponent<ItemPanelBase>());
                newItemPanel2.GetComponent<ItemPanelBase>().InitPanelContent("Level III");
            }
            else if (i == 9)
            {
                GameObject newItemPanel2 = Instantiate(itemPanel);
                itemPanelList.Add(newItemPanel2);
                newItemPanel2.GetComponent<ItemPanelBase>().SetItemParent(itemPanelList[2].GetComponent<ItemPanelBase>());
                newItemPanel2.GetComponent<ItemPanelBase>().InitPanelContent("Level III");
            }
            else if (i == 10)
            {
                GameObject newItemPanel2 = Instantiate(itemPanel);
                itemPanelList.Add(newItemPanel2);
                newItemPanel2.GetComponent<ItemPanelBase>().SetItemParent(itemPanelList[2].GetComponent<ItemPanelBase>());
                newItemPanel2.GetComponent<ItemPanelBase>().InitPanelContent("Level III");
            }
            //Level 4 menu
            else if (i == 11)
            {
                GameObject newItemPanel2 = Instantiate(itemPanel);
                itemPanelList.Add(newItemPanel2);
                newItemPanel2.GetComponent<ItemPanelBase>().SetItemParent(itemPanelList[3].GetComponent<ItemPanelBase>());
                newItemPanel2.GetComponent<ItemPanelBase>().InitPanelContent("Level IV");
                newItemPanel2.GetComponent<ItemPanelBase>().SetName("Level IV", NameSort.Active);
            }
            else if (i == 12)
            {
                GameObject newItemPanel2 = Instantiate(itemPanel);
                itemPanelList.Add(newItemPanel2);
                newItemPanel2.GetComponent<ItemPanelBase>().SetItemParent(itemPanelList[3].GetComponent<ItemPanelBase>());
                newItemPanel2.GetComponent<ItemPanelBase>().InitPanelContent("Level IV");
                newItemPanel2.GetComponent<ItemPanelBase>().SetName("Level IV", NameSort.Active);
            }
            else if (i == 13)
            {
                GameObject newItemPanel2 = Instantiate(itemPanel);
                itemPanelList.Add(newItemPanel2);
                newItemPanel2.GetComponent<ItemPanelBase>().SetItemParent(itemPanelList[4].GetComponent<ItemPanelBase>());
                newItemPanel2.GetComponent<ItemPanelBase>().InitPanelContent("Level IV");
                newItemPanel2.GetComponent<ItemPanelBase>().SetName("Level IV", NameSort.Active);
            }
            else if (i == 14)
            {
                GameObject newItemPanel2 = Instantiate(itemPanel);
                itemPanelList.Add(newItemPanel2);
                newItemPanel2.GetComponent<ItemPanelBase>().SetItemParent(itemPanelList[4].GetComponent<ItemPanelBase>());
                newItemPanel2.GetComponent<ItemPanelBase>().InitPanelContent("Level IV");
                newItemPanel2.GetComponent<ItemPanelBase>().SetName("Level IV", NameSort.Active);
            }
            else if (i == 15)
            {
                GameObject newItemPanel2 = Instantiate(itemPanel);
                itemPanelList.Add(newItemPanel2);
                newItemPanel2.GetComponent<ItemPanelBase>().SetItemParent(itemPanelList[5].GetComponent<ItemPanelBase>());
                newItemPanel2.GetComponent<ItemPanelBase>().InitPanelContent("Level IV");
                newItemPanel2.GetComponent<ItemPanelBase>().SetName("Level IV", NameSort.Active);
            }
            else if (i == 16)
            {
                GameObject newItemPanel2 = Instantiate(itemPanel);
                itemPanelList.Add(newItemPanel2);
                newItemPanel2.GetComponent<ItemPanelBase>().SetItemParent(itemPanelList[5].GetComponent<ItemPanelBase>());
                newItemPanel2.GetComponent<ItemPanelBase>().InitPanelContent("Level IV");
                newItemPanel2.GetComponent<ItemPanelBase>().SetName("Level IV", NameSort.Active);
            }
            else if (i == 17)
            {
                GameObject newItemPanel2 = Instantiate(itemPanel);
                itemPanelList.Add(newItemPanel2);
                newItemPanel2.GetComponent<ItemPanelBase>().SetItemParent(itemPanelList[6].GetComponent<ItemPanelBase>());
                newItemPanel2.GetComponent<ItemPanelBase>().InitPanelContent("Level IV");
                newItemPanel2.GetComponent<ItemPanelBase>().SetName("Level IV", NameSort.Active);
            }
            else if (i == 18)
            {
                GameObject newItemPanel2 = Instantiate(itemPanel);
                itemPanelList.Add(newItemPanel2);
                newItemPanel2.GetComponent<ItemPanelBase>().SetItemParent(itemPanelList[6].GetComponent<ItemPanelBase>());
                newItemPanel2.GetComponent<ItemPanelBase>().InitPanelContent("Level IV");
                newItemPanel2.GetComponent<ItemPanelBase>().SetName("Level IV", NameSort.Active);
            }
            else if (i == 19)
            {
                GameObject newItemPanel2 = Instantiate(itemPanel);
                itemPanelList.Add(newItemPanel2);
                newItemPanel2.GetComponent<ItemPanelBase>().SetItemParent(itemPanelList[7].GetComponent<ItemPanelBase>());
                newItemPanel2.GetComponent<ItemPanelBase>().InitPanelContent("Level IV");
                newItemPanel2.GetComponent<ItemPanelBase>().SetName("Level IV", NameSort.Passive);
            }
            else if (i == 20)
            {
                GameObject newItemPanel2 = Instantiate(itemPanel);
                itemPanelList.Add(newItemPanel2);
                newItemPanel2.GetComponent<ItemPanelBase>().SetItemParent(itemPanelList[7].GetComponent<ItemPanelBase>());
                newItemPanel2.GetComponent<ItemPanelBase>().InitPanelContent("Level IV");
                newItemPanel2.GetComponent<ItemPanelBase>().SetName("Level IV", NameSort.Passive);
            }
            else if (i == 21)
            {
                GameObject newItemPanel2 = Instantiate(itemPanel);
                itemPanelList.Add(newItemPanel2);
                newItemPanel2.GetComponent<ItemPanelBase>().SetItemParent(itemPanelList[8].GetComponent<ItemPanelBase>());
                newItemPanel2.GetComponent<ItemPanelBase>().InitPanelContent("Level IV");
                newItemPanel2.GetComponent<ItemPanelBase>().SetName("Level IV", NameSort.Passive);
            }
            else if (i == 22)
            {
                GameObject newItemPanel2 = Instantiate(itemPanel);
                itemPanelList.Add(newItemPanel2);
                newItemPanel2.GetComponent<ItemPanelBase>().SetItemParent(itemPanelList[8].GetComponent<ItemPanelBase>());
                newItemPanel2.GetComponent<ItemPanelBase>().InitPanelContent("Level IV");
                newItemPanel2.GetComponent<ItemPanelBase>().SetName("Level IV", NameSort.Passive);
            }
            else if (i == 23)
            {
                GameObject newItemPanel2 = Instantiate(itemPanel);
                itemPanelList.Add(newItemPanel2);
                newItemPanel2.GetComponent<ItemPanelBase>().SetItemParent(itemPanelList[9].GetComponent<ItemPanelBase>());
                newItemPanel2.GetComponent<ItemPanelBase>().InitPanelContent("Level IV");
                newItemPanel2.GetComponent<ItemPanelBase>().SetName("Level IV", NameSort.Passive);
            }
            else if (i == 24)
            {
                GameObject newItemPanel2 = Instantiate(itemPanel);
                itemPanelList.Add(newItemPanel2);
                newItemPanel2.GetComponent<ItemPanelBase>().SetItemParent(itemPanelList[9].GetComponent<ItemPanelBase>());
                newItemPanel2.GetComponent<ItemPanelBase>().InitPanelContent("Level IV");
                newItemPanel2.GetComponent<ItemPanelBase>().SetName("Level IV", NameSort.Passive);
            }
            else if (i == 25)
            {
                GameObject newItemPanel2 = Instantiate(itemPanel);
                itemPanelList.Add(newItemPanel2);
                newItemPanel2.GetComponent<ItemPanelBase>().SetItemParent(itemPanelList[10].GetComponent<ItemPanelBase>());
                newItemPanel2.GetComponent<ItemPanelBase>().InitPanelContent("Level IV");
                newItemPanel2.GetComponent<ItemPanelBase>().SetName("Level IV", NameSort.Passive);
            }
            else if (i == 26)
            {
                GameObject newItemPanel2 = Instantiate(itemPanel);
                itemPanelList.Add(newItemPanel2);
                newItemPanel2.GetComponent<ItemPanelBase>().SetItemParent(itemPanelList[10].GetComponent<ItemPanelBase>());
                newItemPanel2.GetComponent<ItemPanelBase>().InitPanelContent("Level IV");
                newItemPanel2.GetComponent<ItemPanelBase>().SetName("Level IV", NameSort.Passive);
            }
        }
    }
}

Mount the script on Panel

OK, Great Achievement

The fifth effect


Realization Principle: This is a hierarchical menu built by UI, and then through code control object hiding and display, it can realize the folding and drop-down function of hierarchical menu. It is mainly used in the GridLayout Group component to sort and update.
Advantages and disadvantages:
The advantage is that the operation is simple, the code is simple, and it does not need too much understanding. Then it can display multi-level menus, multi-level content, and the function of the last node and the function of setting pictures.
The disadvantage is that UI needs to be built in advance, which has poor scalability, heavy workload in the early stage, and heavy workload in the later stage. The most important thing is that I think this way of implementation is quite low.
Implementation process:
1. Display making UI
Mount the GridLayoutGroup component on Panel

Making UI


UI is very simple. Two sub-objects under a Button, one text and one image, text is the display content, and image is the display arrow.

At this point, someone asked what to do with the sub-object, which has the same structure as the sub-object.
Just pull back the image.

The same goes for the three-tier menu:

Add a first-level menu:

Is it so easy? Hahaha is really good low

The scripting function is simple.
The first-level menu controls the hiding of all its descending subnodes in the display

The secondary menu controls the hiding of all its descending subnodes in the display

And so on....

2. Editing code PullDown.cs

using UnityEngine;
using UnityEngine.UI;

public class PullDown : MonoBehaviour
{
    public Button m_Btn1;//Level 1 menu button
    public Button m_Btn2;//Level 2 menu button
    public Button m_Btn3;//Three-level menu button

    bool m_is1;//Global parameter control switch
    bool m_is2;//Global parameter control switch

    void Start()
    {
        m_is1 = true;
        m_is2 = true;
        m_Btn1.onClick.AddListener(Btn1_Event);
        m_Btn2.onClick.AddListener(Btn2_Event);
    }

    public void Btn1_Event()
    {
        if (m_is1)
        {
            m_Btn2.gameObject.SetActive(false);
            m_Btn3.gameObject.SetActive(false);
            m_is1 = false;
        }
        else
        {
            m_Btn2.gameObject.SetActive(true);
            m_Btn3.gameObject.SetActive(true);
            m_is1 = true;
        }
    }

    public void Btn2_Event()
    {
        if (m_is2)
        {
            m_Btn3.gameObject.SetActive(false);
            m_is2 = false;
        }
        else
        {
            m_Btn3.gameObject.SetActive(true);
            m_is1 = true;
        }
    }
}

OK, go and try it.

Tags: Unity

Posted on Fri, 30 Aug 2019 03:56:28 -0700 by bdmovies