Перейти к содержанию

PlayerAnimator — TODO

1. Вынести определение скорости в отдельный компонент (MotionSource)

Сейчас скорость считается дважды независимо — в JumpController и в MinimalLocomotion (оба берут (pos − prevPos)/dt в локальных осях). Надо вынести это в один маленький компонент:

  • отдаёт HorizontalSpeed, LocalVelocity (x=стрейф, z=вперёд), может и VerticalVelocity;
  • оба скрипта читают из него, а не считают сами;
  • главная цель — единственная точка подмены под сеть: на owner'е источник = дельта трансформа (или ECM2 Character.GetVelocity()), на реплике = реплицированное значение. Аниматор при этом не меняется вообще.

Плюсы: убирает дублирование; делает сетевой фикс (см. ниже) drop-in.

2. Сетевая репликация (главная нерешённая проблема)

Сейчас всё работает от дельты Transform, синканного через NetworkTransform. Локально заметно лучше, чем на реплике. Причина: реплика анимируется от ИНТЕРПОЛИРОВАННОГО трансформа, а дифференцирование интерполяции даёт шумную/заниженную/лагающую скорость (см. README — «animate from intent, not motion»).

Конкретные симптомы на реплике: - иногда мисы на стрейфах (направление/скорость касания читается не так, как локально); - нельзя поставить узкие интервалы приземления run/walk — из-за шума дельты синка скорость гуляет (спайки 5–7, провалы до 3–3.1), приходится держать интервалы широкими; - ранний выход из LAND-RUN при продолжении бега: скорость временно проваливается ниже _runLandMin (должна быть ~4, а из-за синка падает <3) → moving-ленд обрывается, хотя игрок продолжает бежать. Локально этого нет.

План (после MotionSource)

  • Оставить перемещение на NetworkTransform (позиция как есть).
  • Реплицировать скорость owner'а (квантованный float/локальный вектор, ~15–20 Гц) и кормить её в MotionSource на реплике. Скорость идёт ТОЛЬКО в аниматор, не в движение.
  • Дискретное слать как стейт/флаги, а не выводить из трансформа: isSprinting (кнопка+стамина — им и разделять run/walk вместо интервалов скорости), jumpSeq (фронт прыжка).
  • Landing-триггер оставить локальным (свой grounded реплики), чтобы стопа вставала по её же телу, а не по таймлайну owner'а. Клип выбирать по реплицированной скорости.

Открытые вопросы

  • Точность/частота квантования скорости (баланс трафик ↔ джиттер).
  • Возможный рассинхрон «тело реплики уже на земле, а скорость-стейт ещё нет» — насколько заметен, нужен ли сглаживающий буфер на реплицированной скорости.
  • Разделение sprint/walk точно уходит в стейт контроллера (кнопка+стамина); интервалы скорости — временная заглушка до этого.
  • PurrNet из коробки ECM2 не поддерживает — сетевой слой пишем сами (отдельный NetworkBehaviour с SyncVar поверх MotionSource), по аналогии с Mirror/Netcode примерами ECM2.

3. Мелочи

  • Убрать _debugLog-вызовы или оставить под флагом (сейчас под флагом — ок).