Using Lua scripts in Unity

Source: Internet
Author: User
Tags lua

Foreword: Why Use LUA
First of all, all programming languages inside, my favorite is still c#,visualstudio+c#, can only say too comfortable. So why not use LUA in unity? may be mainly idle egg pain ..... There are other secondary reasons:
Easy to do function of hot update;
The depth and breadth of the Lua language is small, easy to learn and easy to use, can reduce project costs.

Scenarios in which C # and Lua invoke each other
Frankly, I don't have a careful look at all the libraries that C # and LUA call each other now, probably by searching and finding these:
Slua:https://github.com/pangweiwei/slua
nlua:http://nlua.org/
Unilua:https://github.com/xebecnan/unilua
Ulua Plug-in
The specific content of these programs, not the focus of this article, here do not say, interested students, point to open their own to see on the line.

Finally, I chose the Ulua, the main reason is: Ulua scheme is relatively mature, it does not have much of their own code, mainly to the Luainterface and LUA interpreter integration, are relatively mature code, relatively stable. In addition, the individual appreciates luainterface this library. Next we'll take a look at Ulua. :)
Ulua plug-in is very simple to use, basically look at his own several examples to understand.

Game Logic Adhesive Layer Design
The Ulua plugin addresses a language-level problem: a series of underlying issues related to C # and LUA two language code invocation, and parameter passing. In our game logic development, how to use Lua is a problem in the upper layer. Here is a solution I groped, personally think: simple enough, clear enough, is very thin and thin layer, can not be thinner.

How many luastate do you use?
Once saw a Netizen's plan, each time runs the script to new one luastate, personally thinks this kind of plan is very inappropriate. The LUA code for the entire game should run on a luastate for two reasons:
Lua code running on the same luastate can call each other. Believe that a game will always have a certain amount of code, if the code in different LUA files, completely independent operation, can not call each other or call each other very troublesome, the game logical organization adds a lot of obstacles;
One of the principles of mixed-language programming is to minimize the language-context switching of code execution, because the cost of this is often much higher than what the code literally looks like. My goal: Since using LUA, try to put the upper-level logic of UI event response into LUA code.
For these reasons, I think the LUA code of the game is all running on a luastate. This is also the basis of this paper's plan.

Implement Luacomponent
First of all, say my goal:
Since C # is a scripting layer for unity, LUA should have the same logical status as C # script code;
The code for LUA integration should be minimal and should be kept as simple as possible;
Based on the above objectives, I implemented the Luacomponet class, it is implemented similar to Monobehavior, but we do not have C + + source code, only by the C # layer of Monobehavior to forward the call. In this way, our LUA code is implemented by writing and writing a C # Script component that is fully consistent, and can be said to achieve seamless integration with the engine. :) OK, first on the code!

