Tutorial: Component Basics 08 — Tag Component

Report 2 Downloads 77 Views
Tutorial: Component Basics 08 — Tag Component This tutorial walks you through the steps to create and manipulate entities with Tag Component and Lua Scripts. At the end of this tutorial, you will have learned how to setup and assign Tag Components, and how to search and change the associated entity’s attributes through Lua Script. You will learn how to do the following:   

Create Lua Script Lua Script Breakdown Adding Tag Components

Prerequisites This tutorial assumes you have installed the Lumberyard SDK, set up your development environment and have a basic understanding the Lua Script structure. You must have the following before starting this tutorial:    

Lumberyard 1.8.0.0 or greater Installed Microsoft Visual Studio 2013 or 2015 Component Entity Basics Lua Script Basics

Step 1: Create Lua Script First, we’ll need to setup a new level and a Component Entity to control our Tag Components To create a new level and Component Entity 1. Open the Lumberyard Editor. 2. Create a new level, named ‘CompBasics09_TagComp’, with a Heightmap Resolution of 128x128 and Generate Terrain Texture size of 512x512. 3. Create new component entity and open Entity Inspector. 4. In the Entity Inspector, add a Lua Script Component.

This Component Entity will use our sample Lua Script to search for and manipulate various entities that we will later tag with the Tag Component. Go ahead and reference the provided Tag_Sample Lua Script in your Lua Script Component by either Drag & Dropping the script file from your Asset Browser (PREVIEW) onto the Lua Script Component’s Script field or by finding it within the view accessed by the “…” Browse button of your Lua Script Component.

Script Sample: tutorial_tag.lua local tutorial_tag = { Properties = { CountDown = 3.0 } } function tutorial_tag:OnActivate() self.TickBus = TickBus.Connect(self, 0) self.CountDown = self.Properties.CountDown self.TagNotificationA = TagGlobalNotificationBus.Connect(self, Crc32("entityA")) self.TagNotificationB = TagGlobalNotificationBus.Connect(self, Crc32("entityB")) end function tutorial_tag:OnTick(deltaTime, timePoint) self.CountDown = self.CountDown - deltaTime if EntityId.IsValid(self.entityA) and EntityId.IsValid(self.entityB) then TransformBus.Event.SetScaleZ(self.entityA, self.CountDown + 1) TransformBus.Event.SetScaleZ(self.entityB, self.CountDown + 2) end local DynamicTaggedEntities = TagGlobalRequestBus.Broadcast.RequestTaggedEntities(Crc32("ScaleY")) for i = 1, #DynamicTaggedEntities do TransformBus.Event.SetScaleY(DynamicTaggedEntities[i], self.CountDown + 1) end if self.CountDown < 0 then if self.CountDown < 0 then if #DynamicTaggedEntities > 0 then TagComponentRequestBus.Broadcast.RemoveTag(Crc32("ScaleY")) else TagComponentRequestBus.Broadcast.AddTag(Crc32("ScaleY")) end self.CountDown = self.Properties.CountDown end end end function tutorial_tag:OnEntityTagAdded(taggedEntity) if TagGlobalNotificationBus.GetCurrentBusId() == Crc32("entityA") then self.entityA = taggedEntity elseif TagGlobalNotificationBus.GetCurrentBusId() == Crc32("entityB") then self.entityB = taggedEntity end end function tutorial_tag:OnDeactivate() self.TickBus:Disconnect() self.TagNotificationA:Disconnect() self.TagNotificationB:Disconnect() end return tutorial_tag

Step 2: Lua Script Breakdown This section of the tutorial will break down the Lua Script sample attached to this series. Let’s review the script: 1. First, we’ll need a looping timer to indicate when we’re looking for Component Entities with the Tag Component. So we setup a timer variable in the Properties sub-table, connect and disconnect to the Tick Bus, then create the OnTick function to loop our timer in. This results in the following lines: local tutorial_tag = { Properties = { CountDown = 3.0 } } function tutorial_tag:OnActivate() self.TickBus = TickBus.Connect(self, 0) self.Countdown = self.Properties.CountDown end function tutorial_tag:OnTick(deltaTime, timePoint) self.CountDown = self.CountDown – deltaTime if self.CountDown < 0 then self.CountDown = self.Properties.CountDown end end function tutorial_tag:OnDeactivate() self.TickBus:Disconnect() end return tutorial_tag

2. With our looping timer created, now we call and manipulate Component Entities from within the OnTick function. For the purposes of this tutorial, we’ll be looking for 2 unique Tags on our Tag Components: ‘entityA’ and ‘entityB’. a. To search for these two Tagged Component Entities, we’ll want to use the TagGlobalNotificationBus. This will allow us access to functions such as OnEntityTagAdded and OnEntityTagRemoved, informing us when Component Entities have certain Tags added or removed. b. First, we create a Bus connection for each Tag in our OnActivate: self.TagNotificationA = TagGlobalNotificationBus.Connect(self, Crc32("entityA")) self.TagNotificationB = TagGlobalNotificationBus.Connect(self, Crc32("entityB"))

