Unity中如何从物品数据库获取自定义类的独立副本?
解决Unity中自定义类实例独立副本的问题
问题根源很明确:Equipment是引用类型,你从数据库返回的是同一个对象的引用,所以背包里的两把剑本质上是同一个实例,修改其中一个的属性必然会影响另一个。要实现独立升级,必须每次从数据库获取时返回原对象的深拷贝/独立副本。
下面提供三种常用的实现方式:
1. 实现ICloneable接口(手动拷贝属性)
在你的Equipment类中实现ICloneable接口,手动编写克隆逻辑,确保所有属性都被复制到新实例:
public class Equipment : Item, ICloneable { public int itemLevel; // 你的其他装备属性(比如攻击力、耐久度等) public int attackPower; // 实现Clone方法 public object Clone() { // 创建新的Equipment实例 Equipment clonedEquip = new Equipment(); // 复制基类Item的属性 clonedEquip.id = this.id; clonedEquip.itemName = this.itemName; // 其他基类属性... // 复制Equipment子类的属性 clonedEquip.itemLevel = this.itemLevel; clonedEquip.attackPower = this.attackPower; // 其他子类属性... return clonedEquip; } }
然后修改数据库的获取方法,返回克隆后的对象:
public Item GetEquipment(int id) { // 强制转换为Item类型返回 return (Item)equipment[id].Clone(); }
2. 使用复制构造函数
在Equipment类中定义一个以自身类型为参数的构造函数,在构造时完成属性复制:
public class Equipment : Item { public int itemLevel; public int attackPower; // 复制构造函数 public Equipment(Equipment original) { // 复制基类属性 this.id = original.id; this.itemName = original.itemName; // 其他基类属性... // 复制子类属性 this.itemLevel = original.itemLevel; this.attackPower = original.attackPower; // 其他子类属性... } }
修改数据库方法:
public Item GetEquipment(int id) { return new Equipment(equipment[id]); }
3. 序列化反序列化实现深拷贝(适合属性较多的情况)
利用Unity的JsonUtility进行序列化和反序列化,自动完成所有属性的拷贝,无需手动编写每个属性的复制逻辑:
public Item GetEquipment(int id) { Equipment original = equipment[id]; // 将原对象序列化为JSON字符串 string jsonData = JsonUtility.ToJson(original); // 将JSON反序列化为新的Equipment实例 Equipment clonedEquip = JsonUtility.FromJson<Equipment>(jsonData); return clonedEquip; }
注意事项
- 如果你的
Equipment或Item类中包含引用类型的属性(比如自定义的Stat类对象),前两种手动拷贝方式需要对这些引用类型也进行克隆,否则会出现浅拷贝导致的引用共享问题;而序列化反序列化的方式会自动处理深拷贝。 - 确保你的类和所有需要拷贝的属性都标记了
[Serializable]特性,否则JsonUtility无法正常序列化。
内容的提问来源于stack exchange,提问作者Draaken
相关产品推荐
相关产品推荐

