unity滚动循环翻页的pageview

因为业务需求需要做一个循环的列表,无限循环,

而unity自带的scrollview不满足循环的要求,所以就自定义了一个控件

控件结构如下:

下面是写的代码代码里的注释包含我的思路,以及优化方案

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

namespace MocoDog
{
    public class pageView : UIWindowBase
    {
        // Start is called before the first frame update
        public GameObject content;//父控件
        public GameObject preItem;  //cell

        public GameObject btnLeft;//父控件
        public GameObject btnRight;//父控件
        private float posx = 0;//初始位置
        private float cellSize = 0;//每次移动的距离
        private float maxPosX = 0;//当前最大位置X
        private float minPosX = 0;//当前最小位置

        private List<GameObject> itemList;//item存储容器

        void Start()
        {
            this.RegisterEvent(btnLeft, OnClickBtnLeft);
            this.RegisterEvent(btnRight, OnClickBtnRight);
         
            preItem.SetActive(false);
            var rt = preItem.GetComponent<RectTransform>();
            cellSize = rt.sizeDelta.x + 30;
            Debug.Log("====cellSize: " + cellSize);
            // var rt1 = content.GetComponent<RectTransform>();
            // posx = rt1.anchoredPosition.x;
            // Debug.Log("====rt1.posx: " + posx);
            InitItemList();
        }
        void InitItemList()
        {
            itemList = new List<GameObject>();
            for (int i = 0; i < 10; i++)
            {
                GameObject obj = GameObject.Instantiate(preItem);
                obj.transform.SetParent(content.GetComponent<Transform>());
                if (i == 9)
                {
                    obj.transform.localPosition = new Vector3(cellSize * -1,-200,0);
                    minPosX = cellSize * -1;
                }
                else
                {
                    obj.transform.localPosition = new Vector3(cellSize * i,-200,0);
                    maxPosX = cellSize * i;
                }
                obj.transform.Find("bg_count/Text").GetComponent<Text>().text = i.ToString();
                obj.transform.localScale = Vector3.one;
                if (!obj.activeSelf)
                    obj.SetActive(true);
                //添加元素到数组中
                itemList.Add(obj);
            }
            ListSort();
        }
        void OnClickBtnLeft(GameObject objname)
        { 
            posx = posx - cellSize;
            Debug.Log("====posx: " + posx);
            content.transform.DOLocalMoveX(posx, 0.4f);
            //
            var obj2 = itemList[4];
            ani2(obj2);
            var obj1 = itemList[1];
            ani1(obj1);
            //移动第一个子节点到最后面
            var obj = itemList[0];
            maxPosX = maxPosX + cellSize;
            minPosX = minPosX + cellSize;
            obj.transform.localPosition = new Vector3(maxPosX,-200,0);
            ListSort();
        }

        void OnClickBtnRight(GameObject objname)
        {
            posx = posx + cellSize;
            Debug.Log("====posx: " + posx);
            content.transform.DOLocalMoveX(posx, 0.4f);
            var obj1 = itemList[3];
            ani1(obj1);
            var obj2 = itemList[0];
            ani2(obj2);
            //移动一个子节点到最前面
            var obj = itemList[itemList.Count - 1];
            //改变obj的位置
            maxPosX = maxPosX - cellSize;
            minPosX = minPosX - cellSize;
            obj.transform.localPosition = new Vector3(minPosX,-200,0);
            //根据位置对List排序
            ListSort();
        }
        void ListSort()
        {
            itemList.Sort(
                delegate(GameObject p1,GameObject p2)
                {
                    return  p1.transform.localPosition.x.CompareTo( p2.transform.localPosition.x);//升序
                }
            );
            //做优化的话在这里将content位置归零然后遍历子节点更改位置 
            //可以用一个常量数组存储节点位置
            //同时重置最大坐标最小坐标
            //注意一定要在动作结束后执行
        }
        void ani1(GameObject obj)
        {
            RectTransform rectx = obj.GetComponent<RectTransform>();
            Sequence mySequence = DOTween.Sequence();
            mySequence.Append(rectx.DOScale(0.8f, 0.2f).SetEase(Ease.InSine));
            // mySequence.Append(rectx.DOScale(Vector3.one, 0.1f).OnComplete(() =>
            // {
            //     //动画完成
            // }));

        }
        void ani2(GameObject obj)
        {
            RectTransform rectx = obj.GetComponent<RectTransform>();
            Sequence mySequence = DOTween.Sequence();
            mySequence.Append(rectx.DOScale(1.2f, 0.2f).SetEase(Ease.InSine));
            mySequence.Append(rectx.DOScale(Vector3.one, 0.1f).OnComplete(() =>
            {
                //动画完成
            }));

        }
        // Update is called once per frame
        void Update()
        {
            
        }
    }
}

