【Unity自己写框架】FairyGUI UI框架(一)

笔者之前沉迷游戏无法自拔,但是现在之前玩的游戏也不太爱玩了,发现下班到睡觉之前有2-3个小时空闲,仿佛发现了一笔宝贵的财富不能浪费。
笔者从事手游工作也有两年的时间了,主要做的是逻辑和SDK方面的工作,有时候也查查平台相关的闪退卡死问题。从来没有系统的总结归纳过学过的知识,于是决定自己写个框架试试,也可以查漏补缺,不懂得地方就多看看别的怎么处理的。所以开贴记录下自己的学习成果,框架还不完善只是作为记录(可能并不能投入使用),老司机可以随意指点,我会虚心接受的。

一、UI插件的选择

笔者第一个项目用的插件是NGUI,因为当时没得选,市场上就有这一款插件供使用。自从Unity推出了自己的UGUI,大部分新的项目也相继使用开来。我猜想主要原因是UGUI是Unity原生的,所以效率性能应该会好很多,兼容性也会提高。笔者两款UI插件都有用过,但是从去年开始就关注Unity的第三款UI插件FairyGUI,发现此款插件有很多方便开发者的功能,加之笔者自己的实验项目那就研究个没尝试过得好了,所以就选择了FairyGUI。
FairyGUI地址:http://www.fairygui.com/
第一件事就是上官网下demo,看官网的视频、帖子,加官方群询问一些不了解的地方。笔者这里建议在问问题之前最好把自己能查到的能看到的东西都看完,这样也是出于对作者的尊重,也不会让自己遭人嫌弃。

二、语言的选择

说个好玩的事情,笔者想写自己的项目不是一天两天了,之前也放弃过一次,那时候觉得一个项目必须做好热更新,有bug就要及时修复,还能更新出一些新玩法。但是笔者服务器的造诣尚浅,那时候没有找到如果做到lua协议热更新,如果协议不能热更新那么能更新的新功能的太少,在寻找探索的过程中也就放弃了。
当然笔者现在还是不太会服务器罗马不是一天建成的所以此次先用c#写项目,但是我会减少对c#的依赖,等哪天搞定的服务器,就将框架移植到lua中

三、UI插件的使用

FGUI在Unity方面的使用主要关注的是“包”也就是Package。你如果想显示一个UI界面,首先需要找到UI界面所引用的包,将这些包加载进来(UIPackage.AddPackage),你才能看到UI的界面(UIPackage.CreateObject)。
所以UI框架的第一个任务是需要管理Package的加载与卸载,还有Component的显示。
那么第一份代码就是管理包

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using FairyGUI;

public class UIPackageManager : BaseManager<UIPackageManager>
{

    //记录包是否Add的字典
    private Dictionary<string, bool> packageAddDict = new Dictionary<string, bool>();

    /// <summary>
    /// 将一个UI包add进来
    /// </summary>
    /// <param name="packageName">UI包名</param>
    public void AddPackage(string packageName)
    {
        if (CheckPackageHaveAdd(packageName) == false)
        {
            UIPackage.AddPackage("UI/"+packageName);
        }
    }

    /// <summary>
    /// 检查UI包是否已经包进来
    /// </summary>
    /// <param name="packageName">UI包名</param>
    public bool CheckPackageHaveAdd(string packageName)
    {
        return packageAddDict.ContainsKey(packageName);
    }

    /// <summary>
    /// 清理没有用到的UI包
    /// </summary>
    public void ClearNotUsePackage()
    {
        //*****************************
    }
}

通过一个字典来记录UI的包是否已经加载进来,笔者在想何时卸载,由于是第一款小游戏暂时先不做的那么详细(我懒),如果UI资源比较少,完全可以不卸载。也可以等applicationDidReceiveMemoryWarning过来卸载没有用到的资源,这就涉及UI界面与包的引用关系了,等我想明白再开一贴记录。
下面第二份代码是界面的管理

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using FairyGUI;

public class DialogManager : BaseManager<DialogManager>
{

