不在触发区域时的相机逻辑
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using Unity.Cinemachine;
|
||||
|
||||
@@ -181,6 +182,31 @@ namespace BaseGames.Camera
|
||||
}
|
||||
}
|
||||
|
||||
// ── 静态注册表 ────────────────────────────────────────────────────────
|
||||
|
||||
private static readonly List<CameraArea> s_All = new();
|
||||
|
||||
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
|
||||
private static void ResetStaticState() => s_All.Clear();
|
||||
|
||||
/// <summary>
|
||||
/// 从所有已激活的 <see cref="CameraArea"/> 中找出距 <paramref name="worldPos"/> 最近的一个。
|
||||
/// 仅考虑拥有专属 VCam 的区域;无可用区域时返回 <c>null</c>。
|
||||
/// 距离以各区域 <c>transform.position</c> 为参考点。
|
||||
/// </summary>
|
||||
public static CameraArea FindNearest(Vector3 worldPos)
|
||||
{
|
||||
CameraArea best = null;
|
||||
float bestSqDist = float.MaxValue;
|
||||
foreach (var area in s_All)
|
||||
{
|
||||
if (area == null || !area.HasDedicated) continue;
|
||||
float d = (area.transform.position - worldPos).sqrMagnitude;
|
||||
if (d < bestSqDist) { bestSqDist = d; best = area; }
|
||||
}
|
||||
return best;
|
||||
}
|
||||
|
||||
// ── Lifecycle ────────────────────────────────────────────────────────
|
||||
|
||||
private void Awake()
|
||||
@@ -191,6 +217,17 @@ namespace BaseGames.Camera
|
||||
_dedicatedCamera.Priority = 0;
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
if (Application.isPlaying && !s_All.Contains(this))
|
||||
s_All.Add(this);
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
s_All.Remove(this);
|
||||
}
|
||||
|
||||
// ── Gizmo ────────────────────────────────────────────────────────────
|
||||
|
||||
private void OnDrawGizmosSelected()
|
||||
|
||||
@@ -145,8 +145,12 @@ namespace BaseGames.Camera
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 返回当前应激活的区域:<see cref="_activeZones"/> 中优先级最高的
|
||||
/// (同优先级取最近进入的),若触发集合为空则回退到 <see cref="_roomBaselineArea"/>。
|
||||
/// 返回当前应激活的区域:
|
||||
/// <list type="bullet">
|
||||
/// <item><see cref="_activeZones"/> 不为空时,返回其中优先级最高的(同优先级取最近进入的)。</item>
|
||||
/// <item>触发集合为空时,返回距玩家最近的 <see cref="CameraArea"/>;
|
||||
/// 无法确定玩家位置时回退到 <see cref="_roomBaselineArea"/>。</item>
|
||||
/// </list>
|
||||
/// </summary>
|
||||
private CameraArea GetEffectiveArea()
|
||||
{
|
||||
@@ -154,7 +158,16 @@ namespace BaseGames.Camera
|
||||
int bestPriority = -1;
|
||||
foreach (var (a, p) in _activeZones)
|
||||
if (p >= bestPriority) { bestPriority = p; best = a; }
|
||||
return best ?? _roomBaselineArea;
|
||||
if (best != null) return best;
|
||||
|
||||
// 触发集合为空:动态寻找距玩家最近的区域
|
||||
if (_currentFollowTarget != null)
|
||||
{
|
||||
CameraArea nearest = CameraArea.FindNearest(_currentFollowTarget.position);
|
||||
if (nearest != null) return nearest;
|
||||
}
|
||||
|
||||
return _roomBaselineArea;
|
||||
}
|
||||
|
||||
private void ActivateArea(CameraArea area, bool instantCut = false)
|
||||
|
||||
Reference in New Issue
Block a user