げぇむぷろぐらみんぐ

日々の生活で得た知識、経験を書きます

【Unity】uGUIの当たり判定を広げる

はじめに

かなり小さいサイズのボタンを作成する場合にImageのサイズは変えたくないけど、判定だけ少し広めに取りたいということがあります。 今回は、そのような場合に判定を広げる方法とその広げた判定がどんな感じになっているかをGizmoで見えるようにする方法を紹介します。

完成したもの

以下のような白いボタンに対して、判定が緑の範囲となるような感じで調整ができます。

f:id:siguma_sig:20180812162709p:plain

f:id:siguma_sig:20180812162717p:plain

ソースコード

using UnityEngine;
using UnityEngine.UI;

namespace UIColliderSample
{
    [RequireComponent(typeof(RectTransform))]
    [RequireComponent(typeof(CanvasRenderer))]
    public class InvisibleGraphic : Graphic
    {
        private RectTransform _rectTransform;
        private Rect _rect = new Rect();

        private Rect GetRect()
        {
            if (_rectTransform == null)
            {
                _rectTransform = GetComponent<RectTransform>();
            }

            _rect.center = (Vector2) _rectTransform.position + _rectTransform.rect.center;
            Vector2 size = _rectTransform.rect.size;
            size.x *= _rectTransform.lossyScale.x;
            size.y *= _rectTransform.lossyScale.y;
            _rect.size = size;
            return _rect;
        }


        protected override void OnPopulateMesh(VertexHelper vh)
        {
            base.OnPopulateMesh(vh);
            vh.Clear();
        }

        private void OnDrawGizmos()
        {
            var rect = GetRect();
            Gizmos.color = new Color(0.0f, 1.0f, 0.0f, 0.5f);
            Gizmos.DrawCube(rect.center, rect.size);
        }
    }
}

ソースコードの説明

判定を広げる部分に関してはkanさんのブログを参考にしました。 やっていることとしてはGraphicを継承することで判定を取れるようにして、そのままだと白い四角が描画されてしまうので以下の部分で頂点を空にすることで描画されないようにしています。

protected override void OnPopulateMesh(VertexHelper vh)
{
    base.OnPopulateMesh(vh);
    vh.Clear();
}

Gizmoの部分では、このスクリプトがアタッチされているオブジェクトのRectTransformを見て、そのサイズになるようにRectを表示しています。 RectTransformに対して正しいRectになるように、以下の部分でRectを作成しています。

private Rect GetRect()
{
    if (_rectTransform == null)
    {
        _rectTransform = GetComponent<RectTransform>();
    }

    _rect.center = (Vector2) _rectTransform.position + _rectTransform.rect.center;
    Vector2 size = _rectTransform.rect.size;
    size.x *= _rectTransform.lossyScale.x;
    size.y *= _rectTransform.lossyScale.y;
    _rect.size = size;
    return _rect;
}

Rectのサイズはscaleも考慮する必要があるので、lossyScaleを掛けています。

使い方

作成した上記のスクリプトを当たり判定を広げたいuGUIに子オブジェクトを作成してそれにアタッチする。

f:id:siguma_sig:20180812170505p:plain

まとめ

判定を広げるのをもっと簡単にできたらいいなあ…と思いました。 もしもっと良いやり方があれば教えてください!

あとなにげにGizmoを初めていじりました。

参考

kan-kikuchi.hatenablog.com