【问题标题】:Calling a list of coroutines one after another in unity统一调用一系列协程
【发布时间】:2022-08-03 01:22:26
【问题描述】:

C# 和 unity 的新手,我试图做的是让一个单元一个接一个地执行一系列动作,并且这个序列可能会被中断以执行更紧急的动作序列。

例如,对于一个单位类型的樵夫,他的动作顺序可能是:

  1. 查找首页
  2. GoHome
  3. FindTreeToCut
  4. 转到树
  5. cutTree
  6. 收集木材
  7. GoHome

    现在,当他在做这一系列动作时,他可能会被一些更重要的序列打断,比如 runAway,动作如下:

    1. 查找安全空间
    2. 转到安全空间
    3. HideInSafeSpace

      在阅读了一点之后发现 couroutines 可能是一个很好的候选者,这就是我现在所拥有的:

      单位.cs:

        public Dictionary<string, Action> actions;
      
        private void Awake() {
          initActions();
          Task task = TaskManager.Instance.getTask(unit);
          UnitManager.Instance.performTask(unit, task);
      
        }
        private void initActions() {
              actions = new Dictionary<string, Action>() {
                  { \"GoHome\", () => GoHome()},
                  { \"FindHome\", () => FindHome()},
                  { \"FindTreeToCut\", () => FindTreeToCut()},
                  { \"CutTree\", () => CutTree()},
                   // and so on
              };
          }
          public void GoHome() {
            //some code
          }
      
         //More functions 
      
      

      单元管理器.cs

      //**Not sure how to implement this:**
      public void performTask(Unit unit, Task task) {
        for(String action in task.actions) {
          // start action
          StartCoroutine(unit.actions[action]());//? 
          // wait for coroutine to finish then continue loop
      
        }
      
      }
      

      任务管理器.cs

      public getTask() {
        //returns some task
      }
      //approx defination..
      public class Task {
        public string id;
        public int weight;
        public List<string> actions
      }
      

      现在让我们暂时忘记中断当前序列,因为我认为这是一个不同的问题,现在试图了解实现 UnitManager.performTask() 的最佳方法是什么,我包括了中断序列方面,以防它影响 performTask无论如何执行

    标签: c# unity3d coroutine


    【解决方案1】:

    您可以使用以下行等待协程完成:

    yield return StartCoroutine(unit.actions[action]());

    请记住,这仅在此代码位于协程中时才有效,因此performTask 应该是协程,或者您可以为此创建代理方法。第一种情况如下所示:

    public IEnumerator performTask(Unit unit, Task task) 
    {
      foreach (String action in task.actions) 
      {
        // start action
        yield return StartCoroutine(unit.actions[action]());
      }
    }
    

    第二种情况是代理方法:

    public void performTask(Unit unit, Task task) 
    {
        StartCoroutine(PerformAll(unit, task));
    }
    
    private IEnumerator PerformAll(Unit unit, Task task) 
    {
        foreach (String action in task.actions) 
        {
            // start action
            yield return StartCoroutine(unit.actions[action]());
        }
    }
    

    有一个非常重要的细节,为了让协程延迟按预期工作,请确保它们仅在工作结束时停止

    【讨论】:

      猜你喜欢
      • 2014-10-29
      • 1970-01-01
      • 1970-01-01
      • 2013-04-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-28
      • 1970-01-01
      • 2023-03-05
      相关资源
      最近更新 更多