Задержка между выстрелами из скорострельности[Решено]

Программирование на Юнити.

Задержка между выстрелами из скорострельности[Решено]

Сообщение ВерховныйНоуНейм 12 авг 2018, 14:01

Я что-то туплю, не могу придумать формулу.
У меня есть данные из вики о, например, 1100 выстрелах в мин.
Мне из них нужно получить задержку.
По формулам из инета получается, что чем больше выстрелов в мин, тем больше задержка, то есть ниже скорострельность.
Скрипт:
Синтаксис:
Используется csharp
if (Time.time > (ShotLostTime + задержка)) {
//всячина
ShotLostTime = Time.time;
}
Последний раз редактировалось ВерховныйНоуНейм 12 авг 2018, 20:29, всего редактировалось 1 раз.
Изображение
Аватара пользователя
ВерховныйНоуНейм
UNIт
 
Сообщения: 68
Зарегистрирован: 25 фев 2017, 19:56

Re: Задержка между выстрелами из скорострельности

Сообщение getAlex 12 авг 2018, 14:16

Игры не реализуют реальную скорострельность. Визуально они показывают много выстрелов, но реально там всего пара выстрелов. К примеру, огнемёт может наносить урон где-то раз в секунду, хотя визуально огонь идёт непрерывно. Визуально там много гильз вылетает, много партиклов или прочих эффектов, но реально там не более 5 выстрелов в секунду.

Допустим, есть оружие, в описании которого написано "300 выстрелов в минуту по 5 урона" и другое оружие: "600 выстрелов в минуту по 5 урона". Оба они будут наносить урон раз в 0.2 секунды, только первое по 5 урона, в второе по 10 урона. Конечно, визуально всё будет выглядеть иначе и второе оружие вроде бы как будет стрелять чаще и на цели будут вылетать множество цифр по 5 урона. Однако, по факту, второе оружие будет стрелять с той же скорострельностью, но наносить 10 урона, а при попадании выкидывать две надписи о получении 5 урона с небольшой задержкой друг между другом.

Этому есть две причины: 1) производительность 2) мультиплеер, пинг

Игры это искусство иллюзии и обмана. Если делать по реальным формулам и так как в жизни, твоё приложение не запуститься ни на одном компьютере.
getAlex
Адепт
 
Сообщения: 1775
Зарегистрирован: 10 авг 2013, 18:30

Re: Задержка между выстрелами из скорострельности

Сообщение Rando_OM 12 авг 2018, 14:26

Я так понял вам надо поставить скорострельность например 10 и он стрелял 10 пуль в секунду?
У меня вот так сделано, не знаю точно ли все выходит ыы
Синтаксис:
Используется csharp
public float fireRate = 10;
private float _timer;

void Update()
{
 _timer += Time.deltaTime;
 if (_timer < 1/ fireRate) return;
 DoStuff();
  _timer = 0;
}
 
Мои игры доступны онлайн на Kongregate.com! ---->>
Rando_OM
UNIт
 
Сообщения: 94
Зарегистрирован: 22 дек 2015, 03:44
Откуда: Россия
Skype: gorodok402
  • Сайт

Re: Задержка между выстрелами из скорострельности

Сообщение ВерховныйНоуНейм 12 авг 2018, 19:35

Спасибо за информацию!
У меня игра в 2D и пули там - это растянутый и покрашенный спрайт, который исчезает после 2сек полета.
Так, что мне все-же формула не помешает.

Причем в игре многое завязано на оружии и хотелось бы схожести с оригиналом, а не подбора в ручную "на глаз".
Изображение
Аватара пользователя
ВерховныйНоуНейм
UNIт
 
Сообщения: 68
Зарегистрирован: 25 фев 2017, 19:56

Re: Задержка между выстрелами из скорострельности

Сообщение ВерховныйНоуНейм 12 авг 2018, 20:28

Ах да, я слепой. Спасибо.
if (_timer < 1/ fireRate)

у меня:
if (Time.time > (ShotLostTime + (1 / (Weapon.GetComponent<WeaponStatsMenuTest> ().StatsNum [5] / 60)))) {

Протестил со скорострельностью 600 (АК47), все совпадает.
При делении выводит 0.1
Изображение
Аватара пользователя
ВерховныйНоуНейм
UNIт
 
Сообщения: 68
Зарегистрирован: 25 фев 2017, 19:56

Re: Задержка между выстрелами из скорострельности

Сообщение getAlex 12 авг 2018, 21:27

Rando_OM писал(а):Я так понял вам надо поставить скорострельность например 10 и он стрелял 10 пуль в секунду?
У меня вот так сделано, не знаю точно ли все выходит ыы
Синтаксис:
Используется csharp
public float fireRate = 10;
private float _timer;

void Update()
{
 _timer += Time.deltaTime;
 if (_timer < 1/ fireRate) return;
 DoStuff();
  _timer = 0;
}
 


А теперь посмотри как работает твой скрипт, пока твой персонаж не стреляет:

1) каждый фрейм инкременируется значение _timer += Time.deltaTime;
не зависимо от того: стреляешь ты или нет
2) каждый фрейм производится математическая операция 1/ fireRate, а деление жрёт куда больше умножения. Могли бы сразу написать fireRate = 0.1f ( _timer < fireRate)
3) каждый фрейм идёт сравнение if (_timer < 1/ fireRate)
4) скрипт, в котором есть Update() дополнительно прозванивается и дополнительно нагружает машину.

