Unity3d 仅在另一个方法完成后执行该方法

Unity3d 仅在另一个方法完成后执行该方法,unity3d,Unity3d,我正在制作一个有20个“方块”的棋盘游戏的原型,当按下空格键时,一个敌人角色一次跳过一个方块(从1到20)。如果敌人成功进入第20格,那就是赢家 每个区块都有不同的障碍物,敌人可以被冻结、烧毁、困住、融化、传送等等。有些区块可以有多个障碍物 我试图为每个障碍创建一个单独的类,并使用.AddComponent将它们添加到不同的块中。当一个敌人降落在一个区块上时,该区块将通过该区块上增加的障碍物,并相应地惩罚敌人 这是块预制类: public class CompositeBlock : MonoB

我正在制作一个有20个“方块”的棋盘游戏的原型,当按下空格键时,一个敌人角色一次跳过一个方块(从1到20)。如果敌人成功进入第20格,那就是赢家

每个区块都有不同的障碍物,敌人可以被冻结、烧毁、困住、融化、传送等等。有些区块可以有多个障碍物

我试图为每个障碍创建一个单独的类,并使用
.AddComponent
将它们添加到不同的块中。当一个敌人降落在一个区块上时,该区块将通过该区块上增加的障碍物,并相应地惩罚敌人

这是块预制类:

public class CompositeBlock : MonoBehaviour{
    void Start(){
        gameObject.AddComponent<ActionFreeze>();
        gameObject.AddComponent<ActionTrap>();
    }

    // This is called when enemy steps on the block
    public void ExecuteActions(Enemy enemy){
        Debug.Log("Enemy has landed on this block");
        IBlockAction[] actionArray = GetComponents<IBlockAction>();
        foreach(IBlockAction action in actionArray){
            action.Execute(enemy);
        }
    }
}
这可以按预期工作,但由于
ExecuteActions
有一个for循环,因此所有操作都会立即执行。敌人的“冻结”精灵将完全看不见,因为下一个动作将立即执行。下面是日志的外观:

Enemy has landed on this block
Freezing Enemy
Trapping Enemy
Freeze completed
Trap completed
如何才能在调用当前操作的
OnActionComplete()
后调用下一个操作的
.Execute()
,以便显示敌人的“冻结”精灵2秒,然后将敌人的精灵更改为“陷阱”,然后显示3秒。日志应如下所示:

Enemy has landed on this block
Freezing Enemy
Freeze completed
Trapping Enemy
Trap completed

显示精灵的持续时间(冻结或捕获)并不重要,因为可以播放动画而不是精灵更改。无论敌方(冻结或被困)状态如何显示-
OnActionComplete()
应在完成后调用。

您只需等待这样的协同程序即可

同时执行以下操作:

StartCoroutine(A());
StartCoroutine(B());
StartCoroutine(C());
StartCoroutine(D());
按顺序逐个执行这些操作:

yield return StartCoroutine(A());
yield return StartCoroutine(B());
yield return StartCoroutine(C());
yield return StartCoroutine(D());
这里有一个完整的示例可以粘贴

using UnityEngine;
using System.Collections;
public class Examp : MonoBehaviour
{
    void Start()
    {
        StartCoroutine(Test());
    }
    IEnumerator Test()
    {
        yield return StartCoroutine(A());
        yield return StartCoroutine(B());
        yield return StartCoroutine(C());
    }

    IEnumerator A()
    {
        yield return new WaitForSeconds(1f); Debug.Log("..A");
    }
    IEnumerator B()
    {
        yield return new WaitForSeconds(1f); Debug.Log("..B");
    }
    IEnumerator C()
    {
        yield return new WaitForSeconds(1f); Debug.Log("..C");
    }
}

你就等着这样的合作吧

同时执行以下操作:

StartCoroutine(A());
StartCoroutine(B());
StartCoroutine(C());
StartCoroutine(D());
按顺序逐个执行这些操作:

