LuaManager
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using UnityEngine.UI;
using XLua;
/// <summary>
/// Lua管理
/// </summary>
public class LuaManager : MonoBehaviour
{
public static LuaManager _instance;
public LuaEnv luaEnv = new LuaEnv();
public LuaTable luaTable;
private void Awake()
{
_instance = this;
luaTable = luaEnv.NewTable();
LuaTable meta = luaEnv.NewTable();
meta.Set("__index", luaEnv.Global);
luaTable.SetMetaTable(meta);
meta.Dispose();
}
/// <summary>
/// 执行lua代码
/// </summary>
public void DoString(string chunk, string chunkName = "chunk", LuaTable env = null)
{
luaEnv.DoString(chunk, chunkName, env);
}
/// <summary>
/// 获取Lua脚本内容
/// </summary>
/// <param name="name">lua 脚本文件名</param>
/// <returns></returns>
public string GetLuaString(string name) {
string filePath = PathUtil.GetAssetBundleOutPath() + "/Lua/" + name + ".lua.txt";
if (!File.Exists(filePath)) {
return null;
}
return File.ReadAllText(filePath);
}
[LuaCallCSharp]
public static List<Type> LuaCallCSharp = new List<Type>() {
typeof(System.Object),
typeof(UnityEngine.Object),
typeof(Vector2),
typeof(Vector3),
typeof(Vector4),
typeof(Quaternion),
typeof(Color),
typeof(Ray),
typeof(Bounds),
typeof(Ray2D),
typeof(Time),
typeof(GameObject),
typeof(Component),
typeof(Behaviour),
typeof(Transform),
typeof(Resources),
typeof(TextAsset),
typeof(Keyframe),
typeof(AnimationCurve),
typeof(AnimationClip),
typeof(MonoBehaviour),
typeof(ParticleSystem),
typeof(SkinnedMeshRenderer),
typeof(Renderer),
typeof(WWW),
typeof(System.Collections.Generic.List<int>),
typeof(Action<string>),
typeof(UnityEngine.Debug),
typeof(UnityEngine.UI.Text)
};
}
FindUtil
using UnityEngine;
using System.Collections;
public class FindUtil : MonoBehaviour {
/*
FindChild
name LoginPanel
parent NewLogin2Panel
i = 0
FindChild
name LoginPanel
parent NewLogin2Ctrl
i = 0
FindChild
name LoginPanel
parent Bg
i = 0 x
i = 1 x
i = 2 x
i = 1 x
i = 2 √
1 = 3
i = 1
*/
/// <summary>
/// 通过名字找子物体
/// </summary>
/// <param name="name">子物体的名字</param>
/// <param name="parent">子物体的父物体</param>
/// <returns>子物体</returns>
public static GameObject FindChild(string name, Transform parent) {
GameObject target = null;
for (int i = 0; i < parent.childCount; i++) {
//先在parent的子物体中找,如果有名字一致的直接返回
if (parent.GetChild(i).name == name) {
return parent.GetChild(i).gameObject;
}
//如果parent的子物体中没有名字一致的,先判断parent的子物是否有子物体,如果有,递归从子物体里面找
target = FindChild(name, parent.GetChild(i));
if (target != null) {
return target;
}
}
return null;
}
}
GameInit
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using XLua;
/// <summary>
/// 这个是脚本是最先执行的
/// </summary>
public class GameInit : MonoBehaviour
{
private string downloadPath;
void Awake()
{
downloadPath = PathUtil.GetAssetBundleOutPath();
// 检测资源进行比对更新
StartCoroutine(downloadRes());
// 开始游戏的主逻辑
gameObject.AddComponent<AssetBundleManager>();
gameObject.AddComponent<LuaManager>();
}
/// <summary>
/// 检测资源进行比对更新
/// </summary>
private IEnumerator downloadRes()
{
//这里 是 随便写的
string url = "http://127.0.0.1:8000/Windows/";
string fileUrl = url + "files.txt";
WWW www = new WWW(fileUrl);
yield return www;
//进行一些网络的检测
if (www.error != null)
Debug.LogError(www.error);
//判断本地有没有这个目录
//如果发布到手机上: 游戏一运行 就把 streamingAssetsPath 的文件 拷贝到 persistentDataPath 路径下
if (!Directory.Exists(downloadPath))
Directory.CreateDirectory(downloadPath);
//就会把下载的文件写入本地
File.WriteAllBytes(downloadPath + "/files.txt", www.bytes);
//读取里面的内容
string filesText = www.text;
string[] lines = filesText.Split('\n');
for (int i = 0; i < lines.Length; i++)
{
if (string.IsNullOrEmpty(lines[i]))
continue;
string[] kv = lines[i].Split('|');
string fileName = kv[0];
//再拿到本地的这个文件
string localFile = (downloadPath + "/" + fileName).Trim();
//如果本地文件没有 需要下载了
if (!File.Exists(localFile))
{
Debug.Log("本地没有,需要下载");
string dir = Path.GetDirectoryName(localFile);
Directory.CreateDirectory(dir);
//开始网络下载
string tmpUrl = url + fileName;
www = new WWW(tmpUrl);
yield return www;
//进行一些网络的检测
if (www.error != null)
Debug.LogError(www.error);
File.WriteAllBytes(localFile, www.bytes);
}
else //如果文件有 开始比对md5 作用:检测是否更新了
{
string md5 = kv[1].Trim();
string localMd5 = getFileMd5(localFile);
if (md5 == localMd5)
{
//如果 md5 一样的话,那么就没更新
Debug.Log("有最新的,不用更新");
}
else
{
Debug.Log("删除旧的,下载新的");
//如果不一样的话 说明更新了
//删除本地原来的旧文件
File.Delete(localFile);
//下载新文件
string tmpUrl = url + fileName;
www = new WWW(tmpUrl);
yield return www;
//进行一些网络的检测
if (www.error != null)
Debug.LogError(www.error);
File.WriteAllBytes(localFile, www.bytes);
}
}
}
yield return new WaitForEndOfFrame();
Debug.Log("更新完成,可以开始游戏了");
//执行lua 脚本
LuaManager._instance.DoString("require 'Login'");
//LuaManager._instance.CallLuaFunction("Login", "initAssets");
string loginStr = LuaManager._instance.GetLuaString("Login");
LuaManager._instance.DoString(loginStr,"报错啦", LuaManager._instance.luaTable);
LuaFunction initAssets = LuaManager._instance.luaTable.Get<LuaFunction>("initAssets");
//print(initAssets);
initAssets.Call();
}
/// <summary>
/// 获取文件的md5值
/// </summary>
/// <param name="filePath"></param>
private string getFileMd5(string filePath)
{
FileStream fs = new FileStream(filePath, FileMode.Open);
MD5 md5 = new MD5CryptoServiceProvider();
byte[] result = md5.ComputeHash(fs);
fs.Close();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < result.Length; i++)
{
sb.Append(result[i].ToString("x2"));
}
return sb.ToString();
}
}