乌卢阿示例演示简析及SimpleFramework工作流程

先分析乌卢阿的实例代码,了解一下SimpleFramework工作流程,在我们制作实例时便于理解。

1,LuaState

使用UnityEngine;
使用System.Collections;
使用LuaInterface;

public class HelloWorld:MonoBehaviour {

	//用于初始化
	void Start(){
        LuaState l = new LuaState();
        string str =“print('hello world world world)”;
        l.DoString(STR);
	}
	
	//每帧调用一次更新
	void Update(){
	
	}
}

这个示例代码中就使用了LuaState。

2,LuaScriptMgr

使用UnityEngine;
使用System.Collections;
使用LuaInterface;

public class CreateGameObject02:MonoBehaviour {

    私人字符串script = @“
            luanet.load_assembly( 'UnityEngine')
            GameObject = UnityEngine.GameObject
            ParticleSystem = UnityEngine.ParticleSystem
            local newGameObj = GameObject('NewObj')
            newGameObj:AddComponent(ParticleSystem.GetClassType())
        “;

	//非反射调用
	void Start(){
        LuaScriptMgr lua = new LuaScriptMgr();
        lua.Start();
        lua.DoString(脚本);
	}
	
	//每帧调用一次更新
	void Update(){
	
	}
}

这个示例代码中就使用了LuaScriptMgr。

上面的两个示例中,要注意一下的代码:
私人字符串script = @“
            luanet.load_assembly( 'UnityEngine')
            GameObject = UnityEngine.GameObject
            ParticleSystem = UnityEngine.ParticleSystem
            local newGameObj = GameObject('NewObj')
            newGameObj:AddComponent(ParticleSystem.GetClassType())
        “;

大概工作流程就是先加载UnityEngine,然后创建一个游戏物体变量,再调用AddComponent方法。其实就和统一里面使用的差不多。很简单。不多说。

3,在团结中访问的Lua中的变量

使用UnityEngine;
使用System.Collections;
使用LuaInterface;

public class AccessingLuaVariables01:MonoBehaviour {

    私人字符串script = @“
            luanet.load_assembly( 'UnityEngine')
            GameObject = luanet.import_type('UnityEngine.GameObject')
            ParticleSystem = luanet.import_type('UnityEngine.ParticleSystem')
            particle = {}

            对于i = 1,Objs2Spawn,1 do
                local newGameObj = GameObject('NewObj')
            local ps = newGameObj:AddComponent(luanet.ctype(ParticleSystem))
                PS:停止()

                table.insert(particle,ps)
            结束

            var2read = 42
        “;

	void Start(){
        LuaState l = new LuaState();
        l [“Objs2Spawn”] = 5; //就是这里
        l.DoString(脚本);

        print(“从lua读取”+ l [“var2read”]。ToString());

        LuaTable颗粒=(LuaTable)l [“颗粒”];

        foreach(ParticleSystem ps in particle.Values)
        {
            ps.Play();
        }
	}
	void Update(){
	
	}
}

如图4所示,执行的Lua脚本文件,调用的Lua方法,在的Lua中使用协程

使用UnityEngine;
使用System.Collections;
使用LuaInterface;

public class ScriptsFromFile_01:MonoBehaviour
{

    public TextAsset scriptFile;

    //用于初始化
    void Start()
    {
        LuaState l = new LuaState();
        l.DoString(scriptFile.text);
    }

