LuaFramework_UGUI_V2  https://github.com/jarjin/LuaFramework_UGUI_V2

using UnityEngine;
using LuaInterface;
using System.Collections;
using System.Collections.Generic;
using System;
using UnityEngine.UI; namespace LuaFramework {
public class LuaBehaviour : View {
private string data = null;
private Dictionary<string, LuaFunction> buttons = new Dictionary<string, LuaFunction>(); protected void 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);
} /// <summary>
/// 添加单击事件
/// </summary>
public void AddClick(GameObject go, LuaFunction luafunc) {
if (go == null || luafunc == null) return;
buttons.Add(go.name, luafunc);
go.GetComponent<Button>().onClick.AddListener(
delegate() {
luafunc.Call(go);
}
);
} /// <summary>
/// 删除单击事件
/// </summary>
/// <param name="go"></param>
public void RemoveClick(GameObject go) {
if (go == null) return;
LuaFunction luafunc = null;
if (buttons.TryGetValue(go.name, out luafunc)) {
luafunc.Dispose();
luafunc = null;
buttons.Remove(go.name);
}
} /// <summary>
/// 清除单击事件
/// </summary>
public void ClearClick() {
foreach (var de in buttons) {
if (de.Value != null) {
de.Value.Dispose();
}
}
buttons.Clear();
} //-----------------------------------------------------------------
protected void OnDestroy() {
ClearClick();
#if ASYNC_MODE
string abName = name.ToLower().Replace("panel", "");
ResManager.UnloadAssetBundle(abName + AppConst.ExtName);
#endif
Util.ClearMemory();
Debug.Log("~" + name + " was destroy!");
}
}
}

Common/LuaBehaviour

using UnityEngine;
using System.Collections;
using System.IO;
using LuaInterface; namespace LuaFramework {
/// <summary>
/// 集成自LuaFileUtils,重写里面的ReadFile,
/// </summary>
public class LuaLoader : LuaFileUtils {
private ResourceManager m_resMgr; ResourceManager resMgr {
get {
if (m_resMgr == null)
m_resMgr = AppFacade.Instance.GetManager<ResourceManager>(ManagerName.Resource);
return m_resMgr;
}
} // Use this for initialization
public LuaLoader() {
instance = this;
beZip = AppConst.LuaBundleMode;
} /// <summary>
/// 添加打入Lua代码的AssetBundle
/// </summary>
/// <param name="bundle"></param>
public void AddBundle(string bundleName) {
string url = Util.DataPath + bundleName.ToLower();
if (File.Exists(url)) {
var bytes = File.ReadAllBytes(url);
// 已注释, CreateFromMemoryImmediate从5.3开始改为LoadFromMemory,需要用的请自行取消注释~
// AssetBundle bundle = AssetBundle.CreateFromMemoryImmediate(bytes);
AssetBundle bundle = AssetBundle.LoadFromMemory(bytes);
if (bundle != null)
{
bundleName = bundleName.Replace("lua/", "").Replace(".unity3d", "");
base.AddSearchBundle(bundleName.ToLower(), bundle);
}
}
} /// <summary>
/// 当LuaVM加载Lua文件的时候,这里就会被调用,
/// 用户可以自定义加载行为,只要返回byte[]即可。
/// </summary>
/// <param name="fileName"></param>
/// <returns></returns>
public override byte[] ReadFile(string fileName) {
return base.ReadFile(fileName);
}
}
}

Common/LuaLoader

using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic; namespace LuaFramework {
public class 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 bool LuaByteMode = false; //Lua字节码模式-默认关闭
public const bool LuaBundleMode = true; //Lua代码AssetBundle模式 public const int TimerInterval = ;
public const int GameFrameRate = ; //游戏帧频 public const string AppName = "LuaFramework"; //应用程序名称
public const string LuaTempDir = "Lua/"; //临时目录
public const string AppPrefix = AppName + "_"; //应用程序前缀
public const string ExtName = ".unity3d"; //素材扩展名
public const string AssetDir = "StreamingAssets"; //素材目录
public const string WebUrl = "http://localhost:6688/"; //测试更新地址 public static string UserId = string.Empty; //用户ID
public static int SocketPort = ; //Socket服务器端口
public static string SocketAddress = string.Empty; //Socket服务器地址 public static string FrameworkRoot {
get {
return Application.dataPath + "/" + AppName;
}
}
}
}

ConstDefine/AppConst

using UnityEngine;
using System.Collections; namespace LuaFramework {
public class ManagerName {
public const string Lua = "LuaManager";
public const string Game = "GameManager";
public const string Timer = "TimeManager";
public const string Sound = "SoundManager";
public const string Panel = "PanelManager";
public const string Network = "NetworkManager";
public const string Resource = "ResourceManager";
public const string Thread = "ThreadManager";
public const string ObjectPool = "ObjectPoolManager";
}
}

ConstDefine/ManagerName

using UnityEngine;
using System.Collections; public class NotiConst
{
/// <summary>
/// Controller层消息通知
/// </summary>
public const string START_UP = "StartUp"; //启动框架
public const string DISPATCH_MESSAGE = "DispatchMessage"; //派发信息 /// <summary>
/// View层消息通知
/// </summary>
public const string UPDATE_MESSAGE = "UpdateMessage"; //更新消息
public const string UPDATE_EXTRACT = "UpdateExtract"; //更新解包
public const string UPDATE_DOWNLOAD = "UpdateDownload"; //更新下载
public const string UPDATE_PROGRESS = "UpdateProgress"; //更新进度
}

ConstDefine/NotiConst

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using LuaFramework; public class SocketCommand : ControllerCommand { public override void Execute(IMessage message) {
object data = message.Body;
if (data == null) return;
KeyValuePair<int, ByteBuffer> buffer = (KeyValuePair<int, ByteBuffer>)data;
switch (buffer.Key) {
default: Util.CallMethod("Network", "OnSocket", buffer.Key, buffer.Value); break;
}
}
}

Controller/Command/SocketCommand

using UnityEngine;
using System.Collections;
using LuaFramework; public class StartUpCommand : ControllerCommand { public override void Execute(IMessage message) {
if (!Util.CheckEnvironment()) return; GameObject gameMgr = GameObject.Find("GlobalGenerator");
if (gameMgr != null) {
AppView appView = gameMgr.AddComponent<AppView>();
}
//-----------------关联命令-----------------------
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);
AppFacade.Instance.AddManager<GameManager>(ManagerName.Game);
}
}

Controller/Command/StartUpCommand

using UnityEngine;
using System.Collections;
using LuaFramework;
using System.Collections.Generic; public class Base : MonoBehaviour {
private AppFacade m_Facade;
private LuaManager m_LuaMgr;
private ResourceManager m_ResMgr;
private NetworkManager m_NetMgr;
private SoundManager m_SoundMgr;
private TimerManager m_TimerMgr;
private ThreadManager m_ThreadMgr;
private ObjectPoolManager m_ObjectPoolMgr; /// <summary>
/// 注册消息
/// </summary>
/// <param name="view"></param>
/// <param name="messages"></param>
protected void RegisterMessage(IView view, List<string> messages) {
if (messages == null || messages.Count == ) return;
Controller.Instance.RegisterViewCommand(view, messages.ToArray());
} /// <summary>
/// 移除消息
/// </summary>
/// <param name="view"></param>
/// <param name="messages"></param>
protected void RemoveMessage(IView view, List<string> messages) {
if (messages == null || messages.Count == ) return;
Controller.Instance.RemoveViewCommand(view, messages.ToArray());
} protected AppFacade facade {
get {
if (m_Facade == null) {
m_Facade = AppFacade.Instance;
}
return m_Facade;
}
} protected LuaManager LuaManager {
get {
if (m_LuaMgr == null) {
m_LuaMgr = facade.GetManager<LuaManager>(ManagerName.Lua);
}
return m_LuaMgr;
}
} protected ResourceManager ResManager {
get {
if (m_ResMgr == null) {
m_ResMgr = facade.GetManager<ResourceManager>(ManagerName.Resource);
}
return m_ResMgr;
}
} protected NetworkManager NetManager {
get {
if (m_NetMgr == null) {
m_NetMgr = facade.GetManager<NetworkManager>(ManagerName.Network);
}
return m_NetMgr;
}
} protected SoundManager SoundManager {
get {
if (m_SoundMgr == null) {
m_SoundMgr = facade.GetManager<SoundManager>(ManagerName.Sound);
}
return m_SoundMgr;
}
} protected TimerManager TimerManager {
get {
if (m_TimerMgr == null) {
m_TimerMgr = facade.GetManager<TimerManager>(ManagerName.Timer);
}
return m_TimerMgr;
}
} protected ThreadManager ThreadManager {
get {
if (m_ThreadMgr == null) {
m_ThreadMgr = facade.GetManager<ThreadManager>(ManagerName.Thread);
}
return m_ThreadMgr;
}
} protected ObjectPoolManager ObjPoolManager {
get {
if (m_ObjectPoolMgr == null) {
m_ObjectPoolMgr = facade.GetManager<ObjectPoolManager>(ManagerName.ObjectPool);
}
return m_ObjectPoolMgr;
}
}
}

Framework/Core/Base

/*
LuaFramework Code By Jarjin lee
*/ using System;
using System.Collections.Generic;
using UnityEngine; /// <summary>
/// 事件命令
/// </summary>
public class ControllerCommand : ICommand {
public virtual void Execute(IMessage message) {
}
} public class Facade {
protected IController m_controller;
static GameObject m_GameManager;
static Dictionary<string, object> m_Managers = new Dictionary<string, object>(); GameObject AppGameManager {
get {
if (m_GameManager == null) {
m_GameManager = GameObject.Find("GameManager");
}
return m_GameManager;
}
} protected Facade() {
InitFramework();
}
protected virtual void InitFramework() {
if (m_controller != null) return;
m_controller = Controller.Instance;
} public virtual void RegisterCommand(string commandName, Type commandType) {
m_controller.RegisterCommand(commandName, commandType);
} public virtual void RemoveCommand(string commandName) {
m_controller.RemoveCommand(commandName);
} public virtual bool HasCommand(string commandName) {
return m_controller.HasCommand(commandName);
} public void RegisterMultiCommand(Type commandType, params string[] commandNames) {
int count = commandNames.Length;
for (int i = ; i < count; i++) {
RegisterCommand(commandNames[i], commandType);
}
} public void RemoveMultiCommand(params string[] commandName) {
int count = commandName.Length;
for (int i = ; i < count; i++) {
RemoveCommand(commandName[i]);
}
} public void SendMessageCommand(string message, object body = null) {
m_controller.ExecuteCommand(new Message(message, body));
} /// <summary>
/// 添加管理器
/// </summary>
public void AddManager(string typeName, object obj) {
if (!m_Managers.ContainsKey(typeName)) {
m_Managers.Add(typeName, obj);
}
} /// <summary>
/// 添加Unity对象
/// </summary>
public T AddManager<T>(string typeName) where T : Component {
object result = null;
m_Managers.TryGetValue(typeName, out result);
if (result != null) {
return (T)result;
}
Component c = AppGameManager.AddComponent<T>();
m_Managers.Add(typeName, c);
return default(T);
} /// <summary>
/// 获取系统管理器
/// </summary>
public T GetManager<T>(string typeName) where T : class {
if (!m_Managers.ContainsKey(typeName)) {
return default(T);
}
object manager = null;
m_Managers.TryGetValue(typeName, out manager);
return (T)manager;
} /// <summary>
/// 删除管理器
/// </summary>
public void RemoveManager(string typeName) {
if (!m_Managers.ContainsKey(typeName)) {
return;
}
object manager = null;
m_Managers.TryGetValue(typeName, out manager);
Type type = manager.GetType();
if (type.IsSubclassOf(typeof(MonoBehaviour))) {
GameObject.Destroy((Component)manager);
}
m_Managers.Remove(typeName);
}
}

