iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >Unity实现卡片循环滚动效果的示例详解
  • 528
分享到

Unity实现卡片循环滚动效果的示例详解

Unity卡片循环滚动效果Unity循环滚动效果Unity滚动 2022-12-09 12:12:33 528人浏览 薄情痞子
摘要

目录简介定义卡片的摆放规则调整卡片的层级关系调整卡片的尺寸大小动态调整位置、层级和大小移动动画按钮事件简介 功能需求如图所示,点击下一个按钮,所有卡片向右滚动,其中最后一张需要变更为

简介

功能需求如图所示,点击下一个按钮,所有卡片向右滚动,其中最后一张需要变更为最前面的一张,点击上一个按钮,所有卡片向左滚动,最前面的一张需要变更为最后一张,实现循环滚动效果。

最中间的一张表示当前选中项,变更为选中项的滚动过程中,需要逐渐放大到指定值,相反则需要恢复到默认大小。

实现思路:

  • 定义卡片的摆放规则;
  • 调整卡片的层级关系;
  • 调整卡片的尺寸大小;
  • 卡片向指定方向移动,动态调整位置、大小、层级关系。

定义卡片的摆放规则

第一张卡片放在正中间,其余卡片分成两部分分别放在左右两侧,因此如果卡片数量为奇数,则左右两侧卡片数量一致,如果卡片数量为偶数,多出的一张需要放到左侧或者右侧,这里我们定义为放到右侧。

卡片摆放的顺序如下图所示,在遍历生成时会判断当前索引是否小等于卡片数量/2,是则将卡片生成在索引值*指定卡片间距的位置上,否则将其生成在(索引值-卡片数量)*指定卡片间距的位置上。

代码实现:

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

public class LoopScrollView : MonoBehaviour
{
    [SerializeField] private Texture[] roomTextures; //所有卡片
    [SerializeField] private GameObject itemPrefab; //列表项预制体
    [SerializeField] private TransfORM itemParent; //列表项的父级,将卡片生成到该物体下
    [SerializeField] private float interval = 450f; //卡片之间的间距

    private void Start()
    {
        for (int i = 0; i < roomTextures.Length; i++)
        {
            var tex = roomTextures[i];
            var instance = Instantiate(itemPrefab);
            instance.SetActive(true);
            instance.transform.SetParent(itemParent, false);
            instance.GetComponent<RawImage>().texture = tex;
            instance.name = i.ToString();

            //坐标位置
            (instance.transform as RectTransform).anchoredPosition3D = Vector3.right * interval
                * (i <= roomTextures.Length / 2 ? i : (i - roomTextures.Length));
        }
    }
}

调整卡片的层级关系

卡片的层级关系如图所示,第一张也就是中间的照片(编号0)需要在最上层,向左、向右逐渐遮挡下层,在Hierarchy层级窗口的表现则是编号0的卡片在最下方,编号1卡片在编号2卡片下方以遮挡编号2卡片,编号4卡片在编号3卡片下方以遮挡编号3卡片。

在遍历生成卡片时判断当前索引值是否小等于卡片数量/2,是则在层级中将其插入到最上方,也就是SiblingIndex=0,否则将其插入在第一张卡片之上,第一张卡片始终在最下方,也就是说插入为倒数第二个,即SiblingIndex=父节点的子物体数量-2。

代码如下:

//层级关系
instance.transform.SetSiblingIndex(i <= roomTextures.Length / 2 ? 0 : itemParent.childCount - 2);

调整卡片的尺寸大小

大小的调整比较简单,只需要将第一张卡片放大一定倍数即可。

//大小
instance.transform.localScale = (i == 0 ? 1.2f : 1f) * Vector3.one;

至此已经完成了卡片的生成,但是如何在点击上一个、下一个按钮时动态调整所有卡片的坐标、层级和大小才是关键。

动态调整位置、层级和大小

移动动画

首先为每张卡片添加脚本,用于实现卡片的移动逻辑,使用插值的形式来实现动画过程,假设动画所需时长为0.5秒,使用变量float类型变量timer来计时,自增Time.deltaTime * 2以使其在0.5秒内的取值从0增加为1,并使用Mathf.Clamp01来钳制其取值范围不要超过1。

代码如下:

using UnityEngine;

public class LoopScrollViewItem : MonoBehaviour
{
    private RectTransform rectTransform;
    private int index; //用于记录当前所在位置
    private Vector3 cacheScale; //开始移动时的大小
    private Vector3 cacheAnchorPosition3d; //开始移动时的坐标
    private Vector3 targetAnchorPostion3D; //目标坐标
    private int targetSiblingIndex; //目标层级
    private bool isMoving; //是否正在移动标识
    private float timer; //计时
    private bool last; //是否为最右侧的那张卡片

