Script Structure
Structure of a script
A game object script needs to be structured in a specific way.
Check out this sample code:
do -- script Object
-- Get the reference for current script
local script = LUA.Script;
-- start only called at beginning
function script.Start()
end
-- update called every frame
function script.Update()
end
end
You can see there are few sections to the code:
- The
do ... end
block. The purpose of it is to delimit a block explicitly . The Massive Loop uses a single execution context for all Lua scripts. Use thedo ... end
block to create a local context.
Local functions and variables
local
"Using the local
keyword is very important. This will ensure that the declared local variable (or function) won't be mixed up by similarly named variables
Declaring the variables and functions local prevents corruption of the similarly named variables and functions within multiple scripts however, you can choose to use a function in the global scope.
Local functions have to be declared before using them. For example, in order to use the local function Foo
in start
, it needs to be declared before the start function.
do
local script = LUA.script;
local function Foo()
Debug.Log("Fooo");
end
function script.Start()
Foo();
end
end
The following arrangement will cause error
do
local script = LUA.script;
function script.Start()
Foo();
end
local function Foo()
Debug.Log("Fooo");
end
end
local script = LUA.Script;
returns the reference for current Lua Script getting executed. The script contains special properties that are unique to the game object to which the script is attached.
Also, notice how the start and update functions are accessed through this object.
Follow the proper naming convention when naming the object. Think of it as a variable.
function script.Start()
, start callback function: this function is called once when the game object initializes. This is a good place to initialize variables.function script.Update()
, update callback function: this function called once on every frame. This is where most of the action happens. Be careful that the code executed here will have a direct impact on the performance of the game. If you need to run code that may take a while to conclude, you can use Coroutines.
Both of Start and Update functions are optional. You don't require to have any of them in the code. Use them as you need them.
Naming suggestion for the script variable
The object returned by LUA.script
property returns a special reference to the script attached to the object. A good practice is to give a meaningful name to this object. For example, if the script is attached to a door in the scene and controlling it, it's a good idea to name the object Door
.
local Door = LUA.script;
Other consideration with script object
Make sure you keep the reference to the script object local. If you attach the same script to two different game objects, The
Game Object
Another important property of the object is the actual game object reference to the attached game object. You can control the game object using this property.
You can access the game object reference by calling <NameOfTheObject>.gameObject
.
for example, to access the current position of the game object you can do following:
do
local script = LUA.script;
function script.Start()
local currentPosition = script.gameObject.transform.position;
end
end
You can make access to the gameObject
easier by storing its reference in a local variable.
do
local script = LUA.script;
local go = script.gameObject;
function script.Start()
local currentPosition = go.transform.position;
end
end
Adding extra fields:
You can attach extra properties to the script object. Check the example below:
do
local script = LUA.script;
function script.Start()
script.speed = 50;
end
function script.Move()
script.gameObject.transform.Translate(Vector3(0,Object.speed * Time.DeltaTime(), 0));
end
end
On line 5
, we added a speed property to the script
. On line 8
, we added a function to the script
.
This allows that other scripts access the current script custom properties and functions.
Running code in Parsing Phase
As you noticed, so far we have placed all the code inside start or update functions, however, you can have valid code to be executed outside of the callback functions. Any code outside of the callback function will be executed once at the first pass. For example, this is the best place to define local variables or have some code executed initially.
Consider this code:
do
local script = LUA.script;
local speed = 530 * 51;
Debug.Log(speed);
function script.Start()
script.gameObject.transform.Translate(Vector3(speed * Time.DeltaTime(),0,0));
end
end
Here, the code on lines 3
and 4
getting executed on parsing time.
Not everything is guaranteed to be fully loaded when the code is in the first pass! Do not try to access any scene object or property in the first pass. Use start
callback for initialization.
Difference between two variables
In this section, we have seen two different ways of defining a variable outside the function.
- One way is to attach it to the game object
do
local script = LUA.script;
script.myVariable = 50;
function script.Start()
Debug.Log(script.myVariable);
end
end
- Or not attached it
do
local script = LUA.script;
local myVariable = 50;
function script.Start()
Debug.Log(myVariable);
end
end
You may ask what is the difference?
In term of validity, both of the scripts above are valid and works fine. The only difference is scope. The myVariable
which is attached to the script object (case 1) can be accessed from other scripts running on other game objects, however, the other cannot (case 2).
A similar analogy is to set a variable private or public in other programming languages.
You’ll notice that both properties and methods can be defined with the Object name included or not such as:
do
local script = LUA.script;
script.speed = 50; -- attached to the object
local speed = 50; -- not attached to he object
function script.Start() -- attached to object
-- code here
end
local function Start() -- not attached to the object
-- code here
end
end
The difference is that those that start with script Can be called remotely from scripts running on other game objects.
Always use local
with variables and functions that are not attached to the script object.