文章目錄
- 一、前言
- 二、實作原理
- 三、界面制作
- 四、運行測驗
- 五、CustomScrollRect腳本代碼
- 六、結束語
一、前言
點關注不迷路,持續輸出Unity干貨文章,
嗨,大家好,我是新發,我之前寫了一篇文章,《Unity橫豎滑動串列嵌套(UGUI / ScrollRect)》
然后有同學私信我說沒做出來,

由于之前的文章我沒有上傳Demo工程,而且原來的工程我這邊也洗掉了,那么我就重新做一個Demo吧,
最終效果如下:

本文Demo工程已上傳到CodeChina,感興趣的同學可自行下載學習,
地址:https://codechina.csdn.net/linxinfa/UnityNestedScrollViewDemo
注:我使用的Unity版本:2020.2.7f1c1 (64-bit),

二、實作原理
Unity的滑動串列會根據用戶的操作行為捕獲到對應的事件,但是Unity的事件一旦被上層UI捕獲,下層UI就不會回應,如果是嵌套串列,那么二級串列就會劫持掉事件,導致一級串列無法拖動,
要解決滑動串列嵌套的這個問題,可以根據用戶滑動的方向,來進行事件的透傳,比如在橫向滑動的區域,如果用戶是進行豎向滑動,則把事件透傳到父級串列,如果父級串列是豎向滑動串列,則可以進行回應,否則繼續透傳,
UI事件透傳介面:
ExecuteEvents.Execute<T>(GameObject target, BaseEventData eventData,
EventFunction<T> functor) where T : IEventSystemHandler;
三、界面制作
制作一個Scroll View橫豎方向嵌套的界面,如下:

Hierarchy層級結構如下:

Scroll View V節點和Scroll View H節點要掛CustomScrollRect腳本(腳本代碼見文章最下面),并設定好Content物件,根據滑動方向勾選Horizontal或Vertical,


Scroll View H節點的Content掛上布局組件Horizontal Layout Group、Content Size Fitter,并創建n個精靈圖,


四、運行測驗
運行Unity進行測驗,

如果有同學跟著步驟沒做出來,可以下載Demo工程進行學習,對比自身看下是哪一個步驟有問題,相信你可以做到的,
五、CustomScrollRect腳本代碼
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class CustomScrollRect :ScrollRect {
//父CustomScrollRect物件
private CustomScrollRect m_Parent;
public enum Direction
{
Horizontal,
Vertical
}
//滑動方向
private Direction m_Direction = Direction.Horizontal;
//當前操作方向
private Direction m_BeginDragDirection = Direction.Horizontal;
protected override void Awake()
{
base.Awake();
//找到父物件
Transform parent = transform.parent;
if(parent){
m_Parent = parent.GetComponentInParent<CustomScrollRect>();
}
m_Direction = this.horizontal ? Direction.Horizontal : Direction.Vertical;
}
public override void OnBeginDrag(PointerEventData eventData)
{
if(m_Parent){
m_BeginDragDirection = Mathf.Abs(eventData.delta.x) > Mathf.Abs(eventData.delta.y) ? Direction.Horizontal : Direction.Vertical;
if(m_BeginDragDirection != m_Direction){
//當前操作方向不等于滑動方向,將事件傳給父物件
ExecuteEvents.Execute(m_Parent.gameObject, eventData, ExecuteEvents.beginDragHandler);
return;
}
}
base.OnBeginDrag(eventData);
}
public override void OnDrag(PointerEventData eventData)
{
if (m_Parent) {
if (m_BeginDragDirection != m_Direction){
//當前操作方向不等于滑動方向,將事件傳給父物件
ExecuteEvents.Execute(m_Parent.gameObject, eventData, ExecuteEvents.dragHandler);
return;
}
}
base.OnDrag(eventData);
}
public override void OnEndDrag(PointerEventData eventData)
{
if (m_Parent){
if (m_BeginDragDirection != m_Direction){
//當前操作方向不等于滑動方向,將事件傳給父物件
ExecuteEvents.Execute(m_Parent.gameObject, eventData, ExecuteEvents.endDragHandler);
return;
}
}
base.OnEndDrag(eventData);
}
public override void OnScroll(PointerEventData data)
{
if (m_Parent){
if (m_BeginDragDirection != m_Direction){
//當前操作方向不等于滑動方向,將事件傳給父物件
ExecuteEvents.Execute(m_Parent.gameObject, data, ExecuteEvents.scrollHandler);
return;
}
}
base.OnScroll(data);
}
}
六、結束語
完畢,
喜歡Unity的同學,不要忘記點擊關注,如果有什么Unity相關的技術難題,也歡迎留言或私信~
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/274128.html
標籤:其他
上一篇:基于canvas的手風琴特效
下一篇:python硬幣游戲悖論
