情景
我的情景是,在 StartUI 中控制进度条更新,在 StartGameController 中控制进度条的目标,在 AppController 中设置进度条的目标
StartGameController 看上去与 AppController 的功能重合,是因为 AppController 可能还管理着 HomeController, GameController 之类的脚本。AppController 是负责协调这些 Controller 之间的顺序的
现在的问题是,我在 AppController 中使用协程等待 StartUI 中的 Tween 的 WaitForCompletion 失败了,协程在我 yield return XXX.WaitForCompletion(); 这一步直接通过了,但是 Tween 本身还没有结束
AppController.cs
StartGameController.Instance.SetProgress(100);
yield return new WaitForEndOfFrame();
Debug.Log(StartGameController.Instance.startUI.ProgressTween.IsComplete());
yield return StartGameController.Instance.startUI.ProgressTween.WaitForCompletion();
打印出来是 False
StartGameController.cs
using System.Collections;
using DG.Tweening;
using UnityEngine;
using Universal;
public class StartGameController : Singleton<StartGameController>
{
[SerializeField]
public StartUI startUI;
public void SetProgress(int progress)
{
startUI.Progress = progress;
}
}
StartUI.cs
using System;
using System.Collections;
using System.Collections.Generic;
using DG.Tweening;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
public class StartUI : MonoBehaviour
{
[SerializeField]
private GameObject panel;
public GameObject Panel => panel;
[SerializeField]
private Slider slider;
[SerializeField]
private Text sliderText;
private int progress = 0;
public int Progress
{
get => progress;
set
{
int target = value;
progressTween?.Pause();
progressTween = DOTween.To(() => progress, value => progress = value, target, 0.5f);
progressTween.Play();
Debug.Log(progressTween.IsComplete());
}
}
private Tween progressTween;
public Tween ProgressTween => progressTween;
private void Update()
{
sliderText.text = string.Format("{0}%", progress);
slider.value = (float)progress / 100f;
}
}
假设我改成 AppController 会启动 StartUI 中的协程
AppController.cs
yield return StartCoroutine(StartGameController.Instance.SetProgress(100));
StartUI.cs
using System.Collections;
using DG.Tweening;
using UnityEngine;
using Universal;
public class StartGameController : Singleton<StartGameController>
{
[SerializeField]
public StartUI startUI;
public IEnumerator SetProgress(int progress)
{
startUI.Progress = progress;
yield return startUI.ProgressTween.WaitForCompletion();
}
}
结果仍然是 AppController 中直接通过了进度条的等待协程
假如我再把所有的都拆开,在 AppController 中创建和等待 Tween
AppController.cs
Tween progressTween = DOTween.To(() => StartGameController.Instance.Process,
value => StartGameController.Instance.Process = value, 100, 0.5f);
progressTween.Play();
yield return new WaitForSeconds(1f);
yield return progressTween.WaitForCompletion();
Debug.Log(progressTween == null);
Debug.Log(progressTween.IsComplete());
StartUI.cs
using System.Collections;
using DG.Tweening;
using UnityEngine;
using Universal;
public class StartGameController : Singleton<StartGameController>
{
[SerializeField]
private StartUI startUI;
public int Process
{
get => startUI.Progress;
set
{
startUI.Progress = value;
}
}
}
结果也还是没有等待
原因
其实我上面写的都没有错
只是我的异步表现是一个进度条在移动
但是我唤醒进度条移动之后又加载了一个新场景 Additive 方式的
这个新场景的 UI 直接把我的旧场景的 UI 给覆盖掉了,所以我看不到旧场景的 UI 的进度条的情况
这就给我一种错觉是,好像旧场景的 UI 进度条瞬间加载完了一样,实际上不是
所以说如果发现异步加载结果没有显示或者表现为没有异步性,可以检查自己的结果是否被遮挡了