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

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的对象:

  1. 点击operations列表的+号,选择你定义的操作类型(如TranslateOperation)
  2. 直接在列表项中输入该操作的参数(如translation向量)
  3. 运行时无需绑定GameObject,动态传入目标Transform即可执行

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 22:45:32