QFrameWork学习(四)QApp类

文章围绕Unity游戏框架搭建展开,指出App类有接收生命周期事件等职责。针对游戏测试时因模块依赖和层级深导致的时间浪费问题,提出写接口解决。还划分了开发、出包/真机、发布三个阶段,以保证测试逻辑不影响正常游戏,且用多态兼容不同模块。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

文章地址:https://www.cnblogs.com/liangxiegame/p/Unity-you-xi-kuang-jia-da-jian-qi-jian-shao-jia-ba.html

 

App类的职责:

1.接收生命周期事件

2.作为游戏的入口

3.一些框架级别组件的初始化。

 

好吧看看这个职责,我是完全不能体会为什么会有一个类去专门做这些事情。作者本文讲了一下第二个职责,我勉强看了很多遍整理出来他的思想。

问题情景是这样,经常要测很多东西,需要进游戏内才能测。比如我做AI,我要测赛车在赛道的跑动情况,在测试场景中赛车的数据和比赛中是完全不一样的。所以测试的时候经常就写一个功能,打Log,进入游戏---创房间----等AI。重复很多次这种行为,是很浪费时间没错。

 

问题就在于下一个模块要依赖于前一个模块的逻辑和数据,第二可能就是模块太深了,我要比赛就必须从登陆到建房间开始游戏。那么第一个问题的解决方案就是写一个接口,可以直接在模块的入口就做好资源数据的加载和初始化,第二就是在模块的入口写一个接口,可以直接跳转到这个界面。

 

阶段划分:

综上所述,为了以上解决问题而写的代码,其实需要在出包或者正式发布的时候失效。所以就有了阶段的划分:

1.开发阶段

2.出包/真机阶段

3.发布阶段,就是上线了

public enum  AppMode 
{ 
    Developing,
    QA,
    Release
}

 

好,情景和解决方案都大概明白了,开始解析代码。

/// <summary>
/// 全局唯一继承于MonoBehaviour的单例类,保证其他公共模块都以App的生命周期为准
/// </summary>
public class  App : QMonoSingleton<App> 
{
    public AppMode mode = AppMode.Developing;

    private App() {} 

    void Awake()
    {
        // 确保不被销毁
        DontDestroyOnLoad(gameObject);

        mInstance = this;

        Application.targetFrameRate = 60;
    }

    void Start()
    {
        CoroutineMgr.Instance ().StartCoroutine (ApplicationDidFinishLaunching());
    }

    /// <summary>
    /// 进入游戏
    /// </summary>
    IEnumerator ApplicationDidFinishLaunching()
    {

        // 配置文件加载 类似PlayerPrefs
        QSetting.Load();
        
        // 日志输出
        QLog.Instance ();

        yield return GameManager.Instance ().Init ();

        // 进入测试逻辑
        if(App.Instance().mode == AppMode.Developing)
        {
            // 测试资源加载
            ResMgr.Instance ().LoadRes ("TestRes",delegate(string
resName, Object resObj) 
        {
            if(null != resObj) 
            {
                GameObject.Instantiate(resObj);
            }
                // 进入目标界面等等
        });
       
         yield return null;

        // 进入正常游戏逻辑

        } else
        {
            yield return  GameManager.Instance ().Launch ();
        }
        
        yield return null;
    }

 

        按照上面的写法在生命周期里面更新AppMode,就可以保证这部分用于开发期间测试的逻辑不会影响到正常游戏里了,也不用等上线时麻烦地去清理这些代码。

 

之后还有一个问题:

        这个if(App.Instance().mode == AppMode.Developing)为true之后的逻辑,肯定是不能这么写的。这里需要兼容不同的模块,答案是用多态。其实这里用依赖倒置原则来想,就应该抽象出去。

 

public
interface  ITestEntry 
{
    /// <summary>
    /// 这里实现写针对不同模块入口该有的逻辑
    /// </summary>
    IEnumerator Launch();
}

/// <summary>
/// AR模块测试入口
/// </summary>

public
class  ARSceneTestEntry :MonoBehaviour,ITestEntry {

    public IEnumerator Launch()
     {
        Debug.LogWarning ("进入AR场景开始");
        yield return  GameObject.Find ("ARScene").GetComponent<ARScene> ().Launch ();
        
        yield return  null;
    }
}

 

 App类中阶段区分的代码要改成这样:

// 进入测试逻辑

if(App.Instance().mode == AppMode.Developing) 
{
    yield return  GetComponent<ITestEntry> ().Launch ();

    
} 
else // 进入正常游戏逻辑
{
    yield return  GameManager.Instance ().Launch ();
}

 

当然,这里的代码都是原作者写的测试代码,真实的项目中这些逻辑写在哪里就根据情况来定了,但是思想确实是这么回事。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值