Так что, в целом, подобный пример подойдёт только для первого обучающего занятия в школе. Не удивляйтесь потом что ваше приложение тормозит и нужно переписывать 100% кода.
getAlex
Адепт
 
Сообщения: 1775
Зарегистрирован: 10 авг 2013, 18:30

Re: Задержка между выстрелами из скорострельности

Сообщение Rando_OM 13 авг 2018, 05:58

getAlex писал(а):
А теперь посмотри как работает твой скрипт, пока твой персонаж не стреляет:

1) каждый фрейм инкременируется значение _timer += Time.deltaTime;
не зависимо от того: стреляешь ты или нет
2) каждый фрейм производится математическая операция 1/ fireRate, а деление жрёт куда больше умножения. Могли бы сразу написать fireRate = 0.1f ( _timer < fireRate)
3) каждый фрейм идёт сравнение if (_timer < 1/ fireRate)
4) скрипт, в котором есть Update() дополнительно прозванивается и дополнительно нагружает машину.

Так что, в целом, подобный пример подойдёт только для первого обучающего занятия в школе. Не удивляйтесь потом что ваше приложение тормозит и нужно переписывать 100% кода.


Главное, что работает, а оптимизация - это уже другое дело. Я написал так, чтобы было понятнее. У себя я использую максимально оптимизированную версию почти без всех перечисленных вами грехов.
Какой должен быть калькулятор, чтобы не потянуть if в update?
Мои игры доступны онлайн на Kongregate.com! ---->>
Rando_OM
UNIт
 
Сообщения: 94
Зарегистрирован: 22 дек 2015, 03:44
Откуда: Россия
Skype: gorodok402
  • Сайт

Re: Задержка между выстрелами из скорострельности

Сообщение ВерховныйНоуНейм 13 авг 2018, 13:27

getAlex писал(а):
Rando_OM писал(а):Я так понял вам надо поставить скорострельность например 10 и он стрелял 10 пуль в секунду?
У меня вот так сделано, не знаю точно ли все выходит ыы
Синтаксис:
Используется csharp
public float fireRate = 10;
private float _timer;

void Update()
{
 _timer += Time.deltaTime;
 if (_timer < 1/ fireRate) return;
 DoStuff();
  _timer = 0;
}
 


А теперь посмотри как работает твой скрипт, пока твой персонаж не стреляет:

1) каждый фрейм инкременируется значение _timer += Time.deltaTime;
не зависимо от того: стреляешь ты или нет
2) каждый фрейм производится математическая операция 1/ fireRate, а деление жрёт куда больше умножения. Могли бы сразу написать fireRate = 0.1f ( _timer < fireRate)
3) каждый фрейм идёт сравнение if (_timer < 1/ fireRate)
4) скрипт, в котором есть Update() дополнительно прозванивается и дополнительно нагружает машину.

Так что, в целом, подобный пример подойдёт только для первого обучающего занятия в школе. Не удивляйтесь потом что ваше приложение тормозит и нужно переписывать 100% кода.

Спасибо за совет, засунул деление в Start(), что бы не переписывать все значения для оружий.
Изображение
Аватара пользователя
ВерховныйНоуНейм
UNIт
 
Сообщения: 68
Зарегистрирован: 25 фев 2017, 19:56

Re: Задержка между выстрелами из скорострельности

Сообщение getAlex 13 авг 2018, 23:13

ВерховныйНоуНейм писал(а):Спасибо за совет, засунул деление в Start(), что бы не переписывать все значения для оружий.

Да не в делении проблема, а в наличии самого апдейта и самого способа вызова метода. Используй хотя бы https://docs.unity3d.com/ScriptReferenc ... ating.html

Что-то вроде
Синтаксис:
Используется csharp

void BeginShoot()
{
if(current_weapon.ammo>0 && !IsInvoking("Shoot"))
InvokeRepeating("Shoot", current_weapon.attack_speed, current_weapon.attack_speed);
}

void EndShoot()
{
CancelInvoke("Shoot");
}

void Shoot()
{

if(current_weapon.ammo<=0)
{
CancelInvoke("Shoot");
return;
}

...
}

 


Ну и дальше можешь подписывать на System.Action или делать как-то иначе. Т.е. происходит событие: игрок нажимает на кнопку выстрела и вызывается 1 раз BeginShoot(), отжимает кнопку или заканчиваются патроны - вызывается EndShoot(). Суть в том, что любые игровые события должны выполнятся в момент вызова, а не ожидать момента вызова и проверять постоянно не вызвал ли их кто.

