LoginSignup
3
3

More than 5 years have passed since last update.

UGUIButton - uGUIのクリックイベントをコードから使いやすく

Last updated at Posted at 2016-11-08

概要

・クリックしたら自動的に縮小・離したら拡大
・クリックイベントがコードから設定しやすいように
ボタンのスケーリングにDotweenを使用しています。
uGUIのButtonがあまりにも使いづらいので自分でつくってみました。

改良版
http://qiita.com/takeout/items/d612ce8b30e3f16f78bc

ソース

UGUIButton.cs

#if UNITY_EDITOR
using UnityEditor;
#endif
using UnityEngine;
using UnityEngine.EventSystems;
using System;
using System.Collections;
using DG.Tweening;

/// <summary>
/// UGUIボタン
/// </summary>


#if UNITY_EDITOR
    [InitializeOnLoad]
#endif
    [RequireComponent(typeof(EventTrigger))]
    public class UGUIButton : UIBehaviour
    {
        /// 
        /// コンストラクタ
        /// 
        public UGUIButton()
        {
#if UNITY_EDITOR
            // エディタ更新時に自動でトリガーを割り当てる
            EditorApplication.update = () =>
            {
                AutoAttach();
                EditorApplication.update = null;
            };
#endif
        }

#if UNITY_EDITOR
        /// 
        /// 自動的にトリガーを見つけて割り当てる
        /// 
        private void AutoAttach()
        {
            if (_trigger == null)
            {
                Debug.Log("トリガーを自動設定しました",this);
                _trigger = GetComponent<EventTrigger>();
            }
        }
#endif

    /// <summary>
    /// トリガー
    /// </summary>
    [SerializeField,Header("トリガーは自動で割り当てられます")]
    private EventTrigger _trigger;

    /// <summary>
    /// 拡大するかどうか
    /// </summary>
    [SerializeField]
    private bool _isScalable = true;

    /// <summary>
    /// ディセーブル状態かどうか
    /// </summary>
    [SerializeField]
    private bool _isDisable;

    /// <summary>
    /// 押せる状態の時の表示物
    /// null許容
    /// </summary>
    [SerializeField]
    private GameObject _enableRoot;

    /// <summary>
    /// 押せない状態の時の表示物
    /// null許容
    /// </summary>
    [SerializeField]
    private GameObject _disableRoot;

    /// <summary>
    /// クリックされた時のリスナー
    /// </summary>
    public Action OnClickedListener;

    /// <summary>
    /// 拡大可能状態を設定
    /// </summary>
    public void SetScalable(bool isScalable)
    {
        _isScalable = isScalable;
    }

    /// <summary>
    /// ディセーブル状態を設定
    /// </summary>
    public void SetDisable(bool isDisable)
    {
        _isDisable = isDisable;
        OnDisableChanged(isDisable);
    }

    /// <summary>
    /// 生成直後の処理
    /// </summary>
    protected override void Awake()
    {
        base.Awake();

        var clickEntry = new EventTrigger.Entry();
        clickEntry.eventID = EventTriggerType.PointerClick;
        clickEntry.callback.AddListener((_) => OnClicked());
        _trigger.triggers.Add(clickEntry);

        var pointerDown = new EventTrigger.Entry();
        pointerDown.eventID = EventTriggerType.PointerDown;
        pointerDown.callback.AddListener((_) => OnPointerDown());
        _trigger.triggers.Add(pointerDown);

        var pointerUp = new EventTrigger.Entry();
        pointerUp.eventID = EventTriggerType.PointerUp;
        pointerUp.callback.AddListener((_) => OnPointerUp());
        _trigger.triggers.Add(pointerUp);

        OnDisableChanged(_isDisable);
    }

    /// <summary>
    /// クリックされた時
    /// </summary>
    private void OnClicked()
    {
        if (_isDisable)
        {
            return;
        }
        SystemUtility.SafeCall(OnClickedListener);
    }

    /// <summary>
    /// 押された時
    /// </summary>
    private void OnPointerDown()
    {
        if (_isDisable)
        {
            return;
        }
        if (_isScalable)
        {
            transform.DOScale(new Vector3(0.9f, 0.9f, 0.9f), 0.1f);
        }
    }

    /// <summary>
    /// 離された時
    /// </summary>
    private void OnPointerUp()
    {
        if (_isDisable)
        {
            return;
        }
        if (_isScalable)
        {
            transform.DOScale(Vector3.one, 0.1f);
        }
    }

    /// <summary>
    /// ディセーブル状態が変わった時
    /// </summary>
    private void OnDisableChanged(bool isDisable)
    {
        if (_enableRoot == null || _disableRoot == null)
        {
            return;
        }
        _disableRoot.SetActive(isDisable);
        _enableRoot.SetActive(!isDisable);
    }
}


これを使うことで、

[SerializeField]
UGUIButton button;

button.OnClickedListener = () =>
{
    Debug.Log("くりっく!");
};

というふうにコードからも簡単に設定することができます。

RequiredCommponentで自動追加されるEventTriggerを自動で格納してほしかったので、
EditorApplication.updateに自動追加の処理を仕込みました。
これによりImageにUGUIButtonをAddCommponentしたら勝手に割り当ててくれて嬉しい。
http://anchan828.github.io/editor-manual/web/callbacks.html

注意点

ScrollRectに仕込むと、ドラッグ操作まで吸収されてしまいます。

ライセンス

自由に使ってください

3
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
3
3