Components in FlatRedBall Entities
Last updated
Last updated
Gum components can be added to FlatRedBall entities without any code or additional setup. A common example of needing a Gum component on a FRB entity is a health bar in a RTS game. Gum components can be thought of as containers which are "Gum on the inside, FlatRedBall on the outside". In other words, internally the Gum component uses the Gum coordinate and rendering system, but the component is attached to an entity which can be positioned like any other FlatRedBall object.
Before adding a Gum component to an entity, your project must have a Gum project added. If not, you can add one by clicking the Gum icon.
For this example we will add a component called HealthBar to an entity named Soldier. It assumes that your project has a Gum component named HealthBar.
To add an instance of the HealthBar component to a FlatRedBall entity:
Expand the Soldier entity in FlatRedBall
Right-click on the Objects folder
Select Add Object
Verify the FlatRedBall or Custom Type category is selected
Select the type HealthBarRuntime. FRB provides options for every component in your Gum project, with the word Runtime appended to the name. Keep in mind that the search bar can help narrow down the options.
Click OK
An instance of the HealthBar component will now be a part of the entity and will be attached (moves with) the entity automatically.
Component variables can be changed in multiple locations depending on the needs of the project. If a component should be the same across the entire project, then its variables should be changed in Gum.
If the component requires changes specific to each entity, then the variables can be changed in FRB.
If a component requires instance-by-instance modifications, it can be modified in code just like any other component Gum object.
As mentioned above, Gum objects which are added to FRB entities will automatically be attached. This can be disabled by detaching the Gum object from its parent. For example, to detach the HealthBarRuntimeInstance from its parent, the following code could be added to CustomInitialize :
Gum components which are part of an entity are attached to the entity itself (which is a PositionedObject ). Gum component attachment can be changed at runtime. The following code changes the HealthBarRuntimeInstance so it is attached to the SpriteInstance instead of the entire entity.
Gum provides a powerful layout system for positioning objects. Attached Gum objects can take full advantage of this coordinate system. To use Gum layout effectively we must first understand how Gum objects attach to FlatRedBall objects. For starters, consider a simple FRB entity with a single Sprite:
By default the origin of the object is its center. This can be visualized as shown in the following image:
We can therefore visualize the behavior of a Gum object that is added to the entity. By default the component will be positioned at 0,0, and the default position values will make its top-left corner align with the center of the entity.
We can change this by adjusting the origin values:
XOrigin = Center
YOrigin = Center
Keep in mind that FlatRedBall entities do not have size values (width and height), so adjusting the width of the Gum object to be based on its parent width will result in the Gum object behaving as if its parent has Width and Height values of 0:
Width = 0
WidthUnits = RelativeToContainer
YOrigin = Center
Even though the Gum object is attached to a FlatRedBall object, the Gum object is still drawn using the Gum coordinate system (relative to the FlatRedBall object position). For example, by default Gum objects move down when their Y value is increased (assuming YUnits is not set to inverted).
XUnits = PixelsFromLeft
YUnits = PixelsFromTop
X = 20
Y = 40
As shown above, Gum objects can be attached to Sprites within an entity. This provides the added benefit of being able to use the Sprite's size for layout. If the Gum object is attached to the sprite (using the code above), then the Gum object will (by default) position itself according to the top-left of the Sprite:
XUnits = PixelsFromLeft
YUnits = PixelsFromTop
X = 0
Y = 0
We can also reference the Sprite's dimensions by changing the WidthUnits and HeightUnits:
XUnits = PixelsFromLeft
YUnits = PixelsFromTop
X = 0
Y = 0
WidthUnits = RelativeToContainer
Width = 0
HeightUnits = RelativeToContainer
Height = 0
Keep in mind that the relationships are updated constantly, so if the Sprite changes size due to an animation, the Gum object will adjust automatically too.
Although entities do not have a size by default, entities can implement the IReadOnlyScalable interface to define their size. Implementing IReadOnlyScalable serves as an alternative to attaching to a FlatRedBall Sprite.
IReadOnlyScalable can be implemented directly on the entity in custom code as shown in the following code:
The code above returns a Scale of 8 and ScaleY of 16. Keep in mind that Scale values are measured from the center to the edge, so the values above would result in a width of 16 and a height of 32.
Note that FlatRedBall Sprites implement the IReadOnlyScalable interface. If your entity contains a FlatRedBall Sprite, you can use the Scale values from the Sprite in your IReadOnlyScalable implementation. The following code shows how to implement the IReadOnlyScalable interface on an entity called player which has a SpriteInstance:
The example above shows a simple implementation. An actual implementation can have more features, such as having setters on the scale values, or creating width and height values which are not tied to the SpriteInstance.
FlatRedBall.Forms (Gum) components can be added to FlatRedBall Entities just like any other component. If a FlatRedBall.Forms component should be positioned in world space, it can be added to an otherwise-empty entity type, then that entity can be used just like a normal entity.
For example, a DialogBox instance can be positioned in world space by creating an entity in FRB which contains a DialogBox component:
Create a new Entity called DialogBoxContainer in FRB
Add a DialogBoxRuntime instance to the DialogBoxContainer entity
For this demo, all of the code to show the dialog will exist in the Player code, so we need to access the internal DialogBoxRuntime (Gum component). Therefore, it should be marked as public. Select the DialogBoxRuntimeInstance object and change its scope to public.
The DialogBoxRuntime can now be used to show a dialog box on the player. For example, the following code can be added to the Player.cs in a standard platformer project:
Whenever the enter key is pressed, a DialogBox instance is created and appears above the player.