首页 > 解决方案 > C# Unity 项目,运行时冻结

问题描述

我从事 Unity2d 项目已经有一段时间了,最​​近我实现了一种方法,我的脚本中的“敌人”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延迟也不起作用。

作为一个业余爱好者,我显然做错了什么,但我不知道我做错了什么或在哪里做错了,非常感谢你的帮助。

标签: c#unity3dfreeze

解决方案


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

这样,当触发碰撞事件时,您可以将计数器重置为其初始值。之后,更新功能确保在一段时间后触发,并在整个拍摄时间结束后停止。

当然,您可以进一步改进此代码以处理极端情况(如果总时间到期并且间隔时间也同时到期,我们是否射出最后一颗子弹?等等)

希望这可以帮助。如果你欣赏我的努力,请给他们一个大拇指=)


推荐阅读