usingUnityengine; usingSystem.Collections; usingLuainterface; /// <summary>  ///Lua Component-The LUA script it invokes can implement functions similar to monobehaviour derived classes/// </summary>[Addcomponentmenu ("lua/luacomponent")]   Public classLuacomponent:monobehaviour {Private StaticLuastate s_luastate;//Global LUA virtual machine[Tooltip ("path to the bound Lua script")]       PublicTextasset M_luascript;  Publicluatable Luamodule {Get; Private Set;    } luafunction m_luaupdate; //the update function implemented by LUA, possibly null       /// <summary>      ///Find the Lua component (module object) bound to the game object/// </summary>       Public Staticluatable getluacomponent (Gameobject go) {luacomponent Luacomp= go. Getcomponent<luacomponent>(); if(Luacomp = =NULL)              return NULL; returnLuacomp.luamodule; }         /// <summary>      ///Add a LUA component to a gameobject/// </summary>       Public Staticluatable addluacomponent (gameobject go, Textasset luafile) {luacomponent Luacomp= go. Addcomponent<luacomponent>();  Luacomp.initilize (Luafile); //manually invoke the script to run to get the luatable return value        returnLuacomp.luamodule; }         /// <summary>      ///interface for manually executing LUA scripts externally/// </summary>       Public voidinitilize (Textasset luafile) {m_luascript=Luafile;             Runluafile (Luafile); //--Get the usual function callbacks        if( This. Luamodule! =NULL) {m_luaupdate= This. luamodule["Update"] asluafunction; }      }         /// <summary>      ///invoking a LUA virtual machine, executing a script file/// </summary>      voidrunluafile (Textasset luafile) {if(Luafile = =NULL||string. IsNullOrEmpty (luafile.text))return; if(S_luastate = =NULL) S_luastate=Newluastate (); Object[] Luaret = s_luastate.dostring (Luafile.text, Luafile.name,NULL); if(Luaret! =NULL&& Luaret.length >=1)          {              //convention: The first returned Table object acts as a LUA module             This. Luamodule = luaret[0] asluatable; }          Else{debug.logerror ("The Lua script does not return a Table object:"+luafile.name); }      }         //Monobehaviour Callback    voidAwake () {runluafile (m_luascript); Callluafunction ("Awake", This. Luamodule, This. Gameobject); }         //Monobehaviour Callback    voidStart () {callluafunction ("Start", This. Luamodule, This. Gameobject); }         //Monobehaviour Callback    voidUpdate () {if(M_luaupdate! =NULL) M_luaupdate.call ( This. Luamodule, This. Gameobject); }         /// <summary>      ///calling a function in a LUA component/// </summary>      voidCallluafunction (stringFuncName,params Object[] args) {          if( This. Luamodule = =NULL)              return; luafunction func= This. Luamodule[funcname] asluafunction; if(Func! =NULL) func.      Call (args); }  }  



This code is very simple and implements several function points:

    • Management of a global luastate;
    • Responsible for forwarding the Monobehavior call to the corresponding LUA function;
    • The Lua script version interface for Getcomponent () and addcomponent () is provided, which is very important.


LUA Code Conventions
In order to collaborate well with luacomponent, LUA scripts need to follow some conventions:

    • The Lua script should return a table, either the module for LUA or any table object;
    • The returned Table object should contain monobehaviour corresponding callback function;

For example:

[AppleScript]Plain Text view copy code ?
123456789 require "EngineMain"  local demoComponent = {}  function demoComponent:Awake( gameObject )    Debug.Log(gameObject.name.."Awake")end  return demoComponent 



In the luacomponent callback function, the Gameobject object is actively passed as a parameter to the LUA layer to facilitate its processing accordingly.

Mutual invocation between LUA components (in LUA code)
Based on the above structure, it is easy to implement mutual invocation between LUA components. In the demo project, there is a "Sphere" object that binds the following script:

[AppleScript]Plain Text view copy code ?
0102030405060708091011 require "EngineMain"  local sphereComponent = {}  sphereComponent.text = "Hello World"  function sphereComponent:Awake( gameObject )    Debug.Log(gameObject.name.."Awake")end   return sphereComponent 



There is another "Cube" object that binds the following script to demonstrate the invocation of the members of the LUA component above:

[AppleScript]Plain Text view copy code ?
01020304050607080910111213141516171819 require "EngineMain"  local demoComponent = {}   function demoComponent:Awake( gameObject )    Debug.Log(gameObject.name.."Awake") end  function demoComponent:Start( gameObject )    Debug.Log(gameObject.name.."Start")      --演示LuaComponent代码互相调用      local sphereGO = GameObject.Find("Sphere")    local sphereLuaComp = LuaComponent.GetLuaComponent(sphereGO)    Debug.log("Sphere.LuaDemoB:"..sphereLuaComp.text)   end  return demoComponent 




Finally, let's summarize: in the design of the last game logic framework, the better idea is: Under the premise of a thorough understanding of unity's own architecture, the next layer of design under its architecture, rather than a new framework. Because unity itself is a framework. For more information, see the author's blog: http://blog.csdn.net/neil3d/article/details/44200821

Using Lua scripts in Unity

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.