Framework/Core/ControllerCommand, Facade

using UnityEngine;
using System.Collections;
using LuaFramework; public class Manager : Base, IManager { // Use this for initialization
void Start () { } // Update is called once per frame
void Update () { }
}

Framework/Core/Manager

/*
LuaFramework Code By Jarjin lee
*/ using System;
public class Message : IMessage
{
public Message(string name)
: this(name, null, null)
{ } public Message(string name, object body)
: this(name, body, null)
{ } public Message(string name, object body, string type)
{
m_name = name;
m_body = body;
m_type = type;
} /// <summary>
/// Get the string representation of the <c>Notification instance</c>
/// </summary>
/// <returns>The string representation of the <c>Notification</c> instance</returns>
public override string ToString()
{
string msg = "Notification Name: " + Name;
msg += "\nBody:" + ((Body == null) ? "null" : Body.ToString());
msg += "\nType:" + ((Type == null) ? "null" : Type);
return msg;
} /// <summary>
/// The name of the <c>Notification</c> instance
/// </summary>
public virtual string Name
{
get { return m_name; }
} /// <summary>
/// The body of the <c>Notification</c> instance
/// </summary>
/// <remarks>This accessor is thread safe</remarks>
public virtual object Body
{
get
{
// Setting and getting of reference types is atomic, no need to lock here
return m_body;
}
set
{
// Setting and getting of reference types is atomic, no need to lock here
m_body = value;
}
} /// <summary>
/// The type of the <c>Notification</c> instance
/// </summary>
/// <remarks>This accessor is thread safe</remarks>
public virtual string Type
{
get
{
// Setting and getting of reference types is atomic, no need to lock here
return m_type;
}
set
{
// Setting and getting of reference types is atomic, no need to lock here
m_type = value;
}
} /// <summary>
/// The name of the notification instance
/// </summary>
private string m_name; /// <summary>
/// The type of the notification instance
/// </summary>
private string m_type; /// <summary>
/// The body of the notification instance
/// </summary>
private object m_body;
}

Framework/Core/Message

using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;
using LuaInterface;
using LuaFramework; public class View : Base, IView {
public virtual void OnMessage(IMessage message) {
}
}

Framework/Core/View

/*
LuaFramework Code By Jarjin lee
*/
using System; public interface ICommand {
void Execute(IMessage message);
}

Framework/Interface/ICommand

/*
LuaFramework Code By Jarjin leeibution 3.0 License
*/
using System;
using System.Collections.Generic; public interface IController
{
void RegisterCommand(string messageName, Type commandType);
void RegisterViewCommand(IView view, string[] commandNames); void ExecuteCommand(IMessage message); void RemoveCommand(string messageName);
void RemoveViewCommand(IView view, string[] commandNames); bool HasCommand(string messageName);
}

Framework/Interface/IController

/*
LuaFramework Code By Jarjin leeibution 3.0 License
*/ using UnityEngine;
using System.Collections; public interface IManager {
}

Framework/Interface/IManager

/*
LuaFramework Code By Jarjin lee
*/
using System; public interface IMessage
{
string Name { get; } object Body { get; set; } string Type { get; set; } string ToString();
}

Framework/Interface/IMessage

using System;

public interface IView {
void OnMessage(IMessage message);
}

Framework/Interface/IView

using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic; public class AppFacade : Facade
{
private static AppFacade _instance; public AppFacade() : base()
{
} public static AppFacade Instance
{
get{
if (_instance == null) {
_instance = new AppFacade();
}
return _instance;
}
} override protected void InitFramework()
{
base.InitFramework();
RegisterCommand(NotiConst.START_UP, typeof(StartUpCommand));
} /// <summary>
/// 启动框架
/// </summary>
public void StartUp() {
SendMessageCommand(NotiConst.START_UP);
RemoveMultiCommand(NotiConst.START_UP);
}
}

Framework/AppFacade

using System;
using System.Collections; namespace LuaFramework {
public interface ITimerBehaviour {
void TimerUpdate();
}
}

Manager/Interface

using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;
using LuaInterface;
using System.Reflection;
using System.IO; namespace LuaFramework {
public class GameManager : Manager {
protected static bool initialize = false;
private List<string> downloadFiles = new List<string>(); /// <summary>
/// 初始化游戏管理器
/// </summary>
void Awake() {
Init();
} /// <summary>
/// 初始化
/// </summary>
void Init() {
DontDestroyOnLoad(gameObject); //防止销毁自己 CheckExtractResource(); //释放资源
Screen.sleepTimeout = SleepTimeout.NeverSleep;
Application.targetFrameRate = AppConst.GameFrameRate;
} /// <summary>
/// 释放资源
/// </summary>
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()); //启动释放协成
} IEnumerator OnExtractResource() {
string dataPath = Util.DataPath; //数据目录
string resPath = Util.AppContentPath(); //游戏包资源目录 if (Directory.Exists(dataPath)) Directory.Delete(dataPath, true);
Directory.CreateDirectory(dataPath); string infile = resPath + "files.txt";
string outfile = dataPath + "files.txt";
if (File.Exists(outfile)) File.Delete(outfile); string message = "正在解包文件:>files.txt";
Debug.Log(infile);
Debug.Log(outfile);
if (Application.platform == RuntimePlatform.Android) {
WWW www = new WWW(infile);
yield return www; if (www.isDone) {
File.WriteAllBytes(outfile, www.bytes);
}
yield return ;
} else File.Copy(infile, outfile, true);
yield return new WaitForEndOfFrame(); //释放所有文件到数据目录
string[] files = File.ReadAllLines(outfile);
foreach (var file in files) {
string[] fs = file.Split('|');
infile = resPath + fs[]; //
outfile = dataPath + fs[]; message = "正在解包文件:>" + fs[];
Debug.Log("正在解包文件:>" + infile);
facade.SendMessageCommand(NotiConst.UPDATE_MESSAGE, message); string dir = Path.GetDirectoryName(outfile);
if (!Directory.Exists(dir)) Directory.CreateDirectory(dir); if (Application.platform == RuntimePlatform.Android) {
WWW www = new WWW(infile);
yield return www; if (www.isDone) {
File.WriteAllBytes(outfile, www.bytes);
}
yield return ;
} else {
if (File.Exists(outfile)) {
File.Delete(outfile);
}
File.Copy(infile, outfile, true);
}
yield return new WaitForEndOfFrame();
}
message = "解包完成!!!";
facade.SendMessageCommand(NotiConst.UPDATE_MESSAGE, message);
yield return new WaitForSeconds(0.1f); message = string.Empty;
//释放完成,开始启动更新资源
StartCoroutine(OnUpdateResource());
} /// <summary>
/// 启动更新下载,这里只是个思路演示,此处可启动线程下载更新
/// </summary>
IEnumerator OnUpdateResource() {
if (!AppConst.UpdateMode) {
OnResourceInited();
yield break;
}
string dataPath = Util.DataPath; //数据目录
string url = AppConst.WebUrl;
string message = string.Empty;
string random = DateTime.Now.ToString("yyyymmddhhmmss");
string listUrl = url + "files.txt?v=" + random;
Debug.LogWarning("LoadUpdate---->>>" + listUrl); WWW www = new WWW(listUrl); yield return www;
if (www.error != null) {
OnUpdateFailed(string.Empty);
yield break;
}
if (!Directory.Exists(dataPath)) {
Directory.CreateDirectory(dataPath);
}
File.WriteAllBytes(dataPath + "files.txt", www.bytes);
string filesText = www.text;
string[] files = filesText.Split('\n'); for (int i = ; i < files.Length; i++) {
if (string.IsNullOrEmpty(files[i])) continue;
string[] keyValue = files[i].Split('|');
string f = keyValue[];
string localfile = (dataPath + f).Trim();
string path = Path.GetDirectoryName(localfile);
if (!Directory.Exists(path)) {
Directory.CreateDirectory(path);
}
string fileUrl = url + f + "?v=" + random;
bool canUpdate = !File.Exists(localfile);
if (!canUpdate) {
string remoteMd5 = keyValue[].Trim();
string localMd5 = Util.md5file(localfile);
canUpdate = !remoteMd5.Equals(localMd5);
if (canUpdate) File.Delete(localfile);
}
if (canUpdate) { //本地缺少文件
Debug.Log(fileUrl);
message = "downloading>>" + fileUrl;
facade.SendMessageCommand(NotiConst.UPDATE_MESSAGE, message);
/*
www = new WWW(fileUrl); yield return www;
if (www.error != null) {
OnUpdateFailed(path); //
yield break;
}
File.WriteAllBytes(localfile, www.bytes);
*/
//这里都是资源文件,用线程下载
BeginDownload(fileUrl, localfile);
while (!(IsDownOK(localfile))) { yield return new WaitForEndOfFrame(); }
}
}
yield return new WaitForEndOfFrame(); message = "更新完成!!";
facade.SendMessageCommand(NotiConst.UPDATE_MESSAGE, message); OnResourceInited();
} void OnUpdateFailed(string file) {
string message = "更新失败!>" + file;
facade.SendMessageCommand(NotiConst.UPDATE_MESSAGE, message);
} /// <summary>
/// 是否下载完成
/// </summary>
bool IsDownOK(string file) {
return downloadFiles.Contains(file);
} /// <summary>
/// 线程下载
/// </summary>
void BeginDownload(string url, string file) { //线程下载
object[] param = new object[] { url, file }; ThreadEvent ev = new ThreadEvent();
ev.Key = NotiConst.UPDATE_DOWNLOAD;
ev.evParams.AddRange(param);
ThreadManager.AddEvent(ev, OnThreadCompleted); //线程下载
} /// <summary>
/// 线程完成
/// </summary>
/// <param name="data"></param>
void OnThreadCompleted(NotiData data) {
switch (data.evName) {
case NotiConst.UPDATE_EXTRACT: //解压一个完成
//
break;
case NotiConst.UPDATE_DOWNLOAD: //下载一个完成
downloadFiles.Add(data.evParam.ToString());
break;
}
} /// <summary>
/// 资源初始化结束
/// </summary>
public void OnResourceInited() {
#if ASYNC_MODE
ResManager.Initialize(AppConst.AssetDir, delegate() {
Debug.Log("Initialize OK!!!");
this.OnInitialize();
});
#else
ResManager.Initialize();
this.OnInitialize();
#endif
} void OnInitialize() {
LuaManager.InitStart();
LuaManager.DoFile("Logic/Game"); //加载游戏
LuaManager.DoFile("Logic/Network"); //加载网络
NetManager.OnInit(); //初始化网络
Util.CallMethod("Game", "OnInitOK"); //初始化完成 initialize = true; //类对象池测试
var classObjPool = ObjPoolManager.CreatePool<TestObjectClass>(OnPoolGetElement, OnPoolPushElement);
//方法1
//objPool.Release(new TestObjectClass("abcd", 100, 200f));
//var testObj1 = objPool.Get(); //方法2
ObjPoolManager.Release<TestObjectClass>(new TestObjectClass("abcd", , 200f));
var testObj1 = ObjPoolManager.Get<TestObjectClass>(); Debugger.Log("TestObjectClass--->>>" + testObj1.ToString()); //游戏对象池测试
var prefab = Resources.Load("TestGameObjectPrefab", typeof(GameObject)) as GameObject;
var gameObjPool = ObjPoolManager.CreatePool("TestGameObject", , , prefab); var gameObj = Instantiate(prefab) as GameObject;
gameObj.name = "TestGameObject_01";
gameObj.transform.localScale = Vector3.one;
gameObj.transform.localPosition = Vector3.zero; ObjPoolManager.Release("TestGameObject", gameObj);
var backObj = ObjPoolManager.Get("TestGameObject");
backObj.transform.SetParent(null); Debug.Log("TestGameObject--->>>" + backObj);
} /// <summary>
/// 当从池子里面获取时
/// </summary>
/// <param name="obj"></param>
void OnPoolGetElement(TestObjectClass obj) {
Debug.Log("OnPoolGetElement--->>>" + obj);
} /// <summary>
/// 当放回池子里面时
/// </summary>
/// <param name="obj"></param>
void OnPoolPushElement(TestObjectClass obj) {
Debug.Log("OnPoolPushElement--->>>" + obj);
} /// <summary>
/// 析构函数
/// </summary>
void OnDestroy() {
if (NetManager != null) {
NetManager.Unload();
}
if (LuaManager != null) {
LuaManager.Close();
}
Debug.Log("~GameManager was destroyed");
}
}
}

