Решили: камера в мире логически ОДНА, а режимов у неё два — сценарный (слежение за дракой) и
свободный (руль у игрока). Три следствия, каждое было отдельной развилкой. Первое: владелец ответа
«какой вид сейчас» — фаза боя (IBattleClock), а не тот, кто эту фазу переключает; сценарный вид
существует только в Fighting и вне боя из цикла Tab выпадает. Второе: выбор игрока внутри боя
персистится (ISettingsService, prefs → GameplaySettings.FreeCombatCamera) и переживает бой,
забег и запуск игры. Третье: переходы несимметричны — в свободный вид камера входит, подхватывая
живой кадр с выхода Brain (в блендах он поэтому Cut), в сценарный её ведёт DefaultBlend Brain
(EaseInOut 0.7 с), а зум сценарной взводится сразу, чтобы кадр приехал одним движением.
Почему: прежде вид расставлял DeploymentController — расстановка звала FrameArena(), старт
боя ExitToActionView(). Два владельца, и оба перебивали выбор игрока на каждом бою. Отвергли и
вариант «свободная камера просто стоит, где стояла»: без подхвата кадра Tab читался как телепорт
через пол-арены, а с подхватом переход не виден вовсе — что и значит «камера одна». Кадрирование
арены на каждый вход в расстановку тоже снято (решение Макса): стартовый кадр «вся арена в
отдалении» ставится один раз, на включении, дальше камера помнит игрока.
Грабли:
PointerPositionлежала в карте действийPointer, а она в контекстеCombatвыключена — в боюReadValueотдавал ноль. Зум к курсору из-за этого утаскивал кадр в левый нижний угол экрана. Позиция переехала в картуCamera: она нужна везде, где есть камера, а не только там, где кликают.CinemachineBrain.IgnoreTimeScaleстоял в 0, а пауза боя — этоTime.timeScale = 0. Подводка вида на паузе замирала насмерть, хотя пан и зум уже давно считались поunscaledDeltaTime.- Кламп зума брал МЕНЬШУЮ сторону зоны, поэтому увидеть арену целиком было нельзя в принципе: стартовый широкий кадр схлопывался первым же делением колеса. Теперь по большей — за краем зоны не чернота, а тот же мир.
- Переименование сериализованных полей (
_zoomStep→_zoomFactor,_panSpeed→_panScreens) сделано намеренно: смысл величины изменился (разы вместо единиц, доли кадра вместо ед/сек), и старое имя молча донесло бы в сцену несовместимое значение.
Владелец правды: Presentation/Camera/CameraModeController.cs, тест CameraViewCycleTests;
времена и стиль переходов — WorldCameraBlends.asset + DefaultBlend на Brain в WorldScene.