ScriptEvent with LUA

Hi, I try to found some information about using ScriptEvent via Lua. I found information to use ScriptEvent with ScriptCanvas but nothing for Lua.
Does somebody have some examples?

Hi @underhand. If you havent found yet here are the docs.
https://docs.aws.amazon.com/lumberyard/latest/userguide/script-events-lua.html

1 Like

Yes, I found it previously in the lumberyard documentation, but, in my opinion, these examples are not very clear…

1 Like

Script events are a bit more tedious in lua, I will try to put together a simplified version for lua for you guys

hopefully we will have parity soon where creating a script event in the asset editor works in lua without repeating the setup!.

Hey @underhand. I read through the Lua Script Event Sample code and Documentation and although I haven’t used ScriptEvents in Lua yet, I do feel like that I have enough of an understanding the try to provide an explanation.

I have to say that the explanation in the documentation isn’t very clear especially for newcomers to the engine or Lua. I didn’t understand it the first time I read it as well. In fact, it wasn’t until I saw @TheDevShop’s SC ScriptEvents video and then looked back at the ScriptEvent documentation that it began to click for me.

In general, ScriptEvents are interfaces which are used as communication channels between Lua scripts. First a ScriptEvent is defined. Then it gets registered(enabled globally). Then Lua scripts can subscribe to a ScriptEvent by implementing some of the methods of it’s interface, and other scripts can call these methods with the required parameters. The main advantage of using ScriptEvents over GameNotifications is that you can send multiple parameters in a single call to a ScriptEvent whereas GameNotifications only allow you to send one piece of data at a time.

The other important thing to understand about ScriptEvents is that you can choose how they are addressable. What this means is that you have great control over who gets what message. A ScriptEvent can be designed to only get sent to 1 entity, a group of entities, or all entities depending on the way it’s addressable but this needs to be decided and defined when the ScriptEvent is defined. The LY typeid() function is used to indicate a type(string, float, entityId) by passing it an instance of the type. This will be more clear when we look at the code.

--Define the script event by giving it a name, and address type
--This SE is called UIEvemts and the second parameter indicates it's addressable by string
--in this case, we're saying scripts which subscribe to this SE must supply an identifying string as their address and scripts which send events must supply a string as the message destination.

local scriptEventRef = ScriptEvent("UIEvents", typeid("")) -- Event address is of string type

--We can define as many events or "methods" in a SE as we want.
--A SE is like an umbrella with any number of associated methods.
--Think of this as a class type or interface or C++ header file and we're describing the publicly accessible methods which others scripts can call. 
--If a Lua script A decides to use this interface, any other Lua script B can call these methods on Lua Script A as long as B provides A's string address when making the call. 
--When defining a SE we're not implementing the methods, just describing them like an interface
--Describe a method by it's name and return type
--Here we're adding an event called "Hover" to the "UIEvents" SE. This method returns a string.

local hoverMethod = scriptEventRef:AddMethod("Hover", typeid("")) -- specify this function returns a string type

--A script which subscribes to this SE can also expose a "Click" event to outside scripts

local clickMethod = scriptEventRef:AddMethod("Click", typeid("")) -- specify this function returns a string type

--A script which subscribes to this SE can also expose a "Release" event to outside scripts

local releaseMethod = scriptEventRef:AddMethod("Release", typeid("blah")) -- specify this function returns a string type. For typeid(), any string can be used, even "blah".

--We can define any number of parameters to be required when calling a method
--For the release method, when an outside script calls this method, we can, for instance, decide that they are required to pass in a numeric parameter as the first parameter.
-- Use "Param1" for the second parameter and so on.  
--The typeid function is used to specify a data type.  typeid("") indicates a string, typeid(0) means number etc.  444 is used here but you could use any number.  Use typeid(EntityId()) if a parameter should be of type entityId.

releaseMethod:AddParameter("Param0", typeid(444)) --specify this function should be called with a parameter of type number.


-- NOTE: Types are specified using the typeid keyword with a VALUE of the type you want. For example, typeid("EntityId") 
-- produces the type id for a string, not the EntityId type.

-- After the Script Event is defined, call Register to enable it. Typically this should be done within the OnActivate method.

scriptEventRef:Register()

At this point, it’s important to understand that everything so far as just been creating the ScriptEvent. No one has actually done anything with it yet. In fact, conceptually the script above isn’t necessarily associated with any particular receiver or sender. It could reside in a separate standalone script. It’s just defining the shape of an interface that other scripts can subscribe to and expose their methods in such a way that other scripts can call those methods when called with a matching string Id. That is, string or however you decided the SE should be addressable by.

The tricky part is done and the rest is standard Lua scripting. A script can choose to subscribe to the SE and expose this set of methods by just defining them in a table. A Lua entity script could define the following table:

local subscriber = {
   Hover = function(self)
        return "Some private data only my entity has but other entities need."
    end,

    Click = function(self)
        return "Some private data only my entity has but other entities need"
    end,

    Release = function(self, heldTime)
        return "Some private data only my entity has but other entities need"
    end
}

Since the function names and function parameters and return types match those in the SE description, this table is suitable for subscribing to our SE. But our SE requires an identifying address:

scriptEventHandler = UIEvents.Connect(subscriber, "myaddress")

Here we’re saying I want this table called subscriber to subscribe to the UIEvents ScriptEvent under the address of “myaddress”. Now, any outside script can call these 3 methods when “myaddress” is used as the destination. Once a SE is registered, we can use it’s name directly(UIEvents). We decided this SE would be addressable by string so we pass in this table’s identifying string, “myaddress”. Multiple scripts can use the same string address for broadcasting to a group of objects with one call.

Finally an outside script can call the methods using the string address “myaddress” as the destination:

local privateData = UIEvents.Event.Hover("myaddress")

Any script can now use a call similar to the one above to access any of the methods. Because these methods can accept any type and number of parameters and can define any return type, these methods can be used for effective data transfer between tables as well as raising events.

local privateData = UIEvents.Event.Release("myaddress", 15)–this method requires a numeric parameter in addition to the address

I hope this explanation makes ScriptEvents in Lua in LY more clear.