Unity開発中に遭遇した、ちょっと厄介なバグについて共有します!
「ButtonのImageが真っ黒になる問題」、みなさんも遭遇したことありませんか?
この記事では、実際に詰まったコード例と、なぜ起きたか、どう直したかをコンパクトにまとめました。
現象
- Buttonに付属するImageのColorを変えたら真っ黒に
- Playするたびにリセットされる
たとえば、こんなコードを書いても:
if (dodgeButton != null)
{
var image = dodgeButton.GetComponent<Image>();
if (image != null)
{
image.color = (currentMoveResource >= dodgeCost) ? dodgeAvailableColor : dodgeUnavailableColor;
}
}
Playしてみると、意図せず真っ黒になってしまう……。
(リソースがあればボタンの色を使える色合いに、リソースがなかったら使えない色合いに変更するだけのスクリプトです。当然使えない際の色に黒色を設定しているわけではありません。)
原因
UnityのButtonには、デフォルトで**Transitionが"Color Tint"**になっており、
- Hoverしたとき
- クリックしたとき
などにImage.colorを内部的に書き換えています。
そのため、スクリプトで設定しても、Buttonの処理で上書きされてしまうわけです。
実際の発生コード
発生したのは、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=ColorTintの罠にはまっていました。
解決策
ButtonのTransitionを"None"に変更するだけでOKです!
- Buttonを選択
- Inspectorで
Transition
をNone
に変更
これで、スクリプトから設定したImage.colorが正しく反映されるようになります!
まとめ
- UnityのButtonはTransition=ColorTintだとImage.colorが自動上書きされる
- 自前で色制御するならTransition=Noneにするのが安全
- UI制御は「一体化」することがバグ回避の基本!
Unity UIバグは"仕組み"を知ればすぐ対処できるので、こういった基本挙動を押さえておくと開発がスムーズになります!
ブログでもUnityや個人開発ネタを発信中!
開発ノウハウやアプリ制作過程、Unity連携系のハマりポイントなど
より深堀りした内容をブログにまとめています!
▶ https://syunpp.com
公開中のアプリ一覧はこちら!
実際にUnityで開発してリリース済みのアプリ一覧をまとめています!
▶ https://syunpp.com/公開中のアプリ一覧/