基本游戏流程:
1、打开游戏需要检测是否需要热更(涉及热更相关的东西就不说了太多了,百度就可以了)加载loading界面。下载资源完成
2、进入登录界面,执行登录方面以及注册方面的校验逻辑。
3、退出登录场景(状态),进入主城(主界面),然后正八经进入游戏开始玩了。
上面的虽然都是废话,但是整个游戏UI的控制,其实就是一直进行这样一个简单的循环。
退出上一个场景(可能需要做一些事情:清理内存,销毁一些不必要的预制体)——进入新的场景(可能需要做一些事情:加载Loading界面,加载状态内的资源,例如场景中的一些房子模型,人物模型等等)——加载完成(关闭loading界面)
下面三个是常用的一些工具或者框架中简单但是挺重要的模块,因为简单就不过多介绍了。
1、小工具之类的东西:单例基类。不多介绍,这个不会的话可能真的需要自己去补一下C#基础知识了啊~~
using System.Collections; using System.Collections.Generic; using UnityEngine; public class AutoSingleton<T> :MonoBehaviour where T:MonoBehaviour { private static T instance; public static T Instance { get { if (instance == null) { GameObject go = new GameObject(typeof(T).ToString()); instance = go.AddComponent<T>(); } return instance; } } }
2、小工具:拓展方法,递归查找子物体;
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Events; public static class ExpandFunc { public static Transform FindChildWithName(this Transform self,string targetName) { if (self.name == targetName) return self; if (self.childCount < 1) return null; Transform target; for (int i = 0; i < self.childCount; i++) { target = self.GetChild(i).FindChildWithName(targetName); if (target) return target; } return null; } }
3、框架中经常用到的一个部分,消息传递:
using System.Collections; using System.Collections.Generic; using UnityEngine; public delegate void LoadDel(float num);//可以自定义泛型委托; public static class MessageManager { //用于存储 想要执行的委托字典; private static Dictionary<string, LoadDel> m_loadDic = new Dictionary<string, LoadDel>(); //将消息或者委托注册到字典中 public static void AddListener(string funcName, LoadDel loadDel) { if (m_loadDic.ContainsKey(funcName)) { m_loadDic.Remove(funcName); } m_loadDic.Add(funcName, loadDel); } //执行的时候,就可以通过string把委托从字典取出来,执行,num是一个参数,可以根据自己的需要自定义泛型委托或者固定参数的委托; public static void DoFunc(string funcName, float num) { LoadDel temDel = null; if (m_loadDic.TryGetValue(funcName, out temDel)) { temDel(num); MDebug.Log("执行了方法:" + funcName); } } public static void RemoveFunc(string funcName) { m_loadDic.Remove(funcName); } public static void ClearAllFunc() { m_loadDic.Clear(); } }
一、状态(通常可以理解为一个状态,就是一个场景,或者在一个模块中想要干的一系列事情。)
由此可知,加载场景就需要两个东西:第一加载场景管理类,第二状态管理类。这两个是有区别的,第一个是从硬盘中把场景资源加载进来,第二个是决定管理这些状态什么时候加载,什么时候卸载。这两个管理类暂时先不说,之后详细介绍,也是核心的部分!
1)状态基类:
public abstract class BaseScene { //开始加载 public void Start() { UIManager.LoadPanel(); //通过UI管理类加载LoadingPanel; OnStart(); } //退出场景 public void Stop() { OnStop(); } //场景加载完成,这个参数的用处,之后会介绍的; public void LoadComplete(params object[] args) { OnLoadComplete(args); } protected abstract void OnStart(); protected abstract void OnStop(); protected abstract void OnLoadComplete(params object[] args); }
2)先简单举一个例子,作为具体实现状态基类的方法,当进入登录场景的时候,实现具体的虚方法,会在基类BaseScene中调用。
public class LoginStateScene : BaseScene { protected override void OnLoadComplete(params object[] args) { //关于UIManger以后介绍; UIManager.LoadPanel(PanelNameEnum.LoginPanel, PanelNameEnum.None); } protected override void OnStart() { } protected override void OnStop() { UIManager.DestoryPanel(PanelNameEnum.LoginPanel); } }
这两个没什么难度,就是简单的继承而已。在之后要写的状态管理类中,就会发现进入一个场景之前,想要执行Stop方法,然后执行场景的Start方法。这个流程就是在状态管理类中控制的;
至于UIManager这管理类先不要去管它。之后会详细介绍UI代码如何处理;接下来可能需要先介绍一下AB包管理器了(本来想着直接用本地加载算了,不用ab包了。后来想着反正都写了框架,多介绍一点是一点吧);