ulua插件下载地址 www.ulua.org,下面要说的是ulua的开发框架。

首先是 LuaLoader 类,它负责把一个 lua 的 table 加载起来,使此 lua 的 table 像一个 unity 的 component 一样挂在游戏对象上,代码如下:

using LuaInterface;
using System;
using UnityEngine; public class LuaLoader : MonoBehaviour
{
public string Name; LuaTable m_table;
LuaFunction m_updateFunc;
LuaFunction m_fixedUpdateFunc; /// <summary>
/// 通过 Name 名,加载对应的 lua table,并将之“挂”在游戏对象上。
/// </summary>
/// <returns>是否加载成功</returns>
public bool Load()
{
if (string.IsNullOrEmpty(Name))
return false; m_table = LuaHelper.GetLuaTable(Name);
if (m_table == null)
return false; // Init lua
m_table["transform"] = transform;
m_table["gameObject"] = gameObject; //
m_updateFunc = GetMethod("Update");
m_fixedUpdateFunc = GetMethod("FixedUpdate"); return true;
} void Awake()
{
if (Load())
CallMethod("Awake");
else
{
if (!string.IsNullOrEmpty(Name)) // 如果 Name 为空,可能是 Add component
throw new ArgumentNullException("Load lua table failed, no table in " + Name);
}
} void Start()
{
if (m_table == null) // 此处应为 Add component 的情况
{
if (string.IsNullOrEmpty(Name))
throw new ArgumentException("string.IsNullOrEmpty(Name)"); if (!Load())
throw new ArgumentNullException("Load lua table failed, no table in " + Name);
} CallMethod("Start");
} void Update()
{
if (m_updateFunc != null)
m_updateFunc.Call(Time.deltaTime);
} void FixedUpdate()
{
if (m_fixedUpdateFunc != null)
m_fixedUpdateFunc.Call();
} void OnEnable()
{
CallMethod("OnEnable");
} void OnDisable()
{
CallMethod("OnDisable");
} void OnDestroy()
{
CallMethod("OnDestroy"); // 释放内存
m_table["transform"] = null;
m_table["gameObject"] = null; m_table.Release();
m_table = null; if (m_updateFunc != null)
m_updateFunc.Release(); if (m_fixedUpdateFunc != null)
m_fixedUpdateFunc.Release(); LuaScriptMgr.Instance.LuaGC();
} LuaFunction GetMethod(string methodName)
{
return m_table != null ? m_table[methodName] as LuaFunction : null;
} void CallMethod(string name)
{
var func = GetMethod(name); if (func != null)
{
func.Call();
func.Release(); // 释放内存
}
} public LuaTable Table
{
get { return m_table; }
}
}

LuaLoader

  

其次是 lua 与 c# 的交互,提供了两个帮助类,一个是 LuaHelper ,与游戏逻辑无关的方法封装在里面;另外一个是 LuaUtils, lua 中要访问 c# 代码的方法(与游戏逻辑有关的)都封装在里面。

LuaHelper 关键的几个方法代码如下:

