using System.Collections.Generic; using UnityEngine; using Unity.Cinemachine; using BaseGames.Core; namespace BaseGames.Camera { /// /// 相机状态单例控制器。管理房间相机切换、限位器更新与屏幕抖动。 /// 须放置在持久化场景中。 /// [DefaultExecutionOrder(-100)] public class CameraStateController : MonoBehaviour, ICameraService { [Header("引用")] [SerializeField] private CinemachineBrain _brain; [SerializeField] private CinemachineImpulseSource _impulseSource; [Header("默认混合配置")] [SerializeField] private CameraBlendProfileSO _defaultBlendProfile; // ── 注册表 ──────────────────────────────────────────────────────────── private readonly HashSet _registeredCameras = new HashSet(); private RoomCamera _activeCamera; // ── Unity Lifecycle ─────────────────────────────────────────────────── private void Awake() { if (ServiceLocator.GetOrDefault() != null) { Destroy(gameObject); return; } ServiceLocator.Register(this); } private void OnDestroy() { ServiceLocator.Unregister(this); } // ── 公开 API ────────────────────────────────────────────────────────── /// 向控制器注册一个房间相机(可选,也可由触发器直接调用 SwitchRoom)。 public void RegisterRoomCamera(RoomCamera camera) { if (camera != null) _registeredCameras.Add(camera); } /// 注销房间相机。 public void UnregisterRoomCamera(RoomCamera camera) { if (camera != null) _registeredCameras.Remove(camera); } /// 切换到目标房间相机,并应用对应的混合配置。 public void SwitchRoom(RoomCamera targetCamera) { if (targetCamera == null || targetCamera == _activeCamera) return; // 应用混合配置到 Brain if (_brain != null) { var profile = targetCamera.BlendProfile ?? _defaultBlendProfile; if (profile != null) _brain.DefaultBlend = profile.ToBlendDefinition(); } // 禁用旧相机、启用新相机 _activeCamera?.Deactivate(); _activeCamera = targetCamera; _activeCamera.Activate(); } /// 触发屏幕抖动。 public void TriggerImpulse(Vector3 velocity) { if (_impulseSource != null) _impulseSource.GenerateImpulse(velocity); } /// 以默认强度触发屏幕抖动。 public void TriggerImpulse(float strength = 0.3f) => TriggerImpulse(Vector3.down * strength); } }