    Dictionary<DialogType, BaseDialog> dialogDict = new Dictionary<DialogType, BaseDialog>();
    /// <summary>
    /// 打开界面
    /// </summary>
    public void OpenDialog(DialogType dialogType)
    {
        DialogInfo dialogInfo = DialogConfigManager.GetInstance().GetDialogInfo(dialogType);
        UIPackageManager.GetInstance().AddPackage(dialogInfo.GetPackName());
        GComponent view = UIPackage.CreateObject(dialogInfo.GetPackName(), dialogInfo.GetDialogName()) as GComponent;
        view.SetSize(GRoot.inst.width, GRoot.inst.height);
        GRoot.inst.AddChild(view);
        dialogDict[dialogType] = DialogConfigManager.GetInstance().GetDialogControl(dialogType);
        dialogDict[dialogType].SetDialogView(view);
        dialogDict[dialogType].OnBeforeCreate();
        dialogDict[dialogType].AddListener();
        dialogDict[dialogType].OnCreate();
        dialogDict[dialogType].OnRefresh();
    }

    /// <summary>
    /// 关闭界面
    /// </summary>
    public void CloseDialog(DialogType dialogType)
    {
        if (dialogDict.ContainsKey(dialogType))
        {
            dialogDict[dialogType].RemoveListener();
            dialogDict[dialogType].OnHide();
            dialogDict[dialogType].OnDestory();
            dialogDict[dialogType].GetView().Dispose();
            dialogDict.Remove(dialogType);
        }
    }

}

打开界面判断包是否加载,如果没有则加载包再打开界面
第三份代码是UI配置的管理

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using FairyGUI;

public class DialogConfigManager : BaseManager<DialogConfigManager>
{

    public Dictionary<DialogType, DialogInfo> dialogDict;

    public DialogConfigManager()
    {
        InitDialogConfig();
    }

    public void InitDialogConfig()
    {
        dialogDict = new Dictionary<DialogType, DialogInfo>();
        dialogDict[DialogType.Main] = new DialogInfo("MainUI", "Win_Main");
        dialogDict[DialogType.Farm] = new DialogInfo("FarmUI", "Win_Farm");
    }

    public DialogInfo GetDialogInfo(DialogType dialogType)
    {
        return dialogDict[dialogType];
    }

    public BaseDialog GetDialogControl(DialogType dialogType)
    {
        switch (dialogType)
        {
            case DialogType.Main:
                return new MainUIDialog();
            case DialogType.Farm:
                return new FramUIDialog();
            default:
                return null;
        }

    }
}


public class DialogInfo {

    private string _packName;
    private string _dialogName;

    public DialogInfo(string packName, string dialogName)
    {
        _packName = packName;
        _dialogName = dialogName;
    }

    public string GetPackName()
    {
        return _packName;
    }

    public string GetDialogName()
    {
        return _dialogName;
    }

}

笔者的UI框架没有采用AddComponent挂脚本的方法,因为如果过度使用,未来很难移植到lua中。
界面配置管理通过GetDialogControl拿到每一个界面对应的累,并将Component Set到类中,方便之后Find组件和控制。

using UnityEngine;
using System.Collections;
using FairyGUI;

public class BaseDialog {

    private GComponent _view;
    private DialogType _dialogType;

    public BaseDialog()
    {

    }

    public void SetDialogView(GComponent view)
    {
        _view = view;
    }

    public void SetDialogType(DialogType dialogType)
    {
        _dialogType = dialogType;
    }

    public GComponent GetView()
    {
        return _view;
    }

    /// <summary>
    /// 创建前期 主要用于寻找view上的组件
    /// </summary>
    public virtual void OnBeforeCreate()
    {

    }

    /// <summary>
    /// 添加监听事件
    /// </summary>
    public virtual void AddListener()
    {

    }

    /// <summary>
    /// 删除添加事件
    /// </summary>
    public virtual void RemoveListener()
    {

    }

    /// <summary>
    /// 创建成功 主要用于逻辑注册
    /// </summary>
    public virtual void OnCreate()
    {

    }

    /// <summary>
    /// 用于缓存界面后的第二次以上打开
    /// </summary>
    public virtual void OnRefresh()
    {

    }

    /// <summary>
    /// 界面隐藏
    /// </summary>
    public virtual void OnHide()
    {

    }

    /// <summary>
    /// 界面销毁
    /// </summary>
    public virtual void OnDestory()
    {

    }

    public void Update()
    {

    }
}

本帖只作为学习记录,只为提供一个思路,还有很多坑要去填,比如AB模式的异步加载包,包的删除管理等。

猜你喜欢

转载自blog.csdn.net/tj134679258/article/details/69153286
今日推荐