mirror of
http://47.107.252.169:3000/Roguelite-Game-Developing-Team/Gen_Hack-and-Slash-Roguelite.git
synced 2025-11-20 12:37:12 +08:00
(client) feat:健康给予,路径优化,结算界面,商店界面 (#60)
Co-authored-by: m0_75251201 <m0_75251201@noreply.gitcode.com> Reviewed-on: http://47.107.252.169:3000/Roguelite-Game-Developing-Team/Gen_Hack-and-Slash-Roguelite/pulls/60
This commit is contained in:
@@ -1,14 +1,16 @@
|
||||
using System;
|
||||
using Base;
|
||||
using Map;
|
||||
using UnityEngine;
|
||||
using Utils;
|
||||
|
||||
namespace CameraControl
|
||||
{
|
||||
/// <summary>
|
||||
/// 控制游戏摄像机的移动、缩放和维度切换。
|
||||
/// 继承自 MonoSingleton 以确保场景中只有一个实例,并实现 ITick 接口以在游戏循环中更新。
|
||||
/// 控制游戏摄像机的移动、缩放和维度切换。
|
||||
/// 继承自 MonoSingleton 以确保场景中只有一个实例,并实现 ITick 接口以在游戏循环中更新。
|
||||
/// </summary>
|
||||
public class CameraControl : Utils.MonoSingleton<CameraControl>, ITick
|
||||
public class CameraControl : MonoSingleton<CameraControl>, ITick
|
||||
{
|
||||
// 摄像机移动相关变量
|
||||
[SerializeField] private float _zoomSpeed = 5f; // 摄像机缩放速度
|
||||
@@ -16,13 +18,16 @@ namespace CameraControl
|
||||
[SerializeField] private float _maxZoom = 20f; // 摄像机最大缩放级别
|
||||
[SerializeField] private float _focusLerpSpeed = 5f; // 摄像机跟随目标时的平滑插值速度
|
||||
|
||||
private Vector3 _dragOrigin; // 拖拽操作的起始世界坐标
|
||||
private bool _isDragging; // 标记摄像机是否正在被拖拽
|
||||
|
||||
private Camera _cachedCamera; // 缓存的场景摄像机引用
|
||||
|
||||
private Vector3 _dragOrigin; // 拖拽操作的起始世界坐标
|
||||
private bool _isDragging; // 标记摄像机是否正在被拖拽
|
||||
private Dimension currentDimension;
|
||||
|
||||
private int dimensionId; // 当前摄像机控制器关注的维度索引
|
||||
|
||||
/// <summary>
|
||||
/// 获取当前生效的场景摄像机。懒加载并缓存。
|
||||
/// 获取当前生效的场景摄像机。懒加载并缓存。
|
||||
/// </summary>
|
||||
public Camera CurrentCamera
|
||||
{
|
||||
@@ -37,10 +42,7 @@ namespace CameraControl
|
||||
_cachedCamera = FindFirstObjectByType<Camera>();
|
||||
}
|
||||
|
||||
if (!_cachedCamera)
|
||||
{
|
||||
Debug.LogError("[CameraControl] 场景中未找到可用的摄像机!摄像机控制功能将受限。");
|
||||
}
|
||||
if (!_cachedCamera) Debug.LogError("[CameraControl] 场景中未找到可用的摄像机!摄像机控制功能将受限。");
|
||||
}
|
||||
|
||||
return _cachedCamera;
|
||||
@@ -48,14 +50,49 @@ namespace CameraControl
|
||||
}
|
||||
|
||||
public Vector3 Position => CurrentCamera.transform.position;
|
||||
|
||||
private int dimensionId; // 当前摄像机控制器关注的维度索引
|
||||
private string[] dimensionList=>Program.Instance.Dimensions; // 维度名称列表
|
||||
private Dimension currentDimension;
|
||||
private string[] dimensionList => Program.Instance.Dimensions; // 维度名称列表
|
||||
|
||||
/// <summary>
|
||||
/// MonoSingleton 的 OnStart 方法,在单例首次创建并激活时调用,早于普通的 Start 方法。
|
||||
/// 用于初始化摄像机缓存。
|
||||
/// 当脚本实例被销毁时调用。
|
||||
/// 用于取消订阅 Program.Instance 的事件,防止内存泄漏。
|
||||
/// </summary>
|
||||
private void OnDestroy()
|
||||
{
|
||||
Program.Instance.OnFocusedDimensionChanged -= Init;
|
||||
Clock.RemoveTick(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 在游戏循环中每帧调用,用于处理摄像机跟随聚焦实体和维度切换。
|
||||
/// </summary>
|
||||
public void Tick()
|
||||
{
|
||||
if (!CurrentCamera) return; // 确保相机存在
|
||||
|
||||
// 当没有拖拽且存在聚焦实体时,摄像机跟随聚焦实体
|
||||
if (!_isDragging && Program.Instance.FocusedEntity)
|
||||
{
|
||||
var targetPosition = new Vector3(
|
||||
Program.Instance.FocusedEntity.Position.x,
|
||||
Program.Instance.FocusedEntity.Position.y,
|
||||
CurrentCamera.transform.position.z);
|
||||
|
||||
// 使用 deltaTime 进行平滑的摄像机跟随
|
||||
CurrentCamera.transform.position = Vector3.Lerp(
|
||||
CurrentCamera.transform.position,
|
||||
targetPosition,
|
||||
Time.deltaTime * _focusLerpSpeed);
|
||||
}
|
||||
|
||||
HandleMiddleMouseDrag(); // 处理鼠标中键拖拽
|
||||
// HandleMouseZoom(); // 处理鼠标滚轮缩放
|
||||
// 按下 Tab 键时切换到下一个维度
|
||||
if (Input.GetKeyDown(KeyCode.Tab)) NextDimension();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// MonoSingleton 的 OnStart 方法,在单例首次创建并激活时调用,早于普通的 Start 方法。
|
||||
/// 用于初始化摄像机缓存。
|
||||
/// </summary>
|
||||
protected override void OnStart()
|
||||
{
|
||||
@@ -63,31 +100,17 @@ namespace CameraControl
|
||||
Clock.AddTick(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 当脚本实例被销毁时调用。
|
||||
/// 用于取消订阅 Program.Instance 的事件,防止内存泄漏。
|
||||
/// </summary>
|
||||
private void OnDestroy()
|
||||
{
|
||||
Program.Instance.OnFocusedDimensionChanged -= Init;
|
||||
Clock.RemoveTick(this);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 根据指定的维度对象初始化摄像机控制器。
|
||||
/// 主要用于在聚焦维度改变时更新摄像机状态和内部的维度ID。
|
||||
/// 根据指定的维度对象初始化摄像机控制器。
|
||||
/// 主要用于在聚焦维度改变时更新摄像机状态和内部的维度ID。
|
||||
/// </summary>
|
||||
/// <param name="obj">当前聚焦的维度对象。</param>
|
||||
private void Init(Dimension obj)
|
||||
{
|
||||
Clock.AddTick(this);
|
||||
// 处理 obj 为 null 的情况 - 此时 dimensionList 已更新
|
||||
if (!obj)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!obj) return;
|
||||
if (!CurrentCamera) // 如果摄像机仍未找到,记录错误并返回
|
||||
{
|
||||
Debug.LogWarning("[CameraControl] 未找到摄像机!摄像机控制功能将无法完全初始化。");
|
||||
@@ -95,7 +118,7 @@ namespace CameraControl
|
||||
}
|
||||
|
||||
// 根据当前聚焦维度同步 CameraControl 内部的 dimensionId
|
||||
var focusedIndex = System.Array.IndexOf(dimensionList, obj.DimensionId);
|
||||
var focusedIndex = Array.IndexOf(dimensionList, obj.DimensionId);
|
||||
if (focusedIndex != -1)
|
||||
{
|
||||
dimensionId = focusedIndex;
|
||||
@@ -105,27 +128,23 @@ namespace CameraControl
|
||||
Debug.LogWarning($"[CameraControl] 聚焦维度 '{obj.DimensionId}' 未在维度列表中找到。回退到ID 0。");
|
||||
dimensionId = 0; // 找不到时,回退到第一个维度,避免数组越界
|
||||
}
|
||||
|
||||
CurrentCamera.transform.position = new Vector3(obj.cameraPosition.x, obj.cameraPosition.y, -10f);
|
||||
if(currentDimension)
|
||||
{
|
||||
currentDimension.OnDimensionLoaded-=DimensionLoaded;
|
||||
}
|
||||
if (currentDimension) currentDimension.OnDimensionLoaded -= DimensionLoaded;
|
||||
currentDimension = obj;
|
||||
currentDimension.OnDimensionLoaded+=DimensionLoaded;
|
||||
currentDimension.OnDimensionLoaded += DimensionLoaded;
|
||||
}
|
||||
|
||||
private void DimensionLoaded(Dimension obj)
|
||||
{
|
||||
if (obj == Program.Instance.FocusedDimension)
|
||||
{
|
||||
CurrentCamera.transform.position = new Vector3(obj.cameraPosition.x, obj.cameraPosition.y, -10f);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 切换到下一个维度。
|
||||
/// 会保存当前摄像机位置到当前维度,然后加载下一个维度的摄像机位置。
|
||||
/// 切换到下一个维度。
|
||||
/// 会保存当前摄像机位置到当前维度,然后加载下一个维度的摄像机位置。
|
||||
/// </summary>
|
||||
public void NextDimension()
|
||||
{
|
||||
@@ -146,14 +165,10 @@ namespace CameraControl
|
||||
{
|
||||
var currentDimension = Program.Instance.GetDimension(dimensionList[dimensionId]);
|
||||
if (currentDimension != null)
|
||||
{
|
||||
currentDimension.cameraPosition = CurrentCamera.transform.position;
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning(
|
||||
$"[CameraControl] 无法找到ID为 {dimensionId} ({dimensionList[dimensionId]}) 的维度对象,无法保存摄像机位置。");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -169,8 +184,8 @@ namespace CameraControl
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置 Program.Instance 中聚焦的维度。
|
||||
/// 摄像机位置的实际更新将通过 Program.Instance.OnFocusedDimensionChanged 事件在 Init(Dimension obj) 方法中处理。
|
||||
/// 设置 Program.Instance 中聚焦的维度。
|
||||
/// 摄像机位置的实际更新将通过 Program.Instance.OnFocusedDimensionChanged 事件在 Init(Dimension obj) 方法中处理。
|
||||
/// </summary>
|
||||
/// <param name="id">要设置的维度ID。</param>
|
||||
private void SetFocusedDimensionById(int id)
|
||||
@@ -186,59 +201,25 @@ namespace CameraControl
|
||||
Debug.LogWarning($"[CameraControl] 维度ID {id} 超出范围或维度列表为空,无法设置聚焦维度。");
|
||||
return;
|
||||
}
|
||||
|
||||
Program.Instance.SetFocusedDimension(dimensionList[id]);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 在游戏循环中每帧调用,用于处理摄像机跟随聚焦实体和维度切换。
|
||||
/// </summary>
|
||||
public void Tick()
|
||||
{
|
||||
if (!CurrentCamera) return; // 确保相机存在
|
||||
|
||||
// 当没有拖拽且存在聚焦实体时,摄像机跟随聚焦实体
|
||||
if (!_isDragging && Program.Instance.FocusedEntity)
|
||||
{
|
||||
var targetPosition = new Vector3(
|
||||
Program.Instance.FocusedEntity.Position.x,
|
||||
Program.Instance.FocusedEntity.Position.y,
|
||||
CurrentCamera.transform.position.z);
|
||||
|
||||
// 使用 deltaTime 进行平滑的摄像机跟随
|
||||
CurrentCamera.transform.position = Vector3.Lerp(
|
||||
CurrentCamera.transform.position,
|
||||
targetPosition,
|
||||
Time.deltaTime * _focusLerpSpeed);
|
||||
}
|
||||
HandleMiddleMouseDrag(); // 处理鼠标中键拖拽
|
||||
// HandleMouseZoom(); // 处理鼠标滚轮缩放
|
||||
// 按下 Tab 键时切换到下一个维度
|
||||
if (Input.GetKeyDown(KeyCode.Tab))
|
||||
{
|
||||
NextDimension();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 设置摄像机的世界坐标位置。
|
||||
/// 设置摄像机的世界坐标位置。
|
||||
/// </summary>
|
||||
/// <param name="position">要设置的摄像机位置。</param>
|
||||
public void SetPosition(Vector3 position)
|
||||
{
|
||||
if (CurrentCamera)
|
||||
{
|
||||
CurrentCamera.transform.position = position;
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning("[CameraControl] 摄像机引用为空,无法设置位置。");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 处理鼠标中键拖拽摄像机的逻辑。
|
||||
/// 处理鼠标中键拖拽摄像机的逻辑。
|
||||
/// </summary>
|
||||
private void HandleMiddleMouseDrag()
|
||||
{
|
||||
@@ -250,10 +231,7 @@ namespace CameraControl
|
||||
_dragOrigin = CurrentCamera.ScreenToWorldPoint(Input.mousePosition);
|
||||
_isDragging = true;
|
||||
// 如果有聚焦实体,则在开始拖拽时取消聚焦,暂停跟随
|
||||
if (Program.Instance.FocusedEntity)
|
||||
{
|
||||
Program.Instance.SetFocusedEntity(null);
|
||||
}
|
||||
if (Program.Instance.FocusedEntity) Program.Instance.SetFocusedEntity(null);
|
||||
}
|
||||
|
||||
// 拖拽中:根据鼠标移动更新摄像机位置
|
||||
@@ -264,14 +242,11 @@ namespace CameraControl
|
||||
}
|
||||
|
||||
// 结束拖拽:检测鼠标中键抬起
|
||||
if (Input.GetMouseButtonUp(2))
|
||||
{
|
||||
_isDragging = false;
|
||||
}
|
||||
if (Input.GetMouseButtonUp(2)) _isDragging = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 处理鼠标滚轮缩放摄像机的逻辑。
|
||||
/// 处理鼠标滚轮缩放摄像机的逻辑。
|
||||
/// </summary>
|
||||
private void HandleMouseZoom()
|
||||
{
|
||||
|
||||
@@ -1,15 +1,25 @@
|
||||
using System;
|
||||
using Base;
|
||||
using UnityEngine;
|
||||
|
||||
namespace CameraControl
|
||||
{
|
||||
public class MiniMapCamera : MonoBehaviour, Base.ITick
|
||||
public class MiniMapCamera : MonoBehaviour, ITick
|
||||
{
|
||||
private void OnEnable()
|
||||
{
|
||||
Clock.AddTick(this);
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
Clock.RemoveTick(this);
|
||||
}
|
||||
|
||||
public void Tick()
|
||||
{
|
||||
if (Program.Instance.FocusedEntity)
|
||||
{
|
||||
transform.position = Program.Instance.FocusedEntity.transform.position + new Vector3(0, 0, -10);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user