1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

"SendMessage cannot be called during Awake"を出さずにインスペクターの値を反映させる

Posted at

グラフィカルなボタンをデザインして、その表示内容をスクリプトで切り替えたい場合があります。
DuaringAwake00.png

ButtonTextSelector.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ButtonTextSelector : MonoBehaviour
{
    public Sprite[] Jp;
    public Sprite[] En;

    public enum TxtList
    {
        Tutorial, Option, GameStart, OK, Tweet, Title, Skip, Close
    }

    public bool isJp = true;

    [SerializeField]
    private TxtList _Txt = TxtList.OK;
    public TxtList Txt
    {
        set
        {
            _Txt = value;
                int idx = (int)Txt;
                if (isJp)
                {
                    GetComponent<SpriteRenderer>().sprite = Jp[idx];
                }
                else
                {
                    GetComponent<SpriteRenderer>().sprite = En[idx];
                }
        }
        get { return _Txt; }
    }
}

ですが、このままでは実行するまで表示内容がかわらないため、インスペクターで設定した値で表示内容を確認したい場合、

    void OnValidate()
    {
        Txt = Txt;
    }

のようにOnValidate()をつけてインスペクターの値が変更されたときの処理を書くことが多いと思いますが、このOnValidate()を使ってインスペクターの値を変更すると、
DuaringAwake01.png
と一応は反映されますが、"SendMessage cannot be called during Awake, CheckConsistency, or OnValidate UnityEngine.StackTraceUtility:ExtractStackTrace ()"という警告が出ます。
DuaringAwake02.png
しかも#pragma warning disable XXX で表示を消すことが出来ず、非常にうざったらしいです。

なのでこの警告を出さずにインスペクターの値を反映させるためには、クラスの頭に[ExecuteAlways]アトリビュートをつけて、Update()で更新させるようにします。

ButtonTextSelector.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[ExecuteAlways]
public class ButtonTextSelector : MonoBehaviour
{
    public Sprite[] Jp;
    public Sprite[] En;

    public enum TxtList
    {
        Tutorial, Option, GameStart, OK, Tweet, Title, Skip, Close
    }

    public bool isJp = true;

    [SerializeField]
    private TxtList _Txt = TxtList.OK;
    public TxtList Txt
    {
        set
        {
            _Txt = value;
                int idx = (int)Txt;
                if (isJp)
                {
                    GetComponent<SpriteRenderer>().sprite = Jp[idx];
                }
                else
                {
                    GetComponent<SpriteRenderer>().sprite = En[idx];
                }
        }
        get { return _Txt; }
    }

    void Update()
    {
        if (!Application.isPlaying)
        {
            Txt = Txt;
        }
    }
}

[ExecuteAlways]をつけるとエディター上でも実行中と同じ処理を行うようになるため、Update()が実際に実行されインスペクターの値が反映されるという仕組みです。
DuaringAwake03.png
"SendMessage cannot be called during Awake"の警告が出なくなりました。

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?