Unity 3 D開発小贴士(五)Lua呼び出しC#
4285 ワード
Unity 3 D開発小贴士(三)Lua開発を楽しく使用してToLuaプラグインをUnityプロジェクトに追加する方法を紹介し、Unity 3 D開発小贴士(四)Luaスクリプトを呼び出してC#でLuaスクリプトを呼び出す方法を説明した.LuaでC#を呼び出す方法について説明します.
まずCクラスを書きます.
次にUnityエディタでLua->Gen LuaWrap+Binderをクリックし、生成が完了するのを待ちます.
シーンにGameObjectを追加し、LuaClientスクリプトを掛けます.
そしてMain.Luaに追加:
実行をクリックすると、次のように印刷されます.
Hello Lua in C#
次に、CSharpFuncにTestCSharpFuncのリロードバージョンを追加します.
再度Gen LuaWrap+Binderをクリックします.
MainでLuaに追加:
実行をクリックすると、1行多く印刷されます.
Hello Lua in C#[Lua]
運用方法を知ってから、ToLuaが私たちのために何をしてくれたか見てみましょう.
Assets/Source/Generate/LuaBinder.csファイル
および
行が1つ増えました.
また、同じレベルのディレクトリの下にCSharpFuncWrapが1つ追加されました.csファイル.
ファイルの内容:
L.BeginClassはこのタイプ(CSharpFunc)とその親(System.Object)をLuaに登録し、それぞれTestCSharpFuncとNewおよび__を登録した.tostring関数、最後にEndClassは登録を終了します.
__TOstringはToLuaの静的メソッドを登録しているが,ここでは後述しない.
New関数ではまずスタックの深さを取得し、数が0(パラメータなし)の場合はCSharpFuncオブジェクトを作成し、スタックに押し込みます.そうでなければ(スタックの深さがゼロより大きい、すなわちNew関数にパラメータが入力されている)、異常が投げ出されます.
TestCSharpFunc関数はNew関数と似ていますが、2つのリロードバージョンがあるため、スタックの深さに2つの相違があります.
もちろん、戻り値を持つC#メソッドを追加することもできます.
例えば簡単な判定:
Gen LuaWrap+Binderをクリック
Main.luaに追加:
意外にもfalseを1つ多く印刷します.
CSharpFuncWrap.csファイルのRegisterメソッドでは、BeginClassとEndClassの間に1行追加されています.
もう一つの方法があります
書き方は変わっていますが、論理は前の関数とあまり違いません.ただ、本方法が戻る前に、
IsPositiveの結果oはLuaスタックに押し込まれる.
まずCクラスを書きます.
using UnityEngine;
using System.Collections;
public class CSharpFunc {
public void TestCSharpFunc()
{
Debug.Log ("Hello lua in C#");
}
}
次にUnityエディタでLua->Gen LuaWrap+Binderをクリックし、生成が完了するのを待ちます.
シーンにGameObjectを追加し、LuaClientスクリプトを掛けます.
そしてMain.Luaに追加:
local csharpFunc = CSharpFunc.New()
csharpFunc:TestCSharpFunc()
実行をクリックすると、次のように印刷されます.
Hello Lua in C#
次に、CSharpFuncにTestCSharpFuncのリロードバージョンを追加します.
public void TestCSharpFunc(string str)
{
Debug.Log ("Hello lua in C#" + str);
}
再度Gen LuaWrap+Binderをクリックします.
MainでLuaに追加:
csharpFunc:TestCSharpFunc("[Lua]")
実行をクリックすると、1行多く印刷されます.
Hello Lua in C#[Lua]
運用方法を知ってから、ToLuaが私たちのために何をしてくれたか見てみましょう.
Assets/Source/Generate/LuaBinder.csファイル
L.BeginModule(null);
および
L.BeginModule("UnityEngine");
行が1つ増えました.
CSharpFuncWrap.Register(L);
また、同じレベルのディレクトリの下にCSharpFuncWrapが1つ追加されました.csファイル.
ファイルの内容:
//this source code was auto-generated by tolua#, do not modify it
using System;
using LuaInterface;
public class CSharpFuncWrap
{
public static void Register(LuaState L)
{
L.BeginClass(typeof(CSharpFunc), typeof(System.Object));
L.RegFunction("TestCSharpFunc", TestCSharpFunc);
L.RegFunction("New", _CreateCSharpFunc);
L.RegFunction("__tostring", ToLua.op_ToString);
L.EndClass();
}
[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
static int _CreateCSharpFunc(IntPtr L)
{
try
{
int count = LuaDLL.lua_gettop(L);
if (count == 0)
{
CSharpFunc obj = new CSharpFunc();
ToLua.PushObject(L, obj);
return 1;
}
else
{
return LuaDLL.luaL_throw(L, "invalid arguments to ctor method: CSharpFunc.New");
}
}
catch(Exception e)
{
return LuaDLL.toluaL_exception(L, e);
}
}
[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
static int TestCSharpFunc(IntPtr L)
{
try
{
int count = LuaDLL.lua_gettop(L);
if (count == 1 && TypeChecker.CheckTypes(L, 1, typeof(CSharpFunc)))
{
CSharpFunc obj = (CSharpFunc)ToLua.ToObject(L, 1);
obj.TestCSharpFunc();
return 0;
}
else if (count == 2 && TypeChecker.CheckTypes(L, 1, typeof(CSharpFunc), typeof(string)))
{
CSharpFunc obj = (CSharpFunc)ToLua.ToObject(L, 1);
string arg0 = ToLua.ToString(L, 2);
obj.TestCSharpFunc(arg0);
return 0;
}
else
{
return LuaDLL.luaL_throw(L, "invalid arguments to method: CSharpFunc.TestCSharpFunc");
}
}
catch(Exception e)
{
return LuaDLL.toluaL_exception(L, e);
}
}
}
L.BeginClassはこのタイプ(CSharpFunc)とその親(System.Object)をLuaに登録し、それぞれTestCSharpFuncとNewおよび__を登録した.tostring関数、最後にEndClassは登録を終了します.
__TOstringはToLuaの静的メソッドを登録しているが,ここでは後述しない.
New関数ではまずスタックの深さを取得し、数が0(パラメータなし)の場合はCSharpFuncオブジェクトを作成し、スタックに押し込みます.そうでなければ(スタックの深さがゼロより大きい、すなわちNew関数にパラメータが入力されている)、異常が投げ出されます.
TestCSharpFunc関数はNew関数と似ていますが、2つのリロードバージョンがあるため、スタックの深さに2つの相違があります.
もちろん、戻り値を持つC#メソッドを追加することもできます.
例えば簡単な判定:
public bool IsPositive(int num)
{
return num > 0;
}
Gen LuaWrap+Binderをクリック
Main.luaに追加:
print(csharpFunc:IsPositive(-10))
意外にもfalseを1つ多く印刷します.
CSharpFuncWrap.csファイルのRegisterメソッドでは、BeginClassとEndClassの間に1行追加されています.
L.RegFunction("IsPositive", IsPositive);
もう一つの方法があります
[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
static int IsPositive(IntPtr L)
{
try
{
ToLua.CheckArgsCount(L, 2);
CSharpFunc obj = (CSharpFunc)ToLua.CheckObject(L, 1, typeof(CSharpFunc));
int arg0 = (int)LuaDLL.luaL_checknumber(L, 2);
bool o = obj.IsPositive(arg0);
LuaDLL.lua_pushboolean(L, o);
return 1;
}
catch(Exception e)
{
return LuaDLL.toluaL_exception(L, e);
}
}
書き方は変わっていますが、論理は前の関数とあまり違いません.ただ、本方法が戻る前に、
IsPositiveの結果oはLuaスタックに押し込まれる.