Manager/GameManager

using UnityEngine;
using System.Collections;
using LuaInterface; namespace LuaFramework {
public class LuaManager : Manager {
private LuaState lua;
private LuaLoader loader;
private LuaLooper loop = null; // Use this for initialization
void Awake() {
loader = new LuaLoader();
lua = new LuaState();
this.OpenLibs();
lua.LuaSetTop(); LuaBinder.Bind(lua);
DelegateFactory.Init();
LuaCoroutine.Register(lua, this);
} public void InitStart() {
InitLuaPath();
InitLuaBundle();
this.lua.Start(); //启动LUAVM
this.StartMain();
this.StartLooper();
} void StartLooper() {
loop = gameObject.AddComponent<LuaLooper>();
loop.luaState = lua;
} //cjson 比较特殊,只new了一个table,没有注册库,这里注册一下
protected void OpenCJson() {
lua.LuaGetField(LuaIndexes.LUA_REGISTRYINDEX, "_LOADED");
lua.OpenLibs(LuaDLL.luaopen_cjson);
lua.LuaSetField(-, "cjson"); lua.OpenLibs(LuaDLL.luaopen_cjson_safe);
lua.LuaSetField(-, "cjson.safe");
} void StartMain() {
lua.DoFile("Main.lua"); LuaFunction main = lua.GetFunction("Main");
main.Call();
main.Dispose();
main = null;
} /// <summary>
/// 初始化加载第三方库
/// </summary>
void OpenLibs() {
lua.OpenLibs(LuaDLL.luaopen_pb);
lua.OpenLibs(LuaDLL.luaopen_sproto_core);
lua.OpenLibs(LuaDLL.luaopen_protobuf_c);
lua.OpenLibs(LuaDLL.luaopen_lpeg);
lua.OpenLibs(LuaDLL.luaopen_bit);
lua.OpenLibs(LuaDLL.luaopen_socket_core); this.OpenCJson();
} /// <summary>
/// 初始化Lua代码加载路径
/// </summary>
void InitLuaPath() {
if (AppConst.DebugMode) {
string rootPath = AppConst.FrameworkRoot;
lua.AddSearchPath(rootPath + "/Lua");
lua.AddSearchPath(rootPath + "/ToLua/Lua");
} else {
lua.AddSearchPath(Util.DataPath + "lua");
}
} /// <summary>
/// 初始化LuaBundle
/// </summary>
void InitLuaBundle() {
if (loader.beZip) {
loader.AddBundle("lua/lua.unity3d");
loader.AddBundle("lua/lua_math.unity3d");
loader.AddBundle("lua/lua_system.unity3d");
loader.AddBundle("lua/lua_system_reflection.unity3d");
loader.AddBundle("lua/lua_unityengine.unity3d");
loader.AddBundle("lua/lua_common.unity3d");
loader.AddBundle("lua/lua_logic.unity3d");
loader.AddBundle("lua/lua_view.unity3d");
loader.AddBundle("lua/lua_controller.unity3d");
loader.AddBundle("lua/lua_misc.unity3d"); loader.AddBundle("lua/lua_protobuf.unity3d");
loader.AddBundle("lua/lua_3rd_cjson.unity3d");
loader.AddBundle("lua/lua_3rd_luabitop.unity3d");
loader.AddBundle("lua/lua_3rd_pbc.unity3d");
loader.AddBundle("lua/lua_3rd_pblua.unity3d");
loader.AddBundle("lua/lua_3rd_sproto.unity3d");
}
} public void DoFile(string filename) {
lua.DoFile(filename);
} // Update is called once per frame
public object[] CallFunction(string funcName, params object[] args) {
LuaFunction func = lua.GetFunction(funcName);
if (func != null) {
return func.LazyCall(args);
}
return null;
} public void LuaGC() {
lua.LuaGC(LuaGCOptions.LUA_GCCOLLECT);
} public void Close() {
loop.Destroy();
loop = null; lua.Dispose();
lua = null;
loader = null;
}
}
}

Manager/LuaManager

using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;
using LuaInterface; namespace LuaFramework {
public class NetworkManager : Manager {
private SocketClient socket;
static readonly object m_lockObject = new object();
static Queue<KeyValuePair<int, ByteBuffer>> mEvents = new Queue<KeyValuePair<int, ByteBuffer>>(); SocketClient SocketClient {
get {
if (socket == null)
socket = new SocketClient();
return socket;
}
} void Awake() {
Init();
} void Init() {
SocketClient.OnRegister();
} public void OnInit() {
CallMethod("Start");
} public void Unload() {
CallMethod("Unload");
} /// <summary>
/// 执行Lua方法
/// </summary>
public object[] CallMethod(string func, params object[] args) {
return Util.CallMethod("Network", func, args);
} ///------------------------------------------------------------------------------------
public static void AddEvent(int _event, ByteBuffer data) {
lock (m_lockObject) {
mEvents.Enqueue(new KeyValuePair<int, ByteBuffer>(_event, data));
}
} /// <summary>
/// 交给Command,这里不想关心发给谁。
/// </summary>
void Update() {
if (mEvents.Count > ) {
while (mEvents.Count > ) {
KeyValuePair<int, ByteBuffer> _event = mEvents.Dequeue();
facade.SendMessageCommand(NotiConst.DISPATCH_MESSAGE, _event);
}
}
} /// <summary>
/// 发送链接请求
/// </summary>
public void SendConnect() {
SocketClient.SendConnect();
} /// <summary>
/// 发送SOCKET消息
/// </summary>
public void SendMessage(ByteBuffer buffer) {
SocketClient.SendMessage(buffer);
} /// <summary>
/// 析构函数
/// </summary>
new void OnDestroy() {
SocketClient.OnRemove();
Debug.Log("~NetworkManager was destroy");
}
}
}

Manager/NetworkManager

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.Events; namespace LuaFramework {
/// <summary>
/// 对象池管理器,分普通类对象池+资源游戏对象池
/// </summary>
public class ObjectPoolManager : Manager {
private Transform m_PoolRootObject = null;
private Dictionary<string, object> m_ObjectPools = new Dictionary<string, object>();
private Dictionary<string, GameObjectPool> m_GameObjectPools = new Dictionary<string, GameObjectPool>(); Transform PoolRootObject {
get {
if (m_PoolRootObject == null) {
var objectPool = new GameObject("ObjectPool");
objectPool.transform.SetParent(transform);
objectPool.transform.localScale = Vector3.one;
objectPool.transform.localPosition = Vector3.zero;
m_PoolRootObject = objectPool.transform;
}
return m_PoolRootObject;
}
} public GameObjectPool CreatePool(string poolName, int initSize, int maxSize, GameObject prefab) {
var pool = new GameObjectPool(poolName, prefab, initSize, maxSize, PoolRootObject);
m_GameObjectPools[poolName] = pool;
return pool;
} public GameObjectPool GetPool(string poolName) {
if (m_GameObjectPools.ContainsKey(poolName)) {
return m_GameObjectPools[poolName];
}
return null;
} public GameObject Get(string poolName) {
GameObject result = null;
if (m_GameObjectPools.ContainsKey(poolName)) {
GameObjectPool pool = m_GameObjectPools[poolName];
result = pool.NextAvailableObject();
if (result == null) {
Debug.LogWarning("No object available in pool. Consider setting fixedSize to false.: " + poolName);
}
} else {
Debug.LogError("Invalid pool name specified: " + poolName);
}
return result;
} public void Release(string poolName, GameObject go) {
if (m_GameObjectPools.ContainsKey(poolName)) {
GameObjectPool pool = m_GameObjectPools[poolName];
pool.ReturnObjectToPool(poolName, go);
} else {
Debug.LogWarning("No pool available with name: " + poolName);
}
} ///----------------------------------------------------------------------------------------------- public ObjectPool<T> CreatePool<T>(UnityAction<T> actionOnGet, UnityAction<T> actionOnRelease) where T : class {
var type = typeof(T);
var pool = new ObjectPool<T>(actionOnGet, actionOnRelease);
m_ObjectPools[type.Name] = pool;
return pool;
} public ObjectPool<T> GetPool<T>() where T : class {
var type = typeof(T);
ObjectPool<T> pool = null;
if (m_ObjectPools.ContainsKey(type.Name)) {
pool = m_ObjectPools[type.Name] as ObjectPool<T>;
}
return pool;
} public T Get<T>() where T : class {
var pool = GetPool<T>();
if (pool != null) {
return pool.Get();
}
return default(T);
} public void Release<T>(T obj) where T : class {
var pool = GetPool<T>();
if (pool != null) {
pool.Release(obj);
}
}
}
}

