How would I write a timer, that correctly works as Coroutine, as void?

278 Views Asked by At

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());
1

There are 1 best solutions below

0
On

You can use Event Programming approach or Callbacks.

Another option is to Invoke method inside Unity.

using UnityEngine;
using System.Collections.Generic;

public class ExampleScript : MonoBehaviour
{
    // Launches a projectile in 2 seconds

    Rigidbody projectile;

    void Start()
    {
        Invoke("LaunchProjectile", 2.0f);
    }

    void LaunchProjectile()
    {
        Rigidbody instance = Instantiate(projectile);
        instance.velocity = Random.insideUnitSphere * 5.0f;
    }
}