    //每帧调用一次更新
    void Update()
    {

    }
}

而我们的档案文件就是在同目录下的与类同名的TXT文件。

注意,我们这里定义的文件文件,是TextAsset类型。
public TextAsset scriptFile;

接下来就是调用Lua中的方法。也很简单。

使用UnityEngine;
使用System.Collections;
使用LuaInterface;

公共课CallLuaFunction_01:MonoBehaviour {

    私人字符串script = @“
            函数luaFunc(message)
                打印(消息)
                返回42
            结束
        “;

	void Start(){
        LuaState l = new LuaState();
        l.DoString(脚本);
        LuaFunction f = l.GetFunction(“luaFunc”);
        object [] r = f.Call(“我叫lua函数!”);
        打印(R [0]);
	}
	void Update(){
	
	}
}

协程的使用:

使用UnityEngine;
使用System.Collections;
使用LuaInterface;

公共课LuaCoroutines:MonoBehaviour 
{
    私人字符串script = @“                                   
            功能fib(n)
                本地a,b = 0,1
                而n> 0
                    a,b = b,a + b
                    n = n-1
                结束

                回来了
            结束

            函数CoFunc()
                print('Coroutine started')
                本地i = 0
                对于i = 0,10,1
                    打印(FIB(i))的                    
                    coroutine.wait(1)
                结束
                print('Conoutine ends')
            结束

            函数myFunc()
                coroutine.start(CoFunc)
            结束
        “;

    私人LuaScriptMgr lua = null;

	void Awake() 
    {
        lua = new LuaScriptMgr();
        lua.Start();
        lua.DoString(脚本);        
        LuaFunction f = lua.GetLuaFunction(“myFunc”);
        f.Call();
        f.Release();
	}
	
	void Update() 
    {        
        lua.Update();
	}

    void LateUpdate()
    {
        lua.LateUpate();
    }

    void FixedUpdate()
    {
        lua.FixedUpdate();
    }
}

好了.uLua的示例代码我们就分析到这里了。接下来的可以自己琢磨,对于我们的案例来说已经够了。下面我们来分析一下自带热更新的案例的工作流程。也就是我们的SimpleFramework的工作流程。

5,框架启动GlobalGenerator,生成APPVIEW和游戏管理

在这里我们首先要看一下框架的目录。
整个SimpleFramework采用的是PureMVC的的框架。看下图。
GlobalGenerator.cs
使用UnityEngine;
使用System.Collections;

命名空间SimpleFramework {
    /// <summary>
    ///全局构造器,每个场景里都有,所以每个场景都会初始化一遍,也会初始化游戏管理器一次
    ///如果游戏管理器已经存在了,就跳过了,否则创建游戏管理器,来保证游戏里只有一个GameManager
    /// </ summary>
    public class GlobalGenerator:MonoBehaviour {

        void Awake(){
            InitGameMangager();
        }

        /// <summary>
        ///实例化游戏管理器
        /// </ summary>
        public void InitGameMangager(){
            string name =“GameManager”;
            gameObject.AddComponent <APPVIEW>();

            GameObject manager = GameObject.Find(name);
            if(manager == null){
                manager = new GameObject(name);
                manager.name = name;

                AppFacade.Instance.StartUp(); //启动游戏
            }
        }
    }
}

这段代码就是我们热更新的入口。

这里GlobalGenerator的任务就完成了。
APPVIEW和游戏管理器都是框架相关的东西。这里我们就只对游戏管理进行分析。

6,游戏管理器中对资源的更新处理及处理的Lua的视图的加载和初始化

游戏管理器的功能就如这个标题所说。
代码中也有详细注释。
我们就不贴代码了。
我们关注一下游戏管理器组件下的脚本。
然后,我们要重点分析的Lua文件夹下的Lua的脚本。
GameManager.cs:

①加载所有的Lua脚本

公共LuaScriptMgr uluaMgr;
        private List <string> downloadFiles = new List <string>();

②初始化

void Init(){
            DontDestroyOnLoad(游戏物体); //防止销毁自己

            CheckExtractResource(); //释放资源
            Screen.sleepTimeout = SleepTimeout.NeverSleep;
            Application.targetFrameRate = AppConst.GameFrameRate;
        }

我们可以看看AppConst.cs文件,里面主要是一些配置。

使用UnityEngine;
使用系统;
使用System.Collections;
使用System.Collections.Generic;

命名空间SimpleFramework {
    公共类AppConst {
        public const bool DebugMode = false; //调试模式 - 用于内部测试
        /// <summary>
        ///如果想删除框架自带的例子,那这个例子模式必须要
        ///关闭,否则会出现一些错误。
        /// </ summary>
        public const bool ExampleMode = true; //例子模式

        /// <summary>
        ///如果开启更新模式,前提必须启动框架自带服务器端。
        ///否则就需要自己将StreamingAssets里面的所有内容
        ///复制到自己的Webserver上面,并修改下面的WebUrl。
        /// </ summary>
        public const bool UpdateMode = false; //更新模式 - 默认关闭

        public const int TimerInterval = 1;
        public const int GameFrameRate = 30; //游戏帧频

        public const bool UsePbc = true; // PBC
        public const bool UseLpeg = true; // LPEG
        public const bool UsePbLua = true; // Protobuff  - 卢阿根
        public const bool UseCJson = true; // CJson
        public const bool UseSproto = true; // Sproto
        public const bool LuaEncode = false; //使用LUA编码

        public const string AppName =“SimpleFramework”; //应用程序名称
        public const string AppPrefix = AppName +“_”; //应用程序前缀
        public const string ExtName =“.assetbundle”; //素材扩展名
        public const string AssetDirname =“StreamingAssets”; //素材目录
        public const string WebUrl =“http:// localhost:6688 /”; //测试更新地址

        public static string UserId = string.Empty; //用户ID
        public static int SocketPort = 0; //套接字服务器端口
        public static string SocketAddress = string.Empty; //套接字服务器地址
    }
}

④资源初始化结束

public void OnResourceInited(){
            LuaManager.Start();
            LuaManager.DoFile( “逻辑/网络”); //加载游戏
            LuaManager.DoFile( “逻辑/游戏管理”); //加载网络
            initialize = true;  

            NetManager.OnInit(); //初始化网络

            object [] panels = CallMethod(“LuaScriptPanel”);
            // --------------------- Lua的面板------------------------- - 
            foreach(面板中的对象){
                string name = o.ToString()。Trim();
                if(string.IsNullOrEmpty(name))继续;
                name + =“Panel”; //添加

                LuaManager.DoFile(“View /”+名称);
                Debug.LogWarning(“LoadLua ---- >>>>”+ name +“.lua”);
            }
            // ------------------------------------------------ ------------
            CallMethod( “OnInitOK”); //初始化完成
        }

我们看到熟悉的字眼了。

LuaManager.DoFile( “逻辑/网络”); //加载游戏
            LuaManager.DoFile( “逻辑/游戏管理”); //加载网络

这正是我们的Lua文件夹的逻辑文件夹下的脚本,我们来看看这两个脚本。

Network.lua文件主要是网络相关的文件,我们就不分析了,重点看GameManager.lua。它相当于Lua的脚本文件的起点。
需要“3rd / pblua / login_pb”
需要“3rd / pbc / protobuf”

local lpeg = require“lpeg”

本地json = require“cjson”
local util = require“3rd / cjson.util”

局部发芽=需要“第3次/发芽/发芽”
local core =需要“sproto.core”
local print_r = require“3rd / sproto / print_r”

要求“逻辑/ luaclass”
需要“Logic / CtrlManager”
要求“常用/功能”
需要“Controller / PromptCtrl”

文件相关。不解释。

GameManager = {};
local this = GameManager;

单例。你懂的。

功能GameManager.LuaScriptPanel()
	返回“提示”,“消息”;
结束

返回我们的UI相关类。

我们结合两个文件一起看。
功能GameManager.LuaScriptPanel()
	返回“提示”,“消息”;
结束
object [] panels = CallMethod(“LuaScriptPanel”);
            // --------------------- Lua的面板------------------------- - 
            foreach(面板中的对象){
                string name = o.ToString()。Trim();
                if(string.IsNullOrEmpty(name))继续;
                name + =“Panel”; //添加

                LuaManager.DoFile(“View /”+名称);
                Debug.LogWarning(“LoadLua ---- >>>>”+ name +“.lua”);
            }

这两段代码是相关联的。

局部变换
本地gameObject;

PromptPanel = {};
local this = PromptPanel;

- 启动事件 - 
函数PromptPanel.Awake(obj)
	gameObject = obj;
	transform = obj.transform;