Manager/ObjectPoolManager

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.UI;
using LuaInterface; namespace LuaFramework {
public class PanelManager : Manager {
private Transform parent; Transform Parent {
get {
if (parent == null) {
GameObject go = GameObject.FindWithTag("GuiCamera");
if (go != null) parent = go.transform;
}
return parent;
}
} /// <summary>
/// ������壬������Դ������
/// </summary>
/// <param name="type"></param>
public void CreatePanel(string name, LuaFunction func = null) {
string assetName = name + "Panel";
string abName = name.ToLower() + AppConst.ExtName;
if (Parent.Find(name) != null) return; #if ASYNC_MODE
ResManager.LoadPrefab(abName, assetName, delegate(UnityEngine.Object[] objs) {
if (objs.Length == ) return;
GameObject prefab = objs[] as GameObject;
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;
go.AddComponent<LuaBehaviour>(); if (func != null) func.Call(go);
Debug.LogWarning("CreatePanel::>> " + name + " " + prefab);
});
#else
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;
go.AddComponent<LuaBehaviour>(); if (func != null) func.Call(go);
Debug.LogWarning("CreatePanel::>> " + name + " " + prefab);
#endif
} /// <summary>
/// �ر����
/// </summary>
/// <param name="name"></param>
public void ClosePanel(string name) {
var panelName = name + "Panel";
var panelObj = Parent.Find(panelName);
if (panelObj == null) return;
Destroy(panelObj.gameObject);
}
}
}

Manager/PanelManager

#if ASYNC_MODE
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;
using System.IO;
using LuaInterface;
using UObject = UnityEngine.Object; public class AssetBundleInfo {
public AssetBundle m_AssetBundle;
public int m_ReferencedCount; public AssetBundleInfo(AssetBundle assetBundle) {
m_AssetBundle = assetBundle;
m_ReferencedCount = ;
}
} namespace LuaFramework { public class ResourceManager : Manager {
string m_BaseDownloadingURL = "";
string[] m_AllManifest = null;
AssetBundleManifest m_AssetBundleManifest = null;
Dictionary<string, string[]> m_Dependencies = new Dictionary<string, string[]>();
Dictionary<string, AssetBundleInfo> m_LoadedAssetBundles = new Dictionary<string, AssetBundleInfo>();
Dictionary<string, List<LoadAssetRequest>> m_LoadRequests = new Dictionary<string, List<LoadAssetRequest>>(); class LoadAssetRequest {
public Type assetType;
public string[] assetNames;
public LuaFunction luaFunc;
public Action<UObject[]> sharpFunc;
} // Load AssetBundleManifest.
public void Initialize(string manifestName, Action initOK) {
m_BaseDownloadingURL = Util.GetRelativePath();
LoadAsset<AssetBundleManifest>(manifestName, new string[] { "AssetBundleManifest" }, delegate(UObject[] objs) {
if (objs.Length > ) {
m_AssetBundleManifest = objs[] as AssetBundleManifest;
m_AllManifest = m_AssetBundleManifest.GetAllAssetBundles();
}
if (initOK != null) initOK();
});
} public void LoadPrefab(string abName, string assetName, Action<UObject[]> func) {
LoadAsset<GameObject>(abName, new string[] { assetName }, func);
} public void LoadPrefab(string abName, string[] assetNames, Action<UObject[]> func) {
LoadAsset<GameObject>(abName, assetNames, func);
} public void LoadPrefab(string abName, string[] assetNames, LuaFunction func) {
LoadAsset<GameObject>(abName, assetNames, null, func);
} string GetRealAssetPath(string abName) {
if (abName.Equals(AppConst.AssetDir)) {
return abName;
}
abName = abName.ToLower();
if (!abName.EndsWith(AppConst.ExtName)) {
abName += AppConst.ExtName;
}
if (abName.Contains("/")) {
return abName;
}
//string[] paths = m_AssetBundleManifest.GetAllAssetBundles(); 产生GC,需要缓存结果
for (int i = ; i < m_AllManifest.Length; i++) {
int index = m_AllManifest[i].LastIndexOf('/');
string path = m_AllManifest[i].Remove(, index + ); //字符串操作函数都会产生GC
if (path.Equals(abName)) {
return m_AllManifest[i];
}
}
Debug.LogError("GetRealAssetPath Error:>>" + abName);
return null;
} /// <summary>
/// 载入素材
/// </summary>
void LoadAsset<T>(string abName, string[] assetNames, Action<UObject[]> action = null, LuaFunction func = null) where T : UObject {
abName = GetRealAssetPath(abName); LoadAssetRequest request = new LoadAssetRequest();
request.assetType = typeof(T);
request.assetNames = assetNames;
request.luaFunc = func;
request.sharpFunc = action; List<LoadAssetRequest> requests = null;
if (!m_LoadRequests.TryGetValue(abName, out requests)) {
requests = new List<LoadAssetRequest>();
requests.Add(request);
m_LoadRequests.Add(abName, requests);
StartCoroutine(OnLoadAsset<T>(abName));
} else {
requests.Add(request);
}
} IEnumerator OnLoadAsset<T>(string abName) where T : UObject {
Debug.Log(abName); AssetBundleInfo bundleInfo = GetLoadedAssetBundle(abName);
if (bundleInfo == null) {
yield return StartCoroutine(OnLoadAssetBundle(abName, typeof(T))); bundleInfo = GetLoadedAssetBundle(abName);
if (bundleInfo == null) {
m_LoadRequests.Remove(abName);
Debug.LogError("OnLoadAsset--->>>" + abName);
yield break;
}
}
List<LoadAssetRequest> list = null;
if (!m_LoadRequests.TryGetValue(abName, out list)) {
m_LoadRequests.Remove(abName);
yield break;
}
for (int i = ; i < list.Count; i++) {
string[] assetNames = list[i].assetNames;
List<UObject> result = new List<UObject>(); AssetBundle ab = bundleInfo.m_AssetBundle;
for (int j = ; j < assetNames.Length; j++) {
string assetPath = assetNames[j];
AssetBundleRequest request = ab.LoadAssetAsync(assetPath, list[i].assetType);
yield return request;
result.Add(request.asset); //T assetObj = ab.LoadAsset<T>(assetPath);
//result.Add(assetObj);
}
if (list[i].sharpFunc != null) {
list[i].sharpFunc(result.ToArray());
list[i].sharpFunc = null;
}
if (list[i].luaFunc != null) {
list[i].luaFunc.Call((object)result.ToArray());
list[i].luaFunc.Dispose();
list[i].luaFunc = null;
}
bundleInfo.m_ReferencedCount++;
}
m_LoadRequests.Remove(abName);
} IEnumerator OnLoadAssetBundle(string abName, Type type) {
string url = m_BaseDownloadingURL + abName; WWW download = null;
if (type == typeof(AssetBundleManifest))
download = new WWW(url);
else {
string[] dependencies = m_AssetBundleManifest.GetAllDependencies(abName);
if (dependencies.Length > ) {
m_Dependencies.Add(abName, dependencies);
for (int i = ; i < dependencies.Length; i++) {
string depName = dependencies[i];
AssetBundleInfo bundleInfo = null;
if (m_LoadedAssetBundles.TryGetValue(depName, out bundleInfo)) {
bundleInfo.m_ReferencedCount++;
} else if (!m_LoadRequests.ContainsKey(depName)) {
yield return StartCoroutine(OnLoadAssetBundle(depName, type));
}
}
}
download = WWW.LoadFromCacheOrDownload(url, m_AssetBundleManifest.GetAssetBundleHash(abName), );
}
yield return download; AssetBundle assetObj = download.assetBundle;
if (assetObj != null) {
m_LoadedAssetBundles.Add(abName, new AssetBundleInfo(assetObj));
}
} AssetBundleInfo GetLoadedAssetBundle(string abName) {
AssetBundleInfo bundle = null;
m_LoadedAssetBundles.TryGetValue(abName, out bundle);
if (bundle == null) return null; // No dependencies are recorded, only the bundle itself is required.
string[] dependencies = null;
if (!m_Dependencies.TryGetValue(abName, out dependencies))
return bundle; // Make sure all dependencies are loaded
foreach (var dependency in dependencies) {
AssetBundleInfo dependentBundle;
m_LoadedAssetBundles.TryGetValue(dependency, out dependentBundle);
if (dependentBundle == null) return null;
}
return bundle;
} /// <summary>
/// 此函数交给外部卸载专用,自己调整是否需要彻底清除AB
/// </summary>
/// <param name="abName"></param>
/// <param name="isThorough"></param>
public void UnloadAssetBundle(string abName, bool isThorough = false) {
abName = GetRealAssetPath(abName);
Debug.Log(m_LoadedAssetBundles.Count + " assetbundle(s) in memory before unloading " + abName);
UnloadAssetBundleInternal(abName, isThorough);
UnloadDependencies(abName, isThorough);
Debug.Log(m_LoadedAssetBundles.Count + " assetbundle(s) in memory after unloading " + abName);
} void UnloadDependencies(string abName, bool isThorough) {
string[] dependencies = null;
if (!m_Dependencies.TryGetValue(abName, out dependencies))
return; // Loop dependencies.
foreach (var dependency in dependencies) {
UnloadAssetBundleInternal(dependency, isThorough);
}
m_Dependencies.Remove(abName);
} void UnloadAssetBundleInternal(string abName, bool isThorough) {
AssetBundleInfo bundle = GetLoadedAssetBundle(abName);
if (bundle == null) return; if (--bundle.m_ReferencedCount <= ) {
if (m_LoadRequests.ContainsKey(abName)) {
return; //如果当前AB处于Async Loading过程中,卸载会崩溃,只减去引用计数即可
}
bundle.m_AssetBundle.Unload(isThorough);
m_LoadedAssetBundles.Remove(abName);
Debug.Log(abName + " has been unloaded successfully");
}
}
}
}
#else using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using LuaFramework;
using LuaInterface;
using UObject = UnityEngine.Object; namespace LuaFramework {
public class ResourceManager : Manager {
private string[] m_Variants = { };
private AssetBundleManifest manifest;
private AssetBundle shared, assetbundle;
private Dictionary<string, AssetBundle> bundles; void Awake() {
} /// <summary>
/// 初始化
/// </summary>
public void Initialize() {
byte[] stream = null;
string uri = string.Empty;
bundles = new Dictionary<string, AssetBundle>();
uri = Util.DataPath + AppConst.AssetDir;
if (!File.Exists(uri)) return;
stream = File.ReadAllBytes(uri);
assetbundle = AssetBundle.CreateFromMemoryImmediate(stream);
manifest = assetbundle.LoadAsset<AssetBundleManifest>("AssetBundleManifest");
} /// <summary>
/// 载入素材
/// </summary>
public T LoadAsset<T>(string abname, string assetname) where T : UnityEngine.Object {
abname = abname.ToLower();
AssetBundle bundle = LoadAssetBundle(abname);
return bundle.LoadAsset<T>(assetname);
} public void LoadPrefab(string abName, string[] assetNames, LuaFunction func) {
abName = abName.ToLower();
List<UObject> result = new List<UObject>();
for (int i = ; i < assetNames.Length; i++) {
UObject go = LoadAsset<UObject>(abName, assetNames[i]);
if (go != null) result.Add(go);
}
if (func != null) func.Call((object)result.ToArray());
} /// <summary>
/// 载入AssetBundle
/// </summary>
/// <param name="abname"></param>
/// <returns></returns>
public AssetBundle LoadAssetBundle(string abname) {
if (!abname.EndsWith(AppConst.ExtName)) {
abname += AppConst.ExtName;
}
AssetBundle bundle = null;
if (!bundles.ContainsKey(abname)) {
byte[] stream = null;
string uri = Util.DataPath + abname;
Debug.LogWarning("LoadFile::>> " + uri);
LoadDependencies(abname); stream = File.ReadAllBytes(uri);
bundle = AssetBundle.CreateFromMemoryImmediate(stream); //关联数据的素材绑定
bundles.Add(abname, bundle);
} else {
bundles.TryGetValue(abname, out bundle);
}
return bundle;
} /// <summary>
/// 载入依赖
/// </summary>
/// <param name="name"></param>
void LoadDependencies(string name) {
if (manifest == null) {
Debug.LogError("Please initialize AssetBundleManifest by calling AssetBundleManager.Initialize()");
return;
}
// Get dependecies from the AssetBundleManifest object..
string[] dependencies = manifest.GetAllDependencies(name);
if (dependencies.Length == ) return; for (int i = ; i < dependencies.Length; i++)
dependencies[i] = RemapVariantName(dependencies[i]); // Record and load all dependencies.
for (int i = ; i < dependencies.Length; i++) {
LoadAssetBundle(dependencies[i]);
}
} // Remaps the asset bundle name to the best fitting asset bundle variant.
string RemapVariantName(string assetBundleName) {
string[] bundlesWithVariant = manifest.GetAllAssetBundlesWithVariant(); // If the asset bundle doesn't have variant, simply return.
if (System.Array.IndexOf(bundlesWithVariant, assetBundleName) < )
return assetBundleName; string[] split = assetBundleName.Split('.'); int bestFit = int.MaxValue;
int bestFitIndex = -;
// Loop all the assetBundles with variant to find the best fit variant assetBundle.
for (int i = ; i < bundlesWithVariant.Length; i++) {
string[] curSplit = bundlesWithVariant[i].Split('.');
if (curSplit[] != split[])
continue; int found = System.Array.IndexOf(m_Variants, curSplit[]);
if (found != - && found < bestFit) {
bestFit = found;
bestFitIndex = i;
}
}
if (bestFitIndex != -)
return bundlesWithVariant[bestFitIndex];
else
return assetBundleName;
} /// <summary>
/// 销毁资源
/// </summary>
void OnDestroy() {
if (shared != null) shared.Unload(true);
if (manifest != null) manifest = null;
Debug.Log("~ResourceManager was destroy!");
}
}
}
#endif

