Я пытаюсь реализовать пользовательские события в моей системе анимации, но, похоже, не могу понять, как обрабатывать события для зацикливания анимации надежным и эффективным способом.
Это включает 3 основных типа:
struct Event { float normalizedTime; System.Action callback; }
EventSequence
- это, в основном, List<Event>
, который автоматически сортируется по времени. EventManager
имеет EventSequence
и Update
метод, который должен использовать время анимации из предыдущего кадра и текущего кадра, чтобы определить, какие события вызывать.
Обработка нецикличных анимаций относительно проста. Если previousTime <= eventTime < currentTime
, то вызовите и перейдите к следующему событию. Инвертируйте все, если анимация воспроизводится задом наперед. Для эффективности запомните, к какому событию вы подходите, и возвращайтесь раньше, если вы еще не достигли следующего события (поскольку последовательность уже отсортирована), поэтому в большинстве кадров нужно только проверять одно событие.
Но обработка циклической анимации намного сложнее по нескольким причинам:
- Очевидно, что весь смысл в том, что события будут запускаться в каждом цикле. Таким образом, событие в 0,5 сработает, когда время пройдет 0,5 и 1,5 и 2,5 и так далее. Это означает, что события вне диапазона от 0 до 1 недопустимы, поскольку они не будут правильно сортироваться в последовательности (легко проверить).
- События всегда должны запускаться по порядку. Поэтому, если у вас есть два события в
0.1
и 0.9
, и вы переходите от previousTime = 0.5
до currentTime = 1.5
в одном кадре, оно должно вызвать второе событие (0,9) перед первым (0,1). - Кроме того, на высокой скорости (или с короткой анимацией) может потребоваться запуск событий более одного раза за обновление, по-прежнему в порядке. Таким образом, если время в приведенном выше примере изменилось с
0.5
до 2.5
, ему нужно будет запустить 2-е событие в 0,9, 1-е в 1,1, 2-е в 1,9 и 1-е в 2,1. - Это такжеНужно учитывать возможность перехода в другое время без запуска событий или изменения скорости воспроизведения между положительным и отрицательным, но они должны быть довольно тривиальными, когда у меня работает ядро.
Индивидуально проблемыне слишком сложны, но, когда я собрал их все вместе, моя система становится все более запутанной и запутанной, поэтому я надеюсь, что кто-то может помочь мне найти эффективный способ приблизиться к нему (или указать мне на реализацию с открытым исходным кодом чего-то подобного).