笔者第一个项目用的插件是NGUI,因为当时没得选,市场上就有这一款插件供使用。自从Unity推出了自己的UGUI,大部分新的项目也相继使用开来。我猜想主要原因是UGUI是Unity原生的,所以效率性能应该会好很多,兼容性也会提高。笔者两款UI插件都有用过,但是从去年开始就关注Unity的第三款UI插件FairyGUI,发现此款插件有很多方便开发者的功能,加之笔者自己的实验项目那就研究个没尝试过得好了,所以就选择了FairyGUI。
FairyGUI地址:http://www.fairygui.com/
第一件事就是上官网下demo,看官网的视频、帖子,加官方群询问一些不了解的地方。笔者这里建议在问问题之前最好把自己能查到的能看到的东西都看完,这样也是出于对作者的尊重,也不会让自己遭人嫌弃。
说个好玩的事情,笔者想写自己的项目不是一天两天了,之前也放弃过一次,那时候觉得一个项目必须做好热更新,有bug就要及时修复,还能更新出一些新玩法。但是笔者服务器的造诣尚浅,那时候没有找到如果做到lua协议热更新,如果协议不能热更新那么能更新的新功能的太少,在寻找探索的过程中也就放弃了。
当然笔者现在还是不太会服务器,罗马不是一天建成的所以此次先用c#写项目,但是我会减少对c#的依赖,等哪天搞定的服务器,就将框架移植到lua中
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
{
//记录包是否Add的字典
private Dictionary<string, bool> packageAddDict = new Dictionary<string, bool>();
///
/// 将一个UI包add进来
///
/// UI包名
public void AddPackage(string packageName)
{
if (CheckPackageHaveAdd(packageName) == false)
{
UIPackage.AddPackage("UI/"+packageName);
}
}
///
/// 检查UI包是否已经包进来
///
/// UI包名
public bool CheckPackageHaveAdd(string packageName)
{
return packageAddDict.ContainsKey(packageName);
}
///
/// 清理没有用到的UI包
///
public void ClearNotUsePackage()
{
//*****************************
}
}
通过一个字典来记录UI的包是否已经加载进来,笔者在想何时卸载,由于是第一款小游戏暂时先不做的那么详细(我懒),如果UI资源比较少,完全可以不卸载。也可以等applicationDidReceiveMemoryWarning过来卸载没有用到的资源,这就涉及UI界面与包的引用关系了,等我想明白再开一贴记录。
下面第二份代码是界面的管理
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using FairyGUI;
public class DialogManager : BaseManager
{
Dictionary dialogDict = new Dictionary();
///
/// 打开界面
///
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();
}
///
/// 关闭界面
///
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
{
public Dictionary dialogDict;
public DialogConfigManager()
{
InitDialogConfig();
}
public void InitDialogConfig()
{
dialogDict = new Dictionary();
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;
}
///
/// 创建前期 主要用于寻找view上的组件
///
public virtual void OnBeforeCreate()
{
}
///
/// 添加监听事件
///
public virtual void AddListener()
{
}
///
/// 删除添加事件
///
public virtual void RemoveListener()
{
}
///
/// 创建成功 主要用于逻辑注册
///
public virtual void OnCreate()
{
}
///
/// 用于缓存界面后的第二次以上打开
///
public virtual void OnRefresh()
{
}
///
/// 界面隐藏
///
public virtual void OnHide()
{
}
///
/// 界面销毁
///
public virtual void OnDestory()
{
}
public void Update()
{
}
}