ゲームのイントロダクション中とかに、説明中に押されたくないボタンとかがあります。
やりたかったのは、以下の2点。
- 説明中もゲーム側のロジックによってボタンのinteractableが切り替わってしまうことがあるので、Buttonのinteractableをいじらない。
- 説明中もゲーム側のロジックによってボタンの位置やサイズが変わることがあってもブロックし続ける。
実装としては、ButtonBlockerクラスがアルファ0のImageを持ってて、それでボタンをブロックしているだけです。
Update内で、ブロック先のポジションやサイズに追従するようになっています。
厳密に言うとUpdateのタイミングをちゃんと管理しないと、1frame分追従が遅れますが、手抜きでそこは考慮されていません。
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
public class ButtonBlocker : MonoBehaviour {
public RectTransform target = null;
private RectTransform rectTransform;
private Image image;
public void SetTarget( RectTransform rt ) {
target = rt;
if( rt != null ) { transform.SetParent( rt.parent ); }
}
public bool EnableBlock {
get { return image.raycastTarget; }
set { image.raycastTarget = value; }
}
void Awake () {
rectTransform = GetComponent< RectTransform >();
image = GetComponent< Image >();
Debug.Assert( rectTransform != null );
Debug.Assert( image != null );
}
void Update () {
if( target != null )
{
rectTransform.rect.Set( target.rect.x, target.rect.y, target.rect.width, target.rect.height );
rectTransform.sizeDelta = target.sizeDelta;
rectTransform.localScale = target.localScale;
rectTransform.localRotation = target.localRotation;
rectTransform.localPosition = target.localPosition;
}
}
}
EnableBlock プロパティで、ブロックのon/offを切り替えることができます。
使い方は、テキトーにImageコンポーネントを持ったPrehabを作って
blocker = Instantiate( buttonBlockerPrehab ).GetComponent< ButtonBlocker >();
RectTransform rect = targetObject.GetComponent< RectTransform >();
blocker.SetTarget( rect );
という感じです。