😃

UnityのButtonのImageが真っ黒になる現象に詰まった話 【実際のコード付き】

に公開

Unityでボタンの色を変えたいだけなのに、

Imageが真っ黒になってしまう現象に跡切りました。

これ、結構はまりやすいので、原因や実際の実装例を付けてまとめてみます!


現象

  • Buttonに付属するImageのColorを変えたら真っ黒に
  • Playするたびにリセットされる

たとえば、こんなコードで色切り替えをしようとしたとします:

if (dodgeButton != null)
{
    var image = dodgeButton.GetComponent<Image>();
    if (image != null)
    {
        image.color = (currentMoveResource >= dodgeCost) ? dodgeAvailableColor : dodgeUnavailableColor;
    }
}

これでも黒くなる。何故?
(リソースがあればボタンの色を使える色合いに、リソースがなかったら使えない色合いに変更するだけのスクリプトです。当然使えない際の色に黒色を設定しているわけではありません。)


原因

ButtonのTransition設定に気づきました。

UnityのButtonはTransitionが"Color Tint"になっていると,
hoverやclickでImage.colorを動的に上書きします

これのせいで,スクリプトでどんなにいじっても、内部で上書きされて真っ黒になりました。


実際の発生コード

今回実際にトラブルが発生していたのは、PlayerUnitController.csの中で、
移動リソース量に応じて回避ボタンの状態を変えたかった場面です。

void Awake()
{
    if (dodgeButton == null)
    {
        GameObject dodgeButtonObj = GameObject.Find("DodgeButton");
        if (dodgeButtonObj != null)
        {
            dodgeButton = dodgeButtonObj.GetComponent<Button>();
        }
    }
    if (dodgeButton != null)
    {
        dodgeButton.onClick.AddListener(TryDodge);
    }
}

private void Update()
{
    if (dodgeButton != null)
    {
        var image = dodgeButton.GetComponent<Image>();
        if (image != null)
        {
            image.color = (currentMoveResource >= dodgeCost) ? dodgeAvailableColor : dodgeUnavailableColor;
        }
    }
}

解決策

Transitionを"None"にする。これだけ。

ButtonコンポーネントのInspectorでTransitionを"None"に切り替えるだけで、
自動書き換えを無効化できます!

それだけで意図した色変更が正常に効くようになりました!


まとめ

  • UnityのButtonはTransition=ColorTintだとImage.colorを上書きする
  • スクリプトから色を変えたいならTransition=Noneにする
  • UI制御は「一体化」が原則

UnityのUI制御は、裏側を知るだけでぐっと解決に近づけます!


ブログでもUnityや個人開発ネタを発信中!

開発ノウハウやアプリ制作過程、Unity連携系のハマりポイントなど
より深採りした内容をブログにまとめています!
https://syunpp.com

公開中のアプリ一覧はこちら!

実際にUnityで開発してリリース済みのアプリ一覧をまとめています!
https://syunpp.com/公開中のアプリ一覧/

Discussion