Manager/ResourceManager, AssetBundleInfo

using UnityEngine;
using System.Collections;
using System.Collections.Generic; namespace LuaFramework {
public class SoundManager : Manager {
private AudioSource audio;
private Hashtable sounds = new Hashtable(); void Start() {
audio = GetComponent<AudioSource>();
} /// <summary>
/// 添加一个声音
/// </summary>
void Add(string key, AudioClip value) {
if (sounds[key] != null || value == null) return;
sounds.Add(key, value);
} /// <summary>
/// 获取一个声音
/// </summary>
AudioClip Get(string key) {
if (sounds[key] == null) return null;
return sounds[key] as AudioClip;
} /// <summary>
/// 载入一个音频
/// </summary>
public AudioClip LoadAudioClip(string path) {
AudioClip ac = Get(path);
if (ac == null) {
ac = (AudioClip)Resources.Load(path, typeof(AudioClip));
Add(path, ac);
}
return ac;
} /// <summary>
/// 是否播放背景音乐,默认是1:播放
/// </summary>
/// <returns></returns>
public bool CanPlayBackSound() {
string key = AppConst.AppPrefix + "BackSound";
int i = PlayerPrefs.GetInt(key, );
return i == ;
} /// <summary>
/// 播放背景音乐
/// </summary>
/// <param name="canPlay"></param>
public void PlayBacksound(string name, bool canPlay) {
if (audio.clip != null) {
if (name.IndexOf(audio.clip.name) > -) {
if (!canPlay) {
audio.Stop();
audio.clip = null;
Util.ClearMemory();
}
return;
}
}
if (canPlay) {
audio.loop = true;
audio.clip = LoadAudioClip(name);
audio.Play();
} else {
audio.Stop();
audio.clip = null;
Util.ClearMemory();
}
} /// <summary>
/// 是否播放音效,默认是1:播放
/// </summary>
/// <returns></returns>
public bool CanPlaySoundEffect() {
string key = AppConst.AppPrefix + "SoundEffect";
int i = PlayerPrefs.GetInt(key, );
return i == ;
} /// <summary>
/// 播放音频剪辑
/// </summary>
/// <param name="clip"></param>
/// <param name="position"></param>
public void Play(AudioClip clip, Vector3 position) {
if (!CanPlaySoundEffect()) return;
AudioSource.PlayClipAtPoint(clip, position);
}
}
}

Manager/SoundManager

using System.Collections;
using System.Threading;
using System.Collections.Generic;
using System.IO;
using System.Diagnostics;
using System.Net;
using System; public class ThreadEvent {
public string Key;
public List<object> evParams = new List<object>();
} public class NotiData {
public string evName;
public object evParam; public NotiData(string name, object param) {
this.evName = name;
this.evParam = param;
}
} namespace LuaFramework {
/// <summary>
/// 当前线程管理器,同时只能做一个任务
/// </summary>
public class ThreadManager : Manager {
private Thread thread;
private Action<NotiData> func;
private Stopwatch sw = new Stopwatch();
private string currDownFile = string.Empty; static readonly object m_lockObject = new object();
static Queue<ThreadEvent> events = new Queue<ThreadEvent>(); delegate void ThreadSyncEvent(NotiData data);
private ThreadSyncEvent m_SyncEvent; void Awake() {
m_SyncEvent = OnSyncEvent;
thread = new Thread(OnUpdate);
} // Use this for initialization
void Start() {
thread.Start();
} /// <summary>
/// 添加到事件队列
/// </summary>
public void AddEvent(ThreadEvent ev, Action<NotiData> func) {
lock (m_lockObject) {
this.func = func;
events.Enqueue(ev);
}
} /// <summary>
/// 通知事件
/// </summary>
/// <param name="state"></param>
private void OnSyncEvent(NotiData data) {
if (this.func != null) func(data); //回调逻辑层
facade.SendMessageCommand(data.evName, data.evParam); //通知View层
} // Update is called once per frame
void OnUpdate() {
while (true) {
lock (m_lockObject) {
if (events.Count > ) {
ThreadEvent e = events.Dequeue();
try {
switch (e.Key) {
case NotiConst.UPDATE_EXTRACT: { //解压文件
OnExtractFile(e.evParams);
}
break;
case NotiConst.UPDATE_DOWNLOAD: { //下载文件
OnDownloadFile(e.evParams);
}
break;
}
} catch (System.Exception ex) {
UnityEngine.Debug.LogError(ex.Message);
}
}
}
Thread.Sleep();
}
} /// <summary>
/// 下载文件
/// </summary>
void OnDownloadFile(List<object> evParams) {
string url = evParams[].ToString();
currDownFile = evParams[].ToString(); using (WebClient client = new WebClient()) {
sw.Start();
client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(ProgressChanged);
client.DownloadFileAsync(new System.Uri(url), currDownFile);
}
} private void ProgressChanged(object sender, DownloadProgressChangedEventArgs e) {
//UnityEngine.Debug.Log(e.ProgressPercentage);
/*
UnityEngine.Debug.Log(string.Format("{0} MB's / {1} MB's",
(e.BytesReceived / 1024d / 1024d).ToString("0.00"),
(e.TotalBytesToReceive / 1024d / 1024d).ToString("0.00")));
*/
//float value = (float)e.ProgressPercentage / 100f; string value = string.Format("{0} kb/s", (e.BytesReceived / 1024d / sw.Elapsed.TotalSeconds).ToString("0.00"));
NotiData data = new NotiData(NotiConst.UPDATE_PROGRESS, value);
if (m_SyncEvent != null) m_SyncEvent(data); if (e.ProgressPercentage == && e.BytesReceived == e.TotalBytesToReceive) {
sw.Reset(); data = new NotiData(NotiConst.UPDATE_DOWNLOAD, currDownFile);
if (m_SyncEvent != null) m_SyncEvent(data);
}
} /// <summary>
/// 调用方法
/// </summary>
void OnExtractFile(List<object> evParams) {
UnityEngine.Debug.LogWarning("Thread evParams: >>" + evParams.Count); ///------------------通知更新面板解压完成--------------------
NotiData data = new NotiData(NotiConst.UPDATE_DOWNLOAD, null);
if (m_SyncEvent != null) m_SyncEvent(data);
} /// <summary>
/// 应用程序退出
/// </summary>
void OnDestroy() {
thread.Abort();
}
}
}

Manager/ThreadManager, ThreadEvent, NotiData

using UnityEngine;
using System.Collections;
using System.Collections.Generic; namespace LuaFramework {
public class TimerInfo {
public long tick;
public bool stop;
public bool delete;
public Object target;
public string className; public TimerInfo(string className, Object target) {
this.className = className;
this.target = target;
delete = false;
}
} public class TimerManager : Manager {
private float interval = ;
private List<TimerInfo> objects = new List<TimerInfo>(); public float Interval {
get { return interval; }
set { interval = value; }
} // Use this for initialization
void Start() {
StartTimer(AppConst.TimerInterval);
} /// <summary>
/// 启动计时器
/// </summary>
/// <param name="interval"></param>
public void StartTimer(float value) {
interval = value;
InvokeRepeating("Run", , interval);
} /// <summary>
/// 停止计时器
/// </summary>
public void StopTimer() {
CancelInvoke("Run");
} /// <summary>
/// 添加计时器事件
/// </summary>
/// <param name="name"></param>
/// <param name="o"></param>
public void AddTimerEvent(TimerInfo info) {
if (!objects.Contains(info)) {
objects.Add(info);
}
} /// <summary>
/// 删除计时器事件
/// </summary>
/// <param name="name"></param>
public void RemoveTimerEvent(TimerInfo info) {
if (objects.Contains(info) && info != null) {
info.delete = true;
}
} /// <summary>
/// 停止计时器事件
/// </summary>
/// <param name="info"></param>
public void StopTimerEvent(TimerInfo info) {
if (objects.Contains(info) && info != null) {
info.stop = true;
}
} /// <summary>
/// 继续计时器事件
/// </summary>
/// <param name="info"></param>
public void ResumeTimerEvent(TimerInfo info) {
if (objects.Contains(info) && info != null) {
info.delete = false;
}
} /// <summary>
/// 计时器运行
/// </summary>
void Run() {
if (objects.Count == ) return;
for (int i = ; i < objects.Count; i++) {
TimerInfo o = objects[i];
if (o.delete || o.stop) { continue; }
ITimerBehaviour timer = o.target as ITimerBehaviour;
timer.TimerUpdate();
o.tick++;
}
/////////////////////////清除标记为删除的事件///////////////////////////
for (int i = objects.Count - ; i >= ; i--) {
if (objects[i].delete) { objects.Remove(objects[i]); }
}
}
}
}

