Alternate cooldown solution and question

@Brian_Trotter This was how i solved the challenge.

  1. in start set the time since attack to the cooldown time to avoid any bugs with first attacks.
  2. created method to increase cooldown but with the check inverted ( i think it should reduce calculations)
  3. reset time since last attack inside of the attack method instead of standalone in update.

i have three questions…

  1. does the inverted check actually help optimize here?
  2. i thought about having the cooldown check manage a a canAttack bool. that way all it is doing is checking canAttack instead of calculating the cooldown directly. I wasn’t sure if that actually optimized or if it really just cost the same amount since its a very small calc.
  3. am i deviating from the code too much and making lessons further into the course more complicated for myself?
 private void Update()
        {
            ManageAttackCooldown();
            if (_target == null) return;
            if (_target != null && !GetIsInRange())
            {
                GetComponent<Mover>().MoveTo(_target.position);
            }
            else
            {
                GetComponent<Mover>().Cancel();
                if (_timeSinceLastAttack >= _timeBetweenAttacks)
                {
                    AttackBehavior();
                }
            }
        }

        private void ManageAttackCooldown()
        {          
            if (_timeSinceLastAttack <= _timeBetweenAttacks)
            {
                _timeSinceLastAttack += Time.deltaTime;
            }
        }

     public void Attack(CombatTarget combatTarget)
        {
            GetComponent<ActionScheduler>().StartAction(this);
            _target = combatTarget.transform;           
            //Hit();
        }

(PS, right after your message last night the course refactored those get components i was asking to about into caches at start. so, Im leaving them in here and just trusting the process)

1 Like

I tend to invert time since last Attack’s logic…

float cooldownTimer = 0f;

And instead of adding, I subtract, so resetting cooldownTimer to cooldownTime and then subtracting Time.deltaTime… But there’s a madness to my method, I like to have a bit of randomness in the attack frequency… so when I reset the timer, I use

cooldownTimer = Random.Range(cooldownTime*.9f, cooldownTime*1.1f);

Maybe… but only a deep profile would tell for sure.

This optimization would be efficient, especially if the two were combined…

bool cooldownExpired = true;
float _timeSincelastAttack = 100000f;

private void ManageAttackCooldown()
{
    if(!cooldownExpired)
    {
        _timeSinceLastAttack = Time.deltaTime;
        cooldownExpired = _timeSinceLastAttack>=_timeBetweenAttacks;
    }
}

All of this is absolutely fine with the course so far.

Try to spot the redundancy in the 2nd line here… :slight_smile:

Thanks brian! I was worried the bool would be a bit too much of a deviation if they refactor later. don’t know how i didn’ spot that redundancy, i just threw the check at the top and didn’t even look i guess.

cooldownTimer = Random.Range(cooldownTime*.9f, cooldownTime*1.1f);

i like this little snippet and will be modifying it for abuse later :slight_smile:

1 Like

It works great for damage too. :slight_smile:

And the abuse has begun.

 private void PatrolBehavior()
        {
            Vector3 nextPosition = _guardPosition;

            if(_patrolPath != null) 
            
            {
                if(AtWaypoint())
                {
                    _timeSinceArrivedAtWaypoint = 0;
                    CycleWaypoint();
                }

                nextPosition = GetCurrentWaypoint();

            }
            if (_timeSinceArrivedAtWaypoint >= BriansSlightlyDirtyRandomization(_waypointDwellTime))
            {
                _mover.StartMoveAction(nextPosition);
            }
        }

//further down in the code.....

 private float BriansSlightlyDirtyRandomization(float value)
        {
            float RandomizedValue = Random.Range(value * .85f, value * 1.2f);
            return RandomizedValue;
        }
1 Like

Not bad. :slight_smile: It does contain one small flaw, every frame, BriansSlightlyDirtyRandomization(_waypointDwellTime) will be a different value… it’s better to cache the value when it’s reset (so the method is called just the one time.

Extra SlightlyDirtyTrick, this should go outside of the class but within the namespace (actually, I’d put it in the Core namespace)

public static class BriansSlightlyDirtyExtensions
{
     public static float BriansSlightDirtyRandom(this float value)
     {
          return Random.Range(value * .85f, value * 1.2f);
     }
}

Then in your patrol code:

 float currentDwellTime;
 private void PatrolBehavior()
        {
            Vector3 nextPosition = _guardPosition;

            if(_patrolPath != null) 
            
            {
                if(AtWaypoint())
                {
                    _timeSinceArrivedAtWaypoint = 0;
                    currentDwellTime = _waypointDwellTime.BriansSlightlyDirtyRandom();
                    CycleWaypoint();
                }

                nextPosition = GetCurrentWaypoint();

            }
            if (_timeSinceArrivedAtWaypoint >= currentDwellTime)
            {
                _mover.StartMoveAction(nextPosition);
            }
        }
1 Like

yeah i actuality thought about dropping it in my personal utils namespace with some cleaning up. i didn’t think about the caching though… good point.

Privacy & Terms