
- [【Unity实战篇】| 游戏滑动框添加特殊效果,如实时高亮显示、曲线滑动等](#【Unity实战篇】| 游戏滑动框添加特殊效果,如实时高亮显示、曲线滑动等)
-
- 一、实战内容
-
- [1.1 介绍](#1.1 介绍)
- [1.2 效果展示](#1.2 效果展示)
- 二、滑动时大小变化
- 三、滑动时实时选中并高亮显示
- 四、曲线滑动
- 五、其他效果
- 总结

前言
- 在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的知识以达到查漏补缺 |

