0评论

Unity3D实现折叠面板效果

文章来自https://blog.csdn.net/weixin_39706943/article/details/80585374 2019-02-19 1.2k浏览

想免费获取内部独家PPT资料库?观看行业大牛直播?点击加入腾讯游戏学院游戏美术行业精英群167422913

Unity使用父对象的概念,要想让一个游戏对象成为另一个的子对象,只需在层次视图中把它拖到另一个上即可。一个子对象将继承其父对象的移动和旋转属性。在层级视图面板展开和折叠父对象来查看它的子对象,不会影响游戏,下面就来看看折叠面板效果的实现。

效果图:

代码如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class ParentMenu : MonoBehaviour
{
    private GameObject childMenu;//子菜单的parent
    private RectTransform[] childs;//所有子菜单的rect
    private RectTransform itemRect;//子菜单的prefab
    private Vector3 offset;//单个子菜单的高度
    private int count;//子菜单的个数
    public bool isOpening { get; private set; }//父菜单是否展开
    public bool isCanClick { get; set; }//父菜单是否可以点击
    public void Init(RectTransform rect, int count)
    {
        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;
    }
}

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class FoldableMenu : MonoBehaviour
{
    private RectTransform content;//父物体的parent
    private TextAsset textAsset;//所有菜单信息
    private RectTransform parentRect;//父菜单的prefab
    private RectTransform[] parentArr;//所有父菜单的数组
    private RectTransform childRect;//子菜单的prefab
    private Vector3 parentOffset;//单个父菜单的高度
    private Vector3 childOffset;//单个子菜单的高度
    private int[] cntArr;//所有父菜单拥有的子菜单个数
    void Awake()
    {
        Init();
    }
    void Init()
    {
        content = transform.Find("Viewport/Content").GetComponent<RectTransform>();
        textAsset = Resources.Load<TextAsset>("menuInfo");
        parentRect = Resources.Load<RectTransform>("parentMenu");
        parentOffset = new Vector3(0, parentRect.rect.height);
        childRect = Resources.Load<RectTransform>("item");
        childOffset = new Vector3(0, childRect.rect.height);
        var info = textAsset.text.Split(',');//获取子菜单个数信息
        cntArr = new int[info.Length];
        parentArr = new RectTransform[info.Length];
        //初始化content高度
        content.sizeDelta = new Vector2(content.rect.width, parentArr.Length * parentRect.rect.height);
        for (int i = 0; i < cntArr.Length; i++)
        {
            parentArr[i] = Instantiate(parentRect, content.transform);
            parentArr[i].localPosition -= i * parentOffset;
            cntArr[i] = int.Parse(info[i]);
            parentArr[i].GetComponent<ParentMenu>().Init(childRect, cntArr[i]);
            int j = i;
            parentArr[i].GetComponent<Button>().onClick.AddListener(() => { OnButtonClick(j); });
        }
    }
    void OnButtonClick(int i)
    {
        if (!parentArr[i].GetComponent<ParentMenu>().isCanClick) return;
        parentArr[i].GetComponent<ParentMenu>().isCanClick = false;
        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++)
        {
            //更新content高度
            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++)
        {
            //更新content高度
            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);
        }
    }
}

链接:https://pan.baidu.com/s/1K1clvQFMGzXGBus3fKve-g  密码:25v3