如何在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é
相关产品推荐
相关产品推荐

