[C#] IEnumerator function never gets called when called

hi all,

im making a weapon script, that requires the script to wait when the gun reloads. becuase im using C# the only way to do this(other than System.threading, but then everything freezes) is to make the reload function return a IEnumerator , then put in the line

yield return new WaitForSeconds(reloadtime);

inside the function, but , this particular function never runs, even when called. but when i change the return type to void, then forced to remove the line above. the function calls perfectly.

heres the full code.

using UnityEngine;
using System.Collections;

public class Deagle : MonoBehaviour {

    public int ClipAmmo;
    public const int FULLclip = 16;
    public int Currentclip = 12;
    public float fireRate = 0.5f;
    public int damage = 10;
    public float range = 100.0f;
    public float force = 2.0f;
    public uint Clips;
    public int FrameTimer;
    public GameObject Child;

    private float nextFireTime = 0.0f;
    public ParticleEmitter hitParticles;

 
    public Renderer MuzzleFlash;

    public float reloadTime = 0.5f;

	// Use this for initialization
	void Start () {

      //  hitParticles = Child.GetComponent("ParticleEmitter") as ParticleEmitter;

        // We don't want to emit particles all the time, only when we hit something.
        if (hitParticles)
            hitParticles.emit = false;
        Currentclip = FULLclip;
	}
	
	// Update is called once per frame
	void LateUpdate () {
        audio.Stop();

        MuzzleFlash.enabled = false;
        if(Input.GetButtonDown("Reload")) {
            Reload();

        }
        if(Input.GetButtonDown("Fire1")) {

           FireOneShot();
        }
        Clips = (uint)(ClipAmmo / FULLclip);

        if (Currentclip <= 0)
        {

            Reload();
            FrameTimer = 0;
        }
        
      
	}

    
 IEnumerator  Reload()
    {
        // Wait for reload time first - then add more bullets!

       // System.Threading.Thread.Sleep(500 );
    yield return new WaitForSeconds(reloadTime)
	// We have a clip left reload
	if (Clips > 0) {
        ClipAmmo = ClipAmmo - FULLclip;
		Currentclip = FULLclip;
       /print("RELOAD!");
	}
      
    }
    void Aim()
    {

    }
 

void FireOneShot() {
    Vector3 direction = transform.TransformDirection(Vector3.forward);
       RaycastHit hit;
	
	// Did we hit anything?
	if (Physics.Raycast (transform.position, direction,out hit, range)) {
		// Apply a force to the rigidbody we hit
		if (hit.rigidbody)
			hit.rigidbody.AddForceAtPosition(force * direction, hit.point);
		
		// Place the particle system for spawing out of place where we hit the surface!
		// And spawn a couple of particles
		if (hitParticles) {
			hitParticles.transform.position = hit.point;
			hitParticles.transform.rotation = Quaternion.FromToRotation(Vector3.up, hit.normal);
			hitParticles.Emit();
		}

		// Send a damage message to the hit object			
		hit.collider.SendMessageUpwards("ApplyDamage" , damage, SendMessageOptions.DontRequireReceiver);
	}

    Currentclip--;

	// Register that we shot this frame,
	// so that the LateUpdate function enabled the muzzleflash renderer for one frame
    MuzzleFlash.enabled = true;
    audio.Play();
	
	// Reload gun in reload Time		
    if (Currentclip <= 0)
    {

        Reload();
    }
}
}

is there anything in this code that would make this happen? do i need another using statement? is calling a function from JS my only option? or is there a way to make a timer that counts the frame being called then when it hits a certain number the rest of the reload function is called?

You can’t have the return type be void, coroutines must be IEnumerator. You have to use StartCoroutine in C#, like the docs say.

–Eric

i didn’t use void, if you look at the Reload function which is what i was trying to call, unless you mean no return type can ever be void in the class when using a co-routine in one function.

ive added the StartCouritine Call as it says in the docs herehttp://unity3d.com/support/documentation/ScriptReference/MonoBehaviour.StartCoroutine.html?from=index

the code is now

using UnityEngine;
using System.Collections;

public class Deagle : MonoBehaviour {

    public int ClipAmmo;
    public const int FULLclip = 16;
    public int Currentclip = 12;
    public float fireRate = 0.5f;
    public int damage = 10;
    public float range = 100.0f;
    public float force = 2.0f;
    public uint Clips;
    public int FrameTimer;
    public GameObject Child;

    private float nextFireTime = 0.0f;
    public ParticleEmitter hitParticles;

 
    public Renderer MuzzleFlash;

    public float reloadTime = 0.5f;

	// Use this for initialization
	void Start () {

      //  hitParticles = Child.GetComponent("ParticleEmitter") as ParticleEmitter;

        // We don't want to emit particles all the time, only when we hit something.
        if (hitParticles)
            hitParticles.emit = false;
        Currentclip = FULLclip;
	}
	
	// Update is called once per frame
	void LateUpdate () {
        audio.Stop();

        MuzzleFlash.enabled = false;
        if(Input.GetButtonDown("Reload")) {
            Reload();
             
        }
        if(Input.GetButtonDown("Fire1")) {

           FireOneShot();
        }
        Clips = (uint)(ClipAmmo / FULLclip);

        if (Currentclip <= 0)
        {

            Reload();
            FrameTimer = 0;
        }
        
      
	}

    
  IEnumerator Reload()
    {
        // Wait for reload time first - then add more bullets!

       // System.Threading.Thread.Sleep(500 );
        yield return StartCoroutine(WaitAndPrint(reloadTime));
	// We have a clip left reload
	if (Clips > 0) {
        ClipAmmo = ClipAmmo - FULLclip;
		Currentclip = FULLclip;
       // print("RELOAD!");
	}
      
    }
  IEnumerator WaitAndPrint(float waitTime)
  {
      yield return new WaitForSeconds(waitTime);
      print("WaitAndPrint " + Time.time);
  }
    void Aim()
    {

    }
 

void FireOneShot() {
    Vector3 direction = transform.TransformDirection(Vector3.forward);
       RaycastHit hit;
	
	// Did we hit anything?
	if (Physics.Raycast (transform.position, direction,out hit, range)) {
		// Apply a force to the rigidbody we hit
		if (hit.rigidbody)
			hit.rigidbody.AddForceAtPosition(force * direction, hit.point);
		
		// Place the particle system for spawing out of place where we hit the surface!
		// And spawn a couple of particles
		if (hitParticles) {
			hitParticles.transform.position = hit.point;
			hitParticles.transform.rotation = Quaternion.FromToRotation(Vector3.up, hit.normal);
			hitParticles.Emit();
		}

		// Send a damage message to the hit object			
		hit.collider.SendMessageUpwards("ApplyDamage" , damage, SendMessageOptions.DontRequireReceiver);
	}

    Currentclip--;

	// Register that we shot this frame,
	// so that the LateUpdate function enabled the muzzleflash renderer for one frame
    MuzzleFlash.enabled = true;
    audio.Play();
	
	// Reload gun in reload Time		
    if (Currentclip <= 0)
    {

        Reload();
    }
}
}

still this function Reload is not being called. at least not running anyway,

StartCoroutine(Reload());

3 Likes

thanks! im sorry if this was stupid, noobish and the answer could of been buried in the docs Somewhere. im kinda more of a 3d modeler not a C# programmer.

thanks,

Not realy burried : http://unity3d.com/support/documentation/ScriptReference/30_search.html?q=coroutine

Allways usefull to read about it and how to use.