Проект C # Unity, зависание при запуске - PullRequest
0 голосов
/ 26 октября 2018

Я уже некоторое время работаю над проектом 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 голосов
/ 26 октября 2018

Вот ваш цикл: вы увеличиваете timeBetweenShot в каждом кадре, но ваше время должно выполняться в одном кадре, этот 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;
                }
            }
0 голосов
/ 26 октября 2018
while(shot == true)

это заморозит редактор, если тело никогда не останется

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

если это не будет выполнено в первой итерации, то не будет во второй, потому что вы никогда не измените значение "timeBetweenShot" в этом цикле

Важно понимать, что ваша функция обновления должна завершаться, чтобы игровой кадр продолжался со следующим обновлением игрового объекта и т. Д., Пока не будет достигнут конец кадра, прежде чем будет вызвано следующее обновление для этого игрового объекта в следующий игровой кадр, так что

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

никогда не выполняется, пока ваш цикл while становится мошенническим

EDIT:

попробуйте что-то вроде:

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

таким образом, когда происходит событие столкновения, вы сбрасываете счетчики до их начальных значений. После этого функция обновления срабатывает через определенные промежутки времени и останавливается после окончания общего времени съемки.

Конечно, вы можете еще больше улучшить этот код для обработки крайних случаев (если общее время истекает и интервалы времени также истекают в одно и то же время, мы стреляем в последнюю пулю или нет? И т.д.)

надеюсь, это поможет. Если вы цените мои усилия, пожалуйста, поднимите им палец вверх =)

...