您的位置:首页 > 移动开发 > Unity3D

使用Slua框架开发Unity项目的重要步骤

2016-09-27 11:55 417 查看

下载与安装

下载地址 GitHub
安装过程

1.下载最新版,这里, 解压缩,将Assets目录里的所有内容复制到你的工程中,对于最终产品,可以删除slua_src,例子,文档等内容,如果是开发阶段则无所谓。

2.等待unity编译完毕,如果一切顺利的话,将出现slua菜单, 点击slua菜单中 All->Make 命令 手动生成针对当前版本的U3d接口文件。

3.每次更新slua版本,务必记得clear all,然后make all,否则可能运行不正确

主要的内容包括

LuaState
状态机对象执行
Lua
字符串
LuaState
状态机对象执行
Lua
脚本
LuaState
状态机对象调用
Lua
脚本内的自定义函数
LuaState
状态机对象注册
C#
自定义类
Lua
脚本中调用
C#
中的自定义类

创建第一个可以使用Slua框架的Unity项目

MainCamera
对象上创建
AppDelegate.cs
组件

using UnityEngine;
using System.Collections;

public class AppDelegate : MonoBehaviour
{
void Start ()
{
//在下方添加初始化代码
}
}


使用
LuaState
状态机对象执行Lua字符串

using UnityEngine;
using System.Collections;
using SLua;

public class AppDelegate : MonoBehaviour
{
private static LuaState  ls_state = new LuaState();
void Start ()
{
//在下方添加初始化代码
ls_state.doString("print(\"Hello Lua!\")");
}
}


使用
LuaState
状态机对象执行Lua脚本文件
HelloLua.lua


Resources
文件夹下添加
HelloLua.lua
文件

print("Lua Scripts:Hello");


AppDelegate.cs
中设置
LuaState.loaderDelegate
启动文件委托代理

using UnityEngine;
using System.Collections;
using SLua;
using System.IO;

public class AppDelegate : MonoBehaviour
{
void Start ()
{
//设置脚本启动代理
LuaState.loaderDelegate = ((string fn) => {
//获取Lua文件执行目录
string file_path = Directory.GetCurrentDirectory() + "/Assets/Resources/" + fn;

Debug.Log(file_path);

return File.ReadAllBytes(file_path);
});
}
}


AppDelegate.cs
中通过
LuaState
对象执行
HelloLua.lua
脚本

using UnityEngine;
using System.Collections;
using SLua;
using System.IO;

public class AppDelegate : MonoBehaviour
{

void Start ()
{
//设置脚本启动代理
LuaState.loaderDelegate = ((string fn) => {
//获取Lua文件执行目录
string file_path = Directory.GetCurrentDirectory() + "/Assets/Resources/" + fn;

Debug.Log(file_path);

return File.ReadAllBytes(file_path);
});

//设置执行脚本
LuaState ls_state = new LuaState ();
ls_state.doFile ("HelloLua.lua");
}
}


通过
LuaState
对象获取并执行
HelloLua.lua
脚本中的一个函数

HelloLua.lua


function sum( v1,v2 )
-- body
return v1 + v2
end

function mul( v1,v2 )
-- body
return v1 * v2
end


AppDelegate.cs


using UnityEngine;
using System.Collections;
using SLua;
using System.IO;
using LuaInterface;
using System;

