因为有各种窗口类(比如资源加载窗口LoadingWnd.cs、登录窗口LoginWnd.cs)这些窗口类Wnd.cs中有很多共有的代码,为了简化代码,提取出共有的脚本代码
所以创建窗口基类
编写 窗口基类WindowsRoot.cs
using UnityEngine;
//功能 : 窗口基类
public class WindowsRoot : MonoBehaviour{
public void SetWndState(bool isActive = true) {
//判断当前状态是否和目标状态相同
if (gameObject.activeSelf != isActive) {
gameObject.SetActive(isActive);
}
if (isActive){
InitWnd();
}
else {
ClearWnd();
}
}
protected virtual void InitWnd() {
}
protected virtual void ClearWnd() {
}
}
那么编写加载窗口类LoadingWnd.cs 需要继承自 窗口基类WindowsRoot.cs
并且需要重写初始化窗口函数 以及改为 保护类型
using UnityEngine;
using UnityEngine.UI; //文本 命名空间
//加载进度窗口
public class LoadingWnd : WindowsRoot{
//Tips提示信息
public Text txtTips;
//前景
public Image imgFG;
//进度点
public Image imgPoint;
//百分比
public Text txtPrg;
//存储宽度 1700
float fgWidth;
protected override void InitWnd() {
fgWidth = imgFG.GetComponent<RectTransform>().sizeDelta.x;
txtTips.text = "这是一条游戏Tips";
txtPrg.text = "0%";
imgFG.fillAmount = 0;
imgPoint.transform.localPosition = new Vector3(-850f, 0, 0);
}
//设置进度
public void SetProgress(float prg) {
txtPrg.text = (int)(prg * 100) + "%";
imgFG.fillAmount = prg;
float posX = prg * fgWidth - 850;
imgPoint.GetComponent<RectTransform>().anchoredPosition = new Vector2(posX, 0);
}
}
这样写的好处 调用加载窗口LoadingWnd.cs的 资源服务层ResSvc.cs 可以修改代码为
修改前
修改后
using System;
using UnityEngine;
using UnityEngine.SceneManagement; //异步加载 命名空间
//功能 : 资源加载服务
public class ResSvc : MonoBehaviour{
#region 单例模式
public static ResSvc Instance = null;
#endregion
public void InitSvc(){
#region 单例模式
Instance = this;
#endregion
Debug.Log("Init ResSvc...");
}
#region 【委托】更新回调 进度值
Action prgCB = null;
#endregion
//自定义异步加载
public void AsyncLoadScene(string sceneName,Action loaded) {
#region 窗口基类的好处
GameRoot.Instance.loadingWnd.SetWndState();
#endregion
//拿到异步操作
AsyncOperation sceneAsync = SceneManager.LoadSceneAsync(sceneName);
#region 【委托】更新回调 进度值
//Lamd表达式
prgCB = () =>{
//当前加载进度
float val = sceneAsync.progress;
GameRoot.Instance.loadingWnd.SetProgress(val);
if (val == 1){
#region Loaded回调判断
if (loaded != null)
loaded();
#endregion
#region 单例调用打开登录窗口
//LoginSys.Instance.OpenLoginWnd();
#endregion
//当进度满后 进度值 置空
prgCB = null;
sceneAsync = null;
GameRoot.Instance.loadingWnd.gameObject.SetActive(false);
}
};
#endregion
}
#region 【委托】更新回调 进度值
void Update(){
if(prgCB != null)
prgCB();
}
#endregion
}
也就是将 各个窗口的激活与初始化 提取了出来
同样其他窗口类也需要修改 比如登录窗口LoginWnd.cs
而调用登录窗口LoginWnd.cs的 登陆业务系统LoginSys.cs 同样修改代码为
修改前
修改后
using UnityEngine;
//功能 : 登陆注册业务系统
public class LoginSys : MonoBehaviour{
#region 单例模式
public static LoginSys Instance = null;
#endregion
#region 引用登录窗口
public LoginWnd loginWnd;
#endregion
public void InitSys() {
#region 单例模式
Instance = this;
#endregion
Debug.Log("Init LoginSys...");
}
//进入登录界面
public void EnterLogin() {
//TODO
//异步加载登录界面
//并显示加载进度
#region 调用ResSvc单例类
ResSvc.Instance.AsyncLoadScene(Constans.SceneLogin,() => {
#region 窗口基类的好处
loginWnd.SetWndState();
#endregion
});
#endregion
}
}
我们在窗口中是经常需要加载资源的
所以可以将加载资源服务ResSvc.cs引用到窗口基类中
using UnityEngine;
//功能 : 窗口基类
public class WindowsRoot : MonoBehaviour{
#region 引用加载资源服务
public ResSvc resSvc = null;
#endregion
public void SetWndState(bool isActive = true) {
//判断当前状态是否和目标状态相同
if (gameObject.activeSelf != isActive) {
gameObject.SetActive(isActive);
}
if (isActive){
InitWnd();
}
else {
ClearWnd();
}
}
protected virtual void InitWnd() {
//初始化时拿到 加载资源引用
resSvc = ResSvc.Instance;
}
protected virtual void ClearWnd() {
//清空 加载资源引用
resSvc = null;
}
}
而在窗口子类中 比如加载窗口LoadingWnd.cs 在初始化时就需要先调用基类的初始化函数从而拿到加载资源服务层ResSvc.cs
这样我们就可以在加载窗口类LoadingWnd.cs 在基类初始化之后 就可以使用 资源加载服务ResSvc.cs类了
比如
但暂不需要写这段代码
using UnityEngine;
using UnityEngine.UI; //文本 命名空间
//加载进度窗口
public class LoadingWnd : WindowsRoot{
//Tips提示信息
public Text txtTips;
//前景
public Image imgFG;
//进度点
public Image imgPoint;
//百分比
public Text txtPrg;
//存储宽度 1700
float fgWidth;
protected override void InitWnd() {
#region 窗口基类初始化
base.InitWnd();
#endregion
fgWidth = imgFG.GetComponent<RectTransform>().sizeDelta.x;
txtTips.text = "这是一条游戏Tips";
txtPrg.text = "0%";
imgFG.fillAmount = 0;
imgPoint.transform.localPosition = new Vector3(-850f, 0, 0);
}
//设置进度
public void SetProgress(float prg) {
txtPrg.text = (int)(prg * 100) + "%";
imgFG.fillAmount = prg;
float posX = prg * fgWidth - 850;
imgPoint.GetComponent<RectTransform>().anchoredPosition = new Vector2(posX, 0);
}
}
同样登录窗口LoginWnd.cs也需要 基类初始化
窗口基类WindowsRoot.cs的目的是 在该类中写各个子类共有的方法 子类调用基类的公有方法来节省代码使用空间
对于子类的一些频繁调用代码可以进行修改比如
我们可以在窗口基类WindowsRoot.cs中增加函数
那么在子类中就可以进行以下修改
修改前
修改后
最后修改窗口基类WindowsRoot.cs
End.