【Unity实战篇】| 游戏滑动框添加特殊效果,如实时高亮显示、曲线滑动等


前言

  • 在Unity引擎的UGUI中,滑动框ScrollRect是比较常用的组件,其有较多的使用场景。
  • 默认情况下,该组件提供基本的横向滑动和竖向滑动的功能,若想要更多效果只能自己添加逻辑。
  • 本文来介绍几种特殊的滑动效果,让UI交互变得更加有趣多样化。

【Unity实战篇】| 游戏滑动框添加特殊效果,如实时高亮显示、曲线滑动等

一、实战内容

1.1 介绍

  • 本文制作的滑动效果是基于Unity中的 循环列表 SuperScrollView 插件实现的,该插件主要功能就是它的循环列表,但同时也提供了一些其他功能。
  • 插件比较轻量级,简单易用,详细教程可以参考下之前发过的文章:【Unity 实用工具篇】 | UGUI 循环列表 SuperScrollView,快速上手使用
  • 若不想使用该插件,将代码进行调整即可,实现特殊滑动效果的思路都是一致的。

1.2 效果展示

功能 效果
滑动时大小变化
滑动时实时选中并高亮展示
曲线滑动
其它效果

二、滑动时大小变化

滑动时大小变化是一个比较容易实现的功能,在之前的循环组件文章中亦有介绍,可以参考之前的文章:【Unity 实用工具篇】 | UGUI 循环列表 SuperScrollView,快速上手使用

下面介绍一些更复杂的功能。


三、滑动时实时选中并高亮显示

该效果在滑动时大小变化的基础上增加实时选中当前展示的Item。

操作步骤如下

1.添加一个ScrollView组件,在Content下面添加一个item节点用于循环生成,该item节点下有三个节点组件用于测试使用。

2.在ScrollView节点上添加LoopListView2脚本,并点击AddNew 将item节点拖上去,此处注意要把LoopListView2脚本中的ItemSnapPivot 勾上。

3.给item节点添加脚本LoopTestItem.cs,目的是控制其大小和高亮展示。

最后再添加一个生成一百个子对象并控制item大小,并实时控制大小和高亮逻辑的控制器脚本LoopViewSpecialDemo_Mask.cs,将ScrollView节点和LoopListView2脚本拖上去。

两个脚本的完整代码如下:

LoopViewSpecialDemo_Mask.cs

csharp 复制代码
using SuperScrollView;
using System.Collections.Generic;
using UnityEngine;

public class LoopViewSpecialDemo_Mask : MonoBehaviour
{

    [SerializeField] private LoopListView2 m_view = null;
    [SerializeField] private RectTransform m_viewRect = null;

    float m_viewRectWight = 1;//滑动框的大小

    private void Start()
    {
        m_view.InitListView(100, OnUpdate);
        //滑动时的监听事件
        m_view.mOnSnapNearestChanged = (handleKey, obj)=>
        {
            OnSnapChangedRefreshLoopView( handleKey, obj);
        };
        m_viewRectWight = m_viewRect.rect.width;
    }

    private void OnSnapChangedRefreshLoopView(LoopListView2 view2, LoopListViewItem2 item2)
    {
        foreach (var item in view2.ItemList)
        {
            var itemUI = item.GetComponent<LoopTestItem>();
            var isMask = (m_view.CurSnapNearestItemIndex + 1) != itemUI.GetIndex();
            itemUI.SetMask(isMask);
        }
    }

    private void LateUpdate()
    {
        m_view.UpdateAllShownItemSnapData();
        int count = m_view.ShownItemCount;
        for (int i = 0; i < count; ++i)
        {
            var itemObj = m_view.GetShownItemByIndex(i);
            var itemUI = itemObj.GetComponent<LoopTestItem>();
        
            //DistanceWithViewPortSnapCenter为当前Item与ViewPort原点的距离,根据此距离可以判断item的位置。
            var amount = 1 - Mathf.Abs(itemObj.DistanceWithViewPortSnapCenter) / m_viewRectWight;
            var scale = Mathf.Clamp(amount, 0.8f, 1);
            itemUI.SetScale(scale);
        }
    }

    private LoopListViewItem2 OnUpdate(LoopListView2 view, int index)
    {
        if (index < 0 || index > 100) return null;
        index += 1;

        LoopListViewItem2 itemObj = view.NewListViewItem("item");
        LoopTestItem itemUI = itemObj.GetComponent<LoopTestItem>();
        itemUI.SetData(index);
        return itemObj;
    }
}

LoopTestItem .cs:

csharp 复制代码
using UnityEngine;
using UnityEngine.UI;

public class LoopTestItem : MonoBehaviour
{
    public Transform RootTrans;
    public Transform maskRoot;
    public Image imgBg;
    public Text TxtName;

    private int curIndex;

    public void SetData(int _index)
    {
        curIndex = _index;
        TxtName.text = $"<color=#F55F55>{_index}</color>";
        //此处是在 "Resources/UI"文件夹下添加了四张图片test1234,如果没有图可以不加。
        imgBg.sprite = Resources.Load<Sprite>("UI/test" + _index % 4);
    }
    public void SetScale(float scale)
    {
        RootTrans.transform.localScale = new Vector3(scale, scale, 1);
    }

    public void SetMask(bool isMask)
    {
        maskRoot.gameObject.SetActive(isMask);
    }

    public int GetIndex()
    {
        return curIndex;
    }
}

四、曲线滑动

曲线滑动效果的实现与上方高亮类似,只不过是增加了滑动时对位置的控制逻辑,将脚本替换一下即可。

脚本如下所示:

csharp 复制代码
using SuperScrollView;
using UnityEngine;

public class LoopViewSpecialDemo_Curve : MonoBehaviour
{
    [SerializeField] private LoopListView2 m_view = null;
    [SerializeField] private RectTransform m_viewRect = null;

