コガネブログ

平日更新を目標に Unity や C#、Visual Studio、ReSharper などのゲーム開発アレコレを書いていきます

【Unity】UnityでLuaを使用できるようにする「xLua」紹介  Lua から C# のプログラムを実行する方法

f:id:baba_s:20170923092213p:plain

はじめに

xLua は C# ( Unity、.Net、Mono ) で Lua を使用できるようにするアセットで、
Android、iOS、Windows、Linux、OSX などをサポートしており
GitHub からダウンロードして使用することができます

今回は xLua で Lua から C# のプログラムを実行する方法を紹介していきます

ゲームオブジェクトの作成

-- example.lua.txt

local obj1 = CS.UnityEngine.GameObject()
local obj2 = CS.UnityEngine.GameObject( 'ピカチュウ' )
print( obj1, obj2 )

名前空間の省略

-- example.lua.txt

local GameObject = CS.UnityEngine.GameObject
local obj1 = GameObject()
local obj2 = GameObject( 'ピカチュウ' )
print( obj1, obj2 )

Unity の static クラスへアクセス

-- example.lua.txt

local GameObject = CS.UnityEngine.GameObject
local Time = CS.UnityEngine.Time
print( 'deltaTime:', Time.deltaTime )
Time.timeScale = 0.5
print( 'helloworld', GameObject.Find( 'ピカチュウ' ) )

独自クラスのインスタンスの生成

// Example.cs

public class Character
{
    public int m_id;
    public string m_name;

    public void Log()
    {
        Debug.Log( m_id + ": " + m_name );
    }
}
-- example.lua.txt

local Character = CS.Character
local character = Character()
character.m_id = 25
character.m_name = 'ピカチュウ'
print( character.m_id )
print( character.m_name )
character:Log()

f:id:baba_s:20170923115644p:plain

static な変数や関数の呼び出し

// Example.cs

public class Manager
{
    public static int m_score;
    
    public static void Log()
    {
        Debug.Log( m_score );
    }
}
-- example.lua.txt

local Manager = CS.Manager

Manager.m_score = 100
Manager.Log();
print( Manager.m_score )

f:id:baba_s:20170923115707p:plain

オーバーロードされた関数の呼び出し

// Example.cs

public class Character
{
    public void Log( int id )
    {
        Debug.Log( id );
    }
    
    public void Log( string name )
    {
        Debug.Log( name );
    }
}
-- example.lua.txt

local Character = CS.Character
local character = Character()
character:Log( 25 )
character:Log( 'ピカチュウ' )

f:id:baba_s:20170923115715p:plain

デフォルト引数が設定された関数の呼び出し

// Example.cs

public class Character
{
    public void Log( int id = 1, string name = "フシギダネ" )
    {
        Debug.Log( id + ": " + name );
    }
}
-- example.lua.txt

local Character = CS.Character
local character = Character()
character:Log()
character:Log( 25 )
character:Log( 25, 'ピカチュウ' )

f:id:baba_s:20170923115723p:plain

可変長引数が設定された関数の呼び出し

// Example.cs

public class Character
{
    public void Log( params string[] names )
    {
        foreach ( var n in names )
        {
            Debug.Log( n );
        }
    }
}
-- example.lua.txt

local Character = CS.Character
local character = Character()
character:Log()
character:Log( 'フシギダネ' )
character:Log( 'フシギソウ', 'フシギバナ' )

f:id:baba_s:20170923115736p:plain

拡張メソッドの呼び出し

// Example.cs

using XLua;

public class Character
{
}

[LuaCallCSharp]
public static class CharacterExt
{
    public static void Log( this Character self )
    {
        Debug.Log( "拡張メソッド" );
    }
}
-- example.lua.txt

local Character = CS.Character
local character = Character()
character:Log()

f:id:baba_s:20170923115746p:plain

ref や out キーワードの使用

// Example.cs

public class Character
{
    public void Attack( ref int hp, out int exp )
    {
        hp = 25;
        exp = 100;
    }
}
-- example.lua.txt

local Character = CS.Character
local character = Character()

local hp, exp = character:Attack()
print( hp, exp )

f:id:baba_s:20170923115755p:plain

列挙型の使用

// Example.cs

public enum ParamType
{
    FIRE, 
    WATER, 
    GRASS, 
}
-- example.lua.txt

local ParamType = CS.ParamType
local paramType = ParamType.FIRE
print( paramType )
print( ParamType.__CastFrom( 1 ) )
print( ParamType.__CastFrom( 'GRASS' ) )

f:id:baba_s:20170923115805p:plain

デリゲートの使用

// Example.cs
using System;

public class Character
{
    public Action<string> OnLog = str => Debug.Log( "C#: " + str );
}
-- example.lua.txt

local Character = CS.Character
local character = Character()

character.OnLog( 'フシギダネ' )

local function lua_delegate( str )
    print( 'Lua: ', str )
end

-- デリゲートの登録
character.OnLog = character.OnLog + lua_delegate
character.OnLog( 'フシギソウ' )

-- デリゲートの解除
character.OnLog = character.OnLog - lua_delegate
character.OnLog( 'フシギバナ' )

f:id:baba_s:20170923115820p:plain

イベントの使用

// Example.cs

using System;

public class Character
{
    public event Action<string> OnLog;

    public void Log( string str )
    {
        if ( OnLog == null ) return;
        OnLog( str );
    }
}
-- example.lua.txt

local Character = CS.Character
local character = Character()

local function lua_callback( str )
    print( str )
end

-- コールバックの登録
character:OnLog( '+', lua_callback )
character:Log( 'フシギダネ' )

-- コールバックの解除
character:OnLog( '-', lua_callback )
character:Log( 'フシギソウ' )

f:id:baba_s:20170923115830p:plain

typeof の使用

-- example.lua.txt

local GameObject = CS.UnityEngine.GameObject
local ParticleSystem = CS.UnityEngine.ParticleSystem
local gameObject = GameObject()
gameObject:AddComponent( typeof( ParticleSystem ) )

キャストする

// Example.cs

public interface ICharacter
{
    void Log();
}

public class Character : ICharacter
{
    public void Log()
    {
        Debug.Log( "ピカチュウ" );
    }
}
-- example.lua.txt

local Character = CS.Character
local character = Character()
local ICharacter = CS.ICharacter

character:Log()
cast( character, typeof( ICharacter ) )
character:Log()

f:id:baba_s:20170923115841p:plain

関連記事