В целом: каждый метод, возвращающий 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();