C#Unity项目,运行时冻结

时间:2018-10-26 10:03:53

标签: c# unity3d freeze

我已经从事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延迟也不起作用。

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

2 个答案:

答案 0 :(得分:0)

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

通过这种方式,在触发碰撞事件时,可以将计数器重置为其初始值。之后,更新功能将确保在一定时间间隔后启动,并在整个拍摄时间结束后停止。

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

希望这会有所帮助。 如果您感谢我的努力,请给他们一个赞=)

答案 1 :(得分:0)

这是您的循环:您在每帧上增加timeBetweenShot,但必须在一个帧中执行,而这段means的代码将执行while,直到您输入{{ 1}}语句,但您永远不会这样做,因为if仅在下一帧更改值

timeBetweenShot