Could you also store a module state this way? In the modules page (linked above) could you store the local my_state
as a go.property, eg. self.my_state
?
No. Values set with go.property
are limited to a small amount of variable types you can actually set with them. Doing this would be useless and counterintuitive anyways because module states are global and are not local to a single script. They are shared throughout the entire project.
I will explain how to use properties and how to use modules.
I don’t know much about Unity’s “GetComponent”, but I would assume it works similar to go.get
, which allows you to get properties from different scripts.
Example:
Script named “main.script” attached to gameobject “/go” and “/go1”:
go.property("speed", 200) --this is outside of any functions, in the script itself because
--its supposed to be set for all instances of this script
Setting this property would allow it to be visible in the collection. The script can refer to its own property through self.speed
.
Now, remember, I put “main.script” in 2 different objects. These are 2 different script instances with 2 different instances of the same property. I can now go into, let’s say, “/go#main” (script URL) and change “Speed” to 300. Now in runtime, “go#main”'s “Speed” property is 300 and “go1#main”'s Speed property is still 200. If I go into the script and write this code:
local go_speed = go.get("go#main", "speed")
The number returned will be 300, because we set this specific script’s property to 300 from the default 200.
This is a way to share values between scripts, but as I said, it’s only good for numbers, vectors, and URLs to instances and textures because strings are serialized in hashes and are practically useless.
Now for modules:
The way modules work is that you store everything you want to include inside a table and at the very end of the table, you return the table. This is an example of an empty module:
local globals = {}
return globals
Now if I want to store variables and functions multiple scripts can use, I have to store it inside the globals table. Luckily, you don’t have to put everything inside the brackets.
local globals = {}
globals.food = {}
function globals.addFood(food)
table.insert(globals.food, food)
end
function globals.eatEverything()
for i, v in ipairs(globals.food) do
print("i ate the "..v)
end
globals.food = {}
end
return globals
Lets say we have 2 scripts, “/cook#cook” and “/custom#er”. The cook adds the food.
--in script cook.script in object /cook
local globals = require "main.globals" --require the model in every script its used in
--this path will be its path from the project root with each folder separated with periods instead of slashes
function init(self)
globals.addFood("pizza")
globals.addFood("tacos")
globals.addFood("pasta")
end
function update(self, dt)
if #globals.food == 0 then
print("hey! you ate all the food! now i must add another so i dont print this line for all eternity.")
globals.addFood("rotten meat")
end
end
By calling this function, the cook.script adds to the globals.food table.
Without affecting anything, the “er.script” (inside /custom#er) requires the same script.
--er.script inside of object /custom
local globals = require "main.globals" --dont forget to require!
function update(self, dt)
if #globals.food == 3 then
globals.eatEverything()
end
end
Upon running this code, you will find the output to be “I ate the pizza” “I ate the tacos” “I ate the pasta”. The cook will respond with its little message and add the one food item.
(btw #
is the length operator for integer-indexed tables if you didn’t know)
If you go into the update
function of any of these scripts and type print(#globals.food)
, you will see the exact same pattern:
3 --cook adds the food
0 --customer eats it*
1 --cook adds rotten meat
*EDIT: I actually do not know if the pattern will go to 0 then 1 or straight to 1, it depends on whether both things happen in the same frame, which because of the quickness of code, it likely would register the cook adding the food before the next frame. Again, not too sure, but this is irrelevent to my point.
This would not be possible if each script had their own instance of a module, because how would the 2nd script know that the first script added to the food list? How would the 1st script know the 2nd script ate all the food?
This method is very useful and simpler than, for example, sending the same message to multiple scripts. You also won’t have to worry about messaging limitations and you can think of it as a shared variable rather than having to keep track of multiple, locally stored variables and functions.