From ed3a3940491e8d355881e40d9d2d8fe5dcc7ee62 Mon Sep 17 00:00:00 2001 From: Ding Yuntian <1491671119@qq.com> Date: Wed, 15 Apr 2026 22:22:53 +0800 Subject: [PATCH] =?UTF-8?q?refactor(camera-kit):=20=E6=B8=85=E7=90=86?= =?UTF-8?q?=E5=BA=9F=E5=BC=83=E9=80=8F=E8=A7=86=E7=9B=B8=E6=9C=BA=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E5=B9=B6=E5=A2=9E=E5=BC=BA=E5=81=A5=E5=A3=AE=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Scripts/Framework/OtherKit/CameraKit.cs | 154 ++++++++++-------- 1 file changed, 88 insertions(+), 66 deletions(-) diff --git a/Assets/Scripts/Framework/OtherKit/CameraKit.cs b/Assets/Scripts/Framework/OtherKit/CameraKit.cs index 9f5e38c57..238efaf65 100644 --- a/Assets/Scripts/Framework/OtherKit/CameraKit.cs +++ b/Assets/Scripts/Framework/OtherKit/CameraKit.cs @@ -20,24 +20,20 @@ namespace AibisDream.Framework #region 相机组件 - private static Camera _mainCam; public static Camera UICamera => UIManager.Instance.UICamera; private CinemachineBrain _orthoCameraBrain; - // private CinemachineBrain _perspectiveCameraBrain; private readonly Dictionary _virtualCameraDict = new(); private readonly Dictionary _camInitStateDict = new(); private CameraEnum _curCameraEnum; private CamState _curInitState; private Camera _orthoMainCamera; - // private Camera _perspectiveMainCamera; private struct CamState { public Vector3 pos; public float initOrthoSize; - public bool isPerspective; } #endregion @@ -51,19 +47,7 @@ namespace AibisDream.Framework // 获取正交相机 _orthoMainCamera = Camera.main; _orthoCameraBrain = _orthoMainCamera?.GetComponent(); - - // 获取透视相机 - // _perspectiveMainCamera = GameObject.Find("PerspectiveMainCamera")?.GetComponent(); - // _perspectiveCameraBrain = _perspectiveMainCamera?.GetComponent(); - _curCameraEnum = CameraEnum.Default; - - // if (_orthoMainCamera && _perspectiveMainCamera) - // { - // // 默认激活正交相机,禁用透视相机 - // _orthoMainCamera.gameObject.SetActive(true); - // _perspectiveMainCamera.gameObject.SetActive(false); - // } } #region 相机信息注册 @@ -79,18 +63,14 @@ namespace AibisDream.Framework public void RegisterUICamera(Camera overlayCamera) { - // 获取 Main Camera 的 UniversalAdditionalCameraData var mainCameraData = _orthoMainCamera.GetUniversalAdditionalCameraData(); if (mainCameraData != null) { - // 检查 Overlay Camera 是否已经在 Stack 中 if (!mainCameraData.cameraStack.Contains(overlayCamera)) { - overlayCamera.UpdateCameraViewport(); - // 将 Overlay Camera 添加到 Stack + overlayCamera.rect = _orthoMainCamera.rect; mainCameraData.cameraStack.Insert(0, overlayCamera); - Debug.Log("Overlay Camera added to Main Camera stack."); } } else @@ -103,15 +83,15 @@ namespace AibisDream.Framework { // 获取 Main Camera 的 UniversalAdditionalCameraData var mainCameraData = _orthoMainCamera.GetUniversalAdditionalCameraData(); - + if (mainCameraData != null) { - // 检查 Overlay Camera 是否已经在 Stack 中 - if (!mainCameraData.cameraStack.Contains(overlayCamera)) + // 检查 Overlay Camera 是否在 Stack 中 + if (mainCameraData.cameraStack.Contains(overlayCamera)) { - // 将 Overlay Camera 添加到 Stack + // 将 Overlay Camera 从 Stack 移除 mainCameraData.cameraStack.Remove(overlayCamera); - Debug.Log("Overlay Camera added to Main Camera stack."); + Debug.Log("Overlay Camera removed from Main Camera stack."); } } else @@ -120,16 +100,21 @@ namespace AibisDream.Framework } } - public void RegisterCamera(CameraEnum camType, ICinemachineCamera virtualCamera, bool isPerspective = false) + public void RegisterCamera(CameraEnum camType, ICinemachineCamera virtualCamera) { _virtualCameraDict[camType] = virtualCamera; + var vcam = virtualCamera.VirtualCameraGameObject.GetComponent(); + if (vcam == null) + { + Debug.LogWarning($"RegisterCamera: {camType} 的 GameObject 上未找到 CinemachineVirtualCamera 组件"); + return; + } + var initState = new CamState { pos = virtualCamera.VirtualCameraGameObject.transform.localPosition, - initOrthoSize = virtualCamera.VirtualCameraGameObject.gameObject - .GetComponent().m_Lens.OrthographicSize, - isPerspective = isPerspective + initOrthoSize = vcam.m_Lens.OrthographicSize }; _camInitStateDict[camType] = initState; } @@ -161,14 +146,18 @@ namespace AibisDream.Framework /// /// 切换相机 /// - /// - public IEnumerator SwitchCamera(CameraEnum camType) + /// 目标相机 + /// true 则跳过过渡动画立即切换(适用于读档等场景) + public IEnumerator SwitchCamera(CameraEnum camType, bool immediate = false) { - var switchDuration = SwitchCameraSync(camType); - yield return new WaitForSeconds(switchDuration); + var switchDuration = SwitchCameraSync(camType, immediate); + if (switchDuration > 0f) + { + yield return new WaitForSeconds(switchDuration); + } } - private float SwitchCameraSync(CameraEnum camType) + private float SwitchCameraSync(CameraEnum camType, bool immediate = false) { if (_curCameraEnum == camType) { @@ -177,29 +166,38 @@ namespace AibisDream.Framework if (!_virtualCameraDict.ContainsKey(camType)) { - Debug.Log($"{camType.ToString()}相机未注册"); + Debug.LogWarning($"SwitchCamera: {camType} 相机未注册"); return 0; } - // 切换主相机 - bool isPerspective = _camInitStateDict[camType].isPerspective; - _orthoMainCamera.gameObject.SetActive(!isPerspective); - // _perspectiveMainCamera.gameObject.SetActive(isPerspective); - // var activeBrain = isPerspective ? _perspectiveCameraBrain : _orthoCameraBrain; var activeBrain = _orthoCameraBrain; + CinemachineBlendDefinition originalBlend = default; + if (immediate) + { + originalBlend = activeBrain.m_DefaultBlend; + activeBrain.m_DefaultBlend = new CinemachineBlendDefinition( + CinemachineBlendDefinition.Style.Cut, 0f); + } + // 设置虚拟相机优先级 foreach (var camPair in _virtualCameraDict) { - if (camPair.Key == camType) camPair.Value.Priority = HighPriority; - if (camPair.Key != camType) camPair.Value.Priority = LowPriority; + camPair.Value.Priority = camPair.Key == camType ? HighPriority : LowPriority; } _curInitState = _camInitStateDict[camType]; var lastCamEnum = _curCameraEnum; _curCameraEnum = camType; - // 切完之后记得复原 + if (immediate) + { + ResetVirCam(lastCamEnum); + var blend = originalBlend; + ActionKit.Delay(0f, () => activeBrain.m_DefaultBlend = blend).StartGlobal(); + return 0f; + } + ActionKit.Delay(activeBrain.m_DefaultBlend.BlendTime, () => ResetVirCam(lastCamEnum)).StartGlobal(); return activeBrain.m_DefaultBlend.BlendTime; @@ -208,8 +206,7 @@ namespace AibisDream.Framework public void ResetCamera() { _curCameraEnum = CameraEnum.Default; - _camInitStateDict.Clear(); - _camInitStateDict.Clear(); + RemoveAllCam(); } private void ResetVirCam(CameraEnum cameraEnum) @@ -233,7 +230,17 @@ namespace AibisDream.Framework private Tween TransCamera(Vector3 targetPos, float targetOrthographicSize, float duration) { // 寻找现在正在激活的相机 + if (_orthoCameraBrain == null) + { + Debug.LogWarning("TransCamera: CinemachineBrain is null."); + return null; + } var curCamera = _orthoCameraBrain.ActiveVirtualCamera; + if (curCamera == null) + { + Debug.LogWarning("TransCamera: No active virtual camera found."); + return null; + } var sq = DOTween.Sequence(); // 移动 @@ -251,19 +258,36 @@ namespace AibisDream.Framework public IEnumerator TransCameraAsync(Vector3 targetPos, float targetOrthographicSize, float duration) { - yield return TransCamera(targetPos, targetOrthographicSize, duration).WaitForCompletion(); + var tween = TransCamera(targetPos, targetOrthographicSize, duration); + if (tween != null) + { + yield return tween.WaitForCompletion(); + } } public IEnumerator ReturnInitCameraAsync(float duration) { - yield return ReturnInitCamera(duration).WaitForCompletion(); + var tween = ReturnInitCamera(duration); + if (tween != null) + { + yield return tween.WaitForCompletion(); + } } - // 方法已废弃,后面改成用Cinemachine的Shake - [Obsolete] public IEnumerator ShakeCamera(float duration, float strength, int vibrate) { + if (_orthoCameraBrain == null) + { + Debug.LogWarning("ShakeCamera: CinemachineBrain is null."); + yield break; + } var curCamera = _orthoCameraBrain.ActiveVirtualCamera; + if (curCamera == null) + { + Debug.LogWarning("ShakeCamera: No active virtual camera found."); + yield break; + } + yield return curCamera.VirtualCameraGameObject.transform .DOShakePosition(duration, strength, vibrate, 90, false, false) .WaitForCompletion(); @@ -274,10 +298,6 @@ namespace AibisDream.Framework /// public Camera GetCurrentCamera() { - // return _camInitStateDict.TryGetValue(_curCameraEnum, out var state) && state.isPerspective - // ? _perspectiveMainCamera - // : _orthoMainCamera; - return _orthoMainCamera; } @@ -288,17 +308,20 @@ namespace AibisDream.Framework /// 世界位置 public static Vector3 GetMouseWorldPos(Vector3 mousePoint) { - if (!_mainCam) _mainCam = Camera.main; - var pos = _mainCam.ScreenToWorldPoint(mousePoint); + var cam = Instance._orthoMainCamera; + if (cam == null) return Vector3.zero; + + var pos = cam.ScreenToWorldPoint(mousePoint); return new Vector3(pos.x, pos.y, 0); } public static Vector3 GetScreenPos(Vector3 worldPos) { - if (!_mainCam) _mainCam = Camera.main; + var cam = Instance._orthoMainCamera; + if (cam == null) return Vector3.zero; worldPos.z = 0; - return _mainCam.WorldToScreenPoint(worldPos); + return cam.WorldToScreenPoint(worldPos); } } @@ -345,7 +368,7 @@ namespace AibisDream.Framework } else { - // 如果宽高比大于目标,则无需添加黑边 + // 屏幕比目标更宽,左右添加黑边(pillarbox) rect.width = 1.0f / scaleHeight; rect.height = 1.0f; rect.x = (1.0f - 1.0f / scaleHeight) / 2.0f; @@ -367,7 +390,8 @@ namespace AibisDream.Framework [YarnCommand("trans_camera")] public static IEnumerator TransCameraAsync(float x, float y, float targetOrthographicSize, float duration) { - Vector3 targetPos = new Vector3(x, y, -10); + float z = CameraKit.Instance.GetCurrentCamera()?.transform.position.z ?? -10f; + Vector3 targetPos = new Vector3(x, y, z); return CameraKit.Instance.TransCameraAsync(targetPos, targetOrthographicSize, duration); } @@ -378,16 +402,15 @@ namespace AibisDream.Framework } [YarnCommand("switch_camera")] - public static IEnumerator SwitchCamera(string targetStateStr) + public static IEnumerator SwitchCamera(string targetStateStr, bool immediate = false) { - // 字符串转枚举 if (!Enum.TryParse(targetStateStr, out var targetState)) { - Debug.Log($"{targetStateStr}不在FixState枚举中"); + Debug.LogWarning($"SwitchCamera: \"{targetStateStr}\" 不在 CameraEnum 枚举中"); yield break; } - yield return CameraKit.Instance.SwitchCamera(targetState); + yield return CameraKit.Instance.SwitchCamera(targetState, immediate); } } @@ -423,7 +446,6 @@ namespace AibisDream.Framework AnalysisMode, AnalysisModeDeep, SaleCamera, - SaleDeepCamera, - BlockPuzzle, + SaleDeepCamera } } \ No newline at end of file