Structs

From Unreal Wiki, The Unreal Engine Documentation Site
Revision as of 13:50, 17 August 2011 by imported>Wormbo (→‎Accessing structs in arrays: fixed the new example code)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

A struct (or structure) is a composite data type in UnrealScript, that can contain multiple member variables of (almost) any type, including another struct type. Structs are not reference types, that means a variable of a struct type actually contains the struct data itself, not a reference to the struct data. This imposes an important restriction on struct types: a struct may not directly or indirectly contain a variable of that same struct type.

Note: The compiler will probably not complain about a struct violating this restriction. However, if the struct type is used to declare any class or local variables or function parameters or return types, the compiler will likely crash as it attempts to allocate an infinite amount of memory!

Declaration syntax

The general syntax of a struct declaration is:

struct [modifiers] structname [extends parentstruct] {
  ...
};

Like enums, struct declarations may appear either as standalone declaration, in which case they must be followed by a semicolon, or as inline declaration instead of the type specification in variable declarations. Struct declarations may be contained in other struct declarations, both standalone or in variable declarations. There is no difference between declaring a struct at the class level and within another struct or between a standalone and inline declaration, in all cases the struct is a direct member of the class.

Remember that all members of an UnrealScript class share the same namespace. A struct declaration may hide any member of a parent class if it has the same name.

Modifiers

Struct modifiers are not available in Unreal Engine 1. Most struct modifiers are related to native code.

Modifiers affecting UnrealEd

Long2[confirm]
Specifies that the struct contains many members and should not be examined when generating a value string for struct variables in UnrealEd's Actor properties window. Usually structs like Vector are displayed as "(X=1.2,Y=3.4,Z=5.6)", but with the long modifier only "(...)" is displayed.

Modifiers affecting values

Immutable3, ImmutableWhenCooked3 
The struct uses binary serialization(in previous engine versions some structs used hardcoded binary serialization in c++ e.g. Vector, Rotator and Color etc). Without this flag, each struct member will be saved with a nameindex followed by a packedbyte, size and arrayindex, then the value of the specific member, thus increases file size and slows down the serialization process.
Atomic3, AtomicWhenCooked3 
Indicates that this struct should always be serialized as a single unit; if any property in the struct differs from its defaults, then all elements of the struct will be serialized.
StrictConfig3 
When the struct variable is flagged with config/globalconfig then only members with the flag config/globalconfig will be readable from the .ini, instead of all members.
Transient2,3 
See Transient but instead it applies to all the members of the struct.

Other modifiers

Export2,3 
The struct is supposed to be exported to native headers.
Init2,3 
???
Native2,3 
The struct includes native logic.
{native type name}3 
The type to use in native code instead of this struct type. This is mainly a hack in Unreal Engine 3 to declare variables in UnrealScript with types the UnrealScript language does not provide. There are only three instances of this syntax in UT3. The structs Object.qword and Object.double represent the native types QWORD and DOUBLE respectively, and the struct UIEditorOptions.ViewportDimension represents the native type WxRect.

Member declarations

Struct members are declared like class variables. A variable group name or certain variable modifiers don't make sense for struct members, though.

Note that in order to refer to structs declared in other classes, you may need to use dependson modifier.

Default member values

By default all struct member variables are initialized with the null value of the corresponding type.

Starting with Unreal Engine 3, struct members can also have a default value other than the corresponding null value. This can be defined in a structdefaultproperties block inside the struct declaration. See structdefaultproperties for more details.

Native struct code

Like native classes, some structs in Unreal Engine 2 and 3 games may contain native code snippets(cpptext) in UnrealScript. These declarations do not affect UnrealScript directly, but they are exported when auto-generating native headers while compiling UnrealScript classes. In UT2004 there are only two struct like this, GUI.GUITreeNode and GUIMultiColumnList.MultiColumnSortData. In Unreal Engine 3 games this is a much more common sight, especially in UI-related classes.

In Unreal Engine 2 native struct code is enclosed in a cppstruct block. Unreal Engine 3 uses a structcpptext block instead.

Accessing structs

Accessing a struct is as easily as accessing a class, here's an example. <uscript> class A extends Actor;

var() LinearColor RedColor;

// Modify RedColor at Runtime rather than on defaultproperties. event PreBeginPlay() {

   super.PreBeginPlay();  // Call the parent(i.e. Actor) PreBeginPlay() event
   RedColor.R = 1.0; // Make RedColor really red, assuming A is 1.0 and G and B are 0.0.

} </uscript>

Accessing structs in arrays

When working with structs in arrays you need to be aware of the difference between an iterator and a regular loop.

An iterator will create a copy of the actual struct while a loop will use references to the existing structs. That means that you can not change values of the original struct when using iterators. <uscript> class A extends Actor;

var() array<LinearColor> Colors;

// Modify Colors at Runtime rather than on defaultproperties. event PreBeginPlay() {

   local int i;
   local LinearColor Iterator;
   super.PreBeginPlay();  // Call the parent(i.e. Actor) PreBeginPlay() event
   foreach Colors(Iterator)
   {
       if (Iterator.G == 0.0 && Iterator.B == 0.0)
           Iterator.R = 1.0; // This won't have any effect on the struct values in the array.
   }
   for (i = 0; i < Colors.Length; i++)
   {
       if (Colors[i].G == 0.0 && Colors[i].B == 0.0)
           Colors[i].R = 1.0; // This effects the real struct values in the array.
   }

} </uscript>