I am making a FPS game and I noticed that the way it was done, the player could reload and immediately equip another weapon to cancel the reload animation and delay. I tried to fix this using IEnumerators, and it seems to work sort of fine, but I feel like I am doing something wrong…
Will this code cause performance issues? Would it be better to use void Update () for this?
void StartReload ()
{
if (TotalAmmo > 0)
{
if (AnimatorController != null)
{
AnimatorController.CrossFadeInFixedTime(ReloadAnimationName, 0f);
}
ReloadSound.Play();
AnimatorController.SetLayerWeight(1, 0); //Sets the Slide Lock Back in place when reloading//
StartCoroutine(Reload());
StartCoroutine(TryStopReload(true));
}
else
{
NoAmmoSound.Play ();
}
}
IEnumerator TryStopReload (bool Continue)
{
yield return new WaitForSeconds(0.1f);
if (!Equipped)
{
StopCoroutine(Reload());
}
if (Continue)
{
StartCoroutine(TryStopReload(true));
}
else
{
yield break;
}
}
IEnumerator Reload ()
{
yield return new WaitForSeconds(ReloadDelay);
if (SingleBulletReload)
{
TotalAmmo--;
Ammo++;
}
else
{
int ReloadingAmount = AmmoCapacity - Ammo;
if (TotalAmmo > ReloadingAmount)
{
TotalAmmo -= ReloadingAmount;
Ammo += ReloadingAmount;
}
else
{
TotalAmmo = 0;
Ammo += TotalAmmo;
}
}
CurrentFireDelay = ReloadDelay;
if (HUD != null)
{
HUD.AmmoCounter.text = Ammo + "/" + TotalAmmo;
}
StartCoroutine(TryStopReload(false));
}
Explanation:
Basically, the first method void StartReload () starts the reload animation, and calls both the other methods, which are coroutines. The method IEnumerator Reload () changes the number of bullets in the player’s weapon, so it’s only called after all the delays to make sure player can’t skip this by changing weapons. The method IEnumerator TryStopReload (bool Continue) tries to interrupt the call to IEnumerator Reload () if it sees that the player tried to equip another weapon, cancelling the reload and forcing the player to reload again. IEnumerator TryStopReload (bool Continue) is called every tenth of a second (using a normal void method causes a stack overflow, hence it is a coroutine and is only called once per tenth of a second) until IEnumerator Reload () is finally called, cancelling it.
I feel like there is something wrong with this approach, either it’s performant heavy, or it’s just not optimal for some reason… Maybe I should just use something with void Update ().