Skip to content

Script Structure⚓︎

Structure of a script⚓︎

A game object script needs to be structured in a specific way.

Check out this sample code:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
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:

  1. 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 the do ... end block to create a local context.

Local functions and variables⚓︎

Always Use 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

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

  1. 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.

Warning

Follow the proper naming convention when naming the object. Think of it as a variable.

  1. function script.Start(), start callback function: this function is called once when the game object initializes. This is a good place to initialize variables.
  2. 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.

Note

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:

1
2
3
4
5
6
7
8
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:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
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:

1
2
3
4
5
6
7
8
9
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.

Warning

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
1
2
3
4
5
6
7
8
9
do
    local script = LUA.script;

    script.myVariable = 50;

    function script.Start()
        Debug.Log(script.myVariable); 
    end
end
  • Or not attached it
1
2
3
4
5
6
7
8
9
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).

Info

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.

important

Always use local with variables and functions that are not attached to the script object.