	this.InitPanel();
	warn(“Awake lua --- >>”.. gameObject.name);
结束

- 初始化面板 - 
函数PromptPanel.InitPanel()
	this.btnOpen = transform:FindChild(“Open”)。gameObject;
	this.gridParent = transform:FindChild('ScrollView / Grid');
结束

- 单击事件 - 
函数PromptPanel.OnDestroy()
	警告( “----的OnDestroy >>>”);
结束
局部变换
本地gameObject;

MessagePanel = {};
local this = MessagePanel;

- 启动事件 - 
函数MessagePanel.Awake(obj)
	gameObject = obj;
	transform = obj.transform;

	this.InitPanel();
	warn(“Awake lua --- >>”.. gameObject.name);
结束

- 初始化面板 - 
函数MessagePanel.InitPanel()
	this.btnClose = transform:FindChild(“Button”)。gameObject;
结束

- 单击事件 - 
函数MessagePanel.OnDestroy()
	警告( “----的OnDestroy >>>”);
结束

这两段代码得以执行。初始化UI界面。

这里有个疑问?初始化界面是怎么得以实现的?
其实也很简单,结合工程来看:
这是初始化后得到的界面。
其实我们早就把界面打包成预制了。
对,就是这么来的,每个预制对应生成AssetBundle。达到热的目的。