In newer Unity, use OnValidate instead of Awake

Apparently in Unity 2022.1.19, adding a node in Awake doesn’t work too well. It almost does: a node gets added but as soon as you click away, it vanishes. However, if you shut down Unity and restart it, the node comes back. (serialization bug?)

But moving the code to OnValidate fixes this. With a side effect: if you delete all nodes, it will create one again, so you can’t have an empty dialog (not that I know of any use cases for such).

4 Likes

I have a Similar Issue Using Unity 2021.3.12f1

The Awake function does not get called for my already created dialogs. So I had a dialog with no nodes. If I created a new dialog the awake function got called.

OnValidate is only called if you are in the Editor, there is no need to have the Preprocessor Directives.

On a side note if you are building for Web I have had issues when encapsulating Methods inside Preprocessor Directives.

#if UNITY_EDITOR
private void Awake()
{
    if (nodes.Count == 0) nodes.Add(new DialogueNode());
}
#endif

Get an error something about Method does not Exist, I do not remember the exact wording of the error.
To fix this put the Preprocessor Directive inside of the method

private void Awake()
{
    #if UNITY_EDITOR
    if (nodes.Count == 0) nodes.Add(new DialogueNode());
    #endif
}

I see not everyone uses the British (Middle English) spelling. I use to be confused when seeing it spelt dialogue, when I used the spelling dialog, I use to think it was because I can not spell.

Unity is a game engine created by Unity Technologies. It was first released in 2011. Unity is free and open-source software (FOSS) licensed under the MIT License. Unity’s goal is to make it easier for developers to create games, apps, simulations, visualizations, and other interactive content using C and JavaScript.
The problem I am having is that when I try to run my game, it crashes immediately after starting. I have tried everything I could think of to fix this issue, including changing the order of scripts, deleting them, and even reinstalling Unity. Nothing seems to work.
I have attached the error log file below.
Error Log File

A:

You should not put code inside Awake() method. Instead, put it in Start().

Our company is based in England, so for many things, we tend to use the Queen’s (King’s?) English.

Provided you do not call any Editor code within OnValidate(). While OnValidate() is not CALLED, it is still compiled into a built game if it is not code blocked out.

This is actually the preferred method with all Unity Callback methods that you are going to use conditional coding on.

It is all good even for companies in here do now. It is a rarity to see it spelt dialog, and I really can not spell to save my life.

In a future video we add the OnValidate method. Technically the code in the example is not Editor Compile only code. It is Editor Only Use Code. For the dictionary I created a separate Method, and call it from both Awake and OnValidate. Then this might be a more of a me preference thing.

       private void Awake()
        {
            BuildLookUpTable();
        }

        private void OnValidate()
        {
            if (nodes.Count < 1) nodes.Add(new DialogueNode());

            BuildLookUpTable();
        }

        private void BuildLookUpTable()
        {
            _nodeLookUp.Clear();
            foreach (DialogueNode node in GetAllNodes())
            {
                _nodeLookUp[node.uniqueID] = node;
            }
        }

This is one of those lessons learned things. In the course He had it outside the method. I think there was a reference to moving the directive into the Awake method in one of the latter Videos and/or one of the Latter discussions on the form. I have do it this way now even if the Method is not a Unity Callback. At the time of learning it was one of those obscure error messages.

This is the contents of the log file? It’s fine (sometimes preferable) to put code in Awake()…
Here are my rules of what things to put in what methods:

  • Awake() → Cache component references and initialize needed classes like Lists/Dictionaries here. Do not act on cached references here.
  • OnEnable()/OnDisable() → Subscribe/unsubscribe to events here
  • Start() → You should now be free to reference external components. Other components should have been properly initialized in Awake().
3 Likes

Try to use Reset() instead of Awake()
I’m using U2022.1.13 and it was helped me.

Be aware that Reset() will NOT work in a built game. This is an Editor only method.

Don’t see any problem with it, I’m using it in editor script (that script don’t matter in a build game) and only for setup default values (as Unity documentation recommend).
So I think this is perfect solution for discussed case.

It isn’t called in a built game, meaning the first time you go to get a Dialogue, the dialogue will be blank because the Dictionary won’t be built. Trust me, I debugged a lot of students issues with this very problem.

At first - we are talking about lecture when lookup dictionary haven’t implemented yet.
At second - I don’t invoke BuildLookupTable() in Reset(), I’m using the same Awake() and OnValidate() structure as in the lecture to create it.
Putting the code that create a default node in Reset() solve the problem, allows us avoid useless check when we build lookup dictionary and add for us option “Reset” in the inspector.

And solution with OnValidate() works the same as the problem described in the original post in my Unity verison.

Sorry, the discussion at some point wound into the problems with Dialogues not functioning correctly in built games, and I read the Reset() comment in that vein.

It will work for creating a new DialogueNode in the Editor when one doesn’t exist. It won’t work in a built game.

Privacy & Terms