# Lua Scripting Workflow Tests Testing in this area should focus on the functionality of Lua Editor. ## Common Issues to Watch For Test guidance will sometimes note specific issues to watch for. The common issues below should be watched for through all testing, even if unrelated to the current workflow being tested. 1. Asset processor errors when loading/saving .lua files 2. Warnings or assets that appear in the Log 3. Unresponsive UI elements ### Platforms: - Windows - Linux ### Docs: * [O3DE Documentation: Writing Lua Scripts in Open 3D Engine](https://www.o3de.org/docs/user-guide/scripting/lua/) * [O3DE Documentation: Introduction to Open 3D Engine’s Lua Editor](https://www.o3de.org/docs/user-guide/scripting/lua/lua-editor/) * [O3DE Documentation: Basic Structure of a Lua Script](https://www.o3de.org/docs/user-guide/scripting/lua/basic-lua-script/) * [O3DE Documentation: Debugging Lua Scripts](https://www.o3de.org/docs/user-guide/scripting/lua/debugging-scripts/) * [O3DE Documentation: Debugging with Lua Editor](https://www.o3de.org/docs/user-guide/scripting/lua/debugging-tutorial/) * [O3DE Documentation: Using EBuses in Lua](https://www.o3de.org/docs/user-guide/scripting/lua/ebus/) ### Script Files: * ["Area: Creating a Lua skeleton script file" BaseScript.lua](#script_0) * ["Area: Properties usage in Lua scripts" BaseScript.lua](#script_1) * ["Area: Moving entity using Lua script" BaseScript.lua](#script_2) * ["Area: Using ScriptEvents to communicate between two Lua scripts" SendEvent.lua and ReceiveEvent.lua](#script_3) ## Area: Opening Lua Editor, connecting to Editor and using Find tool ### Project Requirements * Any project with the Remote Tools Connection Gem **Product:** Running Lua Editor with basic functions checked. **Suggested Time Box:** 20 minutes | Workflow | Requests | Things to Watch For | |----------|----------|---------------------| | Launch Lua Editor and connect to Editor |
``` -- BaseScript.lua local BaseScript = { Properties = { -- Property definitions } } function BaseScript:OnActivate() Debug.Log(tostring("Hi!")); end function BaseScript:OnDeactivate() Debug.Log(tostring("Bye!")); end return BaseScript ```
``` -- BaseScript.lua local BaseScript = { Properties = { MyValue = 1, } } function BaseScript:OnActivate() Debug.Log(tostring("Hi! My value is: " .. BaseScript.Properties.MyValue)); end function BaseScript:OnDeactivate() Bye = "Bye! " NumberOne = 1 NumberTwo = 2 NumbersAdded = NumberOne + NumberTwo Debug.Log(tostring(Bye .. NumberOne .. " + " .. NumberTwo .. " = " .. NumbersAdded)); end return BaseScript ```
``` -- BaseScript.lua local BaseScript = { Properties = { MyValue = 1, } } function BaseScript:OnActivate() --Bind Input Event Groups from PlayerMovement.inputbindings --Forward self.forwardBusId = InputEventNotificationId("Forward"); self.forwardBus = InputEventNotificationBus.Connect(self, self.forwardBusId); --Strafe self.strafeBusId = InputEventNotificationId("Strafe"); self.strafeBus = InputEventNotificationBus.Connect(self, self.strafeBusId); --Look self.lookBusId = InputEventNotificationId("Look"); self.lookBus = InputEventNotificationBus.Connect(self, self.lookBusId); end --OnHeld is activated when an input is being held or applied constantly (as in the case of mouse movement) function BaseScript:OnHeld(inputValue) --Create a reference to the currently used input local currentBusId = InputEventNotificationBus.GetCurrentBusId(); --If "Forward" input is held (current used input is equal to "Forward") then --Create a vector variable based on the entity's forward vector(EntityEntity_VM.GetEntityForward) with length equal to value of the input(inputValue) --Add velocity (CharacterControllerRequestBus.Event.AddVelocity) equal to the above vector (self.forwardVector) to the entity housing this script (self.entityId) if currentBusId == self.forwardBusId then self.forwardVector = EntityEntity_VM.GetEntityForward(self.entityId, inputValue); CharacterControllerRequestBus.Event.AddVelocity(self.entityId, self.forwardVector); end --If "Strafe" input is held (current used input is equal to "Strafe") then --Create a vector variable based on the entity's right vector(EntityEntity_VM.GetEntityRight) with length equal to value of the input(inputValue) --Add velocity (CharacterControllerRequestBus.Event.AddVelocity) equal to the above vector (self.rightVector) to the entity housing this script (self.entityId) if currentBusId == self.strafeBusId then self.rightVector = EntityEntity_VM.GetEntityRight(self.entityId, inputValue); CharacterControllerRequestBus.Event.AddVelocity(self.entityId, self.rightVector); end --If "Look" input (horizontal mouse movement) is used (current used input is equal to "Forward") then --Create a float variable that is a multiplication of the input value (inputValue) and time elapsed from the last tick (TickRequestBus.Broadcast.GetTickDeltaTime()) --Apply rotation around Z axis of entity housing this script (TransformBus.Event.RotateAroundLocalZ(self.entityId,...) equal to the above float (self.rotateSpeed) if currentBusId == self.lookBusId then self.rotateSpeed = inputValue * TickRequestBus.Broadcast.GetTickDeltaTime(); TransformBus.Event.RotateAroundLocalZ(self.entityId, self.rotateSpeed); end end function BaseScript:OnDeactivate() Bye = "Bye! " NumberOne = 1 NumberTwo = 2 NumbersAdded = NumberOne + NumberTwo Debug.Log(tostring(Bye .. NumberOne .. " + " .. NumberTwo .. " = " .. NumbersAdded)); end return BaseScript ```
*SendEvent.lua* ``` local SendEvent = { } function SendEvent:OnActivate() --Connect to Tick bus, so that OnTick(dt) function is available further on self.tickHandler = TickBus.Connect(self) --Create a timer variable with value of 1, later used in the delay setup timer = 1 --Connect to the created Script Event (SimpleScriptEvent is the name of the Script Event file) self.ScriptEventHandler = SimpleScriptEvent.Connect(self) end --The delay setup is put in place so that the Send event is guaranteed to launch after all other entities/scripts (including the Receive event) are active --OnTick is activated each tick returning delta time (dt) since the last tick function SendEvent:OnTick(dt) --Each tick subtract the time it took since the last tick from the current timer value and overwrite it (Can be looked at as "Count from 1 to 0 using ticks") timer = timer - dt --If timer variable reaches 0 or negative values then if timer <= 0 then --Send the SimpleScriptEvent's SendNumber event with a Number parameter 123 SimpleScriptEvent.Broadcast.SendNumber(123) --Reset the timer variable to 1 timer = 1 end end return SendEvent ``` *ReceiveEvent.lua* ``` local ReceiveEvent = { } function ReceiveEvent:OnActivate() --Connect to the created Script Event (SimpleScriptEvent is the name of the Script Event file) self.ScriptEventHandler = SimpleScriptEvent.Connect(self, self.entityId) end --Receive the SimpleScriptEvent's SendNumber event with it's parameter (number) function ReceiveEvent:SendNumber(number) --Print the received parameter to the Console Debug.Log("Received number: " .. tostring(number)) end return ReceiveEvent ```