    float m_viewRectWight = 1;//滑动框的大小
    private void Start()
    {
        m_view.InitListView(100, OnUpdate);
        m_viewRectWight = m_viewRect.rect.width;
    }


    private void LateUpdate()
    {
        m_view.UpdateAllShownItemSnapData();

        int count = m_view.ShownItemCount;

        for (int i = 0; i < count; ++i)
        {
            var itemObj = m_view.GetShownItemByIndex(i);
            var amount = 1 - Mathf.Abs(itemObj.DistanceWithViewPortSnapCenter + 100) / m_viewRectWight;
            var targetNum = Mathf.Clamp(amount, 0.1f, 1);

            var itemUI = itemObj.GetComponent<LoopTestItem>();
            itemUI.SetScale(targetNum);
            itemUI.SetAlpha(targetNum);
            itemUI.SetPosition(targetNum);
            //Debug.LogError($"测试:::{itemObj.DistanceWithViewPortSnapCenter}");
        }
    }

    private LoopListViewItem2 OnUpdate(LoopListView2 view, int index)
    {
        if (index < 0 || index > 100) return null;
        index += 1;
        var itemType = view.NewListViewItem("item");
        var itemUI = itemType.GetComponent<LoopTestItem>();

        itemUI.SetData(index);
        return itemType;
    }
}
csharp 复制代码
using UnityEngine;
using UnityEngine.UI;

public class LoopTestItem : MonoBehaviour
{
    public Transform RootTrans;
    public Text TxtName;

    public void SetData(int _index)
    {
        TxtName.text = $"<color=#F55F55>活动:{_index}</color>";
    }

    public void SetPosition(float pos)
    {
        //具体位置可根据实际情况调节。
        float posY = 150 / pos - 150;
        RootTrans.localPosition = new Vector3(RootTrans.localPosition.x, posY, RootTrans.localPosition.z);
    }
    public void SetScale(float scale)
    {
        RootTrans.transform.localScale = new Vector3(scale, scale, 1);
    }
    public void SetAlpha(float alpha)
    {
        RootTrans.GetComponent<CanvasGroup>().alpha = alpha;
    }
}

五、其他效果

除了前面介绍的几种简易效果之外,如果想实现更复杂一些的效果则可以借助一些插件实现。

FancyScrollView就是一个可以实现复杂灵活动画效果的通用UI滑动列表组件,可以帮助开发者快速实现表现力丰富的UI滑动列表。

后面有时间应该会出一个该插件的使用教程分享,感兴趣的小伙伴也可以去下载插件使用看下效果。

Github链接:FancyScrollView


总结

  • 本文展示了多种滑动框的效果及制作方法,主要目的是增强游戏交互体验。
  • 制作的滑动效果是基于循环组件,但对于滑动效果的处理逻辑思路是一致的,按照同样思路使用普通的ScrollView也可实现。
  • 且该循环组件已经多个上线项目中使用,除了文中用到的几种之外还有很多种其他功能。

  • 🎬 博客主页:https://xiaoy.blog.csdn.net

  • 🎥 本文由 呆呆敲代码的小Y 原创 🙉

  • 🎄 学习专栏推荐:Unity系统学习专栏

  • 🌲 游戏制作专栏推荐:游戏制作

  • 🌲Unity实战100例专栏推荐:Unity 实战100例 教程

  • 🏅 欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正!

  • 📆 未来很长,值得我们全力奔赴更美好的生活✨

  • ------------------❤️分割线❤️-------------------------

资料白嫖,技术互助

学习路线指引(点击解锁) 知识定位 人群定位
🧡 Unity系统学习专栏 入门级 本专栏从Unity入门开始学习,快速达到Unity的入门水平
💛 Unity实战类项目 进阶级 计划制作Unity的 100个实战案例!助你进入Unity世界,争取做最全的Unity原创博客大全。
❤️ 游戏制作专栏 难度偏高 分享学习一些Unity成品的游戏Demo和其他语言的小游戏!
💚 游戏爱好者万人社区 互助/吹水 数万人游戏爱好者社区,聊天互助,白嫖奖品
💙 Unity100个实用技能 Unity查漏补缺 针对一些Unity中经常用到的一些小知识和技能进行学习介绍,核心目的就是让我们能够快速学习Unity的知识以达到查漏补缺
相关推荐
世洋Blog5 小时前
SiYangUnityEventSystem,一个Unity中的事件系统
观察者模式·unity·c#·游戏引擎·事件系统
Tatalaluola6 小时前
【Quest开发】用unity UI快速实现交互
unity·游戏引擎
技术小甜甜6 小时前
[Godot] 在 Godot 3.1 中配置 ADB 可执行文件的实用指南
游戏·adb·游戏引擎·godot
技术小甜甜6 小时前
【Godot】【入门】Godot 是什么?适合做哪些类型的游戏(附路线图+避坑清单)
游戏·游戏引擎·godot
xiaohai@Linux6 小时前
STM32之移植原生的infoNES nes游戏模拟器源码实现游戏自由!!!(原生纯C版,非汇编版)
stm32·游戏·模拟器·infones·nes游戏机
码界奇点7 小时前
Unity WebGL输入支持终极指南解决浏览器输入难题的完整方案
unity·容器·游戏引擎·鸿蒙系统·webgl
90后小陈老师7 小时前
Unity动画控制
unity·游戏引擎
Miss_SQ18 小时前
Webgl打包后删除StreamingAssets文件夹下多余资源
unity·c#·webgl
Sui_Network20 小时前
备受期待的 POP 射击游戏 XOCIETY 正式在 Epic Games Store 开启体验
人工智能·游戏·rpc·区块链·量子计算·graphql