Manager/TimerManager, TimerInfo

using UnityEngine;
using System.Collections;
using System.IO;
using System.Text;
using System;
using LuaInterface; namespace LuaFramework {
public class ByteBuffer {
MemoryStream stream = null;
BinaryWriter writer = null;
BinaryReader reader = null; public ByteBuffer() {
stream = new MemoryStream();
writer = new BinaryWriter(stream);
} public ByteBuffer(byte[] data) {
if (data != null) {
stream = new MemoryStream(data);
reader = new BinaryReader(stream);
} else {
stream = new MemoryStream();
writer = new BinaryWriter(stream);
}
} public void Close() {
if (writer != null) writer.Close();
if (reader != null) reader.Close(); stream.Close();
writer = null;
reader = null;
stream = null;
} public void WriteByte(byte v) {
writer.Write(v);
} public void WriteInt(int v) {
writer.Write((int)v);
} public void WriteShort(ushort v) {
writer.Write((ushort)v);
} public void WriteLong(long v) {
writer.Write((long)v);
} public void WriteFloat(float v) {
byte[] temp = BitConverter.GetBytes(v);
Array.Reverse(temp);
writer.Write(BitConverter.ToSingle(temp, ));
} public void WriteDouble(double v) {
byte[] temp = BitConverter.GetBytes(v);
Array.Reverse(temp);
writer.Write(BitConverter.ToDouble(temp, ));
} public void WriteString(string v) {
byte[] bytes = Encoding.UTF8.GetBytes(v);
writer.Write((ushort)bytes.Length);
writer.Write(bytes);
} public void WriteBytes(byte[] v) {
writer.Write((int)v.Length);
writer.Write(v);
} public void WriteBuffer(LuaByteBuffer strBuffer) {
WriteBytes(strBuffer.buffer);
} public byte ReadByte() {
return reader.ReadByte();
} public int ReadInt() {
return (int)reader.ReadInt32();
} public ushort ReadShort() {
return (ushort)reader.ReadInt16();
} public long ReadLong() {
return (long)reader.ReadInt64();
} public float ReadFloat() {
byte[] temp = BitConverter.GetBytes(reader.ReadSingle());
Array.Reverse(temp);
return BitConverter.ToSingle(temp, );
} public double ReadDouble() {
byte[] temp = BitConverter.GetBytes(reader.ReadDouble());
Array.Reverse(temp);
return BitConverter.ToDouble(temp, );
} public string ReadString() {
ushort len = ReadShort();
byte[] buffer = new byte[len];
buffer = reader.ReadBytes(len);
return Encoding.UTF8.GetString(buffer);
} public byte[] ReadBytes() {
int len = ReadInt();
return reader.ReadBytes(len);
} public LuaByteBuffer ReadBuffer() {
byte[] bytes = ReadBytes();
return new LuaByteBuffer(bytes);
} public byte[] ToBytes() {
writer.Flush();
return stream.ToArray();
} public void Flush() {
writer.Flush();
}
}
}

Network/ByteBuffer

