0
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Unityで自作スライダーの実装

Last updated at Posted at 2021-03-25

UnityのuGuiのsliderは非常に便利なのですがFillAreaに画像をアタッチしても伸縮で表示されて絵的にイマイチです。なので自作のスライダーを設置しようとしましたが、uGuiのSliderの使い方の解説の情報ばかりで自作のスライダーの設置方法がみつからなかったので自分用につくりました。

Slider1.png
を分解すると
Slider0.png
土台部分はImage、バー部分はSpriteRendererとSpriteMaskで作成します
Slider2.png
ヒエラルキー上ではこんな感じです
Slider3.png
土台部分にEventTriggerをアタッチして、DragEventを追加します。
(EventTriggerはRaycastTargetが有効化されたImageが同じオブジェクトにある場合のみイベントを起こすので土台はImageでなくてはなりません)

受け取り側のスクリプト

using UnityEngine.EventSystems;
    public float PixelPerUnit= 100f;
    public void OnSliderDrag(BaseEventData e)
    {
        PointerEventData pointer = e as PointerEventData;
        if (pointer.dragging)
        {
            Canvas canvas = GetComponentInParent<Canvas>();
            RectTransform rect = GetComponent<RectTransform>();

            Vector3 wpos = Vector3.zero;
            RectTransformUtility.ScreenPointToWorldPointInRectangle(rect, pointer.position, canvas.worldCamera, out wpos);

            Vector2 LeftTop = new Vector2(-rect.sizeDelta.x * rect.pivot.x, -rect.sizeDelta.y * rect.pivot.y) / PixelPerUnit;

            value = (wpos.x - transform.position.x - LeftTop.x) / rect.sizeDelta.x * PixelPerUnit;
        }
    }

PointerEventDataで受け取る座標pointer.positionはスクリーン上の座標なので土台のImageを描画しているキャンバスを

Canvas canvas =  GetComponentInParent<Canvas>();

で取得し、そのキャンバスの対象のカメラを
canvas.worldCamera
から取得し、

RectTransform rect = GetComponent<RectTransform>();
Vector3 wpos = Vector3.zero;
RectTransformUtility.ScreenPointToWorldPointInRectangle(rect, pointer.position, canvas.worldCamera, out wpos);

でワールド座標wposに変換します。

あくまでワールド座標なので、スライダーの表示位置からどのくらいの位置にあるかということも計算しないといけません。
そこでRectTransform のサイズとピボットから左上の座標を取得しているのが

Vector2 LeftTop = new Vector2(-rect.sizeDelta.x * rect.pivot.x, -rect.sizeDelta.y * rect.pivot.y) / PixelPerUnit;

です。

今回は横方向のスライダーなので

value = (wpos.x - transform.position.x - LeftTop.x) / rect.sizeDelta.x * PixelPerUnit;

で正規化されたスライダーのドラッグ位置が取得できます。
ちなみにPixelPerUnitは、TextureのPixelPerUnitの値です。

ここまでやっておいてなんですが透明なuGuiのスライダーを手前に置いて、そのvalue値を表示用のスライダーに反映させるほうが簡単だと思います。

ですが何かに応用できそうなのでメモとして残しておきます。

0
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?