注意这个时候初始化方法已经被封装起来了,在设置状态时会自动调用,而初始化方法设置成了虚函数,方便子类进行定制。
因此加载进度界面和登录注册界面的代码的修改前后为:
using UnityEngine; using UnityEngine.UI; public class LoadingWnd : WindowRoot { //初始化加载进度界面 protected override void InitWnd() { //实际操作代码 } //设置进度 public void SetProgress(float prg) { //实际操作代码 } }
using UnityEngine; using UnityEngine.UI; public class LoginWnd : WindowRoot { //初始化登录注册界面 protected override void InitWnd() { //实际操作代码 } }
注意对比,现在初始化方法要对父类的初始化方法覆写,同时权限不再是公有,因为父类中权限为 protected,所以子类中无法设置成 public,因此此时初始化方法只能被设置状态时自动调用,无需也不能在外部手动调用了。
此时无需改动 GameRoot,但登录注册业务模块和资源加载服务模块对界面的调用也应该发生改变:
using System; using UnityEngine; using UnityEngine.SceneManagement; public class ResSvc : MonoBehaviour { public void AsyncLoadScene(string sceneName,Action loaded) { //显示加载界面 GameRoot.Instance.loadingWnd.SetWndState(true); //异步加载指定名字的场景 AsyncOperation sceneAsync = SceneManager.LoadSceneAsync(sceneName); prgCB = ()=> { //获取当前进度 float val = sceneAsync.progress; //在加载界面设置当前进度 GameRoot.Instance.loadingWnd.SetProgress(val); //加载完成 if(val == 1) { //加载完成后调用回调函数 if(loaded != null) { loaded(); } //清空委托和中间结构 sceneAsync = null; prgCB = null; //取消对加载界面的展示 GameRoot.Instance.loadingWnd.SetWndState(false); } }; } }
using UnityEngine; public class LoginSys : MonoBehaviour { public void EnterLogin() { //加载登录场景 ResSvc.Instance.AsyncLoadScene(Constants.SceneLogin,()=>{ //加载完成后打开登录注册界面 loginWnd.SetWndState(true); }); } }
我们的改动不大,改动部分:(其余部分省略)
//显示加载界面 GameRoot.Instance.loadingWnd.SetWndState(true);
//取消对加载界面的展示 GameRoot.Instance.loadingWnd.SetWndState(false);
//加载完成后打开登录注册界面 loginWnd.SetWndState(true);
其实每个窗口界面里也有可能会用到公共服务 (如资源加载服务模块),如果不作改进,那我们每个窗口界面中都要去获取资源加载服务模块的单例并调用功能,这样改进之后,我们可以在基类窗口脚本中持有对此服务模块的引用,随后在基类初始化方法中对引用赋值,然后在每个窗口的自定义初始化函数中多调用下基类的初始化方法,就可以进一步精简代码,架构也更加清晰。
标红部分即为修改部分:
UI界面基类
加载进度界面
同理,其他界面,如登录注册界面,也可以这么改。