Gah - a solution with more questions. – EntropicLqd

Difference between revisions of "Structs"

From Unreal Wiki, The Unreal Engine Documentation Site
Jump to: navigation, search
m (Modifiers: Sorted modifiers)
m (Accessing structs in arrays: fixed the new example code)
 
(4 intermediate revisions by 3 users not shown)
Line 23: Line 23:
 
===Modifiers affecting values===
 
===Modifiers affecting values===
 
; Immutable<sup>3</sup>, ImmutableWhenCooked<sup>3</sup> : The struct uses [[wp:Serialization|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.
 
; Immutable<sup>3</sup>, ImmutableWhenCooked<sup>3</sup> : The struct uses [[wp:Serialization|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.
 +
; Atomic<sup>3</sup>, AtomicWhenCooked<sup>3</sup> : 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.
 
; StrictConfig<sup>3</sup> : When the struct variable is flagged with ''[[config]]/[[GlobalConfig|globalconfig]]'' then only members with the flag ''config/globalconfig'' will be readable from the .ini, instead of all members.
 
; StrictConfig<sup>3</sup> : When the struct variable is flagged with ''[[config]]/[[GlobalConfig|globalconfig]]'' then only members with the flag ''config/globalconfig'' will be readable from the .ini, instead of all members.
 
; Transient<sup>2,3</sup> : See [[Variables#Modifiers_affecting_values|Transient]] but instead it applies to all the members of the struct.
 
; Transient<sup>2,3</sup> : See [[Variables#Modifiers_affecting_values|Transient]] but instead it applies to all the members of the struct.
  
 
===Other modifiers===
 
===Other modifiers===
; Atomic<sup>3</sup>, AtomicWhenCooked<sup>3</sup> : '''???'''
 
 
; Export<sup>2,3</sup> : The struct is supposed to be exported to native headers.
 
; Export<sup>2,3</sup> : The struct is supposed to be exported to native headers.
 
; Init<sup>2,3</sup> : '''???'''
 
; Init<sup>2,3</sup> : '''???'''
Line 35: Line 35:
 
==Member declarations==
 
==Member declarations==
 
Struct members are declared like class [[variables]]. A variable group name or certain [[Variables#Modifiers|variable modifiers]] don't make sense for struct members, though.
 
Struct members are declared like class [[variables]]. A variable group name or certain [[Variables#Modifiers|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|<code>dependson</code> modifier]].
  
 
===Default member values===
 
===Default member values===
Line 42: Line 45:
  
 
==Native struct code==
 
==Native struct code==
Like native classes, some structs in [[Unreal Engine 2]] and 3 games may contain native code snippets in UnrealScript. These declarations do not affect UnrealScript directly, but they are exported when auto-generating native headers while compiling UnrealScript classes. In [[Unreal Tournament 2004|UT2004]] there are only two struct like this, [[UE2:GUI (UT2004)#GUITreeNode|GUI.GUITreeNode]] and [[UE2:GUIMultiColumnList (UT2004)#MultiColumnSortData|GUIMultiColumnList.MultiColumnSortData]]. In Unreal Engine 3 games this is a much more common sight, especially in UI-related classes.
+
Like native [[class#Native class code|class]]es, 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 [[Unreal Tournament 2004|UT2004]] there are only two struct like this, [[UE2:GUI (UT2004)#GUITreeNode|GUI.GUITreeNode]] and [[UE2:GUIMultiColumnList (UT2004)#MultiColumnSortData|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.
 
In Unreal Engine 2 native struct code is enclosed in a '''cppstruct''' block. Unreal Engine 3 uses a '''structcpptext''' block instead.
Line 58: Line 61:
 
     super.PreBeginPlay();  // Call the parent(i.e. Actor) PreBeginPlay() event
 
     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.
 
     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 [[ForEach loop|iterator]] and a regular [[For loop|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>
 
</uscript>
  
 
{{navbox unrealscript}}
 
{{navbox unrealscript}}

Latest revision as of 06:50, 17 August 2011

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[edit]

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[edit]

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

Modifiers affecting UnrealEd[edit]

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[edit]

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[edit]

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[edit]

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[edit]

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[edit]

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[edit]

Accessing a struct is as easily as accessing a class, here's an example.

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.
}

Accessing structs in arrays[edit]

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.

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.
    }
}