- Home /
Ienumerator not working properly
I am working on a 3d game that involves switching between 3 lanes to avoid obstacles. I am adding a power-up and I have the spawning working, I am currently trying to add a timer that wears off after 5 seconds. My coroutine only works once and skips over the while loop inside it. I have tried starting the coroutine in Start() and Update(), but it only runs the two Debug.Log() commands once, then nothing. I have set the bool for the loop to true in multiple parts of the code but it does not seem to be working. Does anyone know what I am doing wrong? Also sorry, I couldn't get the code coloured.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerControllerSmoothMovement : MonoBehaviour
{
private Vector3 startPosition = new Vector3 (0, 2, -6);
private Vector3 leftPosition = new Vector3 (-3, 2, -6);
private Vector3 rightPosition = new Vector3 (3, 2, -6);
Animator anim;
private Rigidbody playerRB;
public ParticleSystem particle;
public Collision power;
private float timer;
private bool boolean;
private IEnumerator powers;
private float repeatRate = 0.0f;
void Start()
{
powers = PowerUpTimer();
anim = GetComponent<Animator>();
playerRB = GetComponent<Rigidbody>();
particle.Stop();
timer = 0.0f;
StartCoroutine(powers);
}
// Update is called once per frame
void Update()
{
if(Input.GetKeyDown(KeyCode.A))
{
if(transform.position == startPosition)
{
anim.SetTrigger("StartToLeft");
}
if(transform.position == rightPosition)
{
anim.SetTrigger("RightToStart");
}
}
if(Input.GetKeyDown(KeyCode.D))
{
if(transform.position == startPosition)
{
anim.SetTrigger("StartToRight");
}
if(transform.position == leftPosition)
{
anim.SetTrigger("LeftToStart");
}
}
}
void OnTriggerEnter(Collider other)
{
if(other.gameObject.tag == "Obstacle")
{
playerRB.useGravity = true;
anim.gameObject.GetComponent<Animator>().enabled = false;
playerRB.AddTorque(Vector3.left, ForceMode.Impulse);
playerRB.AddExplosionForce(20.0f, transform.position, 20.0f, 5.0f, ForceMode.Impulse);
particle.Play();
StopAllCoroutines();
}
if(other.gameObject.CompareTag("PowerUp"))
{
boolean = true;
timer = (timer + 5.0f);
StartCoroutine(powers);
}
}
IEnumerator PowerUpTimer()
{
Debug.Log("timer is" + timer);
while(boolean == true)
{
yield return new WaitForSeconds(1);
Debug.Log("hi");
timer = (timer - 1.0f);
particle.Play();
}
Debug.Log("passed while loop");
yield return new WaitForSeconds(1);
}
}
Answer by sacredgeometry · Mar 07 at 03:35 PM
This is really confused, all you need to do in your couroutine is essentially this:
IEnumerator PowerUp()
{
particleSystem.Play();
// Add buff or enable power-up here
yield return new WaitForSeconds(5);
// Remove buff or disable power-up here
particleSystem.Stop
}
And I just have this called when I want it activated right? Thank you for this answer.
It only plays once, though. If the power-up gets activated again it doesn't work. Does anyone know any solutions for this?
StartCouroutine(PowerUp()) gets called when ever you want to power up, at the moment its on trigger enter.
What code have you put in the coroutine? It will trigger the coroutine every time you start it so I would probably wrap it in a test to see if it is in fact already started.
Your answer
![](https://koobas.hobune.stream/wayback/20220613053914im_/https://answers.unity.com/themes/thub/images/avi.jpg)
Follow this Question
Related Questions
Coroutine Errors 0 Answers
Coroutine Scale goes past maxSize, but still keeps scaling. 2 Answers
StartCoroutine NullReferenceException: Object reference not set to an instance of an object 1 Answer
Why does this co-routine not function properly after re-entering the scene? 0 Answers
Problems with C# Coroutines 4 Answers