using LuaInterface;
using Resource;
using System;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using UnityEngine;
using UObject = UnityEngine.Object; public static class LuaHelper
{
#region Lua public static LuaTable GetLuaComponent(Transform transform)
{
if (transform == null)
throw new ArgumentNullException("transform"); var loaders = transform.GetComponents<LuaLoader>();
var rightLoader = loaders.FirstOrDefault(lt => lt.Table != null); return rightLoader != null ? rightLoader.Table : null;
} public static LuaTable GetLuaComponent(GameObject gameObject)
{
return GetLuaComponent(gameObject.transform);
} public static LuaTable GetLuaComponent(Transform transform, string type)
{
if (transform == null)
throw new ArgumentNullException("transform");
if (string.IsNullOrEmpty(type))
throw new ArgumentException("type"); var loaders = transform.GetComponents<LuaLoader>();
var rightLoader = loaders.FirstOrDefault(lt => lt.Table != null && lt.Table.name == type); return rightLoader != null ? rightLoader.Table : null;
} public static LuaTable GetLuaComponent(GameObject gameObject, string type)
{
return GetLuaComponent(gameObject.transform, type);
} public static LuaTable AddLuaComponent(GameObject gameObject, string type)
{
var loader = gameObject.AddComponent<LuaLoader>();
loader.Name = type;
loader.Load();
return loader.Table;
} /// <summary>
/// 从ab包中加载table,供lua使用
/// </summary>
/// <param name="name">table名</param>
public static void LoadLuaTable(string name)
{
if (string.IsNullOrEmpty(name))
throw new ArgumentException("name"); LuaTable table = LuaScriptMgr.Instance.GetLuaTable(name); if (table == null)
{
using (var loadLua = new LoadLuaHandler(name))
LuaScriptMgr.Instance.DoString(loadLua.Text);
}
} public static LuaTable GetLuaTable(string name)
{
if (string.IsNullOrEmpty(name))
throw new ArgumentException("name"); LuaTable table = LuaScriptMgr.Instance.GetLuaTable(name); if (table == null)
{
using (var loadLua = new LoadLuaHandler(name))
LuaScriptMgr.Instance.DoString(loadLua.Text); table = LuaScriptMgr.Instance.GetLuaTable(name);
} return table;
} public static LuaFunction GetLuaFunction(string className, string funcName)
{
if (string.IsNullOrEmpty(className))
throw new ArgumentException(className);
if (string.IsNullOrEmpty(funcName))
throw new ArgumentException(funcName); LuaTable table = GetLuaTable(className);
return table[funcName] as LuaFunction;
} public static object[] CallFunction(string className, string funcName, params object[] args)
{
LuaFunction func = GetLuaFunction(className, funcName);
if (func == null)
throw new ArgumentNullException(string.Format("Cann't find lua function: {0}.{1}", className, funcName)); var returnArgs = args == null ? func.Call() : func.Call(args);
func.Release(); return returnArgs;
} #endregion
}

LuaHelper

另外,关于通过 lua 代码给c#打补丁的功能,是在 UIPanel OnEnable 的第一帧检测补丁和打补丁的,c#代码如下:

using LuaInterface;
using System;
using System.Collections.Generic;
using UnityEngine; public class LuaPatchManager : IDisposable
{
List<Patch> m_patches; #region Singleton static LuaPatchManager s_instance; public static LuaPatchManager Instance
{
get { return s_instance; }
} #endregion #region Patch class Patch : IDisposable
{
LuaFunction m_validate;
LuaFunction m_correct; public Patch(LuaFunction validate, LuaFunction correct)
{
if (validate == null)
throw new ArgumentNullException("validate");
if (correct == null)
throw new ArgumentNullException("correct"); m_validate = validate;
m_correct = correct;
} public bool Validate(UIPanel uiPanel)
{
var objs = m_validate.Call(uiPanel);
return (bool)objs[];
} public void Correct(UIPanel uiPanel)
{
m_correct.Call(uiPanel);
} #region IDisposable public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
} void Dispose(bool disposing)
{
if (disposing)
{
m_validate.Release();
m_validate = null;
m_correct.Release();
m_correct = null;
}
} ~Patch()
{
Dispose(false);
} #endregion
} #endregion private LuaPatchManager(LuaTable listTable)
{
if (listTable == null || listTable.Values.Count <= )
throw new ArgumentException("listTable == null || listTable.Values.Count <= 0"); m_patches = new List<Patch>(); foreach (string name in listTable.Values)
{
var patch = LuaHelper.GetLuaTable(name);
if (patch != null)
{
var validateFunc = patch["Validate"] as LuaFunction;
var correctFunc = patch["Correct"] as LuaFunction; if (validateFunc != null && correctFunc != null)
m_patches.Add(new Patch(validateFunc, correctFunc)); patch.Release();
}
} listTable.Release();
LuaScriptMgr.Instance.LuaGC();
} public static void Load()
{
LuaTable listTable = null;
string targetFileName = "LuaPatchList"; try
{
listTable = LuaHelper.GetLuaTable(targetFileName);
}
catch
{
Debug.LogWarning("No file: " + targetFileName);
} if (listTable != null)
{
if (listTable.Values.Count > )
s_instance = new LuaPatchManager(listTable); listTable.Release();
}
} public void DoPatch(UIPanel uiPanel)
{
if (uiPanel == null)
throw new ArgumentNullException("uiPanel"); for (int i = ; i < m_patches.Count; i++)
{
Patch p = m_patches[i];
if (p.Validate(uiPanel))
{
p.Correct(uiPanel);
break;
}
}
} #region IDisposable public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
} void Dispose(bool disposing)
{
if (disposing)
{
for (int i = ; i < m_patches.Count; i++)
m_patches[i].Dispose(); m_patches.Clear();
m_patches = null;
}
} ~LuaPatchManager()
{
Dispose(false);
} #endregion
}

