C# Unity 项目,运行 时冻结

C# Unity project, Freezing when ran

我从事 Unity2d 项目已经有一段时间了,我最近实现了一种方法,我的 "Enemy" 位于 GreyGuardController 脚本中,它会朝它所在的方向发射子弹将面对,使用动画师和

otherAnimator = otherObject.GetComponent<Animator>();

为此。

每次我现在 运行 我的代码,我的游戏都会冻结但不会崩溃(我认为它陷入了循环但我的程序中没有真正的循环)。在有人开始指责它之前,这不是我对子弹的实例化,因为它的循环冻结了,因为我已经评论了这一点并一遍又一遍地改变了事情。

public class HurtPlayer : MonoBehaviour {

public float timeToShoot;
private float timeToShootCounter;
private bool shot;
private Vector3 moveDirection;
public float timeBetweenShot;
public float timeBetweenShotCounter;

public Transform firePoint;
public GameObject Bullet;

// Use this for initialization
void Start()
{
    shot = false;
    timeToShootCounter = timeToShoot;
    timeBetweenShotCounter = timeBetweenShot;
}

IEnumerator ExecuteAfterTime(float time)
{
    yield return new WaitForSeconds(time);
}

// Update is called once per frame
void Update () {
    if (shot == true)
    {
        timeBetweenShot -= Time.deltaTime;
        timeToShoot -= Time.deltaTime;
        if (timeBetweenShot <= 0f)
        {
            shot = false;
            timeToShoot = timeToShootCounter;
            timeBetweenShot = timeBetweenShotCounter;
        }
    }       
}

void OnTriggerStay2D(Collider2D other)
{
    if (other.gameObject.tag == "player")
    {
        if(shot == false)
        {
            if (timeToShoot >= 0f)
            {
                shot = true;
                while(shot == true)
                {
                    Instantiate(Bullet, firePoint.position, firePoint.rotation);
                    if (timeBetweenShot <= 0f)
                    {
                        shot = false;
                        timeToShoot = timeToShootCounter;
                        timeBetweenShot = timeBetweenShotCounter;
                    }
                }

            }
        }
    }
}

这是我附加到我的守卫的代码,它实例化了一颗子弹,并尝试使用变量 "TimeToShoot" 作为敌人剩余射击时间的计数器, "TimeBetweenShoot" 作为敌人两次射击之间的时间计数器。

这不起作用,Enumerator 延迟也不起作用。

作为业余爱好者,我显然做错了一些事情,但我不知道自己做错了什么或哪里做错了,非常感谢您的帮助。

while(shot == true)

如果正文从未离开,这将冻结编辑器

if (timeBetweenShot <= 0f)
{
    shot = false;

如果在第一次迭代中未执行此操作,则不会在第二次迭代中执行,因为您永远不会在该循环中更改 "timeBetweenShot" 的值

重要的是要了解您的更新函数需要终止游戏帧才能继续下一个游戏对象的更新等,直到到达帧末尾,然后在此游戏对象上调用下一个更新在下一个游戏帧中,所以

void Update () {
if (shot == true)
{
    timeBetweenShot -= Time.deltaTime;

当你的 while 循环变得流氓时永远不会执行

编辑:

试试这样的东西:

// Update is called once per frame
void Update()
{
    if (timeToShoot >= 0f) // if we are shooting at all
    {
        timeToShootCounter -= Time.deltaTime; // make sure we'll stop shooting after the given amount of time (decrease countdown until negative
        timeBetweenShotCounter -= Time.deltaTime; // decrease countdown until next shot (after some intervall)

        if (timeBetweenShotCounter <= 0f) // if intervall since last shot expired
        {
            Instantiate(Bullet, firePoint.position, firePoint.rotation); // shoot
            timeBetweenShotCounter += timeBetweenShot; // add the time to wait for the next shot to the intervall (so that we don't shoot anymore in the following frames, until this time expired again (by becoming negative))
        }
    }
}

void OnTriggerStay2D(Collider2D other)
{
    if (other.gameObject.tag == "player")
    {
        timeToShootCounter = -1f; // initialise as expired (start shooting immediately)
        timeBetweenShotCounter = timeBetweenShot; // shoot in intervalls for this amount of time
    }
}

这样,当碰撞事件被触发时,您可以将计数器重置为初始值。之后update函数确保在一定时间间隔后触发,并在整个射击时间结束后停止。

当然你可以进一步改进这段代码来处理边缘情况(如果总时间到期并且间隔时间也同时到期,我们是否发射最后一颗子弹?等等)

希望这对您有所帮助。 如果您欣赏我的努力,请为他们竖起大拇指=)

这是你的循环:你在每一帧增加 timeBetweenShot 但你的 while 必须在一帧中执行,这个 means 你的代码执行这个 while 直到你进入if 声明,但你永远不会这样做,因为 timeBetweenShot 只会在下一帧

中更改值
            while(shot == true)// here is your loop budy
            {
// shot = false; // try this row here you will problably stop having the trouble
                Instantiate(Bullet, firePoint.position, firePoint.rotation);
                if (timeBetweenShot <= 0f)//
                {
                    shot = false;
                    timeToShoot = timeToShootCounter;
                    timeBetweenShot = timeBetweenShotCounter;
                }
            }