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

如何在List<>中嵌套存储并执行含子函数的函数?

解决方案

1. 补全MoveLoop类的正确实现

首先需要让MoveLoop继承Function_并持有内部子函数列表,这样才能存储嵌套的子函数序列:

public class MoveLoop : Function_
{
    public List<Function_> InnerSequence { get; private set; }

    public MoveLoop(string id, List<Function_> innerSequence) : base(id)
    {
        InnerSequence = innerSequence;
    }

    // 该方法留空,因为嵌套序列的执行逻辑会单独处理
    public override void Func(Rigidbody2D mainTarget)
    {
    }
}

2. 修正TranslateCodeFromBlocks的MoveLoop处理逻辑

你原代码里有两个核心错误:遍历了父节点而非MoveLoop自身的子节点、switch判断用错了变量。修正后的代码如下:

private List<Function_> TranslateCodeFromBlocks(Transform parent)
{
    List<Function_> sequence_ = new List<Function_>();

    foreach (Transform child in parent)
    {
        var functionName = child.name.Split('_');

        if (functionName[0] == "Function")
        {
            string function = functionName[1];
            switch (function)
            {
                case "MoveRight":
                    sequence_.Add(new MoveRight("MoveRight"));
                    break;
                case "MoveLeft":
                    sequence_.Add(new MoveLeft("MoveLeft"));
                    break;
                case "MoveUp":
                    sequence_.Add(new MoveUp("MoveUp"));
                    break;
                case "MoveDown":
                    sequence_.Add(new MoveDown("MoveDown"));
                    break;

                case "MoveLoop":
                    // 为每个MoveLoop新建独立的内部列表,避免数据污染
                    List<Function_> insideLoop = new List<Function_>();
                    // 遍历当前MoveLoop节点的子节点,而非父节点
                    foreach (Transform loopChild in child)
                    {
                        var loopName = loopChild.name.Split('_');
                        if (loopName[0] == "Function")
                        {
                            string tempLoop = loopName[1];
                            // 用子节点的函数名进行判断,而非外层的"MoveLoop"
                            switch (tempLoop)
                            {
                                case "MoveRight":
                                    insideLoop.Add(new MoveRight("MoveRight"));
                                    break;
                                case "MoveLeft":
                                    insideLoop.Add(new MoveLeft("MoveLeft"));
                                    break;
                                case "MoveUp":
                                    insideLoop.Add(new MoveUp("MoveUp"));
                                    break;
                                case "MoveDown":
                                    insideLoop.Add(new MoveDown("MoveDown"));
                                    break;
                            }
                        }
                    }
                    // 用正确的构造函数创建MoveLoop实例
                    sequence_.Add(new MoveLoop("MoveLoop", insideLoop));
                    break;
            }
        }
    }

    return sequence_;
}

3. 修改MainLoop的Play方法,支持嵌套执行

原Play方法只会执行顶层函数,现在需要识别MoveLoop类型,优先执行其内部子序列:

public class MainLoop
{
    private bool end;
    private bool stop;
    private Rigidbody2D mainTarget;
    private List<Function_> sequence_;

    public MainLoop(Rigidbody2D mainTarget, List<Function_> sequence_)
    {
        this.end = false;
        this.stop = false;
        this.mainTarget = mainTarget;
        this.sequence_ = sequence_;
    }

    public IEnumerator Play()
    {
        foreach (Function_ fun in sequence_)
        {
            // 判断当前函数是否为MoveLoop,优先执行内部子序列
            if (fun is MoveLoop moveLoop)
            {
                foreach (Function_ innerFun in moveLoop.InnerSequence)
                {
                    innerFun.Func(mainTarget);
                    yield return new WaitForSeconds(1);
                }
            }
            else
            {
                // 普通函数直接执行
                fun.Func(mainTarget);
                yield return new WaitForSeconds(1);
            }

            // 原代码中每次执行后直接停止的逻辑会打断序列,这里注释掉,可根据需求调整
            // this.stop = true;
            // Stop();
        }
        end = true;
    }

    public void Stop()
    {
        stop = true;
        // 可添加停止协程的逻辑
    }
}

关键问题总结

  • 构造函数错误:之前未正确定义接收子序列的MoveLoop构造函数,导致实例化失败
  • 节点遍历错误:处理MoveLoop时应遍历自身子节点,而非父节点的子节点
  • 执行逻辑缺失:必须在Play过程中识别MoveLoop类型,递归执行其内部序列,才能实现嵌套执行的需求

内容的提问来源于stack exchange,提问作者blossom rosé

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 14:12:26