(client) feat:实现掉落物,UI显示,维度

This commit is contained in:
m0_75251201
2025-08-27 13:56:22 +08:00
parent f04c89046b
commit 0c99e2beee
46 changed files with 6150 additions and 1809 deletions

View File

@ -1,5 +1,6 @@
using System; // 添加引用,用于 Action 委托
using System;
using System.Collections.Generic;
using System.Linq;
using Map;
using UnityEngine;
using Utils;
@ -16,18 +17,26 @@ public class Program : Singleton<Program>
public bool needLoad = true;
/// <summary>
/// 当前聚焦的实体对象,可能为空
/// 当前聚焦的实体对象。
/// 变更为属性并私有化setter确保通过 SetFocusedEntity 方法集中管理其更新和事件触发。
/// </summary>
public Entity.Entity focusedEntity = null;
public Entity.Entity FocusedEntity { get; private set; } = null;
/// <summary>
/// 当焦点实体发生变化时触发的事件。
/// 事件参数为新的焦点 Entity 实例,如果焦点被清除则为 null。
/// </summary>
public event Action<Entity.Entity> OnFocusedEntityChanged;
/// <summary>
/// 当前活跃焦点的维度唯一标识符,可能为空。
/// 变更为属性并私有化setter确保通过 SetFocusedDimension 方法集中管理其更新。
/// </summary>
public string focuseDimensionId { get; private set; } = null;
// 逻辑修改1修正属性名 'focuseDimensionId' 为 'focusedDimensionId'
public string FocusedDimensionId { get; private set; } = null;
/// <summary>
/// 当前聚焦的维度对象实例。当 <see cref="focuseDimensionId"/> 不为空时,此属性指向对应的维度实例。
/// 当前聚焦的维度对象实例。当 <see cref="FocusedDimensionId"/> 不为空时,此属性指向对应的维度实例。
/// </summary>
public Dimension FocusedDimension { get; private set; }
@ -47,6 +56,9 @@ public class Program : Singleton<Program>
/// </summary>
public event Action<Dimension> OnFocusedDimensionChanged;
public int DimensionCount => _registeredDimensions.Count;
public string[] Dimensions => _registeredDimensions.Keys.ToArray();
/// <summary>
/// 注册一个维度实例到 Program。
/// </summary>
@ -71,10 +83,13 @@ public class Program : Singleton<Program>
}
_registeredDimensions.Add(id, dimension);
// 修改理由:确保任何对焦点的潜在更新都通过 SetFocusedDimension 进行,
// 逻辑修改此处不需要if语句包裹_registeredDimensions.Add因为前置的ContainsKey已确保不会抛异常。
// 确保任何对焦点的潜在更新都通过 SetFocusedDimension 进行,
// 从而集中管理焦点状态的同步和事件的触发。
// 如果注册的维度恰好是当前 focuseDimensionId SetFocusedDimension(id) 将负责更新 FocusedDimension 并触发事件。
if (focuseDimensionId == id)
// 如果注册的维度恰好是当前 focusedDimensionId SetFocusedDimension(id) 将负责更新 FocusedDimension 并触发事件。
// 并且由于SetFocusedDimension会清空FocusedEntity这也符合新维度的行为。
// 逻辑修改1修正属性名 'focuseDimensionId' 为 'focusedDimensionId'
if (FocusedDimensionId == id)
{
SetFocusedDimension(id);
}
@ -94,10 +109,11 @@ public class Program : Singleton<Program>
var id = dimension.DimensionId;
if (_registeredDimensions.Remove(id))
{
// 修改理由:确保任何对焦点的潜在更新都通过 SetFocusedDimension 进行,
// 确保任何对焦点的潜在更新都通过 SetFocusedDimension 进行,
// 从而集中管理焦点状态的同步和事件的触发。
// 如果注销的维度是当前焦点维度,则调用 SetFocusedDimension(null) 清除焦点并触发事件。
if (focuseDimensionId == id)
// 逻辑修改1修正属性名 'focuseDimensionId' 为 'focusedDimensionId'
if (FocusedDimensionId == id)
{
SetFocusedDimension(null); // 清除焦点
}
@ -128,13 +144,13 @@ public class Program : Singleton<Program>
{
// 1. 确定新的焦点维度及其ID
Dimension newFocusedDimension = null; // 默认为清除焦点
string newFocuseDimensionId = null;
string newFocusedDimensionId = null; // 逻辑修改1修正属性名 'newFocuseDimensionId' 为 'newFocusedDimensionId'
if (!string.IsNullOrEmpty(dimensionId))
{
if (_registeredDimensions.TryGetValue(dimensionId, out var foundDimension))
{
newFocuseDimensionId = dimensionId;
newFocusedDimensionId = dimensionId; // 逻辑修改1修正属性名
newFocusedDimension = foundDimension;
}
else
@ -144,26 +160,53 @@ public class Program : Singleton<Program>
return;
}
}
// 如果 dimensionId 为 null 或空, newFocusedDimension 和 newFocuseDimensionId 将保持为 null表示清除焦点。
// 如果 dimensionId 为 null 或空, newFocusedDimension 和 newFocusedDimensionId 将保持为 null表示清除焦点。
// 2. 优化:检查是否实际发生变化,避免不必要的更新和事件触发
// 只有当新的ID或新的维度对象引用与当前的不一致时才执行更新。
// 例如,如果 focuseDimensionId 已经是 "someId"FocusedDimension 已经是 "someDimensionObject"
// 再次调用 SetFocusedDimension("someId") 不会触发事件。
// 但如果 focuseDimensionId 是 "someId"FocusedDimension 是 null (因为维度还未注册)
// 而此时注册了 "someId" 对应的维度并调用 SetFocusedDimension("someId")FocusedDimension 将从 null 变为实际对象,
// 这算作一次变化,会触发事件。
if (focuseDimensionId == newFocuseDimensionId && FocusedDimension == newFocusedDimension)
// 逻辑修改1修正属性名 'focuseDimensionId' 为 'focusedDimensionId'
// 逻辑修改1修正局部变量名 'newFocuseDimensionId' 为 'newFocusedDimensionId'
if (FocusedDimensionId == newFocusedDimensionId && FocusedDimension == newFocusedDimension)
{
// Debug.Log($"[Program] SetFocusedDimension: ID '{dimensionId}' already current. No change needed.");
return;
}
if (FocusedEntity != null)
{
FocusedEntity.PlayerControlled = false;
}
// 3. 更新内部状态
focuseDimensionId = newFocuseDimensionId;
FocusedDimensionId = newFocusedDimensionId; // 逻辑修改1修正属性名
FocusedDimension = newFocusedDimension;
// 逻辑修改2功能缺失修复 - 切换维度时,焦点实体应该置为空
// 确保功能一致性:当维度焦点改变(或被清除)时,任何实体焦点也应被清除。
SetFocusedEntity(null);
// 4. 触发事件
OnFocusedDimensionChanged?.Invoke(FocusedDimension);
}
/// <summary>
/// 设置当前聚焦的实体。
/// 这是更改焦点实体的唯一官方入口,并会在实体改变时触发 OnFocusedEntityChanged 事件。
/// </summary>
/// <param name="entity">要设置为焦点的实体实例。如果传入null将清除当前焦点实体。</param>
public void SetFocusedEntity(Entity.Entity entity)
{
// 优化:检查是否实际发生变化,避免不必要的更新和事件触发。
// 如果新的实体与当前焦点实体相同(按引用比较),则不执行任何操作。
if (FocusedEntity == entity)
{
// Debug.Log($"[Program] SetFocusedEntity: Entity '{entity?.name ?? "null"}' already current. No change needed.");
return;
}
// 更新内部状态
FocusedEntity = entity;
// 触发事件,将新的焦点实体(或 null作为参数传递。
OnFocusedEntityChanged?.Invoke(FocusedEntity);
}
}