请添加图片描述

请添加图片描述


前言

  • 在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

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:

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;
  }
  }

四、曲线滑动

请添加图片描述

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

脚本如下所示:

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;
      }
      }
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也可实现。
  • 且该循环组件已经多个上线项目中使用,除了文中用到的几种之外还有很多种其他功能。

请添加图片描述请添加图片描述请添加图片描述

请添加图片描述

资料白嫖,技术互助

学习路线指引(点击解锁)知识定位人群定位
Unity系统学习专栏 入门级本专栏从Unity入门开始学习,快速达到Unity的入门水平
Unity实战类项目 进阶级计划制作Unity的 100个实战案例!助你进入Unity世界,争取做最全的Unity原创博客大全。
❤️ 游戏制作专栏 难度偏高分享学习一些Unity成品的游戏Demo和其他语言的小游戏!
游戏爱好者万人社区 互助/吹水数万人游戏爱好者社区,聊天互助,白嫖奖品
Unity100个实用技能Unity查漏补缺针对一些Unity中经常用到的一些小知识和技能进行学习介绍,核心目的就是让我们能够快速学习Unity的知识以达到查漏补缺

请添加图片描述