(:3[kanのメモ帳]

個人ゲーム開発者kan.kikuchiのメモ的技術ブログ。月木更新でUnity関連がメイン。

(:3[kanのメモ帳]


本ブログの運営者kan.kikuchiが個人で開発したゲームです!


ScrollRectのスクロール量がMacとWindows、トラックパッドとマウスで違う問題【Unity】【uGUI】


このエントリーをはてなブックマークに追加


この記事でのバージョン
Unity 6000.1.11f1


はじめに

UnityのuGUIにはScrollRectというスクロールするUIを簡単に実装出来るコンポーネントがあります。



このScrollRectには scrollSensitivity というマウスホイールやトラックパッドの2 本指スクロールなどで

どれだけスクロールさせるかという、スクロールの倍率を設定する事が出来ます。

(スマホのようなタッチ操作や、PCでも引っ張って操作する場合には無関係)


しかし、自分の環境だとMacだと1ぐらい、Windowsだと10ぐらいがちょうどよくなり、

同じマウスを使ったとしてもOSによって挙動が変わってしまっていました。


という事で今回は、ScrollRectのスクロール量( scrollSensitivity )をどう調整するかという話です。


ScrollRectのスクロール量( scrollSensitivity )をどう調整するか

ちょっと調べて見た感じ、この挙動は仕様のようです。

(引用は自動翻訳)

どのバージョンの Unity でも、新しいまたは古い Unity 入力システムを使用しているかどうかに関係なく、スクロール ビューの速度は大きく一貫していないようです。

- Windows と Mac では動作が異なります。
- エディタービルドと WebGL ビルド間で変更されます。
- トラックパッドとマウスホイールによって異なります。
- 最初にどの入力デバイスを使用したかによっても変化します。

デバイスやビルドを問わず、スクロール速度を一定に保つ確実な方法があれば教えてください。スクロールがうまく動作することを願っています。もしそれが役に立つなら、アセットを有料で提供しても構いません。

https://www.reddit.com/r/Unity3D/comments/1lukxws/scroll_view_speed_inconsistency_driving_me_mad/#:~:text=,Mac


つまり、様々な条件で全然違う挙動になってしまうため、一つの設定で調整するのは困難なため、

各ユーザーの環境に合わせて調整してもらうのが確実な感じでした。


なので、ゲーム内にスクロール速度の設定を作り、

(初期値はOSごとに設定してもいいかも)


その設定をもとにScrollRectのscrollSensitivityをプログラムで変えるというのが良さそうです。


その際、ScrollRectを継承した以下のようなクラスを作り、

それをScrollRectの代わりに使うようにようすると、色々と調整しやすくて楽かと思います。

using System;
using UnityEngine;
using UnityEngine.UI;

/// <summary>
/// ScrollRectのオリジナルクラス
/// </summary>
public class ScrollRectEx : ScrollRect {
  
  //=================================================================================
  //初期化
  //=================================================================================

  protected override void Reset() {
    base.Reset();
    
    //子オブジェクトからContentとViewportを自動検索・設定
    var contentTransform = transform.FindFromAllChildren("Content");
    if (contentTransform != null) {
      content = contentTransform.GetComponent<RectTransform>();
    }
    else {
      LogPrinter.Error($"Contentが見つかりませんでした。子オブジェクトに「Content」という名前のRectTransformを配置してください。");
    }
    
    var viewportTransform = transform.FindFromAllChildren("Viewport");
    if (viewportTransform != null) {
      viewport = viewportTransform.GetComponent<RectTransform>();
    }
    else {
      LogPrinter.Error($"Viewportが見つかりませんでした。子オブジェクトに「Viewport」という名前のRectTransformを配置してください。");
    }
  }
  
  protected override void Awake() {
    base.Awake();
    
    UpdateScrollSpeed();
  }
  
  //=================================================================================
  //更新
  //=================================================================================
  
  //スクロール速度を更新
  private void UpdateScrollSpeed() {
    scrollSensitivity = 10;//ここを設定に応じて変える感じ
  }
  
}


余談ですが、先ほどサイトにあったように

OnScrollを実装してscrollSensitivityを無視してスクロールの挙動を変えるという事も可能ですが、

↓ぐらいの感じだと挙動が不自然になり、verticalNormalizedPositionを使ってたりして汎用性も低いので、

個人的にはあまりオススメしません。

(NormalizedやめたりTween使ったりと色々試したが、scrollSensitivityを使った方が良さげという結論に)

public void OnScroll(PointerEventData eventData)
{
    var currentTime = Time.unscaledTime;
    if (currentTime - _lastScrollTime < scrollCooldown)
        return;
    _lastScrollTime = currentTime;
    var rawDelta = eventData.scrollDelta;
    var scrollDelta = Mathf.Sign(rawDelta.y) * scrollMultiplier;
    if (scrollRect.vertical)
        scrollRect.verticalNormalizedPosition += scrollDelta * Time.unscaledDeltaTime;
    else if (scrollRect.horizontal)
        scrollRect.horizontalNormalizedPosition += scrollDelta * Time.unscaledDeltaTime;
}

https://www.reddit.com/r/Unity3D/comments/1lukxws/scroll_view_speed_inconsistency_driving_me_mad/#:~:text=,Mac