Unity中可序列化带参函数的语法实现问题
解决方案
你的核心问题在于直接序列化委托无法关联编辑器中设置的参数——委托本身不存储参数状态,参数是保存在EditorTranslate/EditorRotateAround这类实例里的。以下是适配Unity编辑器和运行时的完整实现方案:
1. 调整核心结构:用可序列化操作类存储参数
放弃直接存储委托,转而保存带参数的操作实例(这些实例可在Unity编辑器中直接编辑参数)。
方式一:适配Unity 2020.1+(推荐,支持接口序列化)
利用Unity的[SerializeReference]特性序列化接口实例,编辑器中可直接选择操作类型并编辑参数:
// 定义操作接口 public interface ITransformOperation { void Execute(Transform target); } // 平移操作:带可编辑参数 [Serializable] public class TranslateOperation : ITransformOperation { public Vector3 translation; // 编辑器中可直接输入该参数 public void Execute(Transform target) { target.Translate(translation); } } // 绕点旋转操作:带可编辑参数 [Serializable] public class RotateAroundOperation : ITransformOperation { public Vector3 pivotPoint; public float angle; public void Execute(Transform target) { target.RotateAround(pivotPoint, Vector3.forward, angle); } } // 存储操作序列的数据结构 [Serializable] public class OperationSequence { [SerializeReference] public List<ITransformOperation> operations = new List<ITransformOperation>(); }
方式二:适配旧版本Unity(无SerializeReference)
用抽象基类代替接口,同样支持编辑器参数编辑:
[Serializable] public abstract class BaseTransformOperation { public abstract void Execute(Transform target); } [Serializable] public class TranslateOperation : BaseTransformOperation { public Vector3 translation; public override void Execute(Transform target) { target.Translate(translation); } } [Serializable] public class RotateAroundOperation : BaseTransformOperation { public Vector3 pivotPoint; public float angle; public override void Execute(Transform target) { target.RotateAround(pivotPoint, Vector3.forward, angle); } } [Serializable] public class OperationSequence { public List<BaseTransformOperation> operations = new List<BaseTransformOperation>(); }
2. 运行时调用:将操作转换为委托或直接执行
直接执行操作
无需转换委托,直接遍历操作列表调用方法:
// 获取操作序列实例 OperationSequence sequence = GetComponent<OperationSequence>(); // 目标Transform(运行时动态指定,无需编辑器绑定) Transform targetTransform = ...; foreach (var op in sequence.operations) { op.Execute(targetTransform); }
转换为自定义委托(CallWrapper)
如果需要将操作存入委托列表,可直接通过方法组转换:
// 自定义委托(和Action<Transform>等价) public delegate void CallWrapper(Transform target); // 转换操作列表为委托列表 List<CallWrapper> wrapperList = new List<CallWrapper>(); foreach (var op in sequence.operations) { // 直接将实例的Execute方法转换为CallWrapper委托 wrapperList.Add(op.Execute); } // 运行时调用委托 foreach (var wrapper in wrapperList) { wrapper(targetTransform); }
编辑器操作说明
在Unity Inspector中,选中包含OperationSequence的对象:
- 点击
operations列表的+号,选择你定义的操作类型(如TranslateOperation) - 直接在列表项中输入该操作的参数(如
translation向量) - 运行时无需绑定GameObject,动态传入目标Transform即可执行
内容的提问来源于stack exchange,提问作者Erymenn
相关产品推荐
相关产品推荐