c. For this tutorial, we’ll only be using the OnEntityTagAdded function, which passes to us the entity it has detected, possessing the tag we are looking for: function tutorial_tag:OnEntityTagAdded(taggedEntity) if TagGlobalNotificationBus.GetCurrentBusId() == Crc32("entityA") then self.entityA = taggedEntity elseif TagGlobalNotificationBus.GetCurrentBusId() == Crc32("entityB") then self.entityB = taggedEntity end end

3. Because these are new Bus Handlers too, we also make sure to properly disconnect from each one in our OnDeactivate function: function tutorial_tag:OnDeactivate() self.TickBus:Disconnect() self.TagNotificationA:Disconnect() self.TagNotificationB:Disconnect() end

a. A good thing to note about the TagGlobalNotificationBus and the function OnEntityTagAdded is that, as soon as you connect to the TagGlobalNotificationBus; not only will you be notified via OnEntityTagAdded of every Component Entity that gets a particular tag added in the future, but it will also be pinged immediately for each Component Entity in a level that already possesses the Tag you are looking for. i. This is handy for picking up on Component Entities that may already exist by the time you connect to the TagGlobalNotificationBus and it is this functionality that we are using for today’s example. 4. Now that we can properly find and register our entityA and entityB, we now perform a simple real time Transform scale deformation on it via the OnTick function to demonstrate they were located successfully. a. As with any function call on a potentially non-existent reference, we make sure to properly validate entityA and entityB before attempting any function calls on them: if EntityId.IsValid(self.entityA) and EntityId.IsValid(self.entityB) then TransformBus.Event.SetScaleZ(self.entityA, self.CountDown + 1) TransformBus.Event.SetScaleZ(self.entityB, self.CountDown + 2) end

b. As you can see, we are performing slightly different ScaleZ deformations on entityA versus entityB. This is to better visually differentiate them in the level from each other. 5. Finally, our Lua Script shows off one more bit of Tag Component functionality before wrapping up: the ability to dynamically add and remove Tags from existing Tag Components.

a. We can call on the RequestTaggedEntities function to determine if any Tag Components have a specific Tag on them and, in the case of this example, add this new specific Tag to all Tag Components if no candidates are found. b. We also check the converse: if we find more than one Entity with this new specific Tag, we remove it from all Tag Components. 6. First we gather them into a local variable, ‘DynamicTaggedEntities’, in OnTick: local DynamicTaggedEntities = TagGlobalRequestBus.Broadcast.RequestTaggedEntities(Crc32("ScaleY"))

Then we toggle granting and removing this Tag every time our looping timer resets: if #DynamicTaggedEntities > 0 then TagComponentRequestBus.Broadcast.RemoveTag(Crc32("ScaleY")) else TagComponentRequestBus.Broadcast.AddTag(Crc32("ScaleY")) end

a. As you may tell by our new specific Tag, we’re using this designation in OnTick to determine if we should scale the Y Transform of any entities we find: for i = 1, #DynamicTaggedEntities do TransformBus.Event.SetScaleY(DynamicTaggedEntities[i], self.CountDown + 1) end

b. This will result in the Y transform only scaling every other timer reset, demonstrating the adding and removing of new dynamic Tags to our Tag Components. That covers it for our Lua Script and what calls we can do with Tag Components via Lua. Now we need to actually create our Component Entities that will utilize our Tag Components.

Step 3: Adding Tag Components This section of the tutorial will go through the steps to add Tag Components used by the Lua Script sample shown in Step 2. To add Tag Components 1. Create two additional Component Entities and give them the following Components:  Static Mesh  Tag

2. For each Static Mesh Component, assign their Static Asset to be the ‘primitive_cube’ static mesh asset that comes with Lumberyard by default. a. In the Preview window, click on Objects and navigate into default > primitive_cube.cgf 3. On the first Component Entity’s Tag Component, add a new Tag with the “+” symbol to the right of the Tags field and name this new Tag, ‘entityA’.

4. On the second Component Entity’s Tag Component, add a new Tag with the “+” symbol to the right of the Tags field and name this new Tag, ‘entityB’.

5. Make sure these 2 Component Entities are not stacked on top of each and are visually in 2 different locations, albeit both still visible from your Camera.

We’re now ready to see our Tag Components and Tag Component functions in action. With those 3 Component Entities in your level (your Lua Script Component Entity, entityA, and entityB), run the Game by hitting Ctrl and G or by selecting ‘Switch to Game’ from Lumberyard’s Game tab to see things in action. What you should see is entityA and entityB scaling vertically in synch with your timer, demonstrating that your Lua Script properly found and located them both via their Tag Component. Then, every other time your timer resets; you’ll notice them scaling along horizontally in synch with the timer, demonstrating they are dynamically Tagged and Untagged each time the timer runs out.

Congratulations! You have successfully interacted with Tagged Component Entities using Tag Components and Lua Script. We’d love to hear from you! Head to our Tutorial Discussion forum to share any feedback you have, including what you do or don’t like about our tutorials or new content you’d like to see in the near future.