Публичный IEnumerator не запускается даже при вызове?

пожалуйста, извините за беспорядочный код, все это было написано очень поспешно, потому что у меня нет времени

    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, так и в том, что он даже не запускается при вызове, поскольку независимо от того, где в методе я помещаю 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;
    }

кто-нибудь понял, где я ошибся?

Можете ли вы показать трассировку стека, пожалуйста?

Paul Sinnema 06.05.2022 16:08
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
1
48
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Ваш метод Shoot на самом деле возвращает не коллекция, а итератор в коллекции. Это то, что мы называем отложенное исполнение. Таким образом, код выполняется только тогда, когда вы вызываете Next на этом итераторе, что обычно достигается с помощью некоторого foreach-цикла. Представьте себе следующий код:

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

Теперь вы пытаетесь вызвать этот метод:

var result = MyMethod();

Поскольку это метод отсрочено (именно для этого используется ключевое слово yield), указанное выше присваивание не вернет все три числа, а только итератор для них. Вы ничего не можете с этим сделать, если только вы не используете выполнять итератор следующим образом:

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

В вашем случае я не понимаю, почему ваш метод должен вообще возвращать что-либо, поскольку вы никак не используете итератор. Поэтому я предлагаю сделать ваш метод void и изменить эту строку

yield return new WaitForSeconds(firerate);

к

WaitForSeconds(firerate);

не могли бы вы перевести это на обычный человеческий язык? я не понимаю что это значит

Oliver Sales Jäderberg 06.05.2022 16:16

@OliverSalesJäderberg Я не уверен, что вы подразумеваете под «говорят нормальные люди», но linq anove должен дать вам более глубокое понимание того, как работает отложенное выполнение. По сути, ключевые слова yield указывают на то, что ваш метод является выполняется отложенно. Что это значит написано по ссылке.

MakePeaceGreatAgain 06.05.2022 16:18

Я просто очень плохо разбираюсь в каких-либо реальных концепциях и терминологии в программировании, я в основном знаю синтаксис. поэтому всякое случается, когда я печатаю, но то, что я делаю, называется «я ничего не понимаю». например, я понятия не имею, что такое IEnumerator, это просто то, что я нашел, кто-то использует в Google для того же самого.

Oliver Sales Jäderberg 06.05.2022 16:22

Чтобы вызвать public IEnumerator, вы не можете просто вызвать его как метод, вы должны запустить сопрограмму

StartCoroutine(Shoot(roboBullet));

Дополнительные сведения о сопрограммах см. в статье это.

Другие вопросы по теме