LuaPatchManager

lua代码如下:

LuaPatchList=
{
"MainInfoControllerPatch",
};

LuaPatchList

一个补丁的例子如下:

MainInfoControllerPatch={};

local function ClickTest()
TipsShowController.Show("Who are you?");
end -- 验证此uiPanel是否是希望打补丁的uiPanel --
function MainInfoControllerPatch.Validate(uiPanel)
return uiPanel.transform.parent~=nil and uiPanel.transform.parent.name=="MainInfoController(Clone)";
end -- 纠正此uiPanel上的展示内容,执行方法等 --
function MainInfoControllerPatch.Correct(uiPanel)
local titleLabel=uiPanel.transform:Find("LabelName"):GetComponent("UILabel");
titleLabel.text="TianJie"; local mustBuyButton=uiPanel.transform:Find("ButtonFashion"):GetComponent("UIButton");
mustBuyButton.onClick:Clear();
EventDelegate.Add(mustBuyButton.onClick,DelegateFactory.EventDelegate_Callback(ClickTest));
end

Patch

转载请注明出处:http://www.cnblogs.com/jietian331/p/4955282.html

unity3d热更新解决方案,使用ulua插件开发的框架。的更多相关文章

  1. Unity3D热更新全书FAQ

    只要有程序员朋友们问过两次的问题 就会收录在此FAQ中 1.C#Light对比LUA有什么好处 C#Light是静态类型脚本语言,语法同C#,Lua是动态类型脚本语言,这两种都有人喜欢. 我更喜欢静态 ...

  2. Unity3D 热更新方案(集合各位专家的汇总)

    http://blog.csdn.net/guofeng526/article/details/52662994 热更新”这个词,在Unity3D的应用下,是有些语义错误的,但是作为大家都熟知的一项技 ...

  3. Unity3D热更新之LuaFramework篇[07]--怎么让unity对象绑定Lua脚本

    前言 在上一篇文章 Unity3D热更新之LuaFramework篇[06]--Lua中是怎么实现脚本生命周期的 中,我分析了由LuaBehaviour来实现lua脚本生命周期的方法. 但在实际使用中 ...

  4. Unity3D热更新全书-重头再来

    之前写了Unity3D热更新全书系列Blog 提出了下载.加载.脚本三个方面的开源类库 下载方面有EasyDown加载方面有GameObjParser脚本方面有C#Light另外有一个没有独立成库,但 ...

  5. Unity3D热更新全书-PageZero

    由于深刻的认识到自己是个思维跳跃的人,深入浅出是个我还要努力很久的目标,为了让大家不至于在我乱七八糟的文字中迷失,特整理目录一份 无分类 <Unity3D热更新全书-何谓热更新,为何热更新,如何 ...

  6. Unity3D热更新全书-何谓热更新,为何热更新,如何热更新

    首先来赞叹一下中文,何谓为何如何,写完才发现这三个词是如此的有规律. 为何赞叹中文?因为这是一篇针对新手程序员的文字,是一节语文课. 然后来做一下说文解字,也就是 何谓热更新 热更新,每个程序员一听就 ...

  7. Unity3D热更新之LuaFramework篇[03]--prefab加载和Button事件

    在上一篇文章 Unity3D热更新之LuaFramework篇[02]--用Lua创建自己的面板 中,我介绍了LuaFramework加载面板的方法,但这个方法并不适用于其它Prefab资源,在这套框 ...

  8. Unity3D热更新之LuaFramework篇[02]--用Lua创建自己的面板

    在上篇文章 Unity3D热更新之LuaFramework篇[01]--从零开始 中,我们了解了怎么获得一个可用的LuaFramework框架. 本篇将我会先介绍一下如何配置Lua开发环境,然后分析在 ...

  9. Unity3D热更新之LuaFramework篇[09]--资源热更新与代码热更新的具体实现

    前言 在上一篇文章 Unity3D热更新之LuaFramework篇[08]--热更新原理及热更服务器搭建 中,我介绍了热更新的基本原理,并且着手搭建一台服务器. 本篇就做一个实战练习,真正的来实现热 ...

