如何在启动脚本2之前等待脚本1中的功能完成?

时间:2018-10-17 23:37:33

标签: c# unity3d

在Unity中,我有GameObjectName,其中附有脚本1和脚本2。 Script1是这样的IEnumerator。

public IEnumerator Sunglasses()
{
    // Do stuff
}

Script2看起来像这样。

public void Start()
{
    Function1();
    String blah = "Things";
    Function2();
    StartCoroutine(Routine2());
    StartCoroutine(Routine3());
}

我需要脚本1才能完成脚本2之前的太阳镜。如果我尝试从Script2访问GameObjectName.Script1,Unity说它不存在。在启动脚本2之前,如何确保脚本1完成?

2 个答案:

答案 0 :(得分:1)

您可以尝试研究事件或观察者模式。我一直在使用的是后者,它允许我添加带有字符串标识符的回调。对于事件,您可以执行类似的操作

public static event System.Action onSunglassesCompleted;
public IEnumerator Sunglasses()
{
    //Sunglasses logic here

    //if there is a listener to the event, call it
    if(onSunglassesCompleted != null)
    {
        onSunglassesCompleted();
    }
}

然后在Script2上,只需将侦听器添加到事件中

void Start()
{
    Script1.onSunglassesCompleted += DoThisAfterSunglasses;
}

//This will be called in Script1
void DoThisAfterSunglasses()
{
    //Make sure you do this to avoid memory leaks or missing reference errors once Sprite1 is destroyed
    Script1.onSunglassesCompleted -= DoThisAfterSunglasses;

    Function1();
    String blah = "Things";
    Function2();
    StartCoroutine(Routine2());
    StartCoroutine(Routine3());
}

在事件中可以避免泄漏的一件事是在调用它后将其设置为null。

if(onSunglassesCompleted != null)
{
    onSunglassesCompleted();
    onSunglassesCompleted = null;
}

答案 1 :(得分:1)

您可以在脚本1中添加一个布尔变量,完成Sunglasses函数调用后,将其设置为true

脚本1:

public bool isDone = false;

public IEnumerator Sunglasses()
{
    // Do stuff

    isDone = true;
}

脚本2:

然后在Script2中,可以使Start函数成为协程或IEnumerator而不是void函数。此后,您可以等待isDone每帧都为真。

public bool isDone;
Script1 script1Ref;

public IEnumerator Start()
{
    GameObject s1Obj = GameObject.Find("GameObjectScript1IsAttachedTo");
    script1Ref = s1Obj.GetComponent<Script1>();

    //Wait here until we are done
    while (!script1Ref.isDone)
        yield return null;

    //Done Waiting, now continue with the rest of the code
    Function1();
    String blah = "Things";
    Function2();
    StartCoroutine(Routine2());
    StartCoroutine(Routine3());
}

最后,如果您还需要确保在执行Script2的Update函数之前执行Script1的工作,只需检查isDone变量并返回是否仍然为false

void Update()
{
    //Return if script 1 is not done
    if (!script1Ref.isDone)
        return;

    //The rest of your code below


}

请注意,您要StartCoroutine(Routine3())等待StartCoroutine(Routine2())完成,必须让步。

StartCoroutine(Routine3())替换为yield return StartCoroutine(Routine3())