启动顺序
Main.cs绑定到场景的一个组件上
public class Main : MonoBehaviour { void Start() { AppFacade.Instance.StartUp(); //启动游戏 } }
StartUpCommand的Execute函数开始初始化必要的东西
public class StartUpCommand : ControllerCommand { public override void Execute(IMessage message) { //首先检查运行环境,这个函数只在UNITY_EDITOR下有用 //其他时候都是直接返回true的 if (!Util.CheckEnvironment()) return; //如果需要显示AppView信息,需要在场景上添加GlobalGenerator对象 //AppView里面只是显示一些消息 GameObject gameMgr = GameObject.Find("GlobalGenerator"); if (gameMgr != null) { AppView appView = gameMgr.AddComponent<AppView>(); } //-----------------关联命令----------------------- //SocketCommand处理网关相关指令 AppFacade.Instance.RegisterCommand(NotiConst.DISPATCH_MESSAGE, typeof(SocketCommand)); //-----------------初始化管理器----------------------- AppFacade.Instance.AddManager<LuaManager>(ManagerName.Lua); AppFacade.Instance.AddManager<PanelManager>(ManagerName.Panel); AppFacade.Instance.AddManager<SoundManager>(ManagerName.Sound); AppFacade.Instance.AddManager<TimerManager>(ManagerName.Timer); AppFacade.Instance.AddManager<NetworkManager>(ManagerName.Network); AppFacade.Instance.AddManager<ResourceManager>(ManagerName.Resource); AppFacade.Instance.AddManager<ThreadManager>(ManagerName.Thread); AppFacade.Instance.AddManager<ObjectPoolManager>(ManagerName.ObjectPool); //游戏下载资源,解包都在GameManager内完成 //GameManager可能要在其他Manager添加后再添加 //这个还不能确定,刚看代码 AppFacade.Instance.AddManager<GameManager>(ManagerName.Game); } }
GameManager首先完成资源的加载和释放(资源都是打包的,需要释放到Util.DataPath目录)
/// 释放资源 public void CheckExtractResource() { bool isExists = Directory.Exists(Util.DataPath) && Directory.Exists(Util.DataPath + "lua/") && File.Exists(Util.DataPath + "files.txt"); if (isExists || AppConst.DebugMode) { StartCoroutine(OnUpdateResource()); return; //文件已经解压过了,自己可添加检查文件列表逻辑 } StartCoroutine(OnExtractResource()); //启动释放协成 }
资源释放后需要下载更新资源,OnUpdateResource函数会完成这个工作
资源初始化结束后,OnInitialize函数开始初始化游戏内容的东西void OnInitialize() { //这里还应该有其他的东西需要设置 //要根据游戏的开发后期再加 LuaManager.InitStart(); LuaManager.DoFile("Logic/Game"); //加载游戏 LuaManager.DoFile("Logic/Network"); //加载网络 NetManager.OnInit(); //初始化网络 //初始化完成,调用lua脚本里面的OnInitOK方法 //游戏进入正常循环 Util.CallMethod("Game", "OnInitOK"); //初始化完成 initialize = true; }
Game.lua的OnInitOK函数开始真正执行lua代码,后续的游戏流程就可以交给lua代码了
function Game.OnInitOK() --网络连接,这里只是举例,如果是登录平台,可能要先调用平台的SDK AppConst.SocketPort = 2012; AppConst.SocketAddress = "127.0.0.1"; networkMgr:SendConnect(); --注册LuaView this.InitViewPanels(); CtrlManager.Init(); end
InitViewPanels函数会载入PanelNames内的所有View视图,PanelNames在define.lua里面定义
InitViewPanels函数的内容function Game.InitViewPanels() for i = 1, #PanelNames do require ("View/"..tostring(PanelNames[i])) end end
PanelNames里面的内容
PanelNames = { "PromptPanel", "MessagePanel", }
CtrlManager.Init()初始化函数会初始化控制器列表
function CtrlManager.Init() logWarn("CtrlManager.Init----->>>"); ctrlList[CtrlNames.Prompt] = PromptCtrl.New(); ctrlList[CtrlNames.Message] = MessageCtrl.New(); return this; end
对于每一个视图都有一个Controller与之对应,Controller负责创建和维护View
Controller的Awake方法通过panelMgr的CreatePanel方法创建对象,panelMgr在define.lua里面初始化
panelMgr是框架的Manager里面的一个管理器,实现在PanelManager.cs文件里面public void CreatePanel(string name, LuaFunction func = null) { //这里会生成View的具体名称,比如PromptPanel string assetName = name + "Panel"; //这个是打包的资源的名字,比如prompt.unity3d //具体打包包含什么东西,可以看同名的manifest文件,比如prompt.unity3d.manifest string abName = name.ToLower() + AppConst.ExtName; //如果已经存在,不需要再创建 if (Parent.Find(name) != null) return; //获取预制体 GameObject prefab = ResManager.LoadAsset<GameObject>(name, assetName); if (prefab == null) return; //创建对象 GameObject go = Instantiate(prefab) as GameObject; go.name = assetName; go.layer = LayerMask.NameToLayer("Default"); go.transform.SetParent(Parent); go.transform.localScale = Vector3.one; go.transform.localPosition = Vector3.zero; //绑定LuaBehaviour,实现Unity消息到Lua里面的调用 go.AddComponent<LuaBehaviour>(); //如果有回调函数,调用回调函数 if (func != null) func.Call(go); }
关于LuaBehaviour类 LuaBehaviour类主要实现Unity消息到Lua的调用
protected void Awake() { //最终lua方法的调用是通过Module.Function的形式实现的 //例如PromptPanel.Awake Util.CallMethod(name, "Awake", gameObject); } protected void Start() { Util.CallMethod(name, "Start"); } protected void OnClick() { Util.CallMethod(name, "OnClick"); } protected void OnClickEvent(GameObject go) { Util.CallMethod(name, "OnClick", go); }
回调方法里面有创建的对象,就可以通过Unity的API获取组件了
function PromptCtrl.OnCreate(obj) gameObject = obj; transform = obj.transform; panel = transform:GetComponent('UIPanel'); prompt = transform:GetComponent('LuaBehaviour'); prompt:AddClick(PromptPanel.btnOpen, this.OnClick); resMgr:LoadPrefab('prompt', { 'PromptItem' }, this.InitPanel); end
View的初始化是在LuaBehaviour的Awake调用时完成的,例如PromptPanel.lua
LuaBehaviour的Awake会调用PromptPanel的Awake函数,这样就能获取到View上的组件--启动事件-- --LuaBehaviour.cs里面的Awake函数会调用这个函数 function PromptPanel.Awake(obj) --这个就是Unity的GameObject对象 gameObject = obj; transform = obj.transform; this.InitPanel(); logWarn("Awake lua--->>"..gameObject.name); end --初始化面板-- function PromptPanel.InitPanel() --使用Unity的API获取组件 this.btnOpen = transform:Find("Open").gameObject; this.gridParent = transform:Find('ScrollView/Grid'); end
这样,基本的框架流程就完成了,UI的交换操作就可以在Controller里面完成了