随机推荐

  1. 转 Windows 7设置定时自动执行任务方法

    在使用电脑的时候可能会遇到一些需要无人值守让电脑自行执行任务后定时关机的情形,在Win7系统中,我们可以使用"任务计划"设置功能结合 shutdown命令灵活设置任务计划,让Win ...

  2. 1.1 sikuli 安装

    JRE7不支持sikuli,必须下载JRE6   更新号必须大于35 sikuli下载: http://www.cr173.com/soft/52775.html 或参照 http://www.cnb ...

  3. Monad / Functor / Applicative 浅析

    前言 Swift 其实比 Objective-C 复杂很多,相对于出生于上世纪 80 年代的 Objective-C 来说,Swift 融入了大量新特性.这也使得我们学习掌握这门语言变得相对来说更加困 ...

  4. USB鼠标线序

    鼠标线断了,找了个废弃的手机充电线接上,特记录线序如下: 红————白          白————橙绿————绿黑————蓝

  5. JavaScript(2)——对象属性、原型与原型链

    对象属性.原型与原型链 哈哈哈,我的第二篇博客哟,说的是对象属性.原型与原型链.可能这些只是某些小点串联起来的,逻辑性没有很强.所以会对文章的可读性和理解性带来一些困扰.不过,今天我又前进了那么一小步 ...

  6. AI 人工智能 探索 (三)

    三类子弹的设计 using UnityEngine; using System.Collections; public class AI : AssembleModel { private Hasht ...

  7. javascript语句语义大全(3)

    1. for(var i=0;i<10;i++){ } for循环,括号里面是循环条件,翻译过来是,初始设定1=0:没循环一次i会+1,直到i<10 2. var i=0: while(i ...

  8. 学习笔记——享元模式Flyweight

    Flyweight模式提供对象的复用. FlyweightFactory类似工厂模式中的工厂,生成对象并提供. 区别在于,享元的工厂会记录生成的对象,当第二次请求到相同的对象时,享元不会再生成一个新对 ...

  9. k-Means和KNN算法简述

    k-means 算法 k-means 算法接受输入量 k :然后将n个数据对象划分为 k个聚类以便使得所获得的聚类满足:同一聚类中的对象相似度较高:而不同聚类中的对象相似度较小.聚类相似度是利用各聚类 ...

  10. EL表达式,保留小数点后两位

    你遇到过页面显示小数有9.987870488E9这个吗? 这是因为没有保留小数的原因 有时候用js保留小数很麻烦的时候,可以用EL表达式 <fmt:formatNumber type=" ...