yield return StartCoroutine(A());
yield return StartCoroutine(B());
yield return StartCoroutine(C());
yield return StartCoroutine(D());
这里有一个完整的示例可以粘贴

using UnityEngine;
using System.Collections;
public class Examp : MonoBehaviour
{
    void Start()
    {
        StartCoroutine(Test());
    }
    IEnumerator Test()
    {
        yield return StartCoroutine(A());
        yield return StartCoroutine(B());
        yield return StartCoroutine(C());
    }

    IEnumerator A()
    {
        yield return new WaitForSeconds(1f); Debug.Log("..A");
    }
    IEnumerator B()
    {
        yield return new WaitForSeconds(1f); Debug.Log("..B");
    }
    IEnumerator C()
    {
        yield return new WaitForSeconds(1f); Debug.Log("..C");
    }
}

我已经更新了这个问题,以便更清楚。我确实使用协同程序,但我不确定在这种情况下如何使用它。幸运的是,这很容易,我已经输入了答案@yeti!cheers@Yeti请注意,我的调用
Test()
有时人们会费心为要顺序调用的项创建一个堆栈(或您在C#中喜欢的任何特性)。实际上,我发现在大多数游戏中,最好只在例程中显式地写出来,比如
TakeOffSequence
WinSequence
或其他什么。几乎所有的游戏都有许多类似于“测试”的调用来表达一系列发生的事情!谢谢,我已经更新了这个问题,这样问题就更清楚了。我确实使用协同程序,但我不确定在这种情况下如何使用它。幸运的是,这很容易,我已经输入了答案@yeti!cheers@Yeti请注意,我的调用
Test()
有时人们会费心为要顺序调用的项创建一个堆栈(或您在C#中喜欢的任何特性)。实际上,我发现在大多数游戏中,最好只在例程中显式地写出来,比如
TakeOffSequence
WinSequence
或其他什么。几乎所有的游戏都有许多类似于“测试”的调用来表达一系列发生的事情!Cheers@Fattie
CompositeBlock
最终将成为一个预制块-我肯定不会复制/粘贴20个块中的每一个块,而不首先将它们作为预制块:D。我已经更新了问题,以便它更清晰。@Fattie我认为这很适合unity。通过这种方式,我可以创建像
ActionMelt
ActionTeleport
ActionKill
ActionShrink
等类,只需通过执行
gameObject.AddComponent()
等操作将它们添加到不同的块预制中。当敌人在该块上着陆时,这些动作将自动对其执行@Fattie我认为“冻结敌人”内部发生的事情是不相关的,因为日志将输出相同的日志序列,即使没有调用该方法。啊!我想我终于明白你在问“雪人”什么了!在unity中很容易。请注意,在几乎所有unity项目中,您的
敌人.Trap()
几乎肯定是一个协同程序。任何需要时间的事情,都是协同工作!顺便说一句,你可能会喜欢使用Tweeng,这是一个简单的扩展。它在很大程度上消除了几乎所有的简单动画(音频、位置等等)@Fattie
CompositeBlock
最终将成为一个预制块-我当然不会复制/粘贴20个块中的每一个块,而不首先将它们制作成一个预制块:D。我已经更新了这个问题,以便它更清晰。@Fattie我认为这很适合unity。通过这种方式,我可以创建像
ActionMelt
ActionTeleport
ActionKill
ActionShrink
等类,只需通过执行
gameObject.AddComponent()
等操作将它们添加到不同的块预制中。当敌人在该块上着陆时,这些动作将自动对其执行@Fattie我认为“冻结敌人”内部发生的事情是不相关的,因为日志将输出相同的日志序列,即使没有调用该方法。啊!我想我终于明白你在问“雪人”什么了!在unity中很容易。请注意,在几乎所有unity项目中,您的
敌人.Trap()
几乎肯定是一个协同程序。任何需要时间的事情,都是协同工作!顺便说一句,你可能会喜欢使用Tweeng,这是一个简单的扩展。它在很大程度上消除了几乎所有的简单动画(音频、位置等)