- Home /
A little help with loops and understanding how to format them (C#)
I currently get this error:
error CS1624: The body of player.Update()' cannot be an iterator block because void' is not an iterator interface type
I'm not sure it will be much help though. It worked fine until I started making a loop.
What I want to be able to do, is to make my character fire a projectile every half a second if the space bar is being held down. But I don't know where to put my loop. should it be in a function, or can it stay in update?
private Transform ship;
public int shipspeed = 5;
public Transform shotPos;
public float shotForce = 1000f;
public Rigidbody projectile;
bool gun1 = false;
void Start () {
//spawn position
ship = transform;
ship.position = new Vector3(0, -7, 2);
}
void Update () {
//Horizontal movement with arrow keys
ship.Translate(Vector3.right * shipspeed * Input.GetAxis("Horizontal") * Time.deltaTime);
//ship wrapping
if(ship.position.x > 6){
ship.position = new Vector3(-6, -7, 2);
}
else if(ship.position.x < -6){
ship.position = new Vector3(6, -7, 2);
}
//guns
if(Input.GetButtonDown("Jump"))
{
gun1 = true;
}
//loop that fires the capsule every 0.5 seconds if you are holding down space
while(gun1 = true){
Rigidbody shot = Instantiate(projectile, shotPos.position, shotPos.rotation) as Rigidbody;
shot.AddForce(shotPos.up * shotForce);
yield return new WaitForSeconds(0.5f);
}
}
}
Edit: The error is on line 22
Answer by Rabwin · Aug 25, 2013 at 05:42 PM
First of all, gun1 will never get set to false inside that while loop. Second, comparator is == not a single =.
A fix for this is to change the while loop to
while(GetButton("Shoot")) {...}
And just get rid of gun1 variable altogether (unless you needed it elsewhere).
I'm not sure what your error is, but I think you should fix that code first, and then we can work from there.
Edit: Okay, I know what your error is now (derp). You can't have a yield return statement inside the Update() function Change it to a function, and call it from the loop:
Waitfor(5.0f); //call this inside the loop
private IEnumerator Waitfor(float t) //new function
{
yield return new WaitForSeconds(t);
}
I don't think that will work either, you cannot yield from Update since Update returns void and you need IEnumerator
I think that still won't do it. You need a coroutine. Your while loop will never stop inside the Update so you are about to call a hell of a lot of WaitFor();
Answer by DESTRUKTORR · Aug 25, 2013 at 05:46 PM
yield return new WaitForSeconds(someTimeFloat); is supposed to be used in an IEnumerator, from what I understand of it, but frankly you don't want to do this, anyway. what would be much simpler would be to use this:
InvokeRepeating("SomeMethodForFiringProjectile", 0.5f, 0.5f);
for example:
void Update () {
//Horizontal movement with arrow keys
ship.Translate(Vector3.right * shipspeed * Input.GetAxis("Horizontal") * Time.deltaTime);
//ship wrapping
if(ship.position.x > 6){
ship.position = new Vector3(-6, -7, 2);
}
else if(ship.position.x < -6){
ship.position = new Vector3(6, -7, 2);
}
//guns
gun1 = Input.GetButton("Jump");
if(gun1 && !IsInvoking("FireGun"))
InvokeRepeating("FireGun",0.5f, 0.5f);
else if(!gun1 && IsInvoking("FireGun"))
CancelInvoke("FireGun");
}
}
private void FireGun()
{
Rigidbody shot = Instantiate(projectile, shotPos.position, shotPos.rotation).rigidbody;
shot.AddForce(shotPos.up * shotForce);
}
[EDIT] noticed some more stuff of yours that you might want to change, and changed it :P
I gave this a shot. I got one error related to braces, so I put the new function inside the class. It fixed it, but now I still get this error:
error CS1061: Type UnityEngine.Object' does not contain a definition for rigidbody' and no extension method rigidbody' of type UnityEngine.Object' could be found (are you missing a using directive or an assembly reference?)
on line 32
Answer by fafase · Aug 25, 2013 at 05:56 PM
If you want to use a loop you need a coroutine
public class Test : MonoBehaviour {
public float fireRate;
void Update(){
if(Input.GetButtonDown("Jump")){
StartCoroutine("Fire");
}
if(Input.GetButtonUp("Jump")){
StopCoroutine("Fire");
}
}
void Shoot (){
print ("Fire");
}
IEnumerator Fire(){
float timer = 0;
Shoot();
while(true){
while(timer < fireRate){
timer += Time.deltaTime;
yield return null;
}
timer = 0;
Shoot ();
yield return null;
}
}
}
One error on line 11
error CS1525: Unexpected symbol (', expecting )', ,', ;', [', or ='
You did something wrong, it goes fine for me. Reviewed and working just fine.
Note that I modified my example. The first one was not working as expected. Now it does.
Your answer
Follow this Question
Related Questions
Running multiple coroutines in loops with different time 2 Answers
Re-using the "same" for loop? 1 Answer
Loop animation with a wait in between 3 Answers
How to have a (wait) yield on a for loop? 0 Answers
Simple rotation script. (loop) 3 Answers