Проблема с Time.deltatime
Есть такой код. При умножении _speed на Time.deltatime у лазеров разная скорость. Убираю - одинаковая скорость. Пересмотрела ролики по дельте - вроде корректно использую. В чем проблема здесь, подскажите, пожалуйста
void Update()
{
_timer += Time.deltaTime;
if (_timer > _shotDelay && Input.GetKeyDown(KeyCode.X))
{
_timer = 0;
Shoot();
}
}
private void Shoot()
{
GameObject NewLaserLeft = Instantiate(_laserPrefab, _gunPositionLeft);
GameObject NewLaserRight = Instantiate(_laserPrefab, _gunPositionRight);
NewLaserLeft.GetComponent<Rigidbody>().velocity = new Vector3(0, 0, _shotSpeed * Time.deltaTime);
NewLaserRight.GetComponent<Rigidbody>().velocity = new Vector3(0, 0, _shotSpeed * Time.deltaTime);
}
Ответы (1 шт):
Проблема не в deltaTime, а в 0...
if (_timer > _shotDelay)
_timer = 0;
А куда девается остаток? deltaTime при 60fps ровна ~1/60 (0,016 сек). При каждом обнулении ты теряешь до 0,016 секунд. Если выстрел раз в секунду, то через 10 секунд ты потеряешь до 0,16 секунд, что является рассинхроном, заметным невооруженным глазом, если это выполняется несколькими одновременно.
Input.GetKeyDown это момент нажатия. Вероятность, что именно в этот фрейм будет нажатие, ничтожная.
Как написать стрельбу
public class FooGun : MonoBehaviour
{
[SerializeField] private float _fireRate = 0.5f;
[Space]
[SerializeField] private Transform _shootPoint;
[SerializeField] private GameObject _bulletTemplate;
private IEnumerator _firing;
public bool IsFire { get; private set; }
public void StartFire ()
{
if (IsFire)
return;
IsFire = true; // меняем флаг стрельбы
// если корутина не запущена, запускаем
if (_firing == null)
{
_firing = Firing();
StartCoroutine(_firing);
}
}
public void StopFire ()
{
if (IsFire == false)
return;
// меняем флаг стрельбы, но не останавливаем корутину,
// поскольку стральба может начаться вновь до
// истечения времени между выстрелами
IsFire = false;
}
private IEnumerator Firing ()
{
float elapsed = _fireRate; // на старте стреляет сразу
while (true)
{
// время стрелять
// при очень высоком темпе стрельбы может быть несколько пуль за фрейм
while (elapsed >= _fireRate)
{
if (IsFire) // если флаг активен стреляем
{
Shoot();
elapsed -= _fireRate;
}
else // если флаг не активен, прерываем корутину
{
_firing = null;
yield break;
}
}
elapsed += Time.deltaTime;
yield return null;
}
}
private void Shoot ()
{
Instantiate(_bulletTemplate, _shootPoint.position, _shootPoint.rotation);
}
}
Стрелять может и игрок, и враг, и ловушка, и что угодно, а Input - это абсолютно другая ответственность, и в пределах одного класса их вместе быть не должно!