Среда, 24 Апреля 2024, 19:28

Приветствую Вас Гость

[ Новые сообщения · Игроделы · Правила · Поиск ]
  • Страница 1 из 1
  • 1
Форум игроделов » Движки для разработки игр и сложные системы разработки » Unity » Таймер с отложенным действием (Полезности для Unity3d)
Таймер с отложенным действием
pixeyeДата: Вторник, 10 Октября 2017, 20:36 | Сообщение # 1
Red Winter Software
Сейчас нет на сайте
Очень простой таймер с действием. Нужен Unirx для работы, он бесплатен.





Код
/*===============================================================
Product:    Unity3dTips&Tricks
Developer:  Dimitry Pixeye - pixeye@hbrew.store
Company:    Homebrew - http://hbrew.store
Date:       08/10/2017 21:54
================================================================*/

using System;
using UniRx;
using UnityEngine;

namespace Homebrew{

public class Timer : IDisposable
{
    public float timer;
    private Action actionComplete;
    private float finishTime;
    private bool isRunning;
    private IDisposable observerDisposable;
    
    public Timer(float finishTime, Action actionComplete)
    {
        this.finishTime = finishTime;
        this.actionComplete = actionComplete;
        observerDisposable =  Observable.EveryGameObjectUpdate().
            Where(x => isRunning).Subscribe(_=>Update());
        
    }
    public void Restart()
    {
        isRunning =true;
        timer = 0.0f;
    }
    public void ShutDown()
    {
        isRunning = false;
    }

    private void Update()
    {
        timer += Time.deltaTime;
        if (timer < finishTime) return;
        
            timer = 0.0f;
            isRunning = false;
            actionComplete();
    }
    public void Dispose()
    {
        observerDisposable.Dispose();
        observerDisposable = null;
        actionComplete = null;
    }
}
}


ACTORS - мой фреймворк на Unity
Until We Die - игра над которой работаю



Сообщение отредактировал pixeye - Вторник, 10 Октября 2017, 20:50
seamanДата: Вторник, 10 Октября 2017, 23:58 | Сообщение # 2
старожил
Сейчас нет на сайте
Недостатки
1. Нужен Unirx, хоть он и бесплатен.
2. Непонятно кто вызывает Update в Timer, ведь Timer не MonoBehaviour. Возможно это делает Unirx, хотя по описанию этого плагина такого не скажешь.
3. Если Это все же MonoBehaviour, то при большом количестве таймеров получим много Update, что плохо.
Достоинства - прост.

Приведу свой таймер.
Сам таймер.
Код
    public class Timer
    {
  private float __timer;
  private bool __start;
  private int __currentCount;

  private readonly float __time;
  private readonly Action __actTick;
  private readonly Action __actEnd;
  private int __count;
  private readonly bool __delete;

  public Timer(float delay, int repeatCount, Action actionTick, Action actionEnd = null, bool autostart = false, bool autodelete = false)
  {
   __actTick = actionTick;
   __actEnd = actionEnd;
   __time = delay;
   __count = repeatCount;
   __timer = 0;
   __delete = autodelete;
   if(autostart) Start();
  }

  public void Start()
  {
   __currentCount = __count;
   __start = true;
  }

  public void Stop() { __start = false; }

  public bool Tick()
  {
   if(!__start) return false;
   __timer += Time.deltaTime;
   if (__timer < __time) return false;
   if(__actTick != null) __actTick.Invoke();
   __currentCount--;
   if(__currentCount != 0) return false;
   if (__actEnd != null) __actEnd.Invoke();
   __start = false;
   return __delete;
  }
    }

Таймер-менеджер
Код
    public class TimerManager : MonoBehaviour
    {
  private static readonly List<Timer> __timers = new List<Timer>();

  public void Update()
  {
   foreach (var timer in __timers)
   {
    if (timer.Tick()) __timers.Remove(timer);
   }
  }

  public static Timer AddTimer(float delay, int repeatCount, Action actionTick, bool autostart = false, bool autodelete = false, Action actionEnd = null)
  {
   var timer = new Timer(delay, repeatCount, actionTick, actionEnd, autostart, autodelete);
   __timers.Add(timer);
   return timer;
  }

  public static void StartTimer(Timer timer)
  {
   if(!__timers.Contains(timer)) __timers.Add(timer);
   timer.Start();
  }

  public static void StopTimer(Timer timer, bool delete = false)
  {
   if (!__timers.Contains(timer)) return;
   timer.Stop();
   if (delete) __timers.Remove(timer);
  }
    }

1. Ничего дополнительного не нужно.
2. Update один - в менеджере.
Создаем таймер через TimerManager.AddTimer
Можно задать количество срабатываний таймера.
Можно вызывать действие каждое срабатывание и дополнительно после последнего срабатывания
Можно указать автостарт при создании, можно сначала создать а запустить потом.
Можно указать автоудаление таймера после последнего срабатывания
Можно приостановить таймер.
Можно при приостановке таймера его автоматически удалить.
pixeyeДата: Среда, 11 Октября 2017, 00:18 | Сообщение # 3
Red Winter Software
Сейчас нет на сайте
Эх.
Цитата seaman ()

Недостатки
1. Нужен Unirx, хоть он и бесплатен.
2. Непонятно кто вызывает Update в Timer, ведь Timer не MonoBehaviour. Возможно это делает Unirx, хотя по описанию этого плагина такого не скажешь.
3. Если Это все же MonoBehaviour, то при большом количестве таймеров получим много Update, что плохо.


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

2.
Код
   observerDisposable =  Observable.EveryGameObjectUpdate().
            Where(x => isRunning).Subscribe(_=>Update());


3. Кажется очевидным, что здесь нет Monobehaviour и апдейта монобехейвера : ) Использовать много апдейтов монобехейверов действительно плохо, ровно как и городить дополнительные менеджеры для апдейтов таймеров, но это дело вкуса конечно : ) реально на производительность это мало повлияет

Цитата
Можно задать количество срабатываний таймера.

Можно, впрочем у меня это делается обычным рестартом самого таймера из метода. Это уже дополнительные плюши

Цитата

Можно приостановить таймер.

У меня он тоже приостанавливается.

Опять таки:) все тут.
Код
   observerDisposable =  Observable.EveryGameObjectUpdate().
            Where(x => isRunning).Subscribe(_=>Update());


ACTORS - мой фреймворк на Unity
Until We Die - игра над которой работаю



Сообщение отредактировал pixeye - Среда, 11 Октября 2017, 00:30
Форум игроделов » Движки для разработки игр и сложные системы разработки » Unity » Таймер с отложенным действием (Полезности для Unity3d)
  • Страница 1 из 1
  • 1
Поиск:

Все права сохранены. GcUp.ru © 2008-2024 Рейтинг