Страница 1 из 1

Счётчик

СообщениеДобавлено: 26 май 2017, 13:23
Rulz009
В нижеприведенном коде нужно выполнять некоторое арифметическое действие через каждые 10 секунд. Причем выполнение этого действия должно происходить в методе OnTriggerStay(). Каким образом можно реализовать возможность такой задержки на 10 секунд? Спасибо.
Синтаксис:
Используется csharp
...
public float health = 6f;
...
void OnTriggerStay(Collision col){
health--;
//здесь должна быть задержка на 10 секунд перед тем как снова выполнить команду health--
}
 

Re: Счётчик

СообщениеДобавлено: 26 май 2017, 14:05
Valentinus
выделите вычисления в отдельную функцию и запускайте ее через Invoke или InvokeRepeat

Re: Счётчик

СообщениеДобавлено: 26 май 2017, 14:18
waruiyume
Синтаксис:
  1. timer = 0; 
  2. TriggerStay() 
  3.     timer+=deltaTime; 
  4.     if(timer>10) 
  5.     { 
  6.         timer=0; 
  7.         DoSomething(); 
  8.     } 
  9. }  

Re: Счётчик

СообщениеДобавлено: 26 май 2017, 15:21
seaman
Так не пойдет?

Синтаксис:
Используется csharp
bool imInTrigger;
Coroutine counterCoroutine;

int counter;

void OnTriggerEnter(Collision col)
{
   imIntrigger = true;
   counter = 0;
   counter = StartCoroutine(Counter());
}
void OnTriggerExit(Collision col)
{
   imIntrigger = true;
   StopCoroutine(counterCoroutine);
}

IEnumerator Counter()
{
   counter++;
   yield return new WaitOfSecond(10f);
}

Re: Счётчик

СообщениеДобавлено: 26 май 2017, 15:33
Valentinus
seaman писал(а):Так не пойдет?



во-первых в OnTriggerExit вы наверное хотели написать imIntrigger = false; ?
во-вторых, в данном коде корутина сразу инкрементирует counter, потом подождет 10 сек и завершит работу.

если вы хотите чтоб она крутилась - сделайте внутри корутины
while (imIntrigger )
{
counter++;
yield return new WaitOfSecond(10f);
}
(и тогда StopCoroutine не надо делать)


вообще, для вашего случая больше подходит Invoke и InvokeRepeat
корутины предназначены для разбиения одного длительного процесса на несколько этапов (например когда создается тысяча gameobject, или вычисляется сложный алгоритм).
а если надо периодически выполнять какую-то процедуру, не занимающую процессор надолго, то для этого Invoke и InvokeRepeat

Re: Счётчик

СообщениеДобавлено: 26 май 2017, 16:26
seaman
Ну да, торопился. Но принцип понятен.
А вот насчет InvokeRepeating - где Вы такое вычитали? Чем она таким лучше корутины? Тем что ей нужно название метода передавать строкой? Не каждая тулза для рефакторинга найдет такой "метод". Т.е. переименовать его уже не так просто. Ну и еще что-то аналогичное может возникнуть в процессе.
Вообще имхо - использовать строки-имена методов, класов и т.п - плохо. Аналогично например GetComponent(string type); - плохо.

Re: Счётчик

СообщениеДобавлено: 26 май 2017, 16:42
Valentinus
seaman писал(а):Ну да, торопился. Но принцип понятен.
А вот насчет InvokeRepeating - где Вы такое вычитали? Чем она таким лучше корутины? Тем что ей нужно название метода передавать строкой? Не каждая тулза для рефакторинга найдет такой "метод". Т.е. переименовать его уже не так просто. Ну и еще что-то аналогичное может возникнуть в процессе.
Вообще имхо - использовать строки-имена методов, класов и т.п - плохо. Аналогично например GetComponent(string type); - плохо.


не лучше и не хуже. просто для каждой вещи свое назначение, для которого она подходит оптимально. обухом топора тоже можно забивать гвозди, но лучше молотком.
с инвоками код был бы как минимум короче, понятней и меньше шансов допустить ошибку.
сравните два куска
Синтаксис:
Используется csharp
bool imInTrigger;
Coroutine counterCoroutine;

int counter;

void OnTriggerEnter(Collision col)
{
   imIntrigger = true;
   counter = 0;
   counter = StartCoroutine(Counter());
}
void OnTriggerExit(Collision col)
{
   imIntrigger = false; // или   StopCoroutine(counterCoroutine);
}

IEnumerator Counter()
{
while(imIntrigger)
{
   counter++;
   yield return new WaitOfSecond(10f);
}
}
 

и
Синтаксис:
Используется csharp
int counter;

void OnTriggerEnter(Collision col)
{
   counter = 0;
   InvokeRepeat("Counter", 10,10);
}
void OnTriggerExit(Collision col)
{
   CancelInvoke("Counter");
}

void  Counter()
{
   counter++;
}
 

какой понятнее и быстрее написать?

а в Юнити без строк-имен вы не обойдетесь никак. переменные в аниматор-контроллере и анимациях, названия event`ов, которые прописываются в настройках анимаций, и т.п.
се ля ви.
что касается именно рефакторинга- я думаю топикстартер еще не скоро озадачится этим. :)

Re: Счётчик

СообщениеДобавлено: 27 май 2017, 19:38
Cr0c
Valentinus писал(а):а в Юнити без строк-имен вы не обойдетесь никак.

В шейдерах можно вместо стрингов хеши использовать. В аниматоре такого нет?

Re: Счётчик

СообщениеДобавлено: 27 май 2017, 20:16
Valentinus
Cr0c писал(а):
В шейдерах можно вместо стрингов хеши использовать. В аниматоре такого нет?
не знаю ответа. посмотрите в справке.

Re: Счётчик

СообщениеДобавлено: 27 май 2017, 21:23
seaman
В аниматоре такого нет?

Есть. Но хеш же сначала нужно из строки получать все равно.
Но это все же не то что я имел в виду.
Строковые переменные - нормальное явление. Ключи строки в словаре похуже, но тоже нормально. А вот вместо типа использовать его имя или вместо метода использовать имя метода - гораздо хуже.
какой понятнее и быстрее написать?

Первый понятнее. Второй быстрее.
Да, в Юнити много вещей не приспособлены для того же рефакторинга. События могут пропасть, функции в onClick, кто-то может взять и переименовать параметр в Аниматоре. Даже просто компоненты, накинутые на объект пропадают. Но зачем же себе еще ухудшать жизнь используя строковые названия методов и типов.
Вот, например обфускация. Обфускатор может стандартные методы Юнити опознать и не обфусцировать. Но откуда он узнает, что Вы имя этого метода строкой где то написали, или в Event-ах использовали? Придется обфускатору явно это указать

В-общем каждый выбирает сам, но я стараюсь нигде не использовать строковые имена методов и типов.

Re: Счётчик

СообщениеДобавлено: 27 май 2017, 22:27
Valentinus
seaman писал(а):
Первый понятнее.

:))