不足之处,由于是不停的移动content的位置,如果用户闲得无聊一直一个方向点击时间过长的话,有可能会出现posx超界的情况,所以可以在移动结束的时候将content的位置归零,然后遍历子节点更改位置,这部分代码我就不放出来了

源码地址:pageview.unitypackage_Unity无限循环滚动列表-Unity3D文档类资源-CSDN下载

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: Unity 中的无限循环滚动指的是在游戏中创建一个物体或背景等,让其在场景中无限循环滚动。这种效果可以在游戏中创建视差背景、无限滚动的平台、道路或是背景音乐等方面起到很好的效果。 实现无限循环滚动的方式有很多种,下面以一个2D平台为例来说明: 首先,我们需要创建一个滚动的背景物体,可以是一个长方形图片或者其他形状的物体。然后将其放在场景内的合适位置。 接下来,使用脚本控制滚动的逻辑。在脚本中,我们可以通过改变物体的位置来实现滚动的效果。 要实现无限循环滚动的效果,我们可以通过以下步骤: 1. 获取背景物体的宽度或长度,以确定每次滚动的距离。 2. 创建一个新的背景物体,并将其放在当前背景物体的后面,以实现无缝连接的效果。 3. 在Update函数中,每帧都向左移动背景物体一定的距离,并检查背景物体是否已经超出屏幕范围。 4. 如果背景物体已经完全离开了屏幕,就将其移动到当前背景物体的后面,形成循环滚动的效果。 通过这种方式,不断移动和循环使用背景物体,就可以实现无限循环滚动的效果。 当然,根据具体的需求,我们还可以根据游戏的逻辑来控制滚动的速度、方向以及触发滚动的条件等。同时,注意在性能方面的考虑,避免过多的无用计算和占用资源。 总结起来,通过在Unity中使用合适的脚本逻辑和循环操作,就可以实现无限循环滚动的效果,为游戏增加更好的视觉体验。 ### 回答2: Unity中实现无限循环滚动可以通过以下步骤: 步骤1:创建滚动组件 首先,在Unity中创建一个滚动组件,可以使用ScrollRect组件(滚动视图)和Content(滚动内容)对象来实现。将需要无限循环滚动项(例如图片、文本等)添加到Content对象中。 步骤2:设置滚动效果 通过调整ScrollRect组件的属性,可以设置滚动的速度、方向等参数。根据实际需求,设置滚动效果为水平或垂直方向。确保Content的大小大于滚动视图的大小,以便产生滚动效果。 步骤3:编写脚本 为了实现无限循环滚动,需要编写一个脚本。这个脚本在滚动项到达滚动边界时,会将该滚动项移动到对应的另一边,以产生无限循环的效果。 编写脚本时,需要监听滚动组件的滚动事件,当滚动事件触发时,判断滚动项是否到达滚动边界。如果到达边界,将该滚动项的位置移动到对应的另一边,从而实现无限循环滚动的效果。 步骤4:应用脚本 将编写好的脚本挂载到滚动组件上,运行游戏时即可看到无限循环滚动的效果。 通过以上步骤,我们可以在Unity中实现无限循环滚动。无论滚动项的数量多少,都能够实现循环滚动的效果,提升用户体验。 ### 回答3: Unity中的无限循环滚动是指在游戏中实现一个背景或者其他元素无限滚动的效果。这样可以给玩家带来一种连续的世界感,增加游戏的真实感。 要实现无限循环滚动,首先需要创建一个背景或者元素的材质(Material)。在这个材质中,我们可以将纹理(Texture)的平铺(Tiling)设置得很大,比如设置为(10, 1)。然后将这个材质应用到相应的模型或者Sprite上。 接下来,创建一个相机(Camera)并调整好它的位置和角度,使得它能够看到需要无限滚动的背景或者元素。然后将这个相机的背景色设为和游戏场景中其他元素的颜色一致,这样背景和其他元素的过渡会更加自然。 然后,我们需要编写一个脚本(Script)来实现滚动效果。在脚本中,我们可以使用相机的位置信息来计算滚动的距离。当相机的位置超过了一定阈值,我们就将背景或者元素的位置重置到初始位置,从而实现无限循环滚动。这个阈值可以根据具体游戏需求进行调整。 最后,将这个脚本挂载到主角(或者相机)上,使得滚动效果与玩家的移动进行同步。 总的来说,实现Unity中的无限循环滚动可以通过创建材质、调整相机位置、编写脚本来实现。这样就能够给玩家带来一个连续的世界感,增加游戏的真实感。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值