unity——滚动显示数据列表

一、脚本设置 

1、使用到数据结构类型

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

/// <summary>
/// 轮播数据
/// </summary>
[Serializable]
public class MessageDatas
{
    public bool success;
    public string message;
    public List<Item> items;
}
/// <summary>
/// 具体轮播内容
/// </summary>
[Serializable]
public class Item
{
    public string inform;
    ...
    ...
    ...
}
/// <summary>
/// 轮播设置
/// </summary>
[Serializable]
public class ScrollSet
{
    //对于一条信息:包含信息的文本在初始位置生成,
    //生成后移动到显示位置显示,一段时间后移动到结束位置销毁;
    public Vector2 endPos;//文本结束位置
    public Vector2 targetPos;//文本显示位置
    public Vector2 startPos;//文本生成初始位置

    public float scrollSpeed = 5;//文本移动速度
    public float stayTime = 5;//当前文本显示/停留时间
    public RectTransform textParent;//文本的父物体
    public TMP_Text textPrefab;//文本预制体
    public Queue<string> messageQueue = new Queue<string>();//信息队列
    public TMP_Text curText { get; set; }//当前显示的文本
    public TMP_Text nextText { get; set; }//下一个显示的文本
}

2、获取轮播显示的数据

using TMPro;
using System;
using UnityEngine;
using System.Collections;
using UnityEngine.Networking;
using System.Collections.Generic;

public class ScrollList : MonoBehaviour
{
    public string host;
    public string url;

    public ScrollSet scrollSet =new ScrollSet();
    public ScrollSet scrollSet2 = new ScrollSet();

    void OnEnable()
    {
        StartCoroutine("GetMessage", scrollSet);
    }

    ...
    ...
    ...

    //使用协程每隔一段时间获取更新信息一次
    IEnumerator GetMessage(ScrollSet scrollSet)
    {
        //更新获取信息的地址
        yield return new WaitUntil(() => !string.IsNullOrEmpty(host));
        StopCoroutine("ScrollInform");
        StartCoroutine("ScrollInform", scrollSet);
        string _url = string.Concat(host, url);
        //获取信息
        while (true)
        {
            UnityWebRequest unityWebRequest = new UnityWebRequest(_url);
            unityWebRequest.downloadHandler = new DownloadHandlerBuffer();
            yield return unityWebRequest.SendWebRequest();
            if (unityWebRequest.error == null)
            {
                //Debug.Log(unityWebRequest.downloadHandler.text);
                //将获取到的数据,转换为MessageDatas格式,并获取MessageDatas里的items数据,
                //并把items数据存到newMessages列表里
                List<Item> newMessages = JsonUtility.FromJson<MessageDatas>(unityWebRequest.downloadHandler.text).items;

                //遍历列表,把一条条数据放进队列里
                for (int i = 0; i < newMessages.Count; i++)
                {
                    if (!scrollSet.messageQueue.Contains(newMessages[i].inform)) scrollSet.messageQueue.Enqueue(newMessages[i].inform);
                }
                //结束请求
                unityWebRequest.Dispose();
            }
            else
            {
                Debug.Log(unityWebRequest.responseCode);
                Debug.Log(unityWebRequest.error);
                unityWebRequest.Dispose();
            }
            //隔段时间再次执行协程,获取数据
            yield return new WaitForSeconds(60f);
        }
    }
    
    ...
    ...
    ...
}

3,根据轮播设置,实现数据的轮播

using TMPro;
using System;
using UnityEngine;
using System.Collections;
using UnityEngine.Networking;
using System.Collections.Generic;

public class ScrollList : MonoBehaviour
{
    ...
    ...
    ...

    /// <summary>
    /// 滚动显示
    /// </summary>
    /// <returns></returns>
    IEnumerator ScrollInform(ScrollSet scrollSet)
    {
        //队列里有可以轮播的数据
        yield return new WaitUntil(() => scrollSet.messageQueue.Count > 0);
        
        //如果当前文本不存在,实例化出文本,并显示位置/目标位置直接显示出来
        if (!scrollSet.curText)
        {
            scrollSet.curText = Instantiate(scrollSet.textPrefab, scrollSet.textParent);
            scrollSet.curText.text = scrollSet.messageQueue.Dequeue();
            scrollSet.curText.rectTransform.anchoredPosition = scrollSet.targetPos;
        }
        while (true)
        {
            //根据轮播设置里的文本显示时间,显示当前文本
            yield return new WaitForSeconds(scrollSet.stayTime);
            //生成下一条显示的文本
            if (scrollSet.messageQueue.Count > 0)
            {
                if (!scrollSet.nextText) scrollSet.nextText = Instantiate(scrollSet.textPrefab, scrollSet.textParent);
                //设置文本值和初始位置
                scrollSet.nextText.text = scrollSet.messageQueue.Dequeue();
                scrollSet.nextText.rectTransform.anchoredPosition = scrollSet.startPos;
            }

            //除非现在的文本接近结束位置,或下个显示的文本接近目标位置/显示位置
            while (Mathf.Abs(scrollSet.endPos.y - scrollSet.curText.rectTransform.anchoredPosition.y) >= 0.01f || Mathf.Abs(scrollSet.targetPos.y - scrollSet.nextText.rectTransform.anchoredPosition.y) >= 0.01f)
            {
                //持续将当前文本和下个文本移动到指定位置
                scrollSet.curText.rectTransform.anchoredPosition = Vector2.Lerp(scrollSet.curText.rectTransform.anchoredPosition, scrollSet.endPos, Time.deltaTime * scrollSet.scrollSpeed);
                scrollSet.nextText.rectTransform.anchoredPosition = Vector2.Lerp(scrollSet.nextText.rectTransform.anchoredPosition, scrollSet.targetPos, Time.deltaTime * scrollSet.scrollSpeed);
                yield return null;
            }
            //将当前文本和下个文本位置更新到指定位置
            scrollSet.curText.rectTransform.anchoredPosition = scrollSet.endPos;
            scrollSet.nextText.rectTransform.anchoredPosition = scrollSet.targetPos;
            //销毁当前文本
            Destroy(scrollSet.curText.gameObject);
            //将下个文本设为当前文本
            scrollSet.curText = scrollSet.nextText;
            //清空当前文本
            scrollSet.nextText = null;
            //轮播完,重新获取数据
            if (scrollSet.messageQueue.Count == 0)
            {
                StopCoroutine("GetMessage");
                StartCoroutine("GetMessage", scrollSet);
                break;
            }
        }
    }

    ...
    ...
    ...
}

二、unity——轮播对象设置

1、轮播管理控制

2、遮罩,仅看得到显示位置的内容

3、设置文本父物体下面的文本位置

猜你喜欢

转载自blog.csdn.net/weixin_43908355/article/details/124450932