Working MVP code for Valentines
This commit is contained in:
169
Assets/Scripts/Common/Camera/CameraStateManager.cs
Normal file
169
Assets/Scripts/Common/Camera/CameraStateManager.cs
Normal file
@@ -0,0 +1,169 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Core;
|
||||
using Core.Lifecycle;
|
||||
using Unity.Cinemachine;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Common.Camera
|
||||
{
|
||||
/// <summary>
|
||||
/// Generic state-based camera controller using Cinemachine.
|
||||
/// Manages camera transitions by setting priorities on virtual cameras.
|
||||
/// Type parameter TState must be an enum representing camera states.
|
||||
/// </summary>
|
||||
public abstract class CameraStateManager<TState> : ManagedBehaviour where TState : Enum
|
||||
{
|
||||
#region Configuration
|
||||
|
||||
[Header("Camera Priority Settings")]
|
||||
[Tooltip("Priority for inactive cameras")]
|
||||
[SerializeField] protected int inactivePriority = 10;
|
||||
|
||||
[Tooltip("Priority for the active camera")]
|
||||
[SerializeField] protected int activePriority = 20;
|
||||
|
||||
[Header("Debug")]
|
||||
[SerializeField] protected bool showDebugLogs = false;
|
||||
|
||||
#endregion
|
||||
|
||||
#region State
|
||||
|
||||
private Dictionary<TState, CinemachineCamera> _cameraMap = new Dictionary<TState, CinemachineCamera>();
|
||||
private TState _currentState;
|
||||
private bool _isInitialized = false;
|
||||
|
||||
public TState CurrentState => _currentState;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Events
|
||||
|
||||
/// <summary>
|
||||
/// Fired when camera state changes. Parameters: (TState oldState, TState newState)
|
||||
/// </summary>
|
||||
public event Action<TState, TState> OnStateChanged;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Initialization
|
||||
|
||||
/// <summary>
|
||||
/// Register a camera for a specific state.
|
||||
/// Call this in subclass OnManagedAwake to set up the camera map.
|
||||
/// </summary>
|
||||
protected void RegisterCamera(TState state, CinemachineCamera pCamera)
|
||||
{
|
||||
if (pCamera == null)
|
||||
{
|
||||
Logging.Warning($"[{GetType().Name}] Attempted to register null camera for state {state}");
|
||||
return;
|
||||
}
|
||||
|
||||
if (_cameraMap.ContainsKey(state))
|
||||
{
|
||||
Logging.Warning($"[{GetType().Name}] Camera for state {state} already registered, overwriting");
|
||||
}
|
||||
|
||||
_cameraMap[state] = pCamera;
|
||||
|
||||
// Set all cameras to inactive priority initially
|
||||
pCamera.Priority.Value = inactivePriority;
|
||||
|
||||
if (showDebugLogs) Logging.Debug($"[{GetType().Name}] Registered camera '{pCamera.gameObject.name}' for state {state}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finalize initialization after all cameras are registered.
|
||||
/// Call this at the end of subclass OnManagedAwake.
|
||||
/// </summary>
|
||||
protected void FinalizeInitialization()
|
||||
{
|
||||
_isInitialized = true;
|
||||
|
||||
if (_cameraMap.Count == 0)
|
||||
{
|
||||
Logging.Warning($"[{GetType().Name}] No cameras registered!");
|
||||
}
|
||||
|
||||
if (showDebugLogs) Logging.Debug($"[{GetType().Name}] Initialized with {_cameraMap.Count} cameras");
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region State Management
|
||||
|
||||
/// <summary>
|
||||
/// Switch to a specific camera state
|
||||
/// </summary>
|
||||
public virtual void SwitchToState(TState newState)
|
||||
{
|
||||
if (!_isInitialized)
|
||||
{
|
||||
Logging.Error($"[{GetType().Name}] Cannot switch state - not initialized!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_cameraMap.ContainsKey(newState))
|
||||
{
|
||||
Logging.Error($"[{GetType().Name}] No camera registered for state {newState}!");
|
||||
return;
|
||||
}
|
||||
|
||||
TState oldState = _currentState;
|
||||
_currentState = newState;
|
||||
|
||||
// Set all cameras to inactive priority
|
||||
foreach (var kvp in _cameraMap)
|
||||
{
|
||||
kvp.Value.Priority.Value = inactivePriority;
|
||||
}
|
||||
|
||||
// Set target camera to active priority
|
||||
_cameraMap[newState].Priority.Value = activePriority;
|
||||
|
||||
if (showDebugLogs) Logging.Debug($"[{GetType().Name}] Switched from {oldState} to {newState} (camera: {_cameraMap[newState].gameObject.name})");
|
||||
|
||||
OnStateChanged?.Invoke(oldState, newState);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the camera for a specific state
|
||||
/// </summary>
|
||||
public CinemachineCamera GetCamera(TState state)
|
||||
{
|
||||
if (_cameraMap.TryGetValue(state, out CinemachineCamera pCamera))
|
||||
{
|
||||
return pCamera;
|
||||
}
|
||||
|
||||
Logging.Warning($"[{GetType().Name}] No camera found for state {state}");
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check if a camera is registered for a state
|
||||
/// </summary>
|
||||
public bool HasCamera(TState state)
|
||||
{
|
||||
return _cameraMap.ContainsKey(state);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Validation
|
||||
|
||||
/// <summary>
|
||||
/// Validate that all required states have cameras registered.
|
||||
/// Subclasses can override to add custom validation.
|
||||
/// </summary>
|
||||
protected virtual void ValidateCameras()
|
||||
{
|
||||
// Subclasses should implement specific validation
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
3
Assets/Scripts/Common/Camera/CameraStateManager.cs.meta
Normal file
3
Assets/Scripts/Common/Camera/CameraStateManager.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c4fc438e61b94c529f7d1e8fe9fb70fa
|
||||
timeCreated: 1764851223
|
||||
Reference in New Issue
Block a user