You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 02:58:28