[Unity3D] Lua in Unity3D game development is connected to the game's (medium) and unity3dlua
Certificate -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
If you like my blog, please remember my name: Qin Yuanpei. My blog address is blog.csdn.net/qinyuanpei.
Reprinted please indicate the source, Author: Qin Yuanpei, the source of this article: http://blog.csdn.net/qinyuanpei/article/details/39910099
Certificate -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Hello everyone, I'm Qin Yuanpei. Welcome to follow my blog. My blog address is blog.csdn.net/qinyuanpei. In the previous article "Unity3D game development: Lua and game puzzles"
In the margin (I), the blogger has led you to explore the close connection between Lua language and the game development field. Let's continue with the Lua language today! Through the previous study, we know that the Lua language is designed to embed Lua into an application, so as to provide flexible extension and customization functions for the application. The Lua language does not provide rich class libraries like other languages, therefore, the Lua language must rely on other languages to complete functional expansion (but it is at the cost of functionality that makes Lua simple and stable at the core ). To gain a deep understanding of the Lua language, we must understand the interaction interfaces between the Lua language and other languages, because this will be the basis for us to use the Lua language. Now, let the bloggers help us learn the interaction between Lua and other languages!
I. Lua Stack
To understand the essence of interaction between Lua and other languages, we must first understand the Lua stack. To put it simply, the reason why Lua can interact with C/C ++ is that there is such a ubiquitous virtual stack. Stack features advanced post-release. In Lua language, Lua stack is an index structure that can be positive or negative, and requires that positive 1 always represents the bottom of the stack, negative-1 always indicates the top of the stack. In other words, without knowing the stack size, we can use index-1 to get the bottom element of the stack and Index 1 to get the top element of the stack. Next, we will use an example to deepen our understanding of this passage:
# Include <iostream> extern "C" {# include "lua. h "# include" lualib. h "# include" lauxlib. h "} using namespace std; int main () {// create Lua environment lua_State * L = lua_open (); // open the Lua standard library, commonly used standard libraries include luaopen_base, plugin, luaopen_table, luaopen_io, // luaopen_ OS, luaopen_string, plugin, luaopen_debug plugin (L); // press a number 20 lua_pushnumber (L, 20 ); // press a number 15 lua_pushnumber (L, 15); // press a string Lua lua_pushstring (L, "Lua"); // press a string C lua_pushstring (L, "C"); // get the number of stack elements int n = lua_gettop (L); // traverse each element in the stack for (int I = 1; I <= n; I ++) {cout <lua_tostring (L, I) <endl;} return 0 ;}
In the above code, we can see that we first created a lua_State variable L, which can be understood as the Context of a Lua runtime environment ), here we put four elements in the Lua Stack: 20, 15, "Lua", and "C" and output them. If you understand the index in the Lua stack, the final output result should be: 20, 15, "Lua", and "C", because Index 1 always points to the bottom of the stack, and the elements first to the stack will be at the bottom of the stack. Therefore, when we output the elements in the stack in an ascending order of index, it is actually a bottom-up output, so that we can get this result.
Well, if there is no problem with this code, Let's explain the interfaces Lua provides for C/C ++. They are all defined in the lua. h file. Most of the C/C ++ interfaces provided by Lua are related to stack operations. Therefore, a deep understanding of the Lua stack is a key and difficult point for Lua language learning. Through the knowledge of data structures, we can know that the stack has two basic operations: the out stack and the in stack. The c api provided by Lua can be implemented through the push series method, as shown in:
The method of the stack or query can be implemented through the to series method, such:
These two parts are things that must be understood when learning Lua language, because if we need to integrate Lua into other projects in the future, these things can be said to be principles and core things. Now let's use the API to transform an example code. Here we add a judgment on the element type in the stack:
# Include <iostream> extern "C" {# include "lua. h "# include" lualib. h "# include" lauxlib. h "} using namespace std; int main () {// create Lua environment lua_State * L = lua_open (); // open the Lua standard library, commonly used standard libraries include luaopen_base, plugin, luaopen_table, luaopen_io, // luaopen_ OS, luaopen_string, plugin, luaopen_debug plugin (L); // press a number 20 lua_pushnumber (L, 20 ); // press a string 15 lua_pushnumber (L, 15); // press a string Lua lua_pushstring (L, "Lua"); // press a string C lua_pushstring (L, "C"); // get the number of elements in the stack int n = lua_gettop (L); // traverse each element in the stack for (int I = 1; I <= n; I ++) {// type judgment switch (lua_type (L, I) {case LUA_TSTRING: cout <"This value's type is string" <endl; break; case LUA_TNUMBER: cout <"This value's type is number" <endl; break;} // output value cout <lua_tostring (L, I) <endl ;} // release Lua lua_close (L );}
2. Interaction between Lua and C ++
The interaction between Lua and C ++ can be divided into two types from the selection of the host language: C ++ calls Lua and Lua calls C ++:
1. C ++ calls Lua
When we use C ++ to call Lua, we can directly use the Lua environment in C ++ to directly execute Lua scripts. For example, we have defined a lua script file externally, how can we access this script using C ++? Here we can use the luaL_loadfile () and luaL_dofile () methods to implement these two methods. The difference is that the former only loads the script file, while the latter calls the script file at the same time. Let's take a look at the following code:
# Include <iostream> using namespace std; # include <iostream> extern "C" {# include "lua. h "# include" lualib. h "# include" lauxlib. h "} using namespace std; int main () {// create Lua environment lua_State * L = luaL_newstate (); // open the Lua standard library, common standard libraries include luaopen_base, luaopen_package, luaopen_table, luaopen_io, // luaopen_ OS, luaopen_string, runtime, luaopen_debug Runtime (L); // the following code can be used with luaL_dofile () to replace // load the Lua script luaL_loadfile (L, "script. lua "); // run Lua script lua_pcall (L, 0); // press the variable arg1 to the top of the stack lua_getglobal (L," arg1 "); // press the variable arg2 to the top of the stack, lua_getglobal (L, "arg2"); // read the value of arg1 and arg2, int arg1 = lua_tonumber (L,-1 ); int arg2 = lua_tonumber (L,-2); // output the two variables cout <"arg1 =" <arg1 <endl; cout <"arg2 =" <arg2 <endl; // press the function printf to the top of the stack, lua_getglobal (L, "printf"); // call printf () method lua_pcall (L, 0); // press the sum function into the top of the stack lua_getglobal (L, "sum"); // input the lua_pushinteger (L, 15) parameter ); lua_pushinteger (L, 25); // call the printf () method lua_pcall (L, 2, 1, 0 ); // here there are two parameters and one return value // The output sum result cout <"sum =" <lua_tonumber (L,-1) <endl; // press the table into the top of the stack lua_getglobal (L, "table"); // obtain the table lua_gettable (L,-1 ); // The first cout element in the output table <"table. a = "<lua_tonumber (L,-2) <endl ;}
In this Code, we call an external file script. lua. This is a Lua script file. In the debugging phase, we need to place it in a directory at the same level as the C ++ project source file, while in the formal running phase, we only need to put it and the final executable file in the same directory. The following is the script code:
-- Define two variables arg1 = 15arg2 = 20 in Lua -- Define a table in Lua = {a = 25, B = 30} -- Define a summation method in Lua function sum (a, B) return a + bend -- Define an output method in Lua function printf () print ("This is a function declared in Lua") end
We noticed that some variables and methods are defined in the script file. In the C ++ code, we first use the lua_getglobal () method to stress the variables or functions in the Lua script to the top of the stack, in this way, we can use the relevant to series methods to obtain them, because every execution of lua_getglobal () is at the top of the stack, because we use the index value-1 to obtain the elements at the top of the stack. C ++ can call the method in Lua. The first step is the same as that of a common variable. It pushes the method defined in Lua to the top of the stack, because only the method is pushed to the stack, we can use this method. Next, we need to pass in parameters for the method in the stack through the push series method. After the parameter is passed in, we can use a lua_pcall () method to execute the method in the stack. It has four parameters. The first parameter is the Lua Environment State Lua_State, and the second parameter is the number of parameters to be passed in, the third parameter is the number of values to be returned, and the fourth parameter is usually 0 by default. Because Lua supports returning multiple results, we can take full advantage of this feature to return multiple values. After this method is executed, the result is pushed to the top of the stack. Therefore, we can index-1 to obtain the function result. If a function has multiple return values, the return order is defined in the function. The value-1 indicates the last return value. Well, this is the specific implementation of C ++'s call to Lua.
2. Lua calls C ++
First, we define a method in C ++. This method must use Lua_State as the parameter and the return value type is int, indicating the number of values to be returned.
Static int AverageAndSum (lua_State * L) {// returns the number of elements in the stack int n = lua_gettop (L); // stores the sum of each element double sum = 0; for (int I = 1; I <= n; I ++) {// process if (! Lua_isnumber (L, I) {// input the error message lua_pushstring (L, "Incorrect argument to 'average'"); lua_error (L);} sum + = lua_tonumber (L, i);} // input the average lua_pushnumber (L, sum/n); // input and lua_pushnumber (L, sum); // number of returned values, here is 2 return 2 ;}
Next, we use the lua_register () method in C ++ to register the method.
lua_register(L, "AverageAndSum", AverageAndSum);
In this way, we can use this method in the Lua environment, provided that the definition must be completed before the code is executed. we add a call to this method under the Lua script file:
-- Call the average, sum = AverageAndSum (,) print ("Average = ". average) print ("Sum = ". sum)
If we need to view the result of this method call in C ++, it is the same to call Lua in C ++. Now, the interaction between C ++ and Lua has finally been finished, and the code has been entangled for several days. Of course, this is just a learning and understanding of the principle. If you want to use Lua to call C ++ better, we suggest you understand these projects:
LuaPlus and LuaBind. I believe you will have a better understanding of how to bind methods in C ++ in Lua!
3. Interaction between Lua and C #
Now that we know how C ++ interacts with Lua, theoretically we can write a dll to continue the previous work in C, however, in doing so, we need to spend a lot of time struggling between the three languages, because this will increase the difficulty of debugging. A coco2dx friend complained that he was running back and forth between C ++, Javascript, and Lua. I didn't think there was anything at the time, because the most difficult time for me is the mixed scenario of C # and Java projects. Now I have a deep understanding of it. Is this a retribution? Haha, Well, let alone this. Fortunately, there is a good solution in front of the interaction between C # And Lua, in the open-source community, we can find many tool libraries that support calling Lua in C #. The author recommends the open-source project LuaInterface, I have found two addresses for this open-source project:
1. https://github.com/Jakosa/LuaInterface
2. http://code.google.com/p/luainterface
The blogger personally thinks this should be the same project, because the source code of the two projects is the same, but an error will be reported when the project downloaded from Github is used, it is estimated that the Lua version on my computer is inconsistent with the Lua version used in its project. The following project can be used. A simple example is provided here:
/// Summary // <summary> // This is a simple program used to demonstrate LuaInterface. Through LuaInterface, we can implement communication between C # And Lua. Lua is a lightweight and efficient language that can be used together with any language. The Lua language was originally not/born for game development, but became famous for game development. Currently, many games in the world use Lua as their script language. Unity uses C # as its language. Lua plays an important role in game development. The method for using LuaInterface is as follows: // 1.C# // you can call the following method when registering Lua: // mLua. registerFunction (Lua call method name, class, class. getMethod (C # method name); // Note: C # Do not use method-level generics, that is, void Fun <T> (string str); if you use, the system automatically determines that T is the type of the first parameter. // Load the Lua code // mLua. doString (Lua Code); // mLua. doFile (absolute path of the Lua file); // call the Lua method // mLua. getFunction (Lua method ). call (parameter). Note: Do not pass the dynamic type class here, otherwise, the Lua cannot obtain the property value // 2.lua// when calling the C # method, you must register the value and follow the Lua method to process it. // </summary> // register using System; using LuaInterface; namespace LuaExample {public class LuaScript {// defines the LuaFile attribute so that you can call a Lua script private string mLuaFile; pub Lic string LuaFile {get {return mLuaFile;} set {mLuaFile = value ;}// Lua Virtual Machine private Lua mLua; // constructor public LuaScript () {// initialize the Lua Virtual Machine mLua = new Lua (); // register the Printf method mLua. registerFunction ("Printf", this, this. getType (). getMethod ("Printf");} // defines a C # method for Lua to use public void Printf (string str) {Console. writeLine ("This Method is Invoked by Lua:" + str);} // call the Lua Method public void DoFile () {if (mLuaFile! = "") // Execute the code mLua In The Lua script. doFile (mLuaFile);} // call the Lau method public void DoString () in C # {// The Lua script string mFuncString = "function Add (, b) io. write (a + B) end "; // define this method in Lua. doString (mFuncString); // call the mLua method. getFunction ("Add "). call ();} // Call the C # script public void Invoke () in Lua {// Call the registered Printf method mLua. getFunction ("Printf "). call ("Hello Lua ");}}}
Next we will compile a main class to call this class:
Using System; using LuaInterface; namespace LuaExample {class MainClass {public static void Main (string [] args) {// instantiate LuaSxriptLuaScript mLua = new LuaScript (); // set LuaFilemLua. luaFile = "D: \ test. lua "; // call the Lua method defined in the string mLua. doString (); // Add an empty-line Console for aesthetic consideration. writeLine (); // execute the script mLua defined in the Lua file. doFile (); // call the mLua method defined in C. invoke ();}}}
Well, the interaction between C # And Lua has been solved. More content is expected to be found in the source code of the project. Okay. Let's do it first!
4. Interaction between Lua and Java
Similar to C #, we can use JNI to call C ++ code in Java. Therefore, in theory, Lua and Java should be able to interact through JNI, this blogger is not currently conducting research. Here we only recommend the following tool libraries:
1. LuaJava
2. luaj
V. Conclusion
Okay, okay. I 've been studying the Lua language API for several days, so I feel a little more rewarding. Since C ++ has not studied many things, problems such as compiling C ++ projects, configuring C ++ environments, referencing C ++ libraries, and header files were not discussed before, I learned it all at once this time. The blogger recommends that you use the C/C ++ Development Environment CodeBlocks. I think it's good to use the built-in gcc compiler, And it's cross-platform, I may be working in Linux and Mac for development in the future. It is not a good thing for us to choose a cross-platform editor or IDE, because learning new things is always costly. Well, today's content is like this. I hope everyone will like it. Hey, I suddenly think this article is a long one.
Daily Rumor: don't always grievance yourself because of accommodating others. Few people in this world deserve your total bending. After bending over for a long time, it will only make people get used to your low posture, and you are not important.
Certificate -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
If you like my blog, please remember my name: Qin Yuanpei. My blog address is blog.csdn.net/qinyuanpei.
Reprinted please indicate the source, Author: Qin Yuanpei, the source of this article: http://blog.csdn.net/qinyuanpei/article/details/39910099
Certificate -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Unity3D game development instances, source code recommendation books, or download Source Code addresses
Unity 3D Game Development
[Unity3D] mobile 3D Game Development: how to use gravity sensing in Unity3D
Wang wanghai's laboratory, Shanghai laboratory-various graphics experiments, data structure experiments, and other trivial little notes are all gathered here for 0-various graphics experiments and data structures the lab and all other trivial notes are gathered here for 0 error (s ), 0 warning (s) the arrival of this magic moment error (s), 0 warning (s) the arrival of this magic moment learning Unity script is recommended: unity3D indexing gravity sensing is very common in mobile game development. Unity3D is a collection of gravity sensing related content. A simple JS script demonstrates the use of gravity sensing. CSDNGravity. js: // object texture var round: Texture2D; // The x y coordinate var x = 0 displayed on the screen; var y = 0; // maximum x y range displayed on the Object Screen var cross_x = 0; var cross_y = 0; function Start () {// initialization value cross_x = Screen. width-round. width; cross_y = Screen. height-round. height;} function OnGUI () {// The overall x y z gravity sensing gravity component GUI is displayed. label (Rect (0,0, 480,100), "position is" + Input. acceleration); // draw the object GUI. drawTexture (Rect (x, y, 256,256), round);} function Update ( ) {// Modify the object position based on the gravity component. Multiply the value by 30 here to make the object move faster x ++ = Input. acceleration. x * 30; y + =-Input. acceleration. y * 30; // avoid an object exceeding the screen if (x <0) {x = 0;} else if (x> cross_x) {x = cross_x ;} if (y <0) {y = 0;} else if (y> cross_y) {y = cross_y ;}} the Input here refers to the Input in Unity, acceleration is its gravity, and x and y represent its gravity. After creating the image, you only need to add the texture image: 12