Unity中如何用泛型函数处理不同类型ScriptableObject
解决Unity ScriptableObject泛型重复代码问题
问题根源
你当前的泛型函数doSomething<T>(T mySO)无法编译的核心原因是:编译器不知道泛型参数T包含CharacterID或ItemID这类成员——因为未加约束的T可以是任意类型,自然无法识别这些专属属性。哪怕给泛型加where T : ScriptableObject也没用,因为ScriptableObject本身并没有这些ID属性。
解决方案:用接口统一约束
通过定义公共接口来规范所有需要共享逻辑的ScriptableObject,让它们实现统一的属性/方法,再给泛型函数加上接口约束,就能一次性完成通用逻辑编写。
1. 定义公共接口
创建一个包含统一ID属性的接口,把不同SO的专属ID映射到统一名称:
public interface IHasUniqueID { string UniqueID { get; } }
2. 修改ScriptableObject类实现接口
让Character和Item都实现这个接口,将各自的ID属性关联到接口的统一属性上:
// Character类 public class Character : ScriptableObject, IHasUniqueID { public string CharacterID; // 你原有的属性 // 实现接口的统一属性 public string UniqueID => CharacterID; } // Item类 public class Item : ScriptableObject, IHasUniqueID { public string ItemID; // 你原有的属性 // 实现接口的统一属性 public string UniqueID => ItemID; }
3. 编写通用泛型函数
现在可以在工具脚本里写一次通用函数,通过约束确保传入的类型既是ScriptableObject,又实现了接口:
public void DoSomething<T>(T mySO) where T : ScriptableObject, IHasUniqueID { // 直接访问统一的ID属性 print(mySO.UniqueID); // 这里执行所有ScriptableObject都需要的相同操作,比如数据校验、持久化等 ... }
4. 调用方式
不管是Character还是Item实例,都能直接调用这个通用函数:
Character characterSO = Resources.Load<Character>("Characters/Warrior"); DoSomething(characterSO); Item itemSO = Resources.Load<Item>("Items/Potion"); DoSomething(itemSO);
方案优势
- 接口约束让编译器明确知道
T具备统一的UniqueID属性,解决编译报错问题 - 后续新增其他需要相同逻辑的ScriptableObject(比如Skill、Mission),只要实现
IHasUniqueID接口,就能直接复用这个函数,彻底消除重复代码 - 兼顾类型安全和通用性,既保证传入的是ScriptableObject,又能访问统一属性
内容的提问来源于stack exchange,提问作者makeITwork
相关产品推荐
相关产品推荐

