一、定義一些簡單的基本需求:
二、一些資源等...準(zhǔn)備工作:
[ulua](http://www.ulua.org/index.html)
[模型](http://www.aigei.com/s?q=%E5%9D%A6%E5%85%8B&type=3d)
三、Unity(2017)UI搭建(UGUI)
選擇角色界面我用的是RawImage+RenderTexture將模型渲染到Panel
四裂问、代碼編寫(這里用的是ulua提供的框架)
1皮壁、為了方便我們先把AssetBundle模式關(guān)掉(關(guān)于AssetBundle我會后面另開文章單獨(dú)介紹)
2滴须、場景管理器(場景跳轉(zhuǎn))
lua-view-新建StartPanel
3、初始化
當(dāng)運(yùn)行的時候加載出所有Manager
游戲初始化管理器Game Manager
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; //文件已經(jīng)解壓過了岂膳,自己可添加檢查文件列表邏輯
}
StartCoroutine(OnExtractResource()); //啟動釋放協(xié)成
}
IEnumerator OnExtractResource() {
string dataPath = Util.DataPath; //數(shù)據(jù)目錄
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 0;
} else File.Copy(infile, outfile, true);
yield return new WaitForEndOfFrame();
//釋放所有文件到數(shù)據(jù)目錄
string[] files = File.ReadAllLines(outfile);
foreach (var file in files) {
string[] fs = file.Split('|');
infile = resPath + fs[0]; //
outfile = dataPath + fs[0];
message = "正在解包文件:>" + fs[0];
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 0;
} 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; //數(shù)據(jù)目錄
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 = 0; i < files.Length; i++) {
if (string.IsNullOrEmpty(files[i])) continue;
string[] keyValue = files[i].Split('|');
string f = keyValue[0];
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[1].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[2] { 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>
/// 資源初始化結(jié)束
/// </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"); //加載網(wǎng)絡(luò)
NetManager.OnInit(); //初始化網(wǎng)絡(luò)
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", 100, 200f));
var testObj1 = ObjPoolManager.Get<TestObjectClass>();
Debugger.Log("TestObjectClass--->>>" + testObj1.ToString());
//游戲?qū)ο蟪販y試
var prefab = Resources.Load("TestGameObjectPrefab", typeof(GameObject)) as GameObject;
var gameObjPool = ObjPoolManager.CreatePool("TestGameObject", 5, 10, 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>
/// 當(dāng)從池子里面獲取時
/// </summary>
/// <param name="obj"></param>
void OnPoolGetElement(TestObjectClass obj) {
Debug.Log("OnPoolGetElement--->>>" + obj);
}
/// <summary>
/// 當(dāng)放回池子里面時
/// </summary>
/// <param name="obj"></param>
void OnPoolPushElement(TestObjectClass obj) {
Debug.Log("OnPoolPushElement--->>>" + obj);
}
/// <summary>
/// 析構(gòu)函數(shù)
/// </summary>
void OnDestroy() {
if (NetManager != null) {
NetManager.Unload();
}
if (LuaManager != null) {
LuaManager.Close();
}
Debug.Log("~GameManager was destroyed");
}
}
}
這里是lua層的初始化 ↓
加載獲取所有view文件夾文件:
新建并注冊一個ctrl:
加載構(gòu)造:
指定加載面板:
StartCtrl = {}
local this = StartCtrl
function StartCtrl.New()
return this
end
function StartCtrl.Awake()
panelMgr:CreatePanel('Start', InitEnd);
end
function InitEnd()
log("開始面板創(chuàng)建成功")
end
對應(yīng)的調(diào)用方法在c#PanelManager中的CreatePanel方法
四、Assetbundle打包登錄場景加載
AddBuildMap("Start" + AppConst.ExtName, "*.prefab", "Assets/Resources/Panels/Starpanel");
運(yùn)行測試下:
五颜曾、業(yè)務(wù)層邏輯的處理(實現(xiàn)場景跳轉(zhuǎn))
先說一個簡單的跳轉(zhuǎn)處理(這里我們需要寫自己的需求所以自己寫一個管理器)
這里用到了LuaBehaviour中的一些回調(diào)
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!");
}
}
}
StartCtrl (加載面板)
StartCtrl = {}
local this = StartCtrl
function StartCtrl.New()
logWarn("StartCtrl.New--->>");
return this
end
function StartCtrl.Awake()
logWarn("StartCtrl.Awake--->>");
panelMgr:CreatePanel('Start', InitEnd);
end
function InitEnd(go)
log("開始面板創(chuàng)建成功")
behaviour = go:GetComponent("LuaBehaviour")
--(按鈕實例纠拔,回調(diào)函數(shù))
behaviour:AddClick(StartPanel.startBtn,OnStartBtnClick)
behaviour:AddClick(StartPanel.exitBtn,OnExitButtonClick)
end
function OnStartBtnClick()
log("開始按鈕被點擊了")
end
function OnExitButtonClick()
log("退出按鈕被點擊了")
end
StartPanel (獲取組件)
--處理業(yè)務(wù)邏輯
StartPanel = { }
local this = StartPanel
function StartPanel.Awake(go)
gameObject = go
transform = go.transform
this.init()
end
function StartPanel.init()
--獲取組件
this.startBtn = transform:Find("StartButton").gameObject
this.exitBtn = transform:Find("ExitButton").gameObject
end
六、場景管理器(管理頁面跳轉(zhuǎn))
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SceneMgr : MonoBehaviour {
//同步跳轉(zhuǎn)
public void LoadScene(int index)
{
UnityEngine.SceneManagement.SceneManager.LoadScene(index);
}
public void LoadScene(string index)
{
UnityEngine.SceneManagement.SceneManager.LoadScene(index);
}
//異步跳轉(zhuǎn)
public void LoadSceneAsync(int index)
{
StartCoroutine(LoadSceneA(index));
}
private IEnumerator LoadSceneA(int index)
{
AsyncOperation asyncOperation = UnityEngine.SceneManagement.SceneManager.LoadSceneAsync(index);
yield return asyncOperation;
}
}
lua中define:
sceneMgr = LuaHelper.GetSceneManager();
StartPanel點擊事件:
function OnStartBtnClick()
log("開始按鈕被點擊了")
sceneMgr:LoadScene(1)
end
運(yùn)行效果如下:
//cjson(lua表轉(zhuǎn)json)
#!/usr/bin/env lua
-- usage: json2lua.lua [json_file]
--
-- Eg:
-- echo '[ "testing" ]' | ./json2lua.lua
-- ./json2lua.lua test.json
local json = require "cjson"
local util = require "cjson.util"
local json_text = util.file_load(arg[1])
local t = json.decode(json_text)
print(util.serialise_value(t))
七泛豪、場景二和場景一相同:
1.首先我們要用一個空物體初始化這個場景
我們這里沒有用這種方法因為需要加載面板很多話不方便管理
2.需要注意的是OnLevelLoaded
我們需要去注冊一個事件它才會去通知跳轉(zhuǎn)(5.4以及高版本以上是需要注冊一個事件绿语,才會在跳轉(zhuǎn)場景的時候發(fā)送通知低版本相反)
using UnityEngine;
using System.Collections;
using LuaInterface;
using UnityEngine.SceneManagement;
namespace LuaFramework {
public class LuaManager : Manager {
private LuaState lua;
private LuaLoader loader;
private LuaLooper loop = null;
LuaFunction levelLoaded;
// Use this for initialization
void Awake() {
loader = new LuaLoader();
lua = new LuaState();
this.OpenLibs();
lua.LuaSetTop(0);
LuaBinder.Bind(lua);
DelegateFactory.Init();
LuaCoroutine.Register(lua, this);
//注冊事件
SceneManager.sceneLoaded += OnSceneLoaded;
}
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(-2, "cjson");
lua.OpenLibs(LuaDLL.luaopen_cjson_safe);
lua.LuaSetField(-2, "cjson.safe");
}
void StartMain() {
lua.DoFile("Main.lua");
levelLoaded = lua.GetFunction("OnLevelWasLoaded");
//main.Call();
//main.Dispose();
//main = null;
}
//監(jiān)聽場景跳轉(zhuǎn)事件的方法
void OnSceneLoaded(Scene scene, LoadSceneMode mode)
{
OnLevelLoaded(scene.buildIndex);
}
//場景跳轉(zhuǎn)回調(diào)
void OnLevelLoaded(int level)
{
if (levelLoaded != null)
{
levelLoaded.BeginPCall();
levelLoaded.Push(level);
levelLoaded.PCall();
levelLoaded.EndPCall();
}
if (lua != null)
{
lua.RefreshDelegateMap();
}
}
/// <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() {
//取消注冊
SceneManager.sceneLoaded -= OnSceneLoaded;
loop.Destroy();
loop = null;
lua.Dispose();
lua = null;
loader = null;
}
}
}
3.在lua Main函數(shù)中接受回調(diào)
--主入口函數(shù)。從這里開始lua邏輯
function Main()
print("logic start")
end
--場景切換通知
function OnLevelWasLoaded(level)
print("回調(diào)函數(shù)執(zhí)行了 --------"..level)
if level == 1 then--選塔克場景
--調(diào)用此面板點擊事件
panelMgr:CreatePanel("SelectTank",SelectTankCtrl.CreateTankHandler)
end
collectgarbage("collect")
Time.timeSinceLevelLoad = 0
end
function OnApplicationQuit()
end
function SelectTankCtrl.CreateTankHandler(go)
log("開始面板創(chuàng)建成功")
behaviour = go:GetComponent("LuaBehaviour")
--(按鈕實例岗仑,回調(diào)函數(shù))
behaviour:AddClick(SelectTankPanel.LeftBtn,OnLeftBtnClick)
behaviour:AddClick(SelectTankPanel.RigthBtn,OnRigthButtonClick)
behaviour:AddClick(SelectTankPanel.EnterBtn,OnEnterButtonClick)
end
function OnLeftBtnClick()
log("向左按鈕被點擊了")
end
function OnRigthButtonClick()
log("向右按鈕被點擊了")
end
function OnEnterButtonClick()
log("進(jìn)入游戲按鈕被點擊了")
end
4.根據(jù)情況角色模型是分開打包或者打包到一起
5.SelectTankPanel 獲取相機(jī)
--獲取Camera
this.Camera = transform:Find("Camera").gameObject
6.SelectTankCtrl(角色選擇與加載邏輯代碼)
SelectTankCtrl = {}
local this = SelectTankCtrl
local tanks = { }
local disPlayTankIndex = 1
function SelectTankCtrl.New()
logWarn("SelectTankCtrl.New--->>");
return this
end
function SelectTankCtrl.Awake()
logWarn("SelectTankCtrl.Awake--->>");
--panelMgr:CreatePanel('SelectTank', this.InitEnd);
panelMgr:CreatePanel("SelectTank",SelectTankCtrl.CreateTankHandler)
end
function SelectTankCtrl.CreateTankHandler(go)
log("開始面板創(chuàng)建成功")
behaviour = go:GetComponent("LuaBehaviour")
--(按鈕實例匹耕,回調(diào)函數(shù))
behaviour:AddClick(SelectTankPanel.LeftBtn,OnLeftBtnClick)
behaviour:AddClick(SelectTankPanel.RigthBtn,OnRigthButtonClick)
behaviour:AddClick(SelectTankPanel.EnterBtn,OnEnterButtonClick)
--獲取加載角色
tankNames = {"Buggy","Cube"}
resMgr:LoadPrefab("Tanks",tankNames,this.InitTankHandler)
end
function SelectTankCtrl.InitTankHandler(gos)
print(gos[0].name)
print(gos[1].name)
local go = newObject(gos[0]);
--將預(yù)制體加載到相機(jī)并且固定坐標(biāo)
go.transform:SetParent(SelectTankPanel.Camera.transform,false)
local go1 = newObject(gos[1]);
go1.transform:SetParent(SelectTankPanel.Camera.transform,false)
tanks[1] = go
tanks[2] = go1
for i=1, #tanks do
tanks[i]:SetActive(false)
end
ShowTank()
end
function ShowTank()
tanks[disPlayTankIndex]:SetActive(true)
for i = 1, #tanks do
if i ~= disPlayTankIndex then
tanks[i]:SetActive(false)
end
end
end
function OnLeftBtnClick()
log("向左按鈕被點擊了")
disPlayTankIndex = disPlayTankIndex - 1
if disPlayTankIndex == 0 then
disPlayTankIndex = #tanks
end
ShowTank()
end
function OnRigthButtonClick()
log("向右按鈕被點擊了")
disPlayTankIndex = disPlayTankIndex + 1
if disPlayTankIndex == #tanks + 1 then
disPlayTankIndex = 1
end
ShowTank()
end
function OnEnterButtonClick()
log("進(jìn)入游戲按鈕被點擊了")
end
八、游戲場景
[場景搭建](https://blog.csdn.net/nicolelili1/article/details/72843163)
lua TankCtrl
TankCtrl = {}
local this = TankCtrl
local gameObject
local transform
function TankCtrl.GetInstance()
return this
end
function TankCtrl.Awake(go)
gameObject = go
transform = go.transform
end
c#(掛在角色上的)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using LuaFramework;
public class TankCtrl : MonoBehaviour {
public void Awake()
{
Util.CallMethod("Tankctrl","Awake",gameObject);
}
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
}
1.角色移動
2.角色控制器
TankCtrl = {}
local this = TankCtrl
local gameObject
local transform
--角色控制器
local characterController
function TankCtrl.GetInstance()
return this
end
function TankCtrl.Awake(go)
gameObject = go
transform = go.transform
--characterController = go:GetComponent("CharacterController")
characterController = gameObject:GetComponent("CharacterController")
end
function TankCtrl.Update()
horizontal = UnityEngine.Input.GetAxis("Horizontal")
vertical = UnityEngine.Input.GetAxis("Vertical")
--[[if horizontal ~= 0 or vertical ~= 0 then
dir = Vector3.New()
dir.x = horizontal
dir.y = -vertical
transform:Translate(dir)
end]]
if UnityEngine.Input.GetKey(UnityEngine.KeyCode.W) then
characterController:SimpleMove(-transform.up * UnityEngine.Time.deltaTime * 650)
elseif UnityEngine.Input.GetKey(UnityEngine.KeyCode.S) then
characterController:SimpleMove(transform.up * UnityEngine.Time.deltaTime * 420)
elseif UnityEngine.Input.GetKey(UnityEngine.KeyCode.A) then
transform:Rotate(Vector3.back * 2)
elseif UnityEngine.Input.GetKey(UnityEngine.KeyCode.D) then
transform:Rotate(Vector3.forward * 2)
end
end
c#接收
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using LuaFramework;
public class TankCtrl : MonoBehaviour {
public void Awake()
{
Util.CallMethod("TankCtrl", "Awake",gameObject);
}
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
Util.CallMethod("TankCtrl", "Update", gameObject);
}
}
2.子彈發(fā)射
tankctrl
TankCtrl = {}
local this = TankCtrl
local gameObject
local transform
local bullet--子彈
local firPos--父物體
--角色控制器
local characterController
function TankCtrl.GetInstance()
return this
end
function TankCtrl.Awake(go)
gameObject = go
transform = go.transform
--characterController = go:GetComponent("CharacterController")
characterController = gameObject:GetComponent("CharacterController")
--子彈加載(返回到回調(diào)函數(shù)中)
resMgr:LoadPrefab("Bullet",{"RedBullet"},TankCtrl.loadHandler)
--firPos = child("FirePos")
firPos = transform:Find("FirePos")
print(firPos)
end
--返回的子彈
function TankCtrl.loadHandler(gos)
print(gos[0])
bullet = gos[0]
end
function TankCtrl.Update()
horizontal = UnityEngine.Input.GetAxis("Horizontal")
vertical = UnityEngine.Input.GetAxis("Vertical")
--[[if horizontal ~= 0 or vertical ~= 0 then
dir = Vector3.New()
dir.x = horizontal
dir.y = -vertical
transform:Translate(dir)
end]]
if UnityEngine.Input.GetKey(UnityEngine.KeyCode.W) then
characterController:SimpleMove(-transform.up * UnityEngine.Time.deltaTime * 650)
elseif UnityEngine.Input.GetKey(UnityEngine.KeyCode.S) then
characterController:SimpleMove(transform.up * UnityEngine.Time.deltaTime * 420)
elseif UnityEngine.Input.GetKey(UnityEngine.KeyCode.A) then
transform:Rotate(Vector3.back * 2)
elseif UnityEngine.Input.GetKey(UnityEngine.KeyCode.D) then
transform:Rotate(Vector3.forward * 2)
end
--加載子彈(按下鼠標(biāo)左鍵)
if UnityEngine.Input.GetMouseButtonDown(0) then
print(bullet)
--獲取子彈
temp = newObject(bullet)
--設(shè)置父物體
temp.transform:SetParent(firPos,false)
--temp.transform.localScale = Vector3(1,1,1)
temp.transform.localScale = Vector3.one
temp.transform.localPosition = Vector3(0,0,0)
end
end
3.給子彈掛一個腳本
4.子彈的生成移動
BulletCtrl = {}
local this = BulletCtrl
BulletCtrl.gameObject = nil
BulletCtrl.transform = nil
--[[local gameObject = nil
local transform = nil--]]
function BulletCtrl:New(o,go)
--print(o)
o = o or{}
o = setmetatable(o,self)
self.__index = self
o.gameObject = go
o.transform = o.gameObject.transform
return o
end
--[[function BulletCtrl.Awake(go)
gameObject = go
transform = gameObject.transform
end--]]
function BulletCtrl:Update()
self.transform:Translate(-self.transform.forward * UnityEngine.Time.deltaTime * 50)
end
5.坦克發(fā)射子彈調(diào)用
require "Battle/BulletCtrl"
TankCtrl = {}
local this = TankCtrl
local gameObject
local transform
local bullet--子彈
local firPos--父物體
--儲存子彈的表
local bullets = { }
--角色控制器
local characterController
function TankCtrl.GetInstance()
return this
end
function TankCtrl.Awake(go)
gameObject = go
transform = go.transform
--characterController = go:GetComponent("CharacterController")
characterController = gameObject:GetComponent("CharacterController")
--子彈加載(返回到回調(diào)函數(shù)中)
resMgr:LoadPrefab("Bullet",{"RedBullet"},TankCtrl.loadHandler)
--firPos = child("FirePos")
firPos = transform:Find("FirePos")
print(firPos)
end
function TankCtrl.loadHandler(gos)
print(gos[0])
bullet = gos[0]
end
function TankCtrl.Update()
horizontal = UnityEngine.Input.GetAxis("Horizontal")
vertical = UnityEngine.Input.GetAxis("Vertical")
--[[if horizontal ~= 0 or vertical ~= 0 then
dir = Vector3.New()
dir.x = horizontal
dir.y = -vertical
transform:Translate(dir)
end]]
if UnityEngine.Input.GetKey(UnityEngine.KeyCode.W) then
characterController:SimpleMove(-transform.up * UnityEngine.Time.deltaTime * 250)
elseif UnityEngine.Input.GetKey(UnityEngine.KeyCode.S) then
characterController:SimpleMove(transform.up * UnityEngine.Time.deltaTime * 220)
end
if UnityEngine.Input.GetKey(UnityEngine.KeyCode.A) then
transform:Rotate(Vector3.back * 2)
elseif UnityEngine.Input.GetKey(UnityEngine.KeyCode.D) then
transform:Rotate(Vector3.forward * 2)
end
if UnityEngine.Input.GetKey(UnityEngine.KeyCode.P) then
--加載子彈(按下鼠標(biāo)左鍵)
--if UnityEngine.Input.GetMouseButtonDown(0) then
print(bullet)
--獲取子彈
temp = newObject(bullet)
--把每一個發(fā)射的子彈存入戰(zhàn)斗子彈管理類
BattleCtrl.GetInstance().Bullets[temp] = bc
--將每個子彈存儲
bc = BulletCtrl:New(nil,temp)
table.insert(bullets,bc)
--設(shè)置父物體
temp.transform:SetParent(firPos,false)
temp.transform.localScale = Vector3(1,1,1)
--temp.transform.localScale = Vector3.one
temp.transform.localPosition = Vector3(0,0,0)
temp.transform.parent = nil
--取消設(shè)置父物體
temp.transform.DetachChildren(firPos)
end
if table.getn(bullets) > 0 then
for i,v in ipairs(bullets) do
v:Update()
end
end
end
6.戰(zhàn)斗時子彈射中敵人的管理類BattleCtrl
--模擬一個子彈類
BattleCtrl = {}
local this = BattleCtrl
BattleCtrl.Bullets = {}
function BattleCtrl.GetInstance()
return this
end
function BattleCtrl.OnTriggerEnter(go,other)
local enemyTank = go
bulletCtrl = this.Bullets[other.gameObject]
--把子彈和野怪(被擊中的敵人)傳遞給bulletCtrl
bulletCtrl.Attack(other.gameObject, enemyTank)
end
添加子彈碰撞管理及銷毀
require "Battle/BulletCtrl"
TankCtrl = {}
local this = TankCtrl
local gameObject
local transform
local bullet--子彈
local firPos--父物體
--儲存子彈的表
local bullets = { }
--角色控制器
local characterController
function TankCtrl.GetInstance()
return this
end
function TankCtrl.Awake(go)
gameObject = go
transform = go.transform
--characterController = go:GetComponent("CharacterController")
characterController = gameObject:GetComponent("CharacterController")
--子彈加載(返回到回調(diào)函數(shù)中)
resMgr:LoadPrefab("Bullet",{"RedBullet"},TankCtrl.loadHandler)
--firPos = child("FirePos")
firPos = transform:Find("FirePos")
print(firPos)
end
function TankCtrl.loadHandler(gos)
print(gos[0])
bullet = gos[0]
end
function TankCtrl.Update()
horizontal = UnityEngine.Input.GetAxis("Horizontal")
vertical = UnityEngine.Input.GetAxis("Vertical")
--[[if horizontal ~= 0 or vertical ~= 0 then
dir = Vector3.New()
dir.x = horizontal
dir.y = -vertical
transform:Translate(dir)
end]]
if UnityEngine.Input.GetKey(UnityEngine.KeyCode.W) then
characterController:SimpleMove(-transform.up * UnityEngine.Time.deltaTime * 250)
elseif UnityEngine.Input.GetKey(UnityEngine.KeyCode.S) then
characterController:SimpleMove(transform.up * UnityEngine.Time.deltaTime * 220)
end
if UnityEngine.Input.GetKey(UnityEngine.KeyCode.A) then
transform:Rotate(Vector3.back * 2)
elseif UnityEngine.Input.GetKey(UnityEngine.KeyCode.D) then
transform:Rotate(Vector3.forward * 2)
end
if UnityEngine.Input.GetKey(UnityEngine.KeyCode.P) then
--加載子彈(按下鼠標(biāo)左鍵)
--if UnityEngine.Input.GetMouseButtonDown(0) then
print(bullet)
--獲取子彈
temp = newObject(bullet)
--把每一個發(fā)射的子彈存入戰(zhàn)斗子彈管理類
BattleCtrl.GetInstance().Bullets[temp] = bc
--將每個發(fā)射的子彈單個實例
bc = BulletCtrl:New(nil,temp)
table.insert(bullets,bc)
--設(shè)置父物體
temp.transform:SetParent(firPos,false)
temp.transform.localScale = Vector3(1,1,1)
--temp.transform.localScale = Vector3.one
temp.transform.localPosition = Vector3(0,0,0)
temp.transform.parent = nil
--取消設(shè)置父物體
temp.transform.DetachChildren(firPos)
end
if table.getn(bullets) > 0 then
for i,v in ipairs(bullets) do
v:Update()
end
end
end
7.掛在所有敵人身上用于反饋自身及撞擊子彈
using LuaFramework;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnemyTankCtrl : MonoBehaviour {
//tank檢測到碰撞
private void OnTriggerEnter(Collider other)
{
//調(diào)用亂函數(shù)獲取射擊的子彈以及被擊中的坦克
Util.CallMethod("BattleCtrl", "OnTriggerEnter", new object[] { this.gameObject, other });
//將other傳給lua
}
}
8.子彈掛的腳本
using LuaFramework;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BulletCtrl : MonoBehaviour {
public void Awake()
{
Util.CallMethod("BulletCtrl", "Awake", gameObject);
}
// Use this for initialization
void Start()
{
}
// Update is called once per frame
//void Update()
//{
// //Util.CallMethod("BulletCtrl", "Update", gameObject);
// //if (gameObject != null)
// //{
// // Destroy(gameObject,5);
// //}
//}
}
BulletCtrl = {}
local this = BulletCtrl
BulletCtrl.gameObject = nil
BulletCtrl.transform = nil
--[[local gameObject = nil
local transform = nil--]]
function BulletCtrl:New(o,go)
--print(o)
o = o or{}
o = setmetatable(o,self)
self.__index = self
o.gameObject = go
o.transform = o.gameObject.transform
return o
end
--[[function BulletCtrl.Awake(go)
gameObject = go
transform = gameObject.transform
end--]]
function BulletCtrl:Update()
self.transform:Translate(-self.transform.forward * UnityEngine.Time.deltaTime * 50)
end
--[[--碰撞完處理攻擊業(yè)務(wù)
function BulletCtrl.Attack(bullet,enemy)
--bullet.self = nil
destroy(bullet)
destroy(enemy)
end--]]
--模擬一個子彈類
BattleCtrl = {}
local this = BattleCtrl
BattleCtrl.Bullets = {}
function BattleCtrl.GetInstance()
return this
end
function BattleCtrl.OnTriggerEnter(...)
local res = {...}
--tanke
local enemyTank = res[1].gameObject
print("我是坦克.................."..enemyTank.name)
--zidan
local bullet = res[2].gameObject
print("我是子彈.................."..bullet.name)
destroy(bullet)
--print("我是子彈.................."..bullet.name)
destroy(enemyTank)
--print("我是坦克.................."..enemyTank.name)
--[[bulletCtrl = this.Bullets[bullet]
--把子彈和野怪(被擊中的敵人)傳遞給bulletCtrl
bulletCtrl.Attack(bullet, enemyTank)--]]
end
9.坦克管理類
require "Battle/BulletCtrl"
TankCtrl = {}
local this = TankCtrl
local gameObject
local transform
local bullet--子彈
local firPos--父物體
--儲存子彈的表
local bullets = { }
--角色控制器
local characterController
function TankCtrl.GetInstance()
return this
end
function TankCtrl.Awake(go)
gameObject = go
transform = go.transform
characterController = gameObject:GetComponent("CharacterController")
--子彈加載(返回到回調(diào)函數(shù)中)
resMgr:LoadPrefab("Bullet",{"bc"},TankCtrl.loadHandler)
firPos = transform:Find("FirePos")
print(firPos)
end
function TankCtrl.loadHandler(gos)
print(gos[0])
bullet = gos[0]
end
function TankCtrl.Update()
horizontal = UnityEngine.Input.GetAxis("Horizontal")
vertical = UnityEngine.Input.GetAxis("Vertical")
--[[if horizontal ~= 0 or vertical ~= 0 then
dir = Vector3.New()
dir.x = horizontal
dir.y = -vertical
transform:Translate(dir)
end]]
if UnityEngine.Input.GetKey(UnityEngine.KeyCode.W) then
characterController:SimpleMove(-transform.up * UnityEngine.Time.deltaTime * 250)
elseif UnityEngine.Input.GetKey(UnityEngine.KeyCode.S) then
characterController:SimpleMove(transform.up * UnityEngine.Time.deltaTime * 220)
end
if UnityEngine.Input.GetKey(UnityEngine.KeyCode.A) then
transform:Rotate(Vector3.back * 2)
elseif UnityEngine.Input.GetKey(UnityEngine.KeyCode.D) then
transform:Rotate(Vector3.forward * 2)
end
--if UnityEngine.Input.GetKey(UnityEngine.KeyCode.P) then
--加載子彈(按下鼠標(biāo)左鍵)
if UnityEngine.Input.GetMouseButtonDown(0) then
print(bullet)
--獲取子彈
temp = newObject(bullet)
--把每一個發(fā)射的子彈存入戰(zhàn)斗子彈管理類
BattleCtrl.GetInstance().Bullets[temp] = bc
--將每個發(fā)射的子彈單個實例
bc = BulletCtrl:New(nil,temp)
table.insert(bullets,bc)
--設(shè)置父物體
temp.transform:SetParent(firPos,false)
temp.transform.localScale = Vector3(1,1,1)
--temp.transform.localScale = Vector3.one
temp.transform.localPosition = Vector3(0,0,0)
temp.transform.parent = nil
--取消設(shè)置父物體
temp.transform.DetachChildren(firPos)
end
if table.getn(bullets) > 0 then
for i,v in ipairs(bullets) do
v:Update()
end
end
end