Component Basics
Components are objects that could be attached to actors to attach low level engine features or resources to those actors.
Component, Components Array
The root class of all components is the class Component
. If you looked at this class in your UDK source, you would see that it is mostly barebones. Aside from the cpptext section, there is not a whole lot there. This class mostly exists for the engine to place some low level code that we're not allowed to see.
The first useful class in the heirarchy is ActorComponent
. While this class is not significantly more useful than Component
, it is the class used for Actor's component array. The following variable is the array that all actor's have that holds all components attached to an actor at any given time:
/**
* Actor components.
* These are not exposed by default to level designers for several reasons.
* The main one being that properties are not propagated to network clients
* when is actor is dynamic (bStatic=FALSE and bNoDelete=FALSE).
* So instead the actor should expose and interface the necessary component variables.
*
* Note that this array is NOT serialized to ensure that the components array is
* always loaded correctly in the editor. See UStruct::SerializeTaggedProperties for details.
*/
/** The actor components which are attached directly to the actor's location/rotation. */
var private const array<ActorComponent> Components;
Adding a Component
To add a component to an actor, first you need to decide what type of component you want to add. For example, let's try adding a StaticMeshComponent
(feel free to look this class up in the source tree). The easiest way to do this is by instantiating this component directly inside the Defaultproperties section of a class. Consider the following actor class:
class ExampleActor extends Actor;
Defaultproperties
{
Begin Object Class=StaticMeshComponent Name=DisplaySM
StaticMesh=StaticMesh'Awesome.Planet.Exterior'
End Object
Components.Add(DisplaySM)
}
In this example, we created a static mesh component, we named it DisplaySM, and we added it to the actor's components list. This was done using the Begin Object block syntax. This syntax is broken down as follows:
Begin Object Block
Begin Object Class=<Class of component to instantiate> Name=<Name to give to object>
Property1=Property1Value
Property2=Property2Value
...
End Object
These blocks can only exist within a Defaultproperties section. By adding such a section, you're telling the UDK to instantiate one of these components every time this actor is instantiated. The Components.Add(...) line tells the UDK to add the created component to the actor's components array.
Let's look at he parts of this block:
- class=<Class of component to instantiate>
- The desired class of the component. There are many types of components in the engine; you tell the engine the type of component class to instantiate here.
- Name=<Name to give to object>
- A name to refer to this component instance by. There can be many Begin Object blocks in a Defaultproperties section so referring to each individual component is done using this name.
Object Name
Note that an object's name is only valid within the Defaultproperties section. If you need to refer to this component inside actor code, create an actor variable and set its value equal to the instanced component. For example, we can add the following to ExampleActor
above:
...
var StaticMeshComponent mySM;
function printSM()
{
`log("My sm is "$mySM.StaticMesh);
}
Defaultproperties
{
...
mySM=DisplaySM
}
Notice how we added a StaticMeshComponent reference variable to our actor and we added a function that could print out the current StaticMesh property on that component.
Updating A Parent Class' Component
It is possible through extending a class to update any of its component's properties through the Defaultproperties section. Look at the following example:
class ExampleBase extends Actor;
Defaultproperties
{
Begin Object class=StaticMeshComponent Name=DisplaySM
StaticMesh=StaticMesh'Foo.Bar.A'
End Object
Components.Add(DisplaySM)
}
We define an actor class named ExampleBase. It has a static mesh component property with a specified static mesh. We can override this in a child class:
class ExampleChild extends ExampleBase;
Defaultproperties
{
Begin Object Name=DisplaySM
StaticMesh=StaticMesh'Foo.Bar.B'
End Object
}
Notice how in ExampleChild
, our begin object block does not have a class= property. When we do this, we are telling the UDK to take the existing properties of the parent's component whose name is DisplaySM and update them with matching properties in this begin object block.
In this case, we changed the StaticMesh property to refer to the static mesh resource Foo.Bar.B instead of Foo.Bar.A which was in the parent.
Notice how we didn't have to add the component to the Components array in the child. This is because this is already being handled for this component in the parent.
More Information
For more information, see the UDN's components technical guide: