Зачем здесь нужен StartCorotine () - PullRequest
0 голосов
/ 18 февраля 2020
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class FirePistol : MonoBehaviour {

    public GameObject TheGun;
    public GameObject MuzzleFlash;
    public AudioSource GunFire;
    public bool IsFiring = false;

    void Update () {
        if (Input.GetButtonDown("Fire1"))
        {
            if (IsFiring == false)
            {
                StartCoroutine(FiringPistol());
            }
        }

    }

    IEnumerator FiringPistol ()
    {
        IsFiring = true;
        TheGun.GetComponent<Animation>().Play("PistolShot");
        MuzzleFlash.SetActive(true);
        MuzzleFlash.GetComponent<Animation>().Play("MuzzleAnim");
        GunFire.Play();
        yield return new WaitForSeconds(0.5f);
        IsFiring = false;
    }
}

Я пишу механик пистолета c И мне интересно, зачем нам нужно yield return new WaitForSeconds(0.5f);. Какая разница без этой команды. На самом деле не нужно писать этот код, потому что время короткое. Будет ли ошибка, как сцена Cra sh после удаления этого кода? Любая помощь с благодарностью!

1 Ответ

1 голос
/ 18 февраля 2020

В целом: каждый метод, возвращающий IEnumerator , имеет , который содержит хотя бы один оператор yield. В Unity у вас есть для использования StartCoroutine для запуска IEnumerator в качестве Coroutine .


В ваших данных c case: Таким образом, вы можете задержать ваш код на 0.5 секунд!

Это короткий, но 0.5 составляет около 30 кадров!

Кто-то использует, например, что-то вроде AutoClicker может зажать огненную клавишу в каждом кадре, чтобы он наносил значительно больше урона, чем кто-либо, играющий «нормально» (из-за физических ограничений вашей клавиатуры и пальца;))

Вы просто избегаете этого и ограничиваете стрельбу до максимум 2 раза в секунду.

В общем, как обычно, есть несколько способов достичь этого, и вы можете go без Coroutines полностью, но это делает кодирование намного более чистым и более легким для поддержки, чем выполнение всего за Update!


В качестве некоторых альтернативных примеров простых задержек, таких как здесь, вы также можете либо сделать простой таймер в Update

private float timer;

void Update () 
{
    if(timer > 0)
    {
        // reduce the timer by time passed since last frame
        timer -= Time.deltaTime;
    }
    else 
    {
        if(Input.GetButtonDown("Fire1"))
        {
            FiringPistol();
            timer = 0.5f;
        }
    }
}

void FiringPistol()
{
    TheGun.GetComponent<Animation>().Play("PistolShot");
    MuzzleFlash.SetActive(true);
    MuzzleFlash.GetComponent<Animation>().Play("MuzzleAnim");
    GunFire.Play();
}

, либо вы можете использовать Invoke с заданной задержкой.

bool canFire;

void Update () 
{
    if (Input.GetButtonDown("Fire1") && canFire)
    {
        FiringPistol();
    }
}

void FiringPistol()
{
    TheGun.GetComponent<Animation>().Play("PistolShot");
    MuzzleFlash.SetActive(true);
    MuzzleFlash.GetComponent<Animation>().Play("MuzzleAnim");
    GunFire.Play();

    Invoke(nameof(AfterCooldown), 0.5f);
}

void AfterCooldown()
{
    canFire = true;
}

В общем, кстати, вы должны хранить Animation ссылки, чтобы не использовать GetComponent снова и снова:

// if possible already reference these via the Inspector
[SerializeField] private Animation theGunAnimation;
[SerializeField] private Animation muzzleFlashAnimation;

private void Awake()
{
    // as fallback get them on runtime
    // since this is a fallback and in best case you already referenced these via the Inspector
    // we can save a bit of resources and use GetComponent
    // only in the case the fields are not already set
    // otherwise we can skip using GetComponent as we already have a reference
    if(!theGunAnimation) theGunAnimation = TheGun.GetComponent<Animation>();
    if(!muzzleFlashAnimation) muzzleFlashAnimation = MuzzleFlash.GetComponent<Animation>();
}

, а затем вы будете использовать их снова

theGunAnimation.Play("PistolShot");
MuzzleFlash.SetActive(true);
muzzleFlashAnimation.Play("MuzzleAnim");
GunFire.Play();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...