vampire-like/Assets/GameMain/Scripts/Runtime/CustomComponent/CameraModule/CameraModuleComponent.cs

189 lines
5.2 KiB
C#

using UnityEngine;
using UnityGameFramework.Runtime;
using Object = UnityEngine.Object;
namespace SepCore.CameraModule
{
/// <summary>
/// UnityGameFramework 侧的相机模块组件。
/// 作为 GameEntry.CameraModule 访问入口,统一持有并转发 CameraModule 控制器能力。
/// </summary>
[DisallowMultipleComponent]
public class CameraModuleComponent : GameFrameworkComponent
{
[SerializeField] private CinemachineCameraController _cinemachineController;
[SerializeField] private bool _autoSearchController = true;
[SerializeField] private bool _logMissingControllerWarnings = true;
private ICameraController _controller;
private bool _hasLoggedMissingController;
public ICameraController Controller
{
get
{
ResolveController(false);
return IsControllerValid(_controller) ? _controller : null;
}
}
public bool HasController => Controller != null;
public Transform Target => Controller?.Target;
public CameraEffectSettings CurrentSettings => Controller?.CurrentSettings ?? CameraEffectSettings.Default;
protected override void Awake()
{
base.Awake();
ResolveController(false);
}
public void RegisterController(ICameraController controller)
{
if (!IsControllerValid(controller))
{
Log.Warning("CameraModuleComponent.RegisterController() controller is invalid.");
return;
}
_controller = controller;
_hasLoggedMissingController = false;
if (controller is CinemachineCameraController cinemachineController)
{
_cinemachineController = cinemachineController;
}
}
public void UnregisterController(ICameraController controller)
{
if (controller != null && !ReferenceEquals(_controller, controller))
{
return;
}
_controller = null;
_cinemachineController = null;
}
public void SetTarget(Transform target)
{
if (!EnsureController())
{
return;
}
_controller.SetTarget(target);
}
public void ApplySettings(CameraEffectSettings settings)
{
if (!EnsureController())
{
return;
}
_controller.ApplySettings(settings);
}
public void EnableEffect(CameraEffectType effect)
{
if (!EnsureController())
{
return;
}
_controller.EnableEffect(effect);
}
public void DisableEffect(CameraEffectType effect)
{
if (!EnsureController())
{
return;
}
_controller.DisableEffect(effect);
}
public bool IsEffectEnabled(CameraEffectType effect)
{
return EnsureController() && _controller.IsEffectEnabled(effect);
}
private bool EnsureController()
{
ResolveController(_logMissingControllerWarnings);
return IsControllerValid(_controller);
}
private void ResolveController(bool logWarning)
{
if (IsControllerValid(_controller))
{
return;
}
if (_cinemachineController != null)
{
_controller = _cinemachineController;
_hasLoggedMissingController = false;
return;
}
if (!_autoSearchController)
{
LogMissingController(logWarning);
return;
}
_cinemachineController = GetComponentInChildren<CinemachineCameraController>(true);
if (_cinemachineController == null)
{
#if UNITY_2023_1_OR_NEWER
_cinemachineController = FindFirstObjectByType<CinemachineCameraController>(FindObjectsInactive.Include);
#else
_cinemachineController = FindObjectOfType<CinemachineCameraController>(true);
#endif
}
if (_cinemachineController != null)
{
_controller = _cinemachineController;
_hasLoggedMissingController = false;
return;
}
LogMissingController(logWarning);
}
private void LogMissingController(bool logWarning)
{
if (!logWarning || _hasLoggedMissingController)
{
return;
}
_hasLoggedMissingController = true;
Log.Warning(
"CameraModuleComponent requires a CinemachineCameraController. " +
"Assign one in Inspector or place one in the loaded scene.");
}
private static bool IsControllerValid(ICameraController controller)
{
if (controller == null)
{
return false;
}
if (controller is Object unityObject && unityObject == null)
{
return false;
}
return true;
}
}
}