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

GOAP系统中Action子类的浅拷贝函数实现方案咨询

实现GOAP Action子类的自动浅拷贝(无需手动重写Copy方法)

核心思路是利用反射在父类的通用Copy方法中动态识别当前实例的实际子类类型,创建对应子类的实例并完成字段浅拷贝,这样所有子类无需单独重写Copy方法。

以下以C#(Unity中GOAP的常用实现语言)为例给出具体实现:

1. 父类Action中实现通用Copy逻辑

public class Action
{
    // 示例规划逻辑字段
    public string ActionName;
    public float ExecutionCost;

    public virtual Action Copy()
    {
        // 获取当前实例的真实类型(子类类型)
        Type instanceType = GetType();
        // 创建对应类型的新实例(要求子类有无参构造函数)
        Action newAction = (Action)Activator.CreateInstance(instanceType);

        // 获取该类型所有公共实例字段(包括父类继承的字段)
        FieldInfo[] allFields = instanceType.GetFields(BindingFlags.Public | BindingFlags.Instance | BindingFlags.FlattenHierarchy);

        // 遍历拷贝所有字段值
        foreach (FieldInfo field in allFields)
        {
            object fieldValue = field.GetValue(this);
            field.SetValue(newAction, fieldValue);
        }

        return newAction;
    }
}

2. 子类直接继承,无需额外编写Copy方法

public class EatFoodAction : Action
{
    // 子类自定义字段
    public int FoodRestorationAmount;
    public bool RequiresCookedFood;
}

3. 使用示例

// 创建原始子类实例
EatFoodAction originalEatAction = new EatFoodAction 
{ 
    ActionName = "Eat Cooked Meat", 
    ExecutionCost = 2.0f, 
    FoodRestorationAmount = 15, 
    RequiresCookedFood = true 
};

// 拷贝得到同类型的实例
EatFoodAction copiedEatAction = (EatFoodAction)originalEatAction.Copy();

注意事项

  • 确保所有子类都有无参构造函数,如果子类只有带参构造,需要修改Activator.CreateInstance的调用,传入对应的构造参数。
  • 这是浅拷贝:如果字段是引用类型(比如自定义类实例),拷贝的是对象引用,原实例和拷贝实例会共享该引用对象。GOAP动作通常以值类型字段为主,这种场景下浅拷贝完全够用;若需要深拷贝,需额外针对引用类型字段做递归拷贝处理。
  • 其他语言(如Java)的实现逻辑一致:通过getClass()获取实际类型,newInstance()创建实例,再通过反射遍历字段完成值拷贝。

内容的提问来源于stack exchange,提问作者Resistnz

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 11:03:36