public class AppDelegate : MonoBehaviour
{
//添加LuaState初始化时的回调函数特性函数
[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
static int init(IntPtr L)
{
//设置初始化LuaObject对象
LuaObject.init(L);
return 0;
}

void Start ()
{
//创建状态机对象
LuaState ls_state = new LuaState ();

//设置脚本启动代理
LuaState.loaderDelegate = ((string fn) => {
//获取Lua文件执行目录
string file_path = Directory.GetCurrentDirectory() + "/Assets/Resources/" + fn;

Debug.Log(file_path);

return File.ReadAllBytes(file_path);
});

//初始化LuaState状态机与C#的转换对象
LuaState.pcall (ls_state.L, init);

//设置状态机对象的执行脚本
ls_state.doFile ("HelloLua.lua");

//获取脚本中的mul函数
LuaFunction mul = ls_state.getFunction ("mul");

//调用该函数并且接收返回值
double result = (double)mul.call (-2, 3);

Debug.Log(result);
}
}


自定义C#对象
LOHuman.cs
,在
HelloLua.lua


LOHuman.cs


using System;
using LuaInterface;
using SLua;
//该特性可以修饰以下类将会注册到Slua执行环境中
[CustomLuaClass]
public class HHHuman
{
//年龄成员
protected int age = 0;
//姓名成员
protected string name = "";

//添加Lua代码中的静态函数
[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
[StaticExport]
public static int CreateHuman(IntPtr l)
{
HHHuman item = new HHHuman ();
LuaObject.pushObject (l, item);
//只执行了1次LuaObject.push,返回值写1
return 1;
}

public int Age {
set;
get;
}

public string Name{ set; get; }
}


通过点击菜单栏中的
SLua->Custom->Clear
将旧版本的自定义类删除

通过点击菜单栏中的
SLua->Custom->Make
重新制作适用于SLua的新的自定义类
Lua_HHHuman.cs

默认存放目录
Assets->SLua->LuaObject->Custom->


同时会自动生成一个
BindCustom.cs
类,代码如下:
using System;
namespace SLua {
[LuaBinder(3)]
public class BindCustom {
public static void Bind(IntPtr l) {
Lua_HHHuman.reg(l);
Lua_System_Collections_Generic_List_1_int.reg(l);
Lua_System_Collections_Generic_Dictionary_2_int_string.reg(l);
Lua_System_String.reg(l);
}
}
}


AppDelegate.cs
init
函数中,绑定自定义类
HHHuman.cs

//添加LuaState初始化时的回调函数特性函数
[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
static int init(IntPtr L)
{
LuaObject.init(L);
BindCustom.Bind (L);
return 0;
}


HelloLua.lua
脚本中,调用C#中的自定义类的静态函数
CreateHuman()

function testHuman()
-- body
local human = HHHuman.CreateHuman()
-- local list = human:getList()
print(human.Age)
end


AppDelegate.cs
Start
函数中,调用
HelloLua.lua
脚本中的
testHuman
函数

static LuaState ls_state;
void Start ()
{
//创建状态机对象
ls_state = new LuaState ();

//设置脚本启动代理
LuaState.loaderDelegate = ((string fn) => {
//获取Lua文件执行目录
string file_path = Directory.GetCurrentDirectory() + "/Assets/Resources/" + fn;

Debug.Log(file_path);

return File.ReadAllBytes(file_path);
});

//初始化LuaState状态机与C#的转换对象
LuaState.pcall (ls_state.L, init);

//设置执行脚本
ls_state.doFile ("HelloLua.lua");

//获取testHuman函数
LuaFunction testHuman = ls_state.getFunction ("testHuman");

//无参函数的调用
testHuman.call ();
}


 

创建新的Unity工程并且导入SLua框架

使用已经注入
UnityEngie
引擎的状态机对象
LuaSvr
调用Lua脚本
AppDelegate.cs


using UnityEngine;
using System.Collections;
using SLua;

public class Main : MonoBehaviour
{

private LuaSvr lua_svr;
// Use this for initialization
void Start()
{
//创建一个已经注入UnityEngine的状态机对象..
lua_svr = new LuaSvr();

//通过Resources文件夹下的main.txt(lua)文件内的main函数启动程序
//当然也可以通过修改LuaState.loaderDelegate来修改默认的路径
lua_svr.start("main");
}
}

main.txt


funcion main()
print("Hello LuaSvr...")
end


main.txt
文件内导入
UnityEngine
包并且创建游戏对象

import "UnityEngine"

function main()
-- 创建Cube对象
local cube=UnityEngine.GameObject.CreatePrimitive(UnityEngine.PrimitiveType.Cube)
end


main.txt
文件内导入
UnityEngine
包并且创建空游戏对象

import "UnityEngine"

function main()
-- 创建空物体对象
local empty=UnityEngine.GameObject("HHEmptyObject")
end


操作游戏对象上的组件

获取
Transform
组件

import "UnityEngine"

function main()
-- 创建Cube对象
local cube=UnityEngine.GameObject.CreatePrimitive(UnityEngine.PrimitiveType.Cube)

-- 获取transform组件上的position属性
local pos = cube.transform.position
pos.x = 10

-- 修改transform组件的position属性
cube.transform.position = pos
end


添加
Rigidbody
组件
导入
import "UnityEngine"

添加刚体组件
cube:AddComponent(Rigidbody)


获取指定类型的组件,例如
BoxCollider

导入
import "UnityEngine"

自定类型字符串获取
local collider = cube:GetComponent("BoxCollider")


由于使用
Lua
编写Unity项目时,无法与C#相比的是对象函数或者对象属性的智能提示不够健全.

所以在此贴出
Slua
框架中注入
LuaState
状态机对象内的一些
UnityEngine
的函数和属性.

UnityEngine.GameObject
对象在
LuaState
中注入的内容

static public void reg(IntPtr l) {
getTypeTable(l,"UnityEngine.GameObject");
addMember(l,GetComponent);
addMember(l,GetComponentInChildren);
addMember(l,GetComponentInParent);
addMember(l,GetComponents);
addMember(l,GetComponentsInChildren);
addMember(l,GetComponentsInParent);
addMember(l,SetActive);
addMember(l,CompareTag);
addMember(l,SendMessageUpwards);
addMember(l,SendMessage);
addMember(l,BroadcastMessage);
addMember(l,AddComponent);
addMember(l,CreatePrimitive_s);
addMember(l,FindGameObjectWithTag_s);
addMember(l,FindWithTag_s);
addMember(l,FindGameObjectsWithTag_s);
addMember(l,Find_s);
addMember(l,"transform",get_transform,null,true);
addMember(l,"layer",get_layer,set_layer,true);
addMember(l,"activeSelf",get_activeSelf,null,true);
addMember(l,"activeInHierarchy",get_activeInHierarchy,null,true);
addMember(l,"isStatic",get_isStatic,set_isStatic,true);
addMember(l,"tag",get_tag,set_tag,true);
addMember(l,"gameObject",get_gameObject,null,true);
createTypeMetatable(l,constructor, typeof(UnityEngine.GameObject),typeof(UnityEngine.Object));
}

只有函数指针位置的部分,在Lua中定义成了Table变量内的函数,例如:
cube:AddCommponent

在函数指针名的末尾部分以
_s
结尾的,在Lua中定义成了元表变量内的函数,例如:
GameObject.CreatePrimitive

在添加成员时,包含了类似于
"transform"
字符串的,在Lua中定义成了Table变量内的键值对属性,例如:
cube.transform


UnityEngine.Transform
对象在
LuaState
中注入的内容

static public void reg(IntPtr l) {
getTypeTable(l,"UnityEngine.Transform");
addMember(l,SetParent);
addMember(l,Translate);
addMember(l,Rotate);
addMember(l,RotateAround);
addMember(l,LookAt);
addMember(l,TransformDirection);
addMember(l,InverseTransformDirection);
addMember(l,TransformVector);
addMember(l,InverseTransformVector);
addMember(l,TransformPoint);
addMember(l,InverseTransformPoint);
addMember(l,DetachChildren);
addMember(l,SetAsFirstSibling);
addMember(l,SetAsLastSibling);
addMember(l,SetSiblingIndex);
addMember(l,GetSiblingIndex);
addMember(l,Find);
addMember(l,IsChildOf);
addMember(l,FindChild);
addMember(l,GetChild);
addMember(l,"position",get_position,set_position,true);
addMember(l,"localPosition",get_localPosition,set_localPosition,true);
addMember(l,"eulerAngles",get_eulerAngles,set_eulerAngles,true);
addMember(l,"localEulerAngles",get_localEulerAngles,set_localEulerAngles,true);
addMember(l,"right",get_right,set_right,true);
addMember(l,"up",get_up,set_up,true);
addMember(l,"forward",get_forward,set_forward,true);
addMember(l,"rotation",get_rotation,set_rotation,true);
addMember(l,"localRotation",get_localRotation,set_localRotation,true);
addMember(l,"localScale",get_localScale,set_localScale,true);
addMember(l,"parent",get_parent,set_parent,true);
addMember(l,"worldToLocalMatrix",get_worldToLocalMatrix,null,true);
addMember(l,"localToWorldMatrix",get_localToWorldMatrix,null,true);
addMember(l,"root",get_root,null,true);
addMember(l,"childCount",get_childCount,null,true);
addMember(l,"lossyScale",get_lossyScale,null,true);
addMember(l,"hasChanged",get_hasChanged,set_hasChanged,true);
createTypeMetatable(l,null, typeof(UnityEngine.Transform),typeof(UnityEngine.Component));
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: