13_窗口基类

因为有各种窗口类(比如资源加载窗口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.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值