(client) feat:实现热重载,实现多维度,实现武器,实现掉落物,实现状态UI,实现攻击AI (#44)
Co-authored-by: zzdxxz <2079238449@qq.com> Co-committed-by: zzdxxz <2079238449@qq.com>
This commit is contained in:
@ -1,61 +1,209 @@
|
||||
using Base;
|
||||
using UnityEngine;
|
||||
using UnityEngine.SceneManagement;
|
||||
|
||||
namespace CameraControl
|
||||
{
|
||||
public class CameraControl : Utils.MonoSingleton<CameraControl>, ITick, ITickUI
|
||||
{
|
||||
// 当前被聚焦的目标实体
|
||||
public Entity.Entity focusedEntity = null;
|
||||
|
||||
// Camera movement variables
|
||||
[SerializeField] private float _zoomSpeed = 5f;
|
||||
[SerializeField] private float _minZoom = 2f;
|
||||
[SerializeField] private float _maxZoom = 20f;
|
||||
[SerializeField] private float _focusLerpSpeed = 5f;
|
||||
|
||||
private Vector3 _dragOrigin;
|
||||
private bool _isDragging = false;
|
||||
private float _zoomSpeed = 5f;
|
||||
private float _minZoom = 2f;
|
||||
private float _maxZoom = 20f;
|
||||
|
||||
private Camera _camera;
|
||||
|
||||
private int dimensionId;
|
||||
private string[] dimensionList;
|
||||
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
// 移除事件监听
|
||||
SceneManager.sceneLoaded -= OnSceneLoaded;
|
||||
}
|
||||
|
||||
protected override void OnStart()
|
||||
{
|
||||
_camera = Camera.main;
|
||||
// 注册场景加载事件。请注意,MonoSingleton中的OnStart通常由Awake调用。
|
||||
// 真正的Init调用已移至Start方法,以确保Program.Instance已完成其Awake阶段的初始化。
|
||||
SceneManager.sceneLoaded += OnSceneLoaded;
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
// 在Start中调用Init,确保所有依赖的单例(如Program.Instance)已完成Awake阶段的初始化。
|
||||
Init();
|
||||
}
|
||||
|
||||
private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
|
||||
{
|
||||
// 场景加载完成后调用 Init 方法,重新获取相机引用并初始化维度状态。
|
||||
// 这确保了如果CameraControl是DontDestroyOnLoad,在切换场景后也能正确工作。
|
||||
Init();
|
||||
}
|
||||
|
||||
|
||||
private void Init()
|
||||
{
|
||||
// 确保相机引用有效
|
||||
if (_camera == null)
|
||||
{
|
||||
_camera = FindFirstObjectByType<Camera>();
|
||||
_camera = Camera.main;
|
||||
if (_camera == null)
|
||||
{
|
||||
_camera = FindFirstObjectByType<Camera>();
|
||||
}
|
||||
}
|
||||
|
||||
if (_camera == null)
|
||||
{
|
||||
Debug.LogError("No Camera found in the scene! CameraControl functionalities will be limited.");
|
||||
return; // 如果没有相机,则无法进行后续初始化
|
||||
}
|
||||
|
||||
// 初始化维度数据 (假设 Program.Instance 总是已初始化)
|
||||
dimensionId = 0; // 默认从第一个维度开始
|
||||
dimensionList = Program.Instance.Dimensions;
|
||||
if (dimensionList != null && dimensionList.Length > 0)
|
||||
{
|
||||
SetCameraPositionForDimension(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning("Dimension list is empty or null from Program.Instance. Cannot set initial camera position for dimensions.");
|
||||
}
|
||||
}
|
||||
|
||||
public void NextDimension()
|
||||
{
|
||||
if (_camera == null)
|
||||
{
|
||||
Debug.LogWarning("Camera reference is null, cannot switch dimensions.");
|
||||
return;
|
||||
}
|
||||
if (dimensionList == null || dimensionList.Length == 0)
|
||||
{
|
||||
Debug.LogWarning("Dimension list is empty.");
|
||||
return;
|
||||
}
|
||||
|
||||
// 1. 保存当前相机的真实位置到当前维度 (假设 Program.Instance 总是已初始化)
|
||||
// 维度ID范围检查仍然保留,因为这是数组访问的安全保障
|
||||
if (dimensionId >= 0 && dimensionId < dimensionList.Length)
|
||||
{
|
||||
// Program.Instance 假设不会为 null
|
||||
var currentDimension = Program.Instance.GetDimension(dimensionList[dimensionId]);
|
||||
if (currentDimension != null)
|
||||
{
|
||||
currentDimension.cameraPosition = _camera.transform.position;
|
||||
// Debug.Log($"Saved camera position {currentDimension.cameraPosition} for dimension {dimensionList[dimensionId]} (ID: {dimensionId})");
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning($"Could not find dimension object for ID {dimensionId} ({dimensionList[dimensionId]}) to save camera position.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning($"Current dimensionId ({dimensionId}) is out of bounds for saving camera position (dimensionList length: {dimensionList.Length}).");
|
||||
}
|
||||
|
||||
// 2. 更新 dimensionId,形成循环
|
||||
dimensionId = (dimensionId + 1) % dimensionList.Length;
|
||||
|
||||
// 3. 更新相机位置到新维度
|
||||
SetCameraPositionForDimension(dimensionId);
|
||||
}
|
||||
|
||||
private void SetCameraPositionForDimension(int id)
|
||||
{
|
||||
if (_camera == null)
|
||||
{
|
||||
Debug.LogWarning("Camera reference is null, cannot set camera position.");
|
||||
return;
|
||||
}
|
||||
if (dimensionList == null || id < 0 || id >= dimensionList.Length)
|
||||
{
|
||||
Debug.LogWarning($"Dimension ID {id} is out of bounds or dimension list is null/empty.");
|
||||
return;
|
||||
}
|
||||
// Program.Instance 假设不会为 null
|
||||
|
||||
// 确保获取到的 Dimension 对象不为 null
|
||||
var dimension = Program.Instance.GetDimension(dimensionList[id]);
|
||||
if (dimension)
|
||||
{
|
||||
Vector3 cameraPosition = dimension.cameraPosition;
|
||||
_camera.transform.position = cameraPosition;
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning($"Dimension object for ID {id} ({dimensionList[id]}) is null. Cannot set camera position.");
|
||||
}
|
||||
}
|
||||
|
||||
public void Tick()
|
||||
{
|
||||
if (focusedEntity)
|
||||
if (_camera == null) return; // 确保相机存在
|
||||
|
||||
// 假设 Program.Instance 总是已初始化
|
||||
if (Program.Instance.FocusedEntity)
|
||||
{
|
||||
// Follow the focused entity's position
|
||||
var targetPosition = new Vector3(
|
||||
focusedEntity.Position.x,
|
||||
focusedEntity.Position.y,
|
||||
Program.Instance.FocusedEntity.Position.x,
|
||||
Program.Instance.FocusedEntity.Position.y,
|
||||
_camera.transform.position.z);
|
||||
|
||||
// 使用 deltaTime 进行平滑的相机跟随
|
||||
_camera.transform.position = Vector3.Lerp(
|
||||
_camera.transform.position,
|
||||
targetPosition,
|
||||
Time.fixedDeltaTime * 5f);
|
||||
Time.deltaTime * _focusLerpSpeed);
|
||||
}
|
||||
|
||||
if (Input.GetKeyDown(KeyCode.Tab))
|
||||
{
|
||||
NextDimension();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void TickUI()
|
||||
{
|
||||
if (!_camera) // 确保相机存在
|
||||
return;
|
||||
|
||||
HandleMiddleMouseDrag();
|
||||
HandleMouseZoom();
|
||||
// HandleMouseZoom();
|
||||
}
|
||||
|
||||
public void SetPosition(Vector3 position)
|
||||
{
|
||||
if (_camera)
|
||||
_camera.transform.position = position;
|
||||
else
|
||||
Debug.LogWarning("Camera reference is null, cannot set position.");
|
||||
}
|
||||
|
||||
private void HandleMiddleMouseDrag()
|
||||
{
|
||||
if (_camera == null) return; // 确保相机存在
|
||||
|
||||
// Start drag
|
||||
if (Input.GetMouseButtonDown(2)) // Middle mouse button
|
||||
{
|
||||
_dragOrigin = _camera.ScreenToWorldPoint(Input.mousePosition);
|
||||
_isDragging = true;
|
||||
focusedEntity = null; // Clear focus when manually moving camera
|
||||
// 假设 Program.Instance 总是已初始化
|
||||
if (Program.Instance.FocusedEntity)
|
||||
{
|
||||
Program.Instance.FocusedEntity.PlayerControlled = false;
|
||||
Program.Instance.SetFocusedEntity(null);
|
||||
}
|
||||
}
|
||||
|
||||
// During drag
|
||||
@ -74,12 +222,12 @@ namespace CameraControl
|
||||
|
||||
private void HandleMouseZoom()
|
||||
{
|
||||
if (_camera == null) return; // 确保相机存在
|
||||
|
||||
var scroll = Input.GetAxis("Mouse ScrollWheel");
|
||||
if (scroll == 0) return;
|
||||
var newSize = _camera.orthographicSize - scroll * _zoomSpeed;
|
||||
_camera.orthographicSize = Mathf.Clamp(newSize, _minZoom, _maxZoom);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user