目的:在游戏开发中,经常会使用到Loading挡片。挡片的存在为后台资源加载及其进度情况作出可视化的存在。
思路:
1. 每个场景或界面所需要的元素千差万别,因此对于共有的元素使用CLoadingBase来进行加载,同时在CloadingBase中定义统一接口及接口中的调用流程,方便各个场景的加载界面进行覆写。
2. 加载有4个状态,分别是“未加载”、“添加加载URL“、’加载中”、“加载完成”.
3. 资源加载分2个阶段,一个是添加资源URL阶段,本阶段中主要负责收集所需加载资源的URL。伪代码如:
StartAddUrl(); //设置进入添加URL状态
AddUrl(url1);//添加所需Url1
AddUrl(url2);//添加所需Url2
EndAddUrl();//结束添加URL状态,同时进入"资源加载中"状态,启动资源加载进度UpdateProgress
4.CLoadingBase完整类
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public enum eResourceType
{
Resource_None = 0,
Resource_Static_Data = 1,
}
public enum eLoadingState
{
None,
AddUrl,
Loading,
Completed,
}
public class CLoadingBase
{
private Dictionary<string, LoadInfoLocal> m_requestList = new Dictionary<string, LoadInfoLocal>();
private eLoadingState m_state;
protected float m_fTotalProgress;
private static List<string> assetList = new List<string>();
public CLoadingBase()
{
Reset();
}
protected void AddAsset(string path)
{
LoadHelpLocal.LoadObject("", path, ThreadPriority.Normal, null, false);
if (!assetList.Contains(path))
assetList.Add(path);
}
public static void ClearAssets()
{
foreach (string path in assetList)
{
//TODOLoadHelpLocal.RemoveObject(path);
}
assetList.Clear();
}
public virtual void Reset()
{
m_state = eLoadingState.None;
m_requestList.Clear();
}
public virtual float GetProgress()
{
return m_fTotalProgress;
}
public virtual void StartAddUrl(bool bEnterLoading)
{
m_state = eLoadingState.AddUrl;
m_fTotalProgress = 0;
}
public virtual void AddUrl(LoadInfoLocal info)
{
if (m_state != eLoadingState.AddUrl)
return;
if (!m_requestList.ContainsKey(info.originPath))
m_requestList.Add(info.originPath, info);
}
public virtual void EndAddUrl()
{
m_state = eLoadingState.Loading;
UpdateProgress();
}
public virtual void SetLoadingContent(eResourceType type, float fMin, float fMax)
{
float fTotal = fMax - fMin;
if (GetProgress() < fMin || GetProgress() < fMax)
return;
}
public void UpdateProgress()
{
switch (m_state)
{
case eLoadingState.AddUrl:
{
}
break;
case eLoadingState.Loading:
{
if (m_requestList.Count <= 0)
{
m_fTotalProgress = 1;
m_state = eLoadingState.Completed;
return;
}
float progress = 0;
foreach (KeyValuePair<string, LoadInfoLocal> kvp in m_requestList)
{
progress += kvp.Value.progress;
}
m_fTotalProgress = progress / (float)m_requestList.Count;
if (m_fTotalProgress >= 1)
{
m_state = eLoadingState.Completed;
}
else
{
Loading();
}
}
break;
case eLoadingState.Completed:
{
Reset();
LoadingCompleted();
}
break;
}
Update();
}
protected virtual void Loading()
{
}
protected virtual void LoadingCompleted()
{
}
protected virtual void Update()
{
}
}
5.CLoadingCommon继承于CLoadingBase,作用是加载公用的资源
public class CLoadingCommon : CLoadingBase
{
}
6.CClientInitLoading初始加载类,作用用于加载加载界面所需的资源,比如挡片图片,进度条资源等。内部会调用CLoadingManager的方法。
public class CClientInitLoading : CLoadingCommon
{
public void StartLoading()
{
CLoadingManager.GetInst().StartAddUrl(this, 5, true);
}
public void EndLoading()
{
CLoadingManager.GetInst().EndAddUrl();
}
public override float GetProgress()
{
float progress = base.GetProgress();
return progress * 0.6f;
}
protected override void LoadingCompleted()
{
Debug.Log("enter first scene!");
}
}
7.CLoadingManager,管理加载类信息。同时提供加载驱动力Update到加载类中。
using UnityEngine;
using System.Collections;
public enum eGameState
{
NONE,
LOADING,
LOGIN,
HOME,
WORLD_MAP,
BATTLE,
CHOOSE_ROLE,
ARENA_UI,
DOWNLOADING,
}
//战斗类型
public enum eBattleType
{
None,
PVE,
//打pve
Arena,
//打竞技场
ClimbTower,
//爬塔
Escort,
//护送
Wasteland,
//末日荒野
GlobalBoss,
//世界BOSS
Mining,
//挖矿
Protect,
//守护
TeamPve,
//团队副本(公会副本)
Run,
//跑酷
Pvp = 19,
//实时Pvp
MultiPve = 20,
//多人PVE
}
public delegate void JumpLoadingCallback();
public class CLoadingManager : SingletonObject<CLoadingManager>
{
private eGameState m_lastGameState = eGameState.LOADING;
private eGameState m_beforeState;
public eGameState GetBeforeState()
{
return m_beforeState;
}
private eGameState m_afterState;
private JumpLoadingCallback m_callback;
private CLoadingBase m_LoadingBase;
private bool m_bEnterLoading = true;
public void StartAddUrl(CLoadingBase pLoadingBase, int apacheNum, bool bEnterLoading)
{
m_LoadingBase = pLoadingBase;
m_LoadingBase.StartAddUrl(bEnterLoading);
if (bEnterLoading)
{
m_lastGameState = ClientInit.GetInst().GetCurrentState();
if (m_lastGameState != eGameState.LOADING)
ClientInit.GetInst().SetGameState(eGameState.LOADING);
}
}
public void EndAddUrl()
{
if (m_LoadingBase != null)
{
m_LoadingBase.EndAddUrl();
}
}
public void AddUrl(LoadInfoLocal info)
{
if (m_LoadingBase == null)
return;
m_LoadingBase.AddUrl(info);
}
public float GetProgress()
{
if (m_LoadingBase == null)
return 0;
return m_LoadingBase.GetProgress();
}
public void Release()
{
m_LoadingBase = null;
}
public void Update()
{
if (m_LoadingBase == null)
return;
m_LoadingBase.UpdateProgress();
}
public void JumpTo(eGameState currState, eGameState nextState, eBattleType type, JumpLoadingCallback callback, bool enterLoading = true, string arg = "0")
{
m_callback = callback;
if (string.IsNullOrEmpty(arg))
{
arg = "0";
}
m_beforeState = currState;
m_afterState = nextState;
m_bEnterLoading = enterLoading;
if (enterLoading)
{
string texturePath = "";
switch (nextState)
{
default:
{
texturePath = "loading_01";
break;
}
}
SingletonObject<LoadingMediator>.GetInst().SetBGPath(texturePath, StartCallBack);
CLoadingBase.ClearAssets();
}
if (!enterLoading)
{
StartCallBack();
}
}
private void StartCallBack()
{
if (m_callback != null)
{
/*
switch(m_beforeState)
{
case
}
*/
m_callback();
}
if (m_bEnterLoading)
{
//todo
}
}
}