概要
漫画アプリとかでよくある縦にスクロールが出来て、横にスライドするとアイテムを削除できるようなスクロールビューです。
ScrollRectを拡張してデフォルトのScrollRectと差し換えて使用します。
サンプル
GitHub:https://github.com/Okamochi000/OverlapScroll
実証環境
- OS:Windows
- Unityバージョン:2020.3.0f1
実装サンプルコード
OverlapScroll.cs
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
/// <summary>
/// スクロール領域が重なるときScrollRect制御
/// </summary>
public class OverlapScrollRect : ScrollRect
{
private enum ScrollType
{
NotDrag, // ドラッグされていない
Self, // 自身
Back // 裏
}
private ScrollRect backScrollRect_ = null;
private ScrollType scrollType_ = ScrollType.NotDrag;
protected override void OnDisable()
{
base.OnDisable();
// 裏のScrollRectを強制的にドラッグ解除する
if (scrollType_ == ScrollType.Back)
{
PointerEventData eventData = new PointerEventData(null);
eventData.button = PointerEventData.InputButton.Left;
backScrollRect_.OnEndDrag(eventData);
scrollType_ = ScrollType.NotDrag;
}
}
/// <summary>
/// 裏にあるScrollRectの設定
/// </summary>
public void SetBackScrollRect(ScrollRect scrollRect)
{
backScrollRect_ = scrollRect;
}
public override void OnDrag(PointerEventData eventData)
{
// スクロール対象確認
ScrollType prevScrollType = scrollType_;
if (backScrollRect_ == null) { scrollType_ = ScrollType.Self; }
if (scrollType_ == ScrollType.NotDrag)
{
if (vertical == horizontal)
{
scrollType_ = ScrollType.Self;
}
else if (vertical)
{
if (Mathf.Abs(eventData.delta.x) < Mathf.Abs(eventData.delta.y)) { scrollType_ = ScrollType.Self; }
else { scrollType_ = ScrollType.Back; }
}
else if (horizontal)
{
if (Mathf.Abs(eventData.delta.x) > Mathf.Abs(eventData.delta.y)) { scrollType_ = ScrollType.Self; }
else { scrollType_ = ScrollType.Back; }
}
}
// 裏をスクロールする場合にScrollRectの値をコピー
if (prevScrollType == ScrollType.NotDrag && scrollType_ == ScrollType.Back)
{
// 裏のScrollRectを強制的にドラッグ開始する
backScrollRect_.OnBeginDrag(eventData);
}
else
{
if (scrollType_ == ScrollType.Back) { backScrollRect_.OnDrag(eventData); }
else { base.OnDrag(eventData); }
}
}
public override void OnEndDrag(PointerEventData eventData)
{
base.OnEndDrag(eventData);
// 裏のScrollRectを強制的にドラッグ解除する
if (scrollType_ == ScrollType.Back) { backScrollRect_.OnEndDrag(eventData); }
scrollType_ = ScrollType.NotDrag;
}
}
ScrollSetting.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
/// <summary>
/// スクロール初期設定
/// </summary>
public class ScrollSetting : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
ScrollRect scrollRect = this.GetComponent<ScrollRect>();
OverlapScrollRect[] overlapScrollRects = this.GetComponentsInChildren<OverlapScrollRect>();
foreach (OverlapScrollRect overlapScrollRect in overlapScrollRects) { overlapScrollRect.SetBackScrollRect(scrollRect); }
}
}
サンプルコード解説
内側のスクロールビューのScrollRectコンポーネントをOverlapScroll.csに差し替えて、OverlapScroll.SetBackScrollRect(ScrollRect)に外側のScrollRectを設定します。
ScrollSetting.csはSetBackScrollRectを呼び出すサンプルコードです。
スクロールビューの内側にスクロールビューを入れると内側のUIだけドラッグされるため、外側のスクロールビューは操作できなくなります。そのため、このスクリプトでは強制的にドラッグイベントを呼び出して操作しています。
アイテムをドラッグした状態で左右にスライドすると離すまで左右スライドのみスクロールされるようになり、縦にスライドすると離すまで縦スライドのみスクロールされるようになります。
投稿者プロフィール
最新の投稿
- 2023年10月9日プログラミング【ライセンス】GPL/LGPLライブラリについて
- 2023年8月19日その他【Pixiv】閲覧注意機能が反映されないときに確認すること
- 2023年4月30日プログラミング【JavaScript】ファイルの保存先をダイアログで指定する方法 – showSaveFilePicker()の使い方
- 2022年10月17日その他「NovelAI Diffusion」を使ってみた (Img2Img)