В идеальном варианте у тебя в проекте вообще не будет Update(), кроме как для Input, но и тот не обязателен, если у тебя управление чем кнопки интерфейса и проект для смартфонов.

Любая структура с логикой
Синтаксис:
Используется csharp
Update()
{
if(...) DoSomething()
}


В 99.999% случаях ошибочна и её можно заменить.
Допускаются только Input и Ray.
Для анимаций и похожего лучше использовать короутину с колбеком.

Синтаксис:
Используется csharp
void Play()
{
StartCoroutine(PlayInternal(..., delegate {Example(); } ) );
}

void Example()
{

}

IEnumerator PlayInternal(..., System.Action deleg)
{
...
yield...

if (deleg != null)
  {
   deleg();
  }
}
 
getAlex
Адепт
 
Сообщения: 1775
Зарегистрирован: 10 авг 2013, 18:30

Re: Задержка между выстрелами из скорострельности[Решено]

Сообщение waruiyume 14 авг 2018, 00:31

а деление жрёт куда больше умножения

ЧЯДНТ?
Синтаксис:
Используется csharp
using System.Diagnostics;
using UnityEngine;
using Debug = UnityEngine.Debug;

public class NewBehaviourScript : MonoBehaviour {

    Stopwatch stopwatchP = new Stopwatch();

    public float res;

    private const float FirstPar = 1.0001f;

    void Start()
    {
        res = FirstPar / 2f;
        res = FirstPar * 0.5f;

        long divTime;
        long mulTime;

        for (int j = 0; j < 100; j++)
        {
            stopwatchP.Reset();
            stopwatchP.Start();
            for (int i = 0; i < 10000; i++)
            {
                res = FirstPar / 2f;
            }
            stopwatchP.Stop();
            divTime = stopwatchP.ElapsedTicks;

            stopwatchP.Reset();
            stopwatchP.Start();
            for (int i = 0; i < 10000; i++)
            {
                res = FirstPar * 0.5f;
            }
            stopwatchP.Stop();
            mulTime = stopwatchP.ElapsedTicks;

            Debug.LogFormat("Mul: {0}, Div:{1}", mulTime, divTime);
        }
    }
}
 


Mul: 568, Div:569
Mul: 567, Div:567
Mul: 570, Div:567
Mul: 567, Div:567
Mul: 567, Div:570
Mul: 567, Div:629
Mul: 567, Div:573
Mul: 567, Div:567
Mul: 613, Div:619
Mul: 567, Div:562
Mul: 567, Div:569
Mul: 567, Div:567
Mul: 570, Div:577
Mul: 577, Div:570
Mul: 567, Div:570
Mul: 598, Div:647
Mul: 567, Div:567
Mul: 567, Div:567
Mul: 567, Div:567
Mul: 567, Div:570
Mul: 567, Div:570
Аватара пользователя
waruiyume
Адепт
 
Сообщения: 6143
Зарегистрирован: 30 окт 2010, 05:03
Откуда: Ростов на Дону

Re: Задержка между выстрелами из скорострельности[Решено]

Сообщение lawsonilka 14 авг 2018, 01:00

а деление жрёт куда больше умножения

а вообще лучше сразу печатать на ассемблер
lawsonilka
UNIверсал
 
Сообщения: 390
Зарегистрирован: 21 окт 2014, 14:48

Re: Задержка между выстрелами из скорострельности[Решено]

Сообщение getAlex 14 авг 2018, 13:04

waruiyume писал(а):
а деление жрёт куда больше умножения

ЧЯДНТ?

Наверное из-за того, что там число, а не переменная, и компилятор сам подменяет перед билдом. Или может я не прав.
getAlex
Адепт
 
Сообщения: 1775
Зарегистрирован: 10 авг 2013, 18:30

Re: Задержка между выстрелами из скорострельности[Решено]

Сообщение waruiyume 14 авг 2018, 14:42

Да, это был компилятор, да, разница 20%. Итоговое сэкономленное время: 1 миллисекунда на 100k операций.
Аватара пользователя
waruiyume
Адепт
 
Сообщения: 6143
Зарегистрирован: 30 окт 2010, 05:03
Откуда: Ростов на Дону

Re: Задержка между выстрелами из скорострельности[Решено]

Сообщение getAlex 14 авг 2018, 16:05

waruiyume писал(а):Да, это был компилятор, да, разница 20%. Итоговое сэкономленное время: 1 миллисекунда на 100k операций.

...это...миллисекунда секунду бережет. :D Ладно, ладно, твоя взяла. Деление/умножение не стоит внимания.
getAlex
Адепт
 
Сообщения: 1775
Зарегистрирован: 10 авг 2013, 18:30

Re: Задержка между выстрелами из скорострельности[Решено]

Сообщение ВерховныйНоуНейм 18 авг 2018, 12:49

@-)
Изображение
Аватара пользователя
ВерховныйНоуНейм
UNIт
 
Сообщения: 68
Зарегистрирован: 25 фев 2017, 19:56


Вернуться в Скрипты

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 9