Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/unity3d/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 通常与通过事件处理程序调用时,协同程序的行为不同_C#_Unity3d_Admob - Fatal编程技术网

C# 通常与通过事件处理程序调用时,协同程序的行为不同

C# 通常与通过事件处理程序调用时,协同程序的行为不同,c#,unity3d,admob,C#,Unity3d,Admob,当按下UI按钮运行时,以下协同程序将正常运行并显示“3…2…1…0”,然后消失。但是,当作为事件处理程序委托HandleRewardBasedVideoClosed(AdMob的一部分)的一部分运行时,它将显示“3…1…”,然后消失。就我的一生而言,我不明白为什么用这两种不同的方式来称呼它会有不同的行为 public IEnumerator Countdown() { timeLeft = 3; while (timeLeft >= 0) { count

当按下UI按钮运行时,以下协同程序将正常运行并显示“3…2…1…0”,然后消失。但是,当作为事件处理程序委托HandleRewardBasedVideoClosed(AdMob的一部分)的一部分运行时,它将显示“3…1…”,然后消失。就我的一生而言,我不明白为什么用这两种不同的方式来称呼它会有不同的行为

public IEnumerator Countdown() {

    timeLeft = 3;

    while (timeLeft >= 0) {
        countdownText.text = timeLeft.ToString();
        yield return new WaitForSecondsRealtime(1.0f);
        timeLeft--;
    }

    if (timeLeft < 0) {
        countdownText.gameObject.SetActive (false);
    }

}

public void HandleRewardBasedVideoClosed(object sender, EventArgs args){

    MonoBehaviour.print("HandleRewardBasedVideoClosed event received");

    if (reward) {
        StartCoroutine ( gm.Countdown ());
    } else
        SceneManager.LoadScene (SceneManager.GetActiveScene ().name);

}
public IEnumerator倒计时(){
时间间隔=3;
while(timeLeft>=0){
countdownText.text=timeLeft.ToString();
收益率返回新WaitForSecondRealTime(1.0f);
时间限制--;
}
如果(时间间隔<0){
countdownText.gameObject.SetActive(false);
}
}
public void HandleRewardBasedVideoClosed(对象发送方、事件参数){
MonoBehavior.print(“收到HandleRewardBasedVideoClosed事件”);
如果(奖励){
开始例行程序(gm.倒计时());
}否则
SceneManager.LoadScene(SceneManager.GetActiveScene().name);
}

我怀疑这一点。是不是倒计时实际上执行“3.2..2.1..0.SetActive(false)”的速度太快,以至于您没有看到它运行两次协同路由?如果是,以下代码将解决该特定问题(如果是这种情况):


timeLeft不应该是协程范围中的局部变量吗?可能在同一个循环中,倒计时被调用了两次,由于变量不是局部变量,所以两个例程都在递减。我可以知道你的时间是不是快了两倍?就像是用1.5秒数到3秒Admob@MatrixTai我没有意识到,但是的,时间似乎是过去的两倍,所以它只计算3和1。为什么会出现这种情况?我以前没有使用admob,所以我希望您先再试一次。使用
WaitForSeconds
而不是
waitforsecondrealtime
。查看问题是否已解决。打印语句是否触发两次?您可以通过将
timeLeft
设置为局部变量而不是成员变量来改进此问题。不这样做似乎没有必要,也很危险(这可能也是他问题的根源之一)。我喜欢使用for循环而不是while来确保它不会跳过。我回家后会试试这个。我仍然很好奇,为什么当运行一个按钮而不是delegates时,它的行为会有所不同,因为您已经有了一个事件处理程序。你的广告经理可能会因为“无论什么”的原因两次召集活动。此外,当您按下按钮时,您是否正在调用协同程序,然后广告经理也会调用该例程?您在自己和测试之后清理了代码吗?没有进一步的信息,很难说,但这些都是可能的原因。事件或方法不会无缘无故地被调用两次。
private bool isCountingDown = false;

public IEnumerator Countdown()
{
    if ( isCountingDown ) return;
    isCountingDown = true;

    for ( int timeLeft = 3; timeLeft >= 0; timeLeft-- )
    {
        countdownText.text = timeLeft.ToString();
        yield return new WaitForSecondsRealtime(1.0f);
    }

    countdownText.gameObject.SetActive (false);
    isCountingDown = false;
}

public void HandleRewardBasedVideoClosed(object sender, EventArgs args)
{
    MonoBehaviour.print("HandleRewardBasedVideoClosed event received");
    if (reward) {
        // This might be a redundant check, as we're doing this in the 
        // Coroutine, but we may as well not go through the process of 
        // calling it in the first place.
        if (! isCountingDown ) StartCoroutine ( gm.Countdown ());
    } else
        SceneManager.LoadScene (SceneManager.GetActiveScene ().name);
}