角色能力,存档
This commit is contained in:
@@ -6,37 +6,81 @@ namespace BaseGames.World
|
||||
{
|
||||
/// <summary>
|
||||
/// 房间控制器。挂在每个房间场景的 [RoomRoot] 下。
|
||||
/// Start 时切换摄像机到该房间的 CameraArea,并提供出生点查询。
|
||||
/// Start 时切换摄像机到玩家当前所在的 CameraArea,并提供出生点查询。
|
||||
/// 支持房间内存在多个 CameraArea 的情况:动态检测玩家位于哪个触发区域,
|
||||
/// 无匹配时回退到场景内第一个 CameraArea。
|
||||
/// </summary>
|
||||
public class RoomController : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private string _roomId;
|
||||
[SerializeField] private PlayerSpawnPoint[] _spawnPoints;
|
||||
[SerializeField] private CameraArea _cameraArea; // 该房间默认的相机区域
|
||||
|
||||
[Tooltip("(可选)显式指定此房间的基线相机区域。\n" +
|
||||
"设置后将优先使用此区域作为房间基准,而非动态检测玩家所在触发区域。\n" +
|
||||
"通常由 SceneObjectPlacerTool 自动赋值,也可手动拖入。")]
|
||||
[SerializeField] private CameraArea _cameraArea;
|
||||
|
||||
public string RoomId => _roomId;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
CameraArea area = _cameraArea;
|
||||
|
||||
// 未手动绑定时,自动在当前场景中查找(每个房间场景通常只有一个 CameraArea)
|
||||
if (area == null)
|
||||
{
|
||||
#if UNITY_6000_0_OR_NEWER
|
||||
area = Object.FindFirstObjectByType<CameraArea>();
|
||||
#else
|
||||
area = Object.FindObjectOfType<CameraArea>();
|
||||
#endif
|
||||
if (area != null)
|
||||
Debug.LogWarning($"[RoomController] {name}:_cameraArea 未绑定,自动找到 {area.name}。建议在 Inspector 中手动指定。");
|
||||
else
|
||||
Debug.LogError($"[RoomController] {name}:未找到 CameraArea,相机不会切换。");
|
||||
}
|
||||
// 显式覆盖优先:直接使用编辑器/工具指定的基线区域
|
||||
CameraArea area = _cameraArea != null ? _cameraArea : FindAreaForPlayer();
|
||||
|
||||
if (area != null)
|
||||
// instantCut = true:房间入口传送后相机硬切,无混合拖影
|
||||
ServiceLocator.GetOrDefault<ICameraService>()?.SwitchArea(area, 0, instantCut: true);
|
||||
else
|
||||
Debug.LogError($"[RoomController] {name}:未找到任何 CameraArea,相机不会切换。");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找玩家当前所在的 CameraArea。
|
||||
/// 优先检测玩家位置与哪个 CameraTriggerZone 重叠,选取其中优先级最高者;
|
||||
/// 无重叠时回退到场景内第一个 CameraArea。
|
||||
/// </summary>
|
||||
private CameraArea FindAreaForPlayer()
|
||||
{
|
||||
GameObject player = GameObject.FindWithTag("Player");
|
||||
if (player != null)
|
||||
{
|
||||
Vector2 playerPos = player.transform.position;
|
||||
|
||||
#if UNITY_6000_0_OR_NEWER
|
||||
var zones = Object.FindObjectsByType<CameraTriggerZone>(FindObjectsSortMode.None);
|
||||
#else
|
||||
var zones = Object.FindObjectsOfType<CameraTriggerZone>();
|
||||
#endif
|
||||
// 选取优先级最高的匹配区域(避免多区域重叠时选错基线)
|
||||
CameraArea bestArea = null;
|
||||
int bestPriority = int.MinValue;
|
||||
|
||||
foreach (var zone in zones)
|
||||
{
|
||||
var poly = zone.GetComponent<PolygonCollider2D>();
|
||||
if (poly != null && poly.OverlapPoint(playerPos))
|
||||
{
|
||||
var area = zone.GetComponentInParent<CameraArea>();
|
||||
if (area != null && zone.Priority > bestPriority)
|
||||
{
|
||||
bestPriority = zone.Priority;
|
||||
bestArea = area;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (bestArea != null) return bestArea;
|
||||
}
|
||||
|
||||
// 回退:返回场景中第一个 CameraArea
|
||||
#if UNITY_6000_0_OR_NEWER
|
||||
var fallback = Object.FindFirstObjectByType<CameraArea>();
|
||||
#else
|
||||
var fallback = Object.FindObjectOfType<CameraArea>();
|
||||
#endif
|
||||
if (fallback != null)
|
||||
Debug.LogWarning($"[RoomController] {name}:玩家不在任何触发区域内,回退到 {fallback.name}。建议确认玩家出生位置与 CameraTriggerZone 的重叠关系。");
|
||||
return fallback;
|
||||
}
|
||||
|
||||
/// <summary>通过 transitionId 查找对应的出生点。</summary>
|
||||
@@ -53,3 +97,4 @@ namespace BaseGames.World
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user