Hello my code is basically on collision it will start the coroutine of slowing the enemy then after 3.2 seconds it reverts back to original.
private void OnTriggerEnter2D(Collider2D collision)
{
if (collision.tag == "slowProjectile")
{
StartCoroutine(slowEnemy());
}
}
// FROZEN ENEMY BEHAVIOUR
public bool isFrozen = true;
IEnumerator slowEnemy()
{
if (isFrozen == true)
{
isFrozen = false;
Debug.Log("FROZEN");
// Turns the enemy into color blue
this.GetComponent<SpriteRenderer>().color = Color.blue;
enemyMovementSpeed = enemyMovementSpeed / 2;
// waits for 3.2 seconds
yield return new WaitForSeconds(3.2f);
// Then return the enemy movement speed and color to its original state.
enemyMovementSpeed = enemyMovementSpeed * 2;
this.GetComponent<SpriteRenderer>().color = Color.white;
}
else
{
isFrozen = true;
}
}
problem is the coroutine is stacking meaning it will run x2 and lost the original value also the projectile fires every 3 seconds. Think of it as A shooter that shoots every 3 seconds and on impact slows the enemy for 3 seconds. ( Like a Snow Pea if you play Plants Vs Zombie )
CodePudding user response:
Other answer is right but adds many coroutines. Here is a solution that uses only one coroutine at a time.
private float m_timer;
private IEnumerator m_coroutine;
private void OnTriggerEnter2D(Collider2D collision)
{
if (collision.tag == "slowProjectile")
{
m_timer = 0f;
if (m_coroutine == null){
m_coroutine = FreezeTime();
StartCoroutine(m_coroutine);
}
}
}
IEnumerator FreezeTime()
{
while (m_timer < 3.2f){
m_timer = Time.deltaTime;
yield return null;
}
m_coroutine = null;
}
When a collision occurs, reset to 0 and if no coroutine is already running, create a new one.
The coroutine keeps increasing the timer, if a collision occurs, it will reset to 0. When done, it resets the coroutine reference.
CodePudding user response:
if what you want is the Frozen effect doesn't stack
:
public bool isFrozen = false;
private void OnTriggerEnter2D(Collider2D collision)
{
if (collision.tag == "slowProjectile")
{
if (!isFrozen)
{
StartCoroutine(slowEnemy());
}
}
}
IEnumerator slowEnemy()
{
isFrozen = true;
Debug.Log("FROZEN");
// Turns the enemy into color blue
this.GetComponent<SpriteRenderer>().color = Color.blue;
enemyMovementSpeed = enemyMovementSpeed / 2;
// waits for 3.2 seconds
yield return new WaitForSeconds(3.2f);
// Then return the enemy movement speed and color to its original state.
enemyMovementSpeed = enemyMovementSpeed * 2;
this.GetComponent<SpriteRenderer>().color = Color.white;
isFrozen = false;
}
The downside of the code above is that while the Speed Change doesn't stack, the Frozen Time neither
.
If you want to stack the Frozen Time and not stack Speed Change at the same time
, maybe you need to add a Forzen Stack Counter
to check whether the Frozen time is ended :
public int forenStackCount = 0;
private void OnTriggerEnter2D(Collider2D collision)
{
if (collision.tag == "slowProjectile")
{
StartCoroutine(slowEnemy());
}
}
private IEnumerator slowEnemy()
{
if (forenStackCount == 0)
{
StartFrozenEffect();
}
forenStackCount ;
yield return new WaitForSeconds(3.2f);
forenStackCount--;
if (forenStackCount == 0)
{
EndFrozenEffect();
}
}
private void StartFrozenEffect()
{
Debug.Log("FROZEN");
// Turns the enemy into color blue
this.GetComponent<SpriteRenderer>().color = Color.blue;
enemyMovementSpeed = enemyMovementSpeed / 2;
}
private void EndFrozenEffect()
{
enemyMovementSpeed = enemyMovementSpeed * 2;
this.GetComponent<SpriteRenderer>().color = Color.white;
}