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
相关产品推荐
相关产品推荐

