[UnityUI]动态滑动列表

UI布局是这样滴:



具体的关于滑动列表的设置可以参考这里,其中Image的Scroll Rect组件的Content赋值为Content,在这里,我们的Content是一个空物体,它的大小就是上图那个方框的大小。这里有两点很重要:

1.Content的Pivot的Y必须设置为Y的最大值,就像这样:


这是为什么呢?其实动态滑动列表的原理主要就是动态改变Content的Height,当中心点处于最顶的位置时,就能保证顶部位置不变,只有下部的位置在变化。假如中心点处于中间位置,那么改变Height,两边都会变化。

2.列表项的设置,要注意列表项预制体的Anchor Presets和Pivot,因为它们都会影响预制体实例化的位置,这里为了方便计算,我设置Anchor Presets为top-center,Pivot为(0.5,1)


最后给出代码:

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

public class TaskPanel : MonoBehaviour {

    public static TaskPanel instance;
    public List<GameObject> items = new List<GameObject>();

    public GameObject content;//内容
    public Vector2 contentSize;//内容的原始高度

    public GameObject item;//列表项
    public float itemHeight;
    public Vector3 itemLocalPos;
    
    void Awake()
    {
        if (!instance)
            instance = this;
        else
            Destroy(this);
    }

    void Start()
    {
        content = GameObject.Find("Content");
        contentSize = content.GetComponent<RectTransform>().sizeDelta;

        item = Resources.Load("Item") as GameObject;
        itemHeight = item.GetComponent<RectTransform>().rect.height;
        itemLocalPos = item.transform.localPosition; 
    }

    //添加列表项
    public void AddItem()
    {
        GameObject a = Instantiate(item) as GameObject;
        a.transform.parent = content.transform;
        a.transform.localPosition = new Vector3(itemLocalPos.x, itemLocalPos.y - items.Count * itemHeight, 0);
        items.Add(a);

        if (contentSize.y <= items.Count * itemHeight)//增加内容的高度
        {
            content.GetComponent<RectTransform>().sizeDelta = new Vector2(contentSize.x, items.Count * itemHeight);
        }
    }

    //移除列表项
    public void RemoveItem(GameObject t)
    {
        int index = items.IndexOf(t);
        items.Remove(t);
        Destroy(t);

        for (int i = index; i < items.Count; i++)//移除的列表项后的每一项都向前移动
        {
            items[i].transform.localPosition += new Vector3(0, itemHeight, 0);
        }

        if (contentSize.y <= items.Count * itemHeight)//调整内容的高度     
            content.GetComponent<RectTransform>().sizeDelta = new Vector2(contentSize.x, items.Count * itemHeight);
        else
            content.GetComponent<RectTransform>().sizeDelta = contentSize;
    }
}

效果图:



///

后面改进了一下:


设置一下Content的描点、中心点和宽高:


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

public class ScrollPanelVerticalLayout : MonoBehaviour {

    private List<Transform> items = new List<Transform>();
    private RectTransform contentRectTra;//内容  
    private VerticalLayoutGroup group;//用于计算内容的高度
    private float itemHeight;//子项的高度

	void Awake () 
    {
        contentRectTra = transform.FindChild("Content").GetComponent<RectTransform>();
        contentRectTra.sizeDelta = new Vector2(contentRectTra.sizeDelta.x, 0);
        group = contentRectTra.GetComponent<VerticalLayoutGroup>();
	}

    //添加列表项  
    public void AddItem(Transform t)
    {
        if (itemHeight == 0f) itemHeight = t.GetComponent<RectTransform>().rect.height;

        t.SetParent(contentRectTra.transform);
        t.localScale = Vector3.one;
        items.Add(t);

        contentRectTra.sizeDelta = new Vector2(contentRectTra.sizeDelta.x, 
            group.padding.top + group.padding.bottom + items.Count * itemHeight + (items.Count - 1) * group.spacing);
    }

    //移除列表项  
    public void RemoveItem(Transform t)
    {
        //Debug.Log(t.gameObject.name);
        int index = items.IndexOf(t);
        items.Remove(t);
        Destroy(t.gameObject);

        contentRectTra.sizeDelta = new Vector2(contentRectTra.sizeDelta.x,
            group.padding.top + group.padding.bottom + items.Count * itemHeight + (items.Count - 1) * group.spacing);
    }  

}

使用起来也很方便:

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

public class Test : MonoBehaviour {

    public ScrollPanelVerticalLayout scrollPanel;

    private int index = 0;
    public void Add()
    {
        GameObject go = Instantiate(Resources.Load("Item")) as GameObject;
        go.name = index.ToString();
        go.transform.FindChild("Text").GetComponent<Text>().text = index.ToString();
        go.transform.FindChild("Button").GetComponent<Button>().onClick.AddListener
        (
            () =>
            {
                Remove(go.transform);
            }
        );

        scrollPanel.AddItem(go.transform);
        index++;
    }

    void Remove(Transform t)
    {
        scrollPanel.RemoveItem(t);
    }

}


Unity UI 滑动旋转菜单是一种常见的交互设计,在游戏或应用程序中经常使用。它可以实现通过滑动手势来控制菜单的旋转方向和角度。 在Unity中,可以通过以下步骤来实现滑动旋转菜单: 1. 创建UI元素:首先,需要创建一个UI元素,例如一个滑动条或一个滑动面板。可以使用Unity内置的UI组件来创建,或者自己编写自定义的UI组件。 2. 添加滑动脚本:给滑动条或滑动面板添加一个脚本,用于处理滑动手势事件。可以使用Unity的事件系统来检测和响应滑动手势。 3. 控制菜单旋转:在滑动脚本中,根据滑动手势的方向和距离计算旋转的角度。可以使用Transform组件中的Rotate()方法来实现菜单的旋转。 4. 更新UI显示:在每一帧中,根据计算得到的旋转角度,更新菜单的UI显示。可以使用RectTransform组件来控制UI元素的位置和大小。 需要注意以下几点: 1. 滑动范围:要限制滑动的范围,避免菜单旋转过度或不足。可以设置滑动条的最小值和最大值,或者设置滑动面板的边界。 2. 交互效果:可以添加一些额外的交互效果,例如菜单随着滑动手势的速度而旋转的快慢,或者添加音效和动画效果。 3. 兼容性:要考虑到不同平台和设备的兼容性,确保滑动旋转菜单在各种设备上都能正常工作。 总的来说,Unity UI 滑动旋转菜单是一种简单而实用的交互方式,可以增加应用程序或游戏的用户体验。通过掌握相关的UI组件和脚本技术,可以轻松实现这种交互效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值