пожалуйста, извините за беспорядочный код, все это было написано очень поспешно, потому что у меня нет времени
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;
}
кто-нибудь понял, где я ошибся?
Ваш метод 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);
не могли бы вы перевести это на обычный человеческий язык? я не понимаю что это значит
@OliverSalesJäderberg Я не уверен, что вы подразумеваете под «говорят нормальные люди», но linq anove должен дать вам более глубокое понимание того, как работает отложенное выполнение. По сути, ключевые слова yield
указывают на то, что ваш метод является выполняется отложенно. Что это значит написано по ссылке.
Я просто очень плохо разбираюсь в каких-либо реальных концепциях и терминологии в программировании, я в основном знаю синтаксис. поэтому всякое случается, когда я печатаю, но то, что я делаю, называется «я ничего не понимаю». например, я понятия не имею, что такое IEnumerator, это просто то, что я нашел, кто-то использует в Google для того же самого.
Чтобы вызвать public IEnumerator
, вы не можете просто вызвать его как метод, вы должны запустить сопрограмму
StartCoroutine(Shoot(roboBullet));
Дополнительные сведения о сопрограммах см. в статье это.
Можете ли вы показать трассировку стека, пожалуйста?