/*
* Copyright (c) 2008 Jonathan Wagner
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/ using System; namespace LuaFramework {
public class Converter {
public static Int32 GetBigEndian(Int32 value) {
if (BitConverter.IsLittleEndian) {
return swapByteOrder(value);
} else {
return value;
}
} public static UInt16 GetBigEndian(UInt16 value) {
if (BitConverter.IsLittleEndian) {
return swapByteOrder(value);
} else {
return value;
}
} public static UInt32 GetBigEndian(UInt32 value) {
if (BitConverter.IsLittleEndian) {
return swapByteOrder(value);
} else {
return value;
}
} public static Int64 GetBigEndian(Int64 value) {
if (BitConverter.IsLittleEndian) {
return swapByteOrder(value);
} else {
return value;
}
} public static Double GetBigEndian(Double value) {
if (BitConverter.IsLittleEndian) {
return swapByteOrder(value);
} else {
return value;
}
} public static float GetBigEndian(float value) {
if (BitConverter.IsLittleEndian) {
return swapByteOrder((int)value); } else {
return value;
}
} public static Int32 GetLittleEndian(Int32 value) {
if (BitConverter.IsLittleEndian) {
return value;
} else {
return swapByteOrder(value);
}
} public static UInt32 GetLittleEndian(UInt32 value) {
if (BitConverter.IsLittleEndian) {
return value;
} else {
return swapByteOrder(value);
}
} public static UInt16 GetLittleEndian(UInt16 value) {
if (BitConverter.IsLittleEndian) {
return value;
} else {
return swapByteOrder(value);
}
} public static Double GetLittleEndian(Double value) {
if (BitConverter.IsLittleEndian) {
return value;
} else {
return swapByteOrder(value);
}
} private static Int32 swapByteOrder(Int32 value) {
Int32 swap = (Int32)((0x000000FF) & (value >> )
| (0x0000FF00) & (value >> )
| (0x00FF0000) & (value << )
| (0xFF000000) & (value << ));
return swap;
} private static Int64 swapByteOrder(Int64 value) {
UInt64 uvalue = (UInt64)value;
UInt64 swap = ((0x00000000000000FF) & (uvalue >> )
| (0x000000000000FF00) & (uvalue >> )
| (0x0000000000FF0000) & (uvalue >> )
| (0x00000000FF000000) & (uvalue >> )
| (0x000000FF00000000) & (uvalue << )
| (0x0000FF0000000000) & (uvalue << )
| (0x00FF000000000000) & (uvalue << )
| (0xFF00000000000000) & (uvalue << )); return (Int64)swap;
} private static UInt16 swapByteOrder(UInt16 value) {
return (UInt16)((0x00FF & (value >> ))
| (0xFF00 & (value << )));
} private static UInt32 swapByteOrder(UInt32 value) {
UInt32 swap = ((0x000000FF) & (value >> )
| (0x0000FF00) & (value >> )
| (0x00FF0000) & (value << )
| (0xFF000000) & (value << ));
return swap;
} private static Double swapByteOrder(Double value) {
Byte[] buffer = BitConverter.GetBytes(value);
Array.Reverse(buffer, , buffer.Length);
return BitConverter.ToDouble(buffer, );
}
}
}

Network/Converter

namespace LuaFramework {
public class Protocal {
///BUILD TABLE
public const int Connect = ; //连接服务器
public const int Exception = ; //异常掉线
public const int Disconnect = ; //正常断线
}
}

Network/Protocal

using UnityEngine;
using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Collections;
using System.Collections.Generic;
using LuaFramework; public enum DisType {
Exception,
Disconnect,
} public class SocketClient {
private TcpClient client = null;
private NetworkStream outStream = null;
private MemoryStream memStream;
private BinaryReader reader; private const int MAX_READ = ;
private byte[] byteBuffer = new byte[MAX_READ];
public static bool loggedIn = false; // Use this for initialization
public SocketClient() {
} /// <summary>
/// 注册代理
/// </summary>
public void OnRegister() {
memStream = new MemoryStream();
reader = new BinaryReader(memStream);
} /// <summary>
/// 移除代理
/// </summary>
public void OnRemove() {
this.Close();
reader.Close();
memStream.Close();
} /// <summary>
/// 连接服务器
/// </summary>
void ConnectServer(string host, int port) {
client = null;
try {
IPAddress[] address = Dns.GetHostAddresses(host);
if (address.Length == ) {
Debug.LogError("host invalid");
return;
}
if (address[].AddressFamily == AddressFamily.InterNetworkV6) {
client = new TcpClient(AddressFamily.InterNetworkV6);
}
else {
client = new TcpClient(AddressFamily.InterNetwork);
}
client.SendTimeout = ;
client.ReceiveTimeout = ;
client.NoDelay = true;
client.BeginConnect(host, port, new AsyncCallback(OnConnect), null);
} catch (Exception e) {
Close(); Debug.LogError(e.Message);
}
} /// <summary>
/// 连接上服务器
/// </summary>
void OnConnect(IAsyncResult asr) {
outStream = client.GetStream();
client.GetStream().BeginRead(byteBuffer, , MAX_READ, new AsyncCallback(OnRead), null);
NetworkManager.AddEvent(Protocal.Connect, new ByteBuffer());
} /// <summary>
/// 写数据
/// </summary>
void WriteMessage(byte[] message) {
MemoryStream ms = null;
using (ms = new MemoryStream()) {
ms.Position = ;
BinaryWriter writer = new BinaryWriter(ms);
ushort msglen = (ushort)message.Length;
writer.Write(msglen);
writer.Write(message);
writer.Flush();
if (client != null && client.Connected) {
//NetworkStream stream = client.GetStream();
byte[] payload = ms.ToArray();
outStream.BeginWrite(payload, , payload.Length, new AsyncCallback(OnWrite), null);
} else {
Debug.LogError("client.connected----->>false");
}
}
} /// <summary>
/// 读取消息
/// </summary>
void OnRead(IAsyncResult asr) {
int bytesRead = ;
try {
lock (client.GetStream()) { //读取字节流到缓冲区
bytesRead = client.GetStream().EndRead(asr);
}
if (bytesRead < ) { //包尺寸有问题,断线处理
OnDisconnected(DisType.Disconnect, "bytesRead < 1");
return;
}
OnReceive(byteBuffer, bytesRead); //分析数据包内容,抛给逻辑层
lock (client.GetStream()) { //分析完,再次监听服务器发过来的新消息
Array.Clear(byteBuffer, , byteBuffer.Length); //清空数组
client.GetStream().BeginRead(byteBuffer, , MAX_READ, new AsyncCallback(OnRead), null);
}
} catch (Exception ex) {
//PrintBytes();
OnDisconnected(DisType.Exception, ex.Message);
}
} /// <summary>
/// 丢失链接
/// </summary>
void OnDisconnected(DisType dis, string msg) {
Close(); //关掉客户端链接
int protocal = dis == DisType.Exception ?
Protocal.Exception : Protocal.Disconnect; ByteBuffer buffer = new ByteBuffer();
buffer.WriteShort((ushort)protocal);
NetworkManager.AddEvent(protocal, buffer);
Debug.LogError("Connection was closed by the server:>" + msg + " Distype:>" + dis);
} /// <summary>
/// 打印字节
/// </summary>
/// <param name="bytes"></param>
void PrintBytes() {
string returnStr = string.Empty;
for (int i = ; i < byteBuffer.Length; i++) {
returnStr += byteBuffer[i].ToString("X2");
}
Debug.LogError(returnStr);
} /// <summary>
/// 向链接写入数据流
/// </summary>
void OnWrite(IAsyncResult r) {
try {
outStream.EndWrite(r);
} catch (Exception ex) {
Debug.LogError("OnWrite--->>>" + ex.Message);
}
} /// <summary>
/// 接收到消息
/// </summary>
void OnReceive(byte[] bytes, int length) {
memStream.Seek(, SeekOrigin.End);
memStream.Write(bytes, , length);
//Reset to beginning
memStream.Seek(, SeekOrigin.Begin);
while (RemainingBytes() > ) {
ushort messageLen = reader.ReadUInt16();
if (RemainingBytes() >= messageLen) {
MemoryStream ms = new MemoryStream();
BinaryWriter writer = new BinaryWriter(ms);
writer.Write(reader.ReadBytes(messageLen));
ms.Seek(, SeekOrigin.Begin);
OnReceivedMessage(ms);
} else {
//Back up the position two bytes
memStream.Position = memStream.Position - ;
break;
}
}
//Create a new stream with any leftover bytes
byte[] leftover = reader.ReadBytes((int)RemainingBytes());
memStream.SetLength(); //Clear
memStream.Write(leftover, , leftover.Length);
} /// <summary>
/// 剩余的字节
/// </summary>
private long RemainingBytes() {
return memStream.Length - memStream.Position;
} /// <summary>
/// 接收到消息
/// </summary>
/// <param name="ms"></param>
void OnReceivedMessage(MemoryStream ms) {
BinaryReader r = new BinaryReader(ms);
byte[] message = r.ReadBytes((int)(ms.Length - ms.Position));
//int msglen = message.Length; ByteBuffer buffer = new ByteBuffer(message);
int mainId = buffer.ReadShort();
NetworkManager.AddEvent(mainId, buffer);
} /// <summary>
/// 会话发送
/// </summary>
void SessionSend(byte[] bytes) {
WriteMessage(bytes);
} /// <summary>
/// 关闭链接
/// </summary>
public void Close() {
if (client != null) {
if (client.Connected) client.Close();
client = null;
}
loggedIn = false;
} /// <summary>
/// 发送连接请求
/// </summary>
public void SendConnect() {
ConnectServer(AppConst.SocketAddress, AppConst.SocketPort);
} /// <summary>
/// 发送消息
/// </summary>
public void SendMessage(ByteBuffer buffer) {
SessionSend(buffer.ToBytes());
buffer.Close();
}
}

Network/SocketClient, DisType

using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic; namespace LuaFramework { [Serializable]
public class PoolInfo {
public string poolName;
public GameObject prefab;
public int poolSize;
public bool fixedSize;
} public class GameObjectPool {
private int maxSize;
private int poolSize;
private string poolName;
private Transform poolRoot;
private GameObject poolObjectPrefab;
private Stack<GameObject> availableObjStack = new Stack<GameObject>(); public GameObjectPool(string poolName, GameObject poolObjectPrefab, int initCount, int maxSize, Transform pool) {
this.poolName = poolName;
this.poolSize = initCount;
this.maxSize = maxSize;
this.poolRoot = pool;
this.poolObjectPrefab = poolObjectPrefab; //populate the pool
for(int index = ; index < initCount; index++) {
AddObjectToPool(NewObjectInstance());
}
} //o(1)
private void AddObjectToPool(GameObject go) {
//add to pool
go.SetActive(false);
availableObjStack.Push(go);
go.transform.SetParent(poolRoot, false);
} private GameObject NewObjectInstance() {
return GameObject.Instantiate(poolObjectPrefab) as GameObject;
} public GameObject NextAvailableObject() {
GameObject go = null;
if(availableObjStack.Count > ) {
go = availableObjStack.Pop();
} else {
Debug.LogWarning("No object available & cannot grow pool: " + poolName);
}
go.SetActive(true);
return go;
} //o(1)
public void ReturnObjectToPool(string pool, GameObject po) {
if (poolName.Equals(pool)) {
AddObjectToPool(po);
} else {
Debug.LogError(string.Format("Trying to add object to incorrect pool {0} ", poolName));
}
}
}
}

ObjectPool/GameObjectPool, PoolInfo

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events; namespace LuaFramework
{
public class ObjectPool<T> where T : class
{
private readonly Stack<T> m_Stack = new Stack<T>();
private readonly UnityAction<T> m_ActionOnGet;
private readonly UnityAction<T> m_ActionOnRelease; public int countAll { get; private set; }
public int countActive { get { return countAll - countInactive; } }
public int countInactive { get { return m_Stack.Count; } } public ObjectPool(UnityAction<T> actionOnGet, UnityAction<T> actionOnRelease)
{
m_ActionOnGet = actionOnGet;
m_ActionOnRelease = actionOnRelease;
} public T Get()
{
T element = m_Stack.Pop();
if (m_ActionOnGet != null)
m_ActionOnGet(element);
return element;
} public void Release(T element)
{
if (m_Stack.Count > && ReferenceEquals(m_Stack.Peek(), element))
Debug.LogError("Internal error. Trying to destroy object that is already released to pool.");
if (m_ActionOnRelease != null)
m_ActionOnRelease(element);
m_Stack.Push(element);
}
}
}

ObjectPool/ObjectPool

using UnityEngine;
using System.Collections; namespace LuaFramework { public class TestObjectClass { public string name;
public int value1;
public float value2; // Use this for initialization
public TestObjectClass(string name, int value1, float value2) {
this.name = name;
this.value1 = value1;
this.value2 = value2;
} public string ToString() {
return string.Format("name={0} value1={1} = value2={2}", name, value1, value2);
}
}
}

ObjectPool/TestObjectClass

using UnityEngine;
using System.Collections.Generic;
using System.Reflection;
using LuaInterface;
using System; namespace LuaFramework {
public static class LuaHelper { /// <summary>
/// getType
/// </summary>
/// <param name="classname"></param>
/// <returns></returns>
public static System.Type GetType(string classname) {
Assembly assb = Assembly.GetExecutingAssembly(); //.GetExecutingAssembly();
System.Type t = null;
t = assb.GetType(classname); ;
if (t == null) {
t = assb.GetType(classname);
}
return t;
} /// <summary>
/// 面板管理器
/// </summary>
public static PanelManager GetPanelManager() {
return AppFacade.Instance.GetManager<PanelManager>(ManagerName.Panel);
} /// <summary>
/// 资源管理器
/// </summary>
public static ResourceManager GetResManager() {
return AppFacade.Instance.GetManager<ResourceManager>(ManagerName.Resource);
} /// <summary>
/// 网络管理器
/// </summary>
public static NetworkManager GetNetManager() {
return AppFacade.Instance.GetManager<NetworkManager>(ManagerName.Network);
} /// <summary>
/// 音乐管理器
/// </summary>
public static SoundManager GetSoundManager() {
return AppFacade.Instance.GetManager<SoundManager>(ManagerName.Sound);
} /// <summary>
/// pbc/pblua函数回调
/// </summary>
/// <param name="func"></param>
public static void OnCallLuaFunc(LuaByteBuffer data, LuaFunction func) {
if (func != null) func.Call(data);
Debug.LogWarning("OnCallLuaFunc length:>>" + data.buffer.Length);
} /// <summary>
/// cjson函数回调
/// </summary>
/// <param name="data"></param>
/// <param name="func"></param>
public static void OnJsonCallFunc(string data, LuaFunction func) {
Debug.LogWarning("OnJsonCallback data:>>" + data + " lenght:>>" + data.Length);
if (func != null) func.Call(data);
}
}
}

Utility/LuaHelper

using UnityEngine;
using System;
using System.IO;
using System.Text;
using System.Collections;
using System.Collections.Generic;
using System.Security.Cryptography;
using System.Text.RegularExpressions;
using LuaInterface;
using LuaFramework; #if UNITY_EDITOR
using UnityEditor;
#endif namespace LuaFramework {
public class Util {
private static List<string> luaPaths = new List<string>(); public static int Int(object o) {
return Convert.ToInt32(o);
} public static float Float(object o) {
return (float)Math.Round(Convert.ToSingle(o), );
} public static long Long(object o) {
return Convert.ToInt64(o);
} public static int Random(int min, int max) {
return UnityEngine.Random.Range(min, max);
} public static float Random(float min, float max) {
return UnityEngine.Random.Range(min, max);
} public static string Uid(string uid) {
int position = uid.LastIndexOf('_');
return uid.Remove(, position + );
} public static long GetTime() {
TimeSpan ts = new TimeSpan(DateTime.UtcNow.Ticks - new DateTime(, , , , , ).Ticks);
return (long)ts.TotalMilliseconds;
} /// <summary>
/// 搜索子物体组件-GameObject版
/// </summary>
public static T Get<T>(GameObject go, string subnode) where T : Component {
if (go != null) {
Transform sub = go.transform.Find(subnode);
if (sub != null) return sub.GetComponent<T>();
}
return null;
} /// <summary>
/// 搜索子物体组件-Transform版
/// </summary>
public static T Get<T>(Transform go, string subnode) where T : Component {
if (go != null) {
Transform sub = go.Find(subnode);
if (sub != null) return sub.GetComponent<T>();
}
return null;
} /// <summary>
/// 搜索子物体组件-Component版
/// </summary>
public static T Get<T>(Component go, string subnode) where T : Component {
return go.transform.Find(subnode).GetComponent<T>();
} /// <summary>
/// 添加组件
/// </summary>
public static T Add<T>(GameObject go) where T : Component {
if (go != null) {
T[] ts = go.GetComponents<T>();
for (int i = ; i < ts.Length; i++) {
if (ts[i] != null) GameObject.Destroy(ts[i]);
}
return go.gameObject.AddComponent<T>();
}
return null;
} /// <summary>
/// 添加组件
/// </summary>
public static T Add<T>(Transform go) where T : Component {
return Add<T>(go.gameObject);
} /// <summary>
/// 查找子对象
/// </summary>
public static GameObject Child(GameObject go, string subnode) {
return Child(go.transform, subnode);
} /// <summary>
/// 查找子对象
/// </summary>
public static GameObject Child(Transform go, string subnode) {
Transform tran = go.Find(subnode);
if (tran == null) return null;
return tran.gameObject;
} /// <summary>
/// 取平级对象
/// </summary>
public static GameObject Peer(GameObject go, string subnode) {
return Peer(go.transform, subnode);
} /// <summary>
/// 取平级对象
/// </summary>
public static GameObject Peer(Transform go, string subnode) {
Transform tran = go.parent.Find(subnode);
if (tran == null) return null;
return tran.gameObject;
} /// <summary>
/// 计算字符串的MD5值
/// </summary>
public static string md5(string source) {
MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
byte[] data = System.Text.Encoding.UTF8.GetBytes(source);
byte[] md5Data = md5.ComputeHash(data, , data.Length);
md5.Clear(); string destString = "";
for (int i = ; i < md5Data.Length; i++) {
destString += System.Convert.ToString(md5Data[i], ).PadLeft(, '');
}
destString = destString.PadLeft(, '');
return destString;
} /// <summary>
/// 计算文件的MD5值
/// </summary>
public static string md5file(string file) {
try {
FileStream fs = new FileStream(file, FileMode.Open);
System.Security.Cryptography.MD5 md5 = new System.Security.Cryptography.MD5CryptoServiceProvider();
byte[] retVal = md5.ComputeHash(fs);
fs.Close(); StringBuilder sb = new StringBuilder();
for (int i = ; i < retVal.Length; i++) {
sb.Append(retVal[i].ToString("x2"));
}
return sb.ToString();
} catch (Exception ex) {
throw new Exception("md5file() fail, error:" + ex.Message);
}
} /// <summary>
/// 清除所有子节点
/// </summary>
public static void ClearChild(Transform go) {
if (go == null) return;
for (int i = go.childCount - ; i >= ; i--) {
GameObject.Destroy(go.GetChild(i).gameObject);
}
} /// <summary>
/// 清理内存
/// </summary>
public static void ClearMemory() {
GC.Collect(); Resources.UnloadUnusedAssets();
LuaManager mgr = AppFacade.Instance.GetManager<LuaManager>(ManagerName.Lua);
if (mgr != null) mgr.LuaGC();
} /// <summary>
/// 取得数据存放目录
/// </summary>
public static string DataPath {
get {
string game = AppConst.AppName.ToLower();
if (Application.isMobilePlatform) {
return Application.persistentDataPath + "/" + game + "/";
}
if (AppConst.DebugMode) {
return Application.dataPath + "/" + AppConst.AssetDir + "/";
}
if (Application.platform == RuntimePlatform.OSXEditor) {
int i = Application.dataPath.LastIndexOf('/');
return Application.dataPath.Substring(, i + ) + game + "/";
}
return "c:/" + game + "/";
}
} public static string GetRelativePath() {
if (Application.isEditor)
return "file://" + System.Environment.CurrentDirectory.Replace("\\", "/") + "/Assets/" + AppConst.AssetDir + "/";
else if (Application.isMobilePlatform || Application.isConsolePlatform)
return "file:///" + DataPath;
else // For standalone player.
return "file://" + Application.streamingAssetsPath + "/";
} /// <summary>
/// 取得行文本
/// </summary>
public static string GetFileText(string path) {
return File.ReadAllText(path);
} /// <summary>
/// 网络可用
/// </summary>
public static bool NetAvailable {
get {
return Application.internetReachability != NetworkReachability.NotReachable;
}
} /// <summary>
/// 是否是无线
/// </summary>
public static bool IsWifi {
get {
return Application.internetReachability == NetworkReachability.ReachableViaLocalAreaNetwork;
}
} /// <summary>
/// 应用程序内容路径
/// </summary>
public static string AppContentPath() {
string path = string.Empty;
switch (Application.platform) {
case RuntimePlatform.Android:
path = "jar:file://" + Application.dataPath + "!/assets/";
break;
case RuntimePlatform.IPhonePlayer:
path = Application.dataPath + "/Raw/";
break;
default:
path = Application.dataPath + "/" + AppConst.AssetDir + "/";
break;
}
return path;
} public static void Log(string str) {
Debug.Log(str);
} public static void LogWarning(string str) {
Debug.LogWarning(str);
} public static void LogError(string str) {
Debug.LogError(str);
} /// <summary>
/// 防止初学者不按步骤来操作
/// </summary>
/// <returns></returns>
public static int CheckRuntimeFile() {
if (!Application.isEditor) return ;
string streamDir = Application.dataPath + "/StreamingAssets/";
if (!Directory.Exists(streamDir)) {
return -;
} else {
string[] files = Directory.GetFiles(streamDir);
if (files.Length == ) return -; if (!File.Exists(streamDir + "files.txt")) {
return -;
}
}
string sourceDir = AppConst.FrameworkRoot + "/ToLua/Source/Generate/";
if (!Directory.Exists(sourceDir)) {
return -;
} else {
string[] files = Directory.GetFiles(sourceDir);
if (files.Length == ) return -;
}
return ;
} /// <summary>
/// 执行Lua方法
/// </summary>
public static object[] CallMethod(string module, string func, params object[] args) {
LuaManager luaMgr = AppFacade.Instance.GetManager<LuaManager>(ManagerName.Lua);
if (luaMgr == null) return null;
return luaMgr.CallFunction(module + "." + func, args);
} /// <summary>
/// 检查运行环境
/// </summary>
public static bool CheckEnvironment() {
#if UNITY_EDITOR
int resultId = Util.CheckRuntimeFile();
if (resultId == -) {
Debug.LogError("没有找到框架所需要的资源,单击Game菜单下Build xxx Resource生成!!");
EditorApplication.isPlaying = false;
return false;
} else if (resultId == -) {
Debug.LogError("没有找到Wrap脚本缓存,单击Lua菜单下Gen Lua Wrap Files生成脚本!!");
EditorApplication.isPlaying = false;
return false;
}
if (Application.loadedLevelName == "Test" && !AppConst.DebugMode) {
Debug.LogError("测试场景,必须打开调试模式,AppConst.DebugMode = true!!");
EditorApplication.isPlaying = false;
return false;
}
#endif
return true;
}
}
}

Utility/Util

using UnityEngine;
using LuaFramework;
using System.Collections.Generic; public class AppView : View {
private string message; ///<summary>
/// 监听的消息
///</summary>
List<string> MessageList {
get {
return new List<string>()
{
NotiConst.UPDATE_MESSAGE,
NotiConst.UPDATE_EXTRACT,
NotiConst.UPDATE_DOWNLOAD,
NotiConst.UPDATE_PROGRESS,
};
}
} void Awake() {
RemoveMessage(this, MessageList);
RegisterMessage(this, MessageList);
} /// <summary>
/// 处理View消息
/// </summary>
/// <param name="message"></param>
public override void OnMessage(IMessage message) {
string name = message.Name;
object body = message.Body;
switch (name) {
case NotiConst.UPDATE_MESSAGE: //更新消息
UpdateMessage(body.ToString());
break;
case NotiConst.UPDATE_EXTRACT: //更新解压
UpdateExtract(body.ToString());
break;
case NotiConst.UPDATE_DOWNLOAD: //更新下载
UpdateDownload(body.ToString());
break;
case NotiConst.UPDATE_PROGRESS: //更新下载进度
UpdateProgress(body.ToString());
break;
}
} public void UpdateMessage(string data) {
this.message = data;
} public void UpdateExtract(string data) {
this.message = data;
} public void UpdateDownload(string data) {
this.message = data;
} public void UpdateProgress(string data) {
this.message = data;
} void OnGUI() {
GUI.Label(new Rect(, , , ), message); GUI.Label(new Rect(, , , ), "(1) 单击 \"Lua/Gen Lua Wrap Files\"。");
GUI.Label(new Rect(, , , ), "(2) 运行Unity游戏");
GUI.Label(new Rect(, , , ), "PS: 清除缓存,单击\"Lua/Clear LuaBinder File + Wrap Files\"。");
GUI.Label(new Rect(, , , ), "PS: 若运行到真机,请设置Const.DebugMode=false,本地调试请设置Const.DebugMode=true");
GUI.Label(new Rect(, , , ), "PS: 加Unity+ulua技术讨论群:>>341746602");
}
}

View/AppView

using UnityEngine;
using System.Collections; namespace LuaFramework { /// <summary>
/// </summary>
public class Main : MonoBehaviour { void Start() {
AppFacade.Instance.StartUp(); //启动游戏
}
}
}

Main

LuaFramework 学习的更多相关文章

  1. Unity3D热更新之LuaFramework篇[10]--总结篇

    背景 19年年初的时候,进到一家新单位,公司正准备将现有的游戏做成支持热更的版本.于是寻找热更方案的任务就落在了我头上. 经过搜索了解,能做Unity热更的方案是有好几种,但是要么不够成熟,要么不支持 ...

  2. Unity3D热更新之LuaFramework篇[04]--自定义UI监听方法

    时隔一个多月我又回来啦! 坚持真的是很难的一件事,其它事情稍忙,就很容易说服自己把写博客的计划给推迟了. 好在终于克服了自己的惰性,今天又开始了. 本篇继续我的Luaframework学习之路. 一. ...

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

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

  4. Unity3D热更新之LuaFramework篇[08]--热更新原理及热更服务器搭建

    前言 前面铺垫了这么久,终于要开始写热更新了. Unity游戏热更新包含两个方面,一个是资源的更新,一个是脚本的更新. 资源更新是Unity本来就支持的,在各大平台也都能用.而脚本的热更新在iOS平台 ...

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

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

  6. 从直播编程到直播教育:LiveEdu.tv开启多元化的在线学习直播时代

    2015年9月,一个叫Livecoding.tv的网站在互联网上引起了编程界的注意.缘于Pingwest品玩的一位编辑在上网时无意中发现了这个网站,并写了一篇文章<一个比直播睡觉更奇怪的网站:直 ...

  7. Angular2学习笔记(1)

    Angular2学习笔记(1) 1. 写在前面 之前基于Electron写过一个Markdown编辑器.就其功能而言,主要功能已经实现,一些小的不影响使用的功能由于时间关系还没有完成:但就代码而言,之 ...

  8. ABP入门系列(1)——学习Abp框架之实操演练

    作为.Net工地搬砖长工一名,一直致力于挖坑(Bug)填坑(Debug),但技术却不见长进.也曾热情于新技术的学习,憧憬过成为技术大拿.从前端到后端,从bootstrap到javascript,从py ...

  9. 消息队列——RabbitMQ学习笔记

    消息队列--RabbitMQ学习笔记 1. 写在前面 昨天简单学习了一个消息队列项目--RabbitMQ,今天趁热打铁,将学到的东西记录下来. 学习的资料主要是官网给出的6个基本的消息发送/接收模型, ...

随机推荐

  1. windows7 php 环境架设

    参考 https://www.jb51.net/article/38048.htm   常见问题解决方案     https://blog.csdn.net/w_yunlong/article/det ...

  2. Java开发笔记汇总

    Java语法与.Net对比 Java规范与约定 Kotlin Maven笔记 SpringBoot笔记2 SpringCloud笔记 MyBatis笔记 发布Jar包到中央仓库

  3. 任意视频批量转码MP4-H264助手

    使用说明 简单的粗暴的小工具,利用windows命令行调用ffmpeg完成任意格式视频转换成H264编码的MP4视频,以确保视频可以在主流浏览器中直接播放,如:Chrome.Firefox等. 只需要 ...

  4. zabbix--完整安装攻略

    zabbix:是一个基于WEB界面的提供分布式系统监视以及网络监视功能的企业级的开源解决方案. zabbix能监视各种网络参数,保证服务器系统的安全运营:并提供灵活的通知机制以让系统管理员快速定位/解 ...

  5. Spring案例--打印机

    目录: 1.applicationContext.xml配置文件 <?xml version="1.0" encoding="UTF-8"?> &l ...

  6. mysql常用命令杂记

    查看版本 mysqladmin -uRootmaster -pRootmaster@777 versionselect version() 查看Log_bin是否开启 show variables l ...

  7. HashMap框架源码深入解读,面试不用愁

    在Java Collections Framework的体系中中,主要有两个重要的接口,一个是List.Set和Queue所属的Collection,还有一个就是Map接口了.在上一篇文章中介绍了Li ...

  8. 用PHP写出计算器

    <body> <?php if (!empty($_POST)) { $op=$_POST['point']; $sum1 = $_POST['sum1']; $sum2 = $_P ...

  9. Define the Data Model and Set the Initial Data 定义数据模型并设置初始数据

    This topic describes how to define the business model and the business logic for WinForms and ASP.NE ...

  10. AQS(抽象队列同步器)

    AQS(全称为AbstractQueuedSynchronizer),即抽象队列同步器,它维护了一个volatile int state(代表共享资源)和一个FIFO线程等待队列. state的访问方 ...