【发布时间】:2020-08-05 16:06:29
【问题描述】:
我在做什么
我正在为我的 Unity 2D RPG 游戏开发一些原型系统(库存、设备……)。我遇到了玩家持有的List<Stat> stats 的问题。
我要做什么
如果玩家捡起一件物品,它会直接装备(目前)。该项目可以包含一个List<StatModifier> modifiers,它被添加到PlayerStats。每当装备一个物品时,就会触发以下委托,这是EquipmentSystem 类(单例)的一部分。
public delegate void OnEquipmentChanged(EquipableItem newItem, EquipableItem oldItem);
public OnEquipmentChanged onEquipmentChanged;
PlayerStats 类在创建时订阅此委托。
// Start is called before the first frame update
void Start()
{
List<StatModifier> empty = new List<StatModifier>();
// Initialize Stats
health = new Stat(100, empty, StatType.HP);
mana = new Stat(200, empty, StatType.MANA);
// Add stats to list
stats = new List<Stat>();
stats.Add(health);
stats.Add(mana);
// Subscribe new Function
EquipmentSystem.instance.onEquipmentChanged += OnEquipmentChanged;
}
OnEquipmentChanged()-方法然后通过从旧项目中删除 StatModifiers 并从新项目中添加 StatModifiers 来重新计算玩家的统计数据。这些统计信息存储在PlayerStats 类中的private List<Stat> stats 中。
我的问题是什么
OnEquipmentChanged()-方法被正确调用,但它没有按预期工作。仅当StatType 与Stat 的StatType 相同时,才应添加项目的StatModifiers。所以HP应该只加到HP上,Mana只加到Mana上等等。 StatType 是一个公共枚举顺便说一句。但该功能目前将所有StatModifiers 添加到玩家拥有的所有Stats 中。函数如下:
void OnEquipmentChanged(EquipableItem newItem, EquipableItem oldItem)
{
if (oldItem != null) { //remove modifiers }
if (newItem != null)
{
// add modifiers of new item if new item exists
foreach (StatModifier item_sm in newItem.GetStatModifiers())
{
int index = stats.FindIndex(stat => stat.GetStatType() == item_sm.GetStatType());
Debug.Log("Found stat " + stats[index].GetStatType());
stats[index].AddModifier(item_sm);
Debug.Log("Added " + item_sm.GetModifierValue() + " " + (StatType)item_sm.GetStatType() + " to " + stats[index].GetStatType());
}
}
}
设置断点显示,在第一次迭代之后,StatModifier 已经被添加到 Stats 中。这是为什么呢?
编辑 1:这是用于将 StatModifier 添加到任何 Stat 的(非常简单的)代码。每个Stat 都有自己的StatModifier 私有列表。
public void AddModifier(StatModifier modifier)
{
if (modifier != null)
{
modifiers.Add(modifier);
}
}
谢谢!
【问题讨论】:
-
我强烈建议将玩家基础统计数据保留为您的基础状态并根据需要计算有效统计数据,而不是让您的状态包含调整后的统计数据。如果您将基本统计数据保持为状态,那么有问题的项目只会在装备时影响事物。如果您保留调整后的统计数据,那么有问题的物品会具有永久效果(每次您重新装备它时可能会叠加)。
-
另外,请不要将单例用于此目的。有时您可能需要另一个库存来存放其他物品,更不用说未经授权的人可能会弄乱您的库存。一般来说,可变的全局状态是不好的。
-
您是否尝试过在第一次迭代之前设置断点?每次迭代我只看到 1 个索引访问,所以我认为它一定是其他东西弄乱了修饰符。
-
@BenVoigt:您能详细说明一下吗?
Stat的最终值由其基值和存储在其私有列表中的所有StatModifiers的总和组成。返回该最终值的方法使用局部变量,因此仅在需要时才进行计算。但为了进行计算,我需要更新我的StatModifiers 列表,对吗?