Unity中设置BattleshipPart属性后battleshipParts.Count异常增长问题
问题描述
在ScriptableObject.Awake方法中执行以下仅循环一次的代码后,battleshipParts.Count返回2:
for (byte i = 0; i < 1; i++) { var battleshipPart = CreateInstance<BattleshipPart>(); battleshipPart.battleshipData = this; battleshipParts.Add(battleshipPart); }
通过调试器逐行排查发现:仅执行完battleshipPart.battleshipData = this;这一行后,battleshipParts.Count就已经变为1。
其中battleshipPart.battleshipData用于存储战舰父对象的引用,BattleshipPart类定义如下:
public class BattleshipPart : ScriptableObject { public Vector2 gridPosition; public BattleshipData battleshipData; public bool isHit = false; }
已知battleshipParts列表仅在上述代码中被修改,为何设置属性后列表会自动添加元素并增长?
问题原因与解决办法
原因
这是Unity Editor序列化机制导致的自动行为:
- 当
battleshipParts是BattleshipData(即代码中的this)的public可序列化列表,且BattleshipPart中存在指向BattleshipData的public引用字段时,Unity Editor会在你修改battleshipPart.battleshipData的引用后,自动将该battleshipPart实例添加到battleshipParts列表中,以此维护对象间的引用关系。 - 该行为仅在Unity Editor模式下触发,Runtime运行时不会出现。
解决办法
- 禁止序列化列表:如果
battleshipParts不需要在Inspector中显示或序列化,给它加上[NonSerialized]特性,阻止Unity的自动序列化逻辑:[NonSerialized] public List<BattleshipPart> battleshipParts; - 手动去重后添加:如果需要保留序列化,在执行
Add前先检查列表中是否已存在该实例,避免重复添加:if (!battleshipParts.Contains(battleshipPart)) { battleshipParts.Add(battleshipPart); } - Runtime模式下验证:这个问题仅存在于Editor环境,打包后或进入Play Mode运行时,该自动添加的行为会消失,代码会正常执行一次Add操作。
内容的提问来源于stack exchange,提问作者Phillip Zoghbi
相关产品推荐
相关产品推荐

