背景
场景A跳转到场景B的时候很容易会内存峰值导致程序崩溃。这时候一般会加入一个小的过渡场景:Loading场景来显示场景B的加载情况这样容易有更好的用户体验项目中遇到的问题
异步加载的方式加载场景A,发现场景的进度是要么0要么1,要不然就是7%,80%这样跳来跳去,尼玛Application.LoadLevelAsync你好坑呀制作人果断抛弃了我。说是还是做个动画吧。虽然会卡一下卡一下,但起码比这个好呀!这里插一个点,就是关于协同的点(我会在另外地方介绍这个)
协同主要的作用是2点:1)延迟(等待)执行一段代码;2:)等待某个操作完成之后再执行代码。这里请你牢记:协程不是线程,也不是异步执行的。协程和 MonoBehaviour 的 Update函数一样也是
但是最后还是搞出了一个相对于之前靠谱的方案
代码如下:
/// <summary>
/// Load界面
/// 原理:由于异步加载的progress不是连续的,所以更新一个假的值来让整个进度条能平滑过渡多去
///
/// </summary>
public class ILoading : MonoBehaviour {
[SerializeField]
private UISlider m_LoadProgress;
private float m_MaxProgress=0f;
private float m_CurrentProgress;
void Start()
{
Init();
StartCoroutine(loadScene());
}
void Update()
{
UpdateUISlider();
UpdateProgressValue();
}
void Init()
{
m_LoadProgress.value = 0f;
}
private IEnumerator loadScene()
{
Debug.LogError("Start LoadScene");
//如果没有这句代码,会导致。刚进行Loading界面就会有一个界面停顿的现象
yield return new WaitForEndOfFrame();
//直接阻塞
AsyncOperation op = Application.LoadLevelAsync("SceneA");
op.allowSceneActivation = false;//加载场景之后不会自动跳转
while (op.progress <= 0.9f)//当allowSceneActivation=false的时候 进度最大值就是0.9f
{
if (m_MaxProgress != op.progress)//更新最大值
{
m_MaxProgress = op.progress;
}
yield return null;
if (m_MaxProgress>=0.9f)
{
m_MaxProgress = 1f;
break;
}
}
while(m_CurrentProgress<1f)
{
yield return null;
}
//这里就处理不好了。实验的大致效果Progress就是0.9直接变成1,导致的效果就是当变成100之后会停顿下再界面跳转
op.allowSceneActivation = true;
//读取完毕后返回, 系统会自动进入C场景
yield return op;
}
//数值更新
private void UpdateProgressValue()
{
float tmpValue=m_CurrentProgress + 0.01f;
if (tmpValue >= m_MaxProgress)
{
m_CurrentProgress = m_MaxProgress;
return;
}
m_CurrentProgress = tmpValue;
}
//界面更新
private void UpdateUISlider()
{
if (m_LoadProgress != null)
{
m_LoadProgress.value = m_CurrentProgress;
}
}
}