I want to train a Unity ML Agent and at one part at its functionality, theres a timer written as Coroutine rightnow. I have the feeling that the Coroutine is not performing well within the training so I would like to write it as void instead of the Coroutine. The Coroutine looks like this:
private IEnumerator AttackExecutionTimer(CharacterSettings opponent, ScriptableAttack attack)
{
float duration = attack.ExecutionTime;
float normalizedTime = 0;
while (normalizedTime <= duration)
{
normalizedTime += Time.fixedDeltaTime / duration;
yield return null;
}
DoDamage(opponent, attack); //for testing, you can replace this with a log
_isCompleted = true;
}
This works fine in normal play mode. But now I want to have it as void for my agent training and every attempt I tried was causing that damage was done over a short period of time, not only once. I guess it's because I don't know how to get the precise moment when the damage should be done. Also, first I had this with Time.deltaTime, I simply switched it to Time.fixedDeltaTime as a test to check if this would perform better in training.
The _isCompleted bool is checked and set within the method that calls this Coroutine like so:
if (!_isCompleted)
{
return;
}
_isCompleted = false;
//check some other conditions
StartCoroutine(AttackExecutionTimer());
You can use Event Programming approach or Callbacks.
Another option is to Invoke method inside Unity.