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
请原谅乱七八糟的代码,因为时间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