iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >Unity ScrollRect实现轨迹滑动效果
  • 164
分享到

Unity ScrollRect实现轨迹滑动效果

2024-04-02 19:04:59 164人浏览 薄情痞子
摘要

本文实例为大家分享了Unity ScrollRect实现轨迹滑动效果的具体代码,供大家参考,具体内容如下 以下内容是根据Unity 2020.1.01f版本进行编写的 1、目的 工作

本文实例为大家分享了Unity ScrollRect实现轨迹滑动效果的具体代码,供大家参考,具体内容如下

以下内容是根据Unity 2020.1.01f版本进行编写的

1、目的

工作中遇到有需要实现轨迹滑动的滑动列表,通常的做法是计算贝塞尔曲线得出轨迹,但是我觉得计算贝塞尔曲线太麻烦了,或许有没有更简单的方法。

2、思考

轨迹滑动可以分两种情况:

第一种是轨迹滑动是比较简单的横向(或纵向)滑动,其中轨迹不会蜿蜒盘旋,也不涉及列表格子之间的重叠关系,这时可以分区间来对Y轴(或X轴)进行设置以达到格子沿着轨迹滑动的效果
例如,轨迹是这样的波浪型的,其中,轨迹点的数量可以无限增加,点越多轨迹可以设置得越平滑,但是消耗的性能也越多:

像这样,类似波浪型的轨迹,可以用一个Vector列表记录下每个点的位置和顺序,然后根据每个格子所在的位置,先由小到大循环判断在哪个区间,例如格子3在pos_5和pos_6中间,所以第三个格子的区间就是5,然后通过pos_5和pos_6两个点相减,得到一个从pos_5指向pos_6的向量vector,通过vector3.distance函数得到pos_5和pos_6两个点的横向距离distanceX1,然后再次通过vector3.distance函数得到pos_5与格子3得横向距离distanceX2,那么,格子3的位置 = pos_5的位置 + distanceX2 / distanceX1 * vector,得到位置后再把位置设置回去就可以了 

第二种就是更为复杂的轨迹滑动,例如蜿蜒盘旋式的轨迹,其中还包括有层级关系

例如,轨迹是蜿蜒盘旋的,同样是轨迹点越多,曲线越平滑,也越消耗性能:

像这样,蜿蜒盘旋的轨迹,就不能使用第一种方法了,因为有些位置,一个X值对应下来有多个Y值,无法区分当前需要的是哪个Y值,所以,需要使用另一种方法

我们可以通过获取所有的轨迹点,计算出每两个相邻轨迹点之间的距离,通过距离确定格子应该在哪个区间内

例如,格子3的位置是95,假设pos_1和pos_2的距离为50,pos_2和pos_3的距离为也是50,那么pos_1到pos_3的总距离就是100,所以格子3应该在区间pos_2和pos_3中间。接下来计算实际位置,因为此时格子的X轴和Y轴都会变化,同样无法使用第一种方法来计算格子的位置,需要通过格子的位置减去前面区间距离的和,在例子中,就是格子3的位置减去pos_1到pos_2的距离,即95 – 50 = 45,再通过剩余的距离除以当前区间的距离得出比例ratio,然后就是通过当前的两个区间点相减得到pos_2指向pos_3的向量vector,那么格子3的位置就是,pos_2的位置 + ratio * vector

最后,还有层级的问题,也就是哪个格子遮挡哪个格子,一般是后面的格子遮挡前面的格子,如果需要前面的遮挡后面的格子,只需要动态修改层级就行,unity提供了这个函数:TransfORM.SetAsFirstSibling()

在实际使用中,我发现使用这种方法后,content的长度有时候会过长,有时候会过短,所以需要确定好格子的数量,设置好content的正确长度

注意:以上都是最基础的思想,因为滑动时改变的是content节点,格子的位置实际上是不变的,或者是由代码设置的,所以实际代码中还需要考虑scrollrect的宽高以及content节点的滑动值(即posX值,滑动时此值会变化)

3、自定义实现轨迹滑动


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

[RequireComponent(typeof(ScrollRect))]
public class CurveSliding : MonoBehaviour
{
    public Transform posListRoot;
    public float contentwidth;              //必须自己设置的content实际长度
    public bool isChangeHierarchy = false;

    private ScrollRect scrollRect;
    private RectTransform content;
    private List<Transform> posTransformList = new List<Transform>();
    private List<RectTransform> item_transformList = new List<RectTransform>();
    private List<float> posX_List = new List<float>();
    private List<float> distanceList = new List<float>();
    private float scrollRectWidth;
    private float scrollRectHeight;
    private float posTotalDistance;
    private float spacing = 0;

