Following code was working fine, stable, before upgrading to U6.
After upgrade, on random it does not work - seems that Awaitable.EndOfFrameAsync() is either never called or never returns.
It works first time, after Editor restart. Any other time I enter Play mode, code is not executed.
What’s going on?
Code:
public static async void Schedule_Async(Func<bool> condition, Action method, string label = null)
{
Func<Task> task = async () =>
{
bool condition_checked = false;
do
{
condition_checked = condition.Invoke();
if (condition_checked)
{
method.Invoke();
break;
}
else
{
await Awaitable.EndOfFrameAsync();
}
}
while (!condition_checked);
};
await task();
}
It seems that it works after each domain reload.
Domain reload → Play → works.
Play → does not work
(change in the script, compile, domain reload)
Play → works
Play → does not work
How to investigate this further? It’s a core functionality in the game (object initialization) and re-writing it all right now is a nightmare!
Your Schedule_Async isn’t returning Awaitable. That’s about the only thing I notice and it’s probably not relevant.
Given the behaviour I suspect you have domain reload disabled in Editor settings? If so, check for any static fields involved in this schedule method.
I don’t know your intent here but on first sight this method seems like something you wouldn’t normally need. Most of these “order of initialization” issues can be resolved by sticking to the rule of assigning references in Awake but not using (make calls to) those references until Start or OnEnable.
Basically: Awake = initialization code (get/find reference), Start = one-time setup code (get/set properties, call methods)
And of course using a class that performs the initialization of a group of objects, then it raises an event when everything is ready to go.
That worked.
I even simplified waiting method.
I have a GO with OnEnable calling this code:
Utilities.AwaitFor(() => true, () =>
{
Game_Logger.T(this.gameObject, $"Ping", 3);
}, "World Spawner");
Utilities.AwaitFor:
public static async void AwaitFor(Func<bool> condition, Action method, string label = null)
{
while(!condition())
{
await Awaitable.NextFrameAsync();
}
method();
}
Works fine for the first time, then it’s dead, until domain reload.
It’s not about patterns but broken unity code - I suspect it’s editor.
And yes, I have domain reload disabled, just like before upgrading to U6 and it worked.