只有在另一种方法完成后才执行方法

时间:2020-10-23 11:27:26

标签: unity3d

我正在制作一个具有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);
        }
    }
}

这里是可以对敌人执行“动作”的类。现在,假设街区只能冻结或诱捕敌人:

public interface IBlockAction{
    void Execute(Enemy enemy);
    void OnActionComplete();
}

public class ActionFreeze : MonoBehaviour, IBlockAction{
    public void Execute(Enemy enemy){
        Debug.Log("Freezing Enemy");
        enemy.Freeze(); // Change enemy's sprite to frozen
        Invoke("OnActionComplete", 2f); // Wait for 2 seconds
    }

    public void OnActionComplete(){
        Debug.Log("Freeze completed");
    }
}

public class ActionTrap : MonoBehaviour, IBlockAction{
    public void Execute(Enemy enemy){
        Debug.Log("Trapping Enemy");
        enemy.Trap(); // Change enemy's sprite to trapped
        Invoke("OnActionComplete", 3f); // Wait for 3 seconds
    }

    public void OnActionComplete(){
        Debug.Log("Trap completed");
    }
}

这可以按预期工作,但是由于ExecuteActions具有for循环,因此所有操作都立即执行。敌人的“冻结”精灵将根本不可见,因为下一个动作将立即执行。日志的外观如下:

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

只有在调用当前动作的.Execute()后才能调用下一个动作的OnActionComplete(),这样才能显示敌人的“冻结”精灵2秒钟,然后将敌人的精灵变为“陷阱” ”,然后显示3秒钟。日志应如下所示:

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

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

1 个答案:

答案 0 :(得分:2)

您只需要等待这样的协程..

同时完成所有操作:

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");
    }
}