Public IEnumerator 即使在被调用时也没有被 运行?

Public IEnumerator not being ran even when called?

请原谅乱七八糟的代码,因为时间c运行ch

所以写的很仓促
    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);
    }
}

所以我有这个 IEnumerator,我需要在另一个脚本中调用它,所以我包含了脚本中的所有内容。问题是,即使我在 unity 和 vs 中都得到零错误,它甚至在调用时都不是 运行 因为无论我把 debug.log 放在方法的哪个位置,它都永远不会到达 unity 的控制台(是的, 它处于调试模式)

这是其调用的脚本的重要部分:

 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;
    }

有人知道我哪里出错了吗?

您的方法 Shoot 并不是真正的 return 一个 集合 ,而是一个集合上的 迭代器 。也就是我们所说的deferred execution。因此,仅当您在该迭代器上调用 Next 时才会执行代码,这通常是通过使用某些 foreach 循环来实现的。想象一下下面的代码:

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

现在您正在尝试调用该方法:

var result = MyMethod();

因为方法是延迟执行(这就是yield关键字的作用),上面的赋值不会return所有三个数字,但只是它们的迭代器。你不能用它做很多事情,除非你像这样执行迭代器:

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

在你的情况下,我不明白为什么你的方法甚至应该 return anything,因为你没有以任何方式使用迭代器。所以我建议将您的方法设为 void 并更改此行

yield return new WaitForSeconds(firerate);

WaitForSeconds(firerate);

要调用一个public IEnumerator,你不能只把它当作一个方法来调用,你必须启动协程

StartCoroutine(Shoot(roboBullet));

有关协程的更多信息,请参阅this