    private void Start()
    {
        scrollRect = GetComponent<ScrollRect>();
        content = scrollRect.content.transform as RectTransform;
        HorizontalLayoutGroup contentLayoutGroup = content.GetComponentsInChildren<HorizontalLayoutGroup>(true)[0];
        if(contentLayoutGroup != null && contentLayoutGroup.name == content.name)
        {
            spacing = contentLayoutGroup.spacing;
        }
        scrollRectWidth = scrollRect.GetComponent<RectTransform>().sizeDelta.x;
        scrollRectHeight = scrollRect.GetComponent<RectTransform>().sizeDelta.y;
        for (int i = 0; i < content.childCount; i++)
        {
            RectTransform item_transform = content.GetChild(i) as RectTransform;
            if (item_transform.gameObject.activeInHierarchy)
            {
                item_transformList.Add(item_transform);
                posX_List.Add(item_transform.localPosition.x);
            }
            else
            {
                continue;
            }
        }
        float totalDistance = 0;
        for(int i = 0;i < posListRoot.childCount;i++)
        {
            Transform posTransform = posListRoot.GetChild(i);
            if (i > 0)
            {
                Transform previousPosTransform = posListRoot.GetChild(i - 1);
                totalDistance += Vector3.Distance(posTransform.localPosition, previousPosTransform.localPosition);
            }
            posTransformList.Add(posTransform);
            distanceList.Add(totalDistance);
        }
        posTotalDistance = distanceList[distanceList.Count - 1];
        content.sizeDelta = new Vector2(contentwidth, content.sizeDelta.y);
        OnValueChange(Vector2.zero);
        scrollRect.onValueChanged.AddListener(OnValueChange);
    }

    public void OnValueChange(Vector2 vector)
    {
        for(int i = 0;i < item_transformList.Count;i++)
        {
            float localPosX = posX_List[i];
            float posX = localPosX + content.anchoredPosition.x;
            //如果当前节点的位置 - content的X轴偏移值 > 滑动列表的宽度,则说明当前item在可视范围外
            if (posX > posTotalDistance + 200 || posX < 0)
            {
                continue;
            }
            int index = -1;
            foreach(var totalDistance in distanceList)
            {
                if(posX < totalDistance)
                {
                    break;
                }
                else
                {
                    index++;
                }
            }
            //如果index+1小于位置列表的数量,则其在位置区间内,否则应该在位置区间外
            if (index + 1 < posListRoot.childCount && index + 1 > 0)
            {
                float ratio = (posX - distanceList[index]) / (distanceList[index + 1] - distanceList[index]);
                Vector3 newPos = posTransformList[index].localPosition - ratio * (posTransformList[index].localPosition - posTransformList[index + 1].localPosition);
                item_transformList[i].localPosition = new Vector3(newPos.x + scrollRectWidth/2 - content.anchoredPosition.x, -scrollRectHeight / 2 + newPos.y, 0);

            }
            else if(index <= -1)
            {
                item_transformList[i].localPosition = new Vector3(item_transformList[i].localPosition.x, -scrollRectHeight / 2 + posListRoot.GetChild(0).localPosition.y, 0);
            }
            else if(index >= posListRoot.childCount - 1)
            {
                if (i < 1)
                {
                    continue;
                }
                RectTransform previousItem_RectTransform = item_transformList[i - 1];
                item_transformList[i].localPosition = new Vector3(previousItem_RectTransform.localPosition.x + spacing + previousItem_RectTransform.sizeDelta.x/2 + item_transformList[i].sizeDelta.x/2, -scrollRectHeight / 2 + posListRoot.GetChild(posListRoot.childCount - 1).localPosition.y, 0);
            }
            if (isChangeHierarchy)
            {
                item_transformList[i].SetAsFirstSibling();
            }
        }
    }
}

4、两种方法的优缺点

1)、 两种方法都不能使用排序组件,因为排序组件会控死格子的位置,通过代码也无法修改
2)、 第二种方法比第一种方法更复杂,同时消耗的性能也更多,但是能实现更复杂的效果
3)、第二种方法需要设置conten的长度,即格子的数量无法动态变化,是一大缺点

5、最终效果

第一种:

第二种:

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程网。

--结束END--

本文标题: Unity ScrollRect实现轨迹滑动效果

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

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

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

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

下载Word文档
猜你喜欢
  • Unity ScrollRect实现轨迹滑动效果
    本文实例为大家分享了Unity ScrollRect实现轨迹滑动效果的具体代码,供大家参考,具体内容如下 以下内容是根据Unity 2020.1.01f版本进行编写的 1、目的 工作...
    99+
    2024-04-02
  • Unity实现物体运动时画出轨迹
    本文实例为大家分享了Unity实现物体运动时画出轨迹的具体代码,供大家参考,具体内容如下 1、新建空物体,上赋LineRenderer 2、新建空物体,把轨迹画出来,设计和脚本。 ...
    99+
    2024-04-02
  • Unity实现物体运动轨迹的绘制
    本文实例为大家分享了unity物体运动轨迹绘制的具体代码,供大家参考,具体内容如下 ① create empty,命名为LineRender ② 在Assects中新建材质,选择Sh...
    99+
    2024-04-02
  • Unity ScrollView实现无限滑动效果
    本文实例为大家分享了Unity ScrollView实现无限滑动效果的具体代码,供大家参考,具体内容如下 一、效果演示 二、前言 当邮件中有1000封邮件,商店列表中有1000个物...
    99+
    2024-04-02
  • Qt编写地图实现实时动态轨迹效果
    目录一、前言二、功能特点三、体验地址四、效果图五、相关代码一、前言 实时动态轨迹经历过很多个版本的迭代,此功能最初是一个客户定制的,主要是需要在地图上动态显示GPS的运动轨迹,有个应...
    99+
    2024-04-02
  • Unity实现滑动更换界面效果
    在做2048这个游戏时,因为菜单页面还能查看游戏规则,而这些规则又不在同一个页上,所以需要滑动页面实现页面切换,但是仅仅使用unity提供的组件做出的效果仅有一个切换的意思,交互感很...
    99+
    2024-04-02
  • Unity ScrollView如何实现无限滑动效果
    小编给大家分享一下Unity ScrollView如何实现无限滑动效果,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!一、效果演示二、前言当邮件中有1000封邮件,...
    99+
    2023-06-20
  • 如何利用CSS+JS实现唯美星空轨迹运动效果
    小编给大家分享一下如何利用CSS+JS实现唯美星空轨迹运动效果,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!css是什么意思css是一种用来表现HTML或XML等...
    99+
    2023-06-08
  • vue利用openlayers实现动态轨迹
    目录实现效果创建一个地图容器引入地图相关对象创建地图对象创建一条线路画一条线路添加起、终点添加小车准备开车完整代码实现效果 今天介绍一个有趣的gis小功能:动态轨迹播放!效果就像这样...
    99+
    2022-11-13
    vue openlayers动态轨迹 vue openlayers
  • Unity实现汽车前后轮倒车轨迹计算
    汽车前后轮倒车轨迹计算附C#源码(Unity),供大家参考,具体内容如下 原理很简单, 都是高中的几何数学部分 需要的参数有: 车前后轴距; 车宽(左前轮与右前轮...
    99+
    2024-04-02
  • 如何使用css3实现轨迹运动
    这篇文章主要介绍如何使用css3实现轨迹运动,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!实现效果:实现代码:<div class="haorooms-dot &qu...
    99+
    2024-04-02
  • Unity UI组件ScrollRect实现无限滚动条
    在游戏开发中经常遇到滚动显示的数据,特别是商店商品 排行榜 .......等数据很多,每一条数据去加载一个UI来显示显然对内存浪费很大,这种情况处理一般就是用几个显示条可滚动循环显示...
    99+
    2024-04-02
  • vue实现滑动和滚动效果
    本文实例为大家分享了vue实现滑动和滚动效果的具体代码,供大家参考,具体内容如下 面板滑动效果,父组件是resultPanel,子组件是resultOption,仿照了iview中,...
    99+
    2024-04-02
  • C#实现滑动开关效果
    C#重绘checkbox生成滑动开关,供大家参考,具体内容如下 通过调用checkbox控件的paint事件,在重绘事件里判断checked属性,如果选中绘制选中图形,如果未选中绘制...
    99+
    2024-04-02
  • js实现滑动轮播效果
    本文实例为大家分享了js实现滑动轮播效果的具体代码,供大家参考,具体内容如下 1、构建html样式,代码如下 <div class="banner"> ...
    99+
    2024-04-02
  • jquery实现滑动楼梯效果
    本文实例为大家分享了jquery实现滑动楼梯效果的具体代码,供大家参考,具体内容如下 思路:鼠标滚动的时候页面跟随变化,点击模块时候,实现指哪打哪效果 代码的实现 1.html和cs...
    99+
    2024-04-02
  • js实现拖动滑块效果
    本文实例为大家分享了js如何拖动滑块的具体代码,供大家参考,具体内容如下 实现拖动滑块,先分析,滑块可以拖动应该改变滑块在页面中的坐标,那就采用定位拿到元素的 top 和 left ...
    99+
    2024-04-02
  • iOS实现背景滑动效果
    本文实例为大家分享了iOS实现背景滑动效果的具体代码,供大家参考,具体内容如下 1、在很多APP中,我们都可以看见那些特效绚丽的滑动选项条,那么如何才能够简单,快速的实现那样的效果呢...
    99+
    2024-04-02
  • react如何实现滑动效果
    今天小编给大家分享一下react如何实现滑动效果的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。react实现滑动的方法:1、...
    99+
    2023-07-04
  • iOS实现无限滑动效果
    在看到这个标题的时候,相信大家心里肯定会想,无限循环轮播的博客已经满天飞了,好有必要写么。这里我想声明一下,这里的无线滑动,但是数据却不循环。 实现原理 由于业务的需求,需要有大量的...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作