Home > Back-end >  Public IEnumerator not being ran even when called?
Public IEnumerator not being ran even when called?

Time:05-07

please excuse the messy code, all of this was written very hastily because I'm on a time crunch

    public class EnemyShoot : MonoBehaviour
{
    [SerializeField] Transform player;
    public float speed = 100f;
    public float angle;
    public Quaternion rotation;
    bool allowforfire;
    [SerializeField] float bulletSpeed, firerate;
    private void Update()
    {
        Vector2 direction = player.position - transform.position;
        angle = Mathf.Atan2(direction.y, direction.x) * Mathf.Rad2Deg;
        rotation = Quaternion.AngleAxis(angle, Vector3.forward);
        transform.rotation = Quaternion.Slerp(transform.rotation, rotation, speed * Time.deltaTime);

        if(player.position.x < transform.parent.position.x)
        {
             transform.localPosition = new Vector2(-0.155f, 0f);
        }
        else
        {
            transform.localPosition = new Vector2(0.155f, 0f);
        }

        
    }
    public IEnumerator Shoot(GameObject bullet)
    {
        Debug.Log("reached shoot");
        yield return new WaitForSeconds(firerate);
        var clone = Instantiate(bullet, transform);
        var bulletRb = clone.GetComponent<Rigidbody2D>();
        bulletRb.velocity = transform.right * bulletSpeed;
        Debug.Log("reached fire");
        clone.transform.position = new Vector3(clone.transform.position.x, clone.transform.position.y, -1f);
    }
}

so I have this IEnumerator that I need to be called in another script so I included everything from the script its from. the problem is that even though I am getting zero errors in both unity and vs its not even being run when called since no matter where in the method I put the debug.log it never gets to unity's console (yes, its in debugging mode)

this is the important part of the script its called in:

 public int robohealth = 4;
    public float speed = 0.2f;
    public float minMoveDist = 3f;
    public SpriteRenderer roboSprite;
    Vector3 oldPos;
    public Animator roboAnim;
    [SerializeField] Transform target;
    public GameObject roboBullet;
    public EnemyShoot shootScript;

    private void Update()
    {
        if (target != null)
        {
            float trueSpeed;
            float PositionDelta = Vector2.Distance(transform.position, target.position);
            if(PositionDelta < minMoveDist)
            {
                trueSpeed = 0f;
                
            }
            else
            {
                trueSpeed = speed * Time.deltaTime;
            }
            
            transform.position = Vector2.MoveTowards(transform.position, target.position, trueSpeed);

            if (oldPos != transform.position)
            {
                roboAnim.SetBool("ShouldWalk", true);
            }
            else 
            { 
                roboAnim.SetBool("ShouldWalk", false);
                //not working ):
                shootScript.Shoot(roboBullet);
            }
            

            oldPos = transform.position;
        }
        
        roboSprite.flipX = transform.position.x > target.position.x;
    }

anyone got any clue as to where I went wrong?

CodePudding user response:

To call a public IEnumerator, you can't just call it as a method, you have to start the coroutine

StartCoroutine(Shoot(roboBullet));

For more info on Coroutines, refer to this

CodePudding user response:

Your method Shoot does not really return a collection, but an iterator on a collection. That's what we call deferred execution. So the code is only executed, when you're calling Next on that iterator, which is typically achieved by using some foreach-loop. Imagine the following code:

IEnumerable<int> MyMethod() 
{
    yield return 3;
    yield return 5;
    yield return 7;
}

Now you're trying to call that method:

var result = MyMethod();

As the method is deferredely executed (that's what the yield-keyword is for), that above assignment won't return all the three numbers, but just an iterator to them. You can't do much with it, unless you execute the iterator like this:

foreach(var number in result)
    Console.WriteLine(number);

In your case I can't see why your method should even return anything, as you're not using the iterator in any way. So I'd suggest to make your method a void and change this line

yield return new WaitForSeconds(firerate);

to

WaitForSeconds(firerate);
  • Related