    private void Awake()
    {
        rectTransform = GetComponent<RectTransform>();
    }

    public int Index
    {
        get
        {
            return index;
        }
        set
        {
            if (index != value)
            {
                index = value;
            }
        }
    }

    private void Update()
    {
        if (isMoving)
        {
            timer += Time.deltaTime * 2f; 
            timer = Mathf.Clamp01(timer);
            if (timer >= .2f)
            {
                transform.SetSiblingIndex(targetSiblingIndex);
            }
            rectTransform.anchoredPosition3D = Vector3.Lerp(cacheAnchorPosition3d, targetAnchorPostion3D, last ? 1f : timer);
            transform.localScale = Vector3.Lerp(cacheScale, (index == 0 ? 1.3f : 1f) * Vector3.one, last ? 1f : timer);
            if (timer == 1f)
            {
                isMoving = false;
            }
        }
    }

    public void Move(LoopScrollViewData data, bool last)
    {
        timer = 0f;
        targetAnchorPostion3D = data.AnchorPosition3D;
        targetSiblingIndex = data.SiblingIndex;
        cacheAnchorPosition3d = rectTransform.anchoredPosition3D;
        cacheScale = transform.localScale;
        isMoving = true;
        this.last = last;
    }
}

其中last变量用于标识是否为最右侧的那张卡片,如果是,使其立即变为最左侧的卡片,不表现动画过程,目的是为了防止如下图所示,卡片从最右侧移动到最左侧的穿帮现象:

在生成卡片时,为卡片物体添加该脚本,并添加到列表中进行缓存,同时,定义一个用于存储各编号对应的层级和坐标的数据结构,代码如下:

using UnityEngine;

public class LoopScrollViewData
{
    public int SiblingIndex { get; private set; }

    public Vector3 AnchorPosition3D { get; private set; }

    public LoopScrollViewData(int siblingIndex, Vector3 anchorPosition3D)
    {
        SiblingIndex = siblingIndex;
        AnchorPosition3D = anchorPosition3D;
    }
}
using UnityEngine;
using UnityEngine.UI;
using System.Collections.Generic;

public class LoopScrollView : MonoBehaviour
{
    [SerializeField] private Texture[] roomTextures; //所有卡片
    [SerializeField] private GameObject itemPrefab; //列表项预制体
    [SerializeField] private Transform itemParent; //列表项的父级,将卡片生成到该物体下
    [SerializeField] private float interval = 400f; //卡片之间的间距
    
    //生成的卡片列表
    private readonly List<LoopScrollViewItem> itemList = new List<LoopScrollViewItem>();
    //字典用于存储各位置对应的卡片层级和坐标
    private readonly Dictionary<int, LoopScrollViewData> map = new Dictionary<int, LoopScrollViewData>();

    private void Start()
    {
        for (int i = 0; i < roomTextures.Length; i++)
        {
            var tex = roomTextures[i];
            var instance = Instantiate(itemPrefab);
            instance.SetActive(true);
            instance.transform.SetParent(itemParent, false);
            instance.GetComponent<RawImage>().texture = tex;
            instance.name = i.ToString();

            //坐标位置
            (instance.transform as RectTransform).anchoredPosition3D = Vector3.right * interval
                * (i <= roomTextures.Length / 2 ? i : (i - roomTextures.Length));
            //层级关系
            instance.transform.SetSiblingIndex(i <= roomTextures.Length / 2 ? 0 : itemParent.childCount - 2);
            //大小
            instance.transform.localScale = (i == 0 ? 1.2f : 1f) * Vector3.one;

            var item = instance.AddComponent<LoopScrollViewItem>();
            item.Index = i;
            itemList.Add(item);
        }
        for (int i = 0; i < itemList.Count; i++)
        {
            var item = itemList[i];
            map.Add(i, new LoopScrollViewData(item.transform.GetSiblingIndex(), (item.transform as RectTransform).anchoredPosition3D));
        }
    }
}

按钮事件

在生成卡片时,记录了卡片当前的编号,以及各编号对应的层级和位置,在点击下一个、上一个按钮时,只需要根据卡片当前的编号+1-1来获取目标层级和位置即可。

编号自增后,如果等于卡片的数量,表示当前卡片已经是列表中最后一个,需要将其编号设为0,相反,当编号自减后,如果小于0,表示当前卡片已经是列表中第一个,需要将其编号设为列表长度-1,以实现循环。

完整代码:

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

public class LoopScrollView : MonoBehaviour
{
    [SerializeField] private Texture[] roomTextures; //所有卡片
    [SerializeField] private GameObject itemPrefab; //列表项预制体
    [SerializeField] private Transform itemParent; //列表项的父级,将卡片生成到该物体下
    [SerializeField] private Button prevButton; //上一个按钮
    [SerializeField] private Button nextButton; //下一个按钮
    [SerializeField] private float interval = 400f; //卡片之间的间距
    
    //生成的卡片列表
    private readonly List<LoopScrollViewItem> itemList = new List<LoopScrollViewItem>();
    //字典用于存储各位置对应的卡片层级和坐标
    private readonly Dictionary<int, LoopScrollViewData> map = new Dictionary<int, LoopScrollViewData>();

    private void Start()
    {
        for (int i = 0; i < roomTextures.Length; i++)
        {
            var tex = roomTextures[i];
            var instance = Instantiate(itemPrefab);
            instance.SetActive(true);
            instance.transform.SetParent(itemParent, false);
            instance.GetComponent<RawImage>().texture = tex;
            instance.name = i.ToString();

            //坐标位置
            (instance.transform as RectTransform).anchoredPosition3D = Vector3.right * interval
                * (i <= roomTextures.Length / 2 ? i : (i - roomTextures.Length));
            //层级关系
            instance.transform.SetSiblingIndex(i <= roomTextures.Length / 2 ? 0 : itemParent.childCount - 2);
            //大小
            instance.transform.localScale = (i == 0 ? 1.2f : 1f) * Vector3.one;

            var item = instance.AddComponent<LoopScrollViewItem>();
            item.Index = i;
            itemList.Add(item);
        }
        for (int i = 0; i < itemList.Count; i++)
        {
            var item = itemList[i];
            map.Add(i, new LoopScrollViewData(item.transform.GetSiblingIndex(), (item.transform as RectTransform).anchoredPosition3D));
        }

        //添加按钮点击事件
        nextButton.onClick.AddListener(OnNextButtonClick);
        prevButton.onClick.AddListener(OnPrevButtonClick);
    }

    //下一个按钮点击事件
    private void OnNextButtonClick()
    {
        for (int i = 0; i < itemList.Count; i++)
        {
            var item = itemList[i];
            bool last = item.Index == itemList.Count / 2;
            int index = item.Index + 1;
            index = index >= itemList.Count ? 0 : index;
            item.Index = index;
            item.Move(map[index], last);
        }
    }
    //上一个按钮点击事件
    private void OnPrevButtonClick()
    {
        for (int i = 0; i < itemList.Count; i++)
        {
            var item = itemList[i];
            int index = item.Index - 1;
            index = index < 0 ? itemList.Count - 1 : index;
            item.Index = index;
            item.Move(map[index], false);
        }
    }
}

到此这篇关于Unity实现卡片循环滚动效果的示例详解的文章就介绍到这了,更多相关Unity卡片循环滚动效果内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: Unity实现卡片循环滚动效果的示例详解

本文链接: https://www.lsjlt.com/news/174635.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Unity实现卡片循环滚动效果的示例详解
    目录简介定义卡片的摆放规则调整卡片的层级关系调整卡片的尺寸大小动态调整位置、层级和大小移动动画按钮事件简介 功能需求如图所示,点击下一个按钮,所有卡片向右滚动,其中最后一张需要变更为...
    99+
    2022-12-09
    Unity卡片循环滚动效果 Unity循环滚动效果 Unity 滚动
  • 怎么用JavaScript实现图片循环滚动效果
    要实现图片循环滚动效果,可以通过JavaScript结合CSS实现。下面是一个简单的示例: HTML部分: <div id=&...
    99+
    2024-03-02
    JavaScript
  • Unity实现老虎机滚动抽奖效果的示例代码
    直接看下效果图吧: 制作思路: 设计四张图片,五个点,每个图片同时向下一个点移动,到最后一个就回到0号点,以此循环。 场景搭建: 创建Image命名为Bg作为电视框背...
    99+
    2024-04-02
  • CSS3如何实现无限循环的滚动效果
    这篇文章主要讲解了“CSS3如何实现无限循环的滚动效果”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“CSS3如何实现无限循环的滚动效果”吧!1. 使用CSS3来实现若要用CSS3的属性实现的...
    99+
    2023-07-04
  • css如何实现文字循环滚动效果
    这篇文章主要介绍“css如何实现文字循环滚动效果”,在日常操作中,相信很多人在css如何实现文字循环滚动效果问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”css如何实现文字循...
    99+
    2024-04-02
  • JS如何实现无缝循环marquee滚动效果
    这篇文章主要介绍JS如何实现无缝循环marquee滚动效果,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!无缝循环marquee滚动JS代码实现,兼容IE, FireFox, Chro...
    99+
    2024-04-02
  • css怎样实现图片循环的动画效果
    这篇文章主要为大家展示了css怎样实现图片循环的动画效果,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带大家一起来研究并学习一下“css怎样实现图片循环的动画效果”这篇文章吧。  <s...
    99+
    2024-04-02
  • 怎么实现Android TV 3D卡片无限循环效果
    这篇文章主要讲解了“怎么实现Android TV 3D卡片无限循环效果”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“怎么实现Android TV 3D卡片无限循环效果”吧!##思路自定义Vi...
    99+
    2023-06-25
  • js文字左右循环滚动效果怎么实现
    要实现文字的左右循环滚动效果,可以使用以下步骤:1. 创建一个包裹文字的容器元素,并设置其宽度为容器元素的父元素宽度的倍数,这样文字...
    99+
    2023-08-09
    js
  • CSS3怎么实现无限循环的无缝滚动效果
    这篇文章主要讲解了“CSS3怎么实现无限循环的无缝滚动效果”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“CSS3怎么实现无限循环的无缝滚动效果”吧!1. 使用CSS3来实现若要用CSS3的属...
    99+
    2023-07-05
  • 怎么使用css实现文字循环滚动效果
    今天小编给大家分享一下怎么使用css实现文字循环滚动效果的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。首先创建一个html文...
    99+
    2023-07-04
  • Flutter实现文本滚动高亮效果的示例讲解
    目录前言功能实现前言 最近有个需求是人工语音播放时文本能随语音朗读时像歌词滚动的效果. 原本第一考虑的时能随时间字体渐变成更改后的颜色, 有比较流畅的走马灯效果. 但最终实践了几次后...
    99+
    2024-04-02
  • Qt实现字幕滚动效果的示例代码
    目录一、项目介绍二、项目基本配置三、UI界面设计四、主程序实现4.1 widget.h头文件4.2 widget.cpp源文件五、效果演示一、项目介绍 利用QTimer实现字幕滚动功...
    99+
    2024-04-02
  • AndroidFlutter实现3D动画效果示例详解
    目录前言AnimatedWidget 简介3D 旋转动画的实现总结前言 上一篇我们介绍了 Animation 和 AnimationController...
    99+
    2024-04-02
  • 如何使用CSS3实现无限循环的无缝滚动效果
    这篇文章将为大家详细讲解有关如何使用CSS3实现无限循环的无缝滚动效果,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。1. 使用CSS3来实现若要用CSS3的属性实现的话,...
    99+
    2024-04-02
  • Android实现横向无限循环滚动的单行弹幕效果
    本期将带领大家实现一个这样的效果,支持无限循环的单行弹幕效果。 实现思路分析 要实现上面的效果,我们先拆分下实现要素: 1、弹幕布局是从屏幕的右侧向左侧滚动,单个弹幕之间的间距是固...
    99+
    2024-04-02
  • Android ViewPager怎么去实现无限循环滚动回绕效果
    不懂Android ViewPager怎么去实现无限循环滚动回绕效果?其实想解决这个问题也不难,下面让小编带着大家一起学习怎么去解决,希望大家阅读完这篇文章后大所收获。android系统提供的ViewPager标准方式是左右可以自由滑动,但...
    99+
    2023-05-30
    android viewpager 滚动效果
  • 如何实现移动端Ionic App资讯上下循环滚动效果
    这篇文章给大家分享的是有关如何实现移动端Ionic App资讯上下循环滚动效果的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。这里借助了jQuery库的选择器和动画函数,并且把jq...
    99+
    2024-04-02
  • vue3实现数字滚动特效实例详解
    目录前言思路文件目录使用示例入口文件index.jsmain.js使用requestAnimationFrame.js思路完整代码:CountTo.vue组件思路总结前言 vue3不...
    99+
    2024-04-02
  • Unity实现跑马灯效果的示例代码
    目录一、效果二、需要动画插件DOTween三、脚本1.每个格子上的脚本文件2.管理脚本文件一、效果 二、需要动画插件DOTween 下载地址 三、脚本 1.每个格子上的脚本文件 u...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作