UDN
Search public documentation:

UnrealScriptVariables
日本語訳
中国翻译
한국어

Interested in the Unreal Engine?
Visit the Unreal Technology site.

Looking for jobs and company info?
Check out the Epic games site.

Questions about support via UDN?
Contact the UDN Staff

UE3 Home > UnrealScript > UnrealScript Language Reference > UnrealScript Variables

UnrealScript Variables


Overview


Properties belonging to a class are called variables. A variable is basically an identifier or name for a piece of data whose value can be assigned and modified during play. A player's health, a weapon's ammo count, the score of the game - these values are all held in variables in one class or another and the modifying or accessing of the values of these and other variables is what makes up a significant portion of the gameplay within a game.

Variable Scope


There are two kinds of variables that can be declared in UnrealScript and these differ based on the intended scope of the variable. The scope of a variable determines the lifetime of the variable and where the variable is available.

The two kinds of variables are:

  • Instance Variables - These apply to an entire object (class or struct) and are available for the lifetime of the object they belong to. Instance variables are created when the object is created and are destroyed when the object is destroyed. These can be used inside any non-static function belonging to the object or accessed from other objects through a reference to the object the variable belongs to.
  • Local Variables - These are "local" to a function or, in other words, they belong to a specific function. They are only active while that function executes. Local variables are created when the function begins executing and destroyed when the function finishes executing. They cannot be used in another function or accessed from other objects.

Variable Declarations


The variable declaration creates a new variable for use within a class, struct, or function. A variable declaration consists of either the var or local keyword followed by any of the optional specifiers followed the type of the variable to declare followed by the name to give the variable.

var Type Name;
...
local Type Name;

Variable declarations can be located in two places in UnrealScript. Instance variable declarations are located immediately after the class declarations (or within struct declarations) before any functions or states are declared. Local variable declarations are located immediately following the function declaration inside the body of a function before any other code. Instance variables are declared with the var keyword. Local variables are declared with the local keyword.

Here are some examples of instance variable declarations in UnrealScript:

class MyClass extends Actor;


// All istance variables must be declared before
// any functions or states are declared
var int A;			// Declare an integer variable named "A".
var byte Table[64];		// Declare a static array of 64 bytes named "Table".
var string PlayerName;		// Declare a string variable named "PlayerName".
var actor Other;		// Declare a variable which can be assigned a reference to an Actor instance.
var() float MaxTargetDist;	// Declare a float variable named "MaxTargetDist" and allow its value to be modified from an UnrealEd property window.

struct RangeVector
{
	var Vector Min;		// Declare a vector variable named "Min" within the struct.
	var Vector Max;		// Declare a vector variable named "Max" within the struct.
};

var RangeVector Bounds;		// Declare a RangeVector variable named "Bounds".

function foo
{
	...
}

var int B;			// This will cause an error

An example of a local varaible declaration is provided below:

function int Foo()
{
	// All local variables must be declared before
	// any other code in the function body
	local int Count;
	local float Seconds;

	Count = 1;

	// Declaring a local variable here would cause an error
	local float Minutes;

	return Count;
}

Variable Specifiers

Variables may also contain additional specifiers such as const that further describe the variable. Actually, there are quite a lot of specifiers which you wouldn't expect to see in a general-purpose programming language, mainly as a result of wanting UnrealScript to natively support many game- and environment- specific concepts:

config
This variable will be made configurable. The current value can be saved to the ini file and will be loaded when created. Cannot be given a value in default properties. Implies const.
globalconfig
Works just like config except that you can't override it in a subclass. Cannot be given a value in default properties. Implies const.
localized
The value of this variable will have a localized value defined. Mostly used for strings. Implies const. Read more about this in the Localization Reference and Unreal Strings.
const
Treats the contents of the variable as a constant. In UnrealScript, you can read the value of const variables, but you can't write to them. "Const" is only used for variables which the engine is responsible for updating, and which can't be safely updated from UnrealScript, such as an actor's Location (which can only be set by calling the MoveActor function).
private
The variable is private, and may only be accessed by the class's script; no other classes (including subclasses) may access it.
protected
The variable can only be accessed from the class and it's subclasses, not from other classes.
privatewrite
The variable is const outside the class it was declared in.
protectedwrite
The variable is const outside the class it was declared in and subclasses.
repnotify
Actors should be notified (via the ReplicatedEvent function) when this value for this property is received via replication.
deprecated
Indicates that this variable is going to be removed in the near future, and should no longer be accessible in the editor. Deprecated properties are loaded, but not saved.
instanced
Object properties only. When an instance of this class is created, it will be given a unique copy of the object assigned to this variable in defaults. Used for instancing subobjects defined in class default properties.
databinding
This property can be manipulated by the data store system.
editoronly
This property's value will only be loaded when running UnrealEd or a commandlet. During the game, the value for this property is discarded.
notforconsole
This property's value will only be loaded when running on the PC. On consoles, the value for this property is discarded.

editconst
Editor. The variable can be seen in UnrealEd but not edited. A variable that is editconst is not implicitly "const".
editfixedsize
Editor. Only useful for dynamic arrays. This will prevent the user from changing the length of an array via the UnrealEd property window.
editinline
Editor. Allows the user to edit the properties of the object referenced by this variable within UnrealEd's property inspector (only useful for object references, including arrays of object reference).
editinlineuse
Editor. In addition to the behavior associated with editinline, adds a "Use" button next to this object reference in the editor
noclear
Editor. Prevents this object reference from being set to None from the editor.
interp
Editor. Indicates that the value can be driven over time by a Float or Vector Property Track in Matinee.

input
Advanced. Makes the variable accessible to Unreal's input system, so that input (such as button presses and joystick movements) can be directly mapped onto it. Only relevent with variables of type "byte" and "float".
transient
Advanced. Declares that the variable is for temporary use, and isn't part of the object's persistent state. Transient variables are not saved to disk. Transient variables are initialized to the class's default value for that variable when an object is loaded.
duplicatetransient
Advanced. Indicates that the variable's value should be reset to the class default value when creating a binary duplicate of an object (via StaticDuplicateObject).
noimport
Advanced. Indicates that this variable should be skipped when importing T3D text. In other words, the value of this variable will not be transferred to new object instances when importing or copy/pasting objects.
native
Advanced. Declares that the variable is loaded and saved by C++ code, rather than by UnrealScript.
export
Advanced. Only useful for object properties (or arrays of objects). Indicates that the object assigned to this property should be exported in its entirety as a subobject block when the object is copied (for copy/paste) or exported to T3D, as opposed to just outputting the object reference itself.
noexport
Advanced. Only useful for native classes. This variable should not be included in the auto-generated class declaration.
nontransactional
Advanced. Indicates that changes to this variable value will not be included in the editor's undo/redo history.
pointer{type}
Advanced. This variable is a pointer to type. (The type is optional). Note the syntax is: pointer varname{type}.
init
Advanced. This property should be exported to the header file as an FString or TArray, rather than an FStringNoInit or TArrayNoInit. Only applicable to strings and dynamic arrays declared in native classes. 'Init' properties should not be given default values, as the default value will be cleared when the object is created. (See Unreal Strings and Native Strings)
repretry
Advanced; struct properties only. Retry replication of this property if it fails to be fully sent (e.g. object references not yet available to serialize over the network). For simple references this is the default, but for structs this is often undesirable due to the bandwidth cost, so it is disabled unless this flag is specified.
allowabstract
Advanced; class references only. Allows abstract classes to be assigned to this variable within the editor.

out
This specifier is only valid for function parameters. See Function Parameter Specifiers for more details.
coerce
This specifier is only valid for function parameters. See Function Parameter Specifiers for more details.
optional
This specifier is only valid for function parameters. See Function Parameter Specifiers for more details.

skip
This specifier is only valid for operator function parameters. It is only used for binary logical operators like && and ||. Tells the compiler to inject a little piece of code into the stream so that the second argument can be skipped over (not evaluated) if the outcome of the logical operation can be determined completely from the first argument.

This assures C stlye behavior in expressions like:
   if( ++a==10 && ++b==10 )
   
Here, the ++b is skipped if the first expression fails.

Metadata

Variables can also have additional information in the form of metadata specified on a per-variable basis to be used by the engine or editor to provide extended functionality. Metadata can be used to specify a display name, tooltip, and min and max values among other things.

To link metadata to a variable, you add it to the variable declaration following the variable's name prior to the semicolon concluding the declaration. Metadata is specified as a series of Tag=Value pairs separated by a pipe character (|) inside of angle brackets < >.

For example:

var float MyVar<DisplayName=My Float Variable|Tooltip=This is a float variable with additional metadata specified|UIMin=0.0|UIMax=10.0|ClampMin=0.0|ClampMax=5.0>;

See UnrealScript Metadata for complete details about using metadata with variables in UnrealScript.

Default Properties

Default values for variables in UnrealScript are not specified when declaring the variable as is possible in some other programming languages. In addition, there is no concept of a "constructor" function for classes created in UnrealScript to allow default values to be set up. UnrealScript, instead, uses a defaultproperties block added at the end of the script defining the class to specify default values for the instance variables declared within that class. This block does not allow code to be executed and follows some rules that differ slightly from the syntax used elsewhere in UnrealScript.

For example:

defaultproperties
{
   IntVar=3
   FloatVar=2.5
   StringVar="This is a string"
   ArrayVar(0)=2
   ArrayVar(1)=4
   ArrayVar(2)=7
   ArrayVar(3)=1
}

See the UnrealScript Default Properties page for comeplete details on specifying default values for variables in UnrealScript, including the syntax used for the various types of data.

Variable Types


UnrealScript contains a number of built-in data types that can be used when declaring variables. The type of the variable determines the kind of data it can hold. Some types are fairly straightforward, while others are more complex to understand and work with.

Basic Data Types

Here is a list of basic variable data types commonly found in other languages that are supported in UnrealScript:

byte
A single-byte value ranging from 0 to 255.
int
A 32-bit integer value.
bool
A boolean value: either true or false.
float
A 32-bit floating point number.
string
A string of characters. (see Unreal Strings)
constant
A variable that cannot be modified.
enumeration
A variable that can take on one of several predefined named integer values. For example, the ELightType enumeration defined in the Actor script describes a dynamic light and takes on a value like LT_None, LT_Pulse, LT_Strobe, and so on.

Aggregate Data Types

array<Type>
A variable length array of Type.
struct
Similar to C structures, UnrealScript structs let you create new variable types that contain sub-variables. For example, two commonly-used Unreal structs are vector, which consists of an X, Y, and Z component; and rotator, which consists of a pitch, yaw, and roll component. (see Structs for more information)

Unreal Types

Name
The name of an item in Unreal (such as the name of a function, state, class, etc). Names are stored as an index into the global name table. Names correspond to simple strings of up to 64 characters. Names are not like strings in that they are immutable once created (see Unreal Strings for more information).
Object and Actor references
A variable that refers to another object or actor in the world. For example, the Pawn class has an Enemy actor reference that specifies which actor the pawn should be trying to attack. Object and actor references are very powerful tools, because they enable you to access the variables and functions of another actor. For example, in the Pawn script, you can write something similar to Enemy.TakeDamage(123) to call your enemy's TakeDamage function; resulting in the enemy taking damage. Object references may also contain a special value called None, which is the equivalent of the C NULL pointer: it says "this variable doesn't refer to any object".
Delegate
Holds a reference to an unrealscript function.

Editability


In UnrealScript, you can make an instance variable "editable", so that users can edit the variable's value in UnrealEd. This mechanism is responsible for the entire contents of the "Actor Properties" dialog in UnrealEd: everything you see there is simply an UnrealScript variable, which has been declared editable.

The syntax for declaring an editable variable is as follows:

var() int MyInteger; // Declare an editable integer in the default
                     // category.

var(MyCategory) bool MyBool; // Declare an editable integer in
                             // "MyCategory".

You can also declare a variable as editconst, which means that the variable should be visible but not editable UnrealEd. Note that this only prevents the variable from being changed in the editor, not in script. If you want a variable that is truly const but still visible in the editor, you must declare it const editconst:

// MyBool is visible but not editable in UnrealEd
var(MyCategory) editconst bool MyBool;

// MyBool is visible but not editable in UnrealEd and
// not changeable in script
var(MyCategory) const editconst bool MyBool;

// MyBool is visible and can be set in UnrealEd but
// not changeable in script
var(MyCategory) const bool MyBool; 

Arrays


Arrays are declared using the following syntax:

var int MyArray[20]; // Declares an array of 20 ints.

UnrealScript supports only single-dimensional arrays, though you can simulate multidimensional arrays by carrying out the row/column math yourself. For information on Dynamic Arrays, see below in the Advanced Language Features section.

Dynamic Arrays

Previously, we covered Arrays, which were static. What that means is that the size (how many elements are in the array) is set at compile time and cannot be changed. Dynamic Arrays and Static Arrays share the following common characteristics :

  • constant seek time - the time code spends accessing any given element of the array is the same, regardless of how many elements are in the array
  • unlimited element type - you can have an array of anything - ints, vectors, Actors, etc. (with the exception that booleans are only valid for dynamic arrays)
  • access behavior - you can access any element with an index into the array, and conversely, attempting to access an element at an index that is outside the bounds of the array will throw an accessed none.

Dynamic Arrays provide a way of having Static Array functionality with the ability to change the number of elements during run-time, in order to accommodate changing needs. In order use Dynamic Arrays, we need to know a few things.

The first is variable declaration. Declaring a dynamic array is much like declaring any other unrealscript variable (i.e. var/local type varname). For dynamic arrays, the type is specified with the array keyword, followed by the array type wrapped in angle brackets. If the array type contains angle brackets as well (such as class<Actor>), you must place a space between the closing bracket of the type and the closing bracket of the array wrapper or the compiler resolves the double closing brackets as the >> operator. For example:
Declare a dynamic array of ints named IntList:

var array<int> IntList;

Declare a dynamic array of type class<PlayerController> named Players:

var array<class<PlayerController> > Players;

When script starts, IntList will start with 0 elements. There are methods supported by Dynamic Arrays that allow us to add elements to the array, take elements out, and increase or decrease the length of the array arbitrarily. The syntax for calling these methods is (using our IntList example): IntList.MethodName(). The following dynamic array methods are available:

  • Add(int Count): extends the length of the array by Count, identical to FArray::AddZeroed().
  • Insert(int Index, int Count): where Index is the array index to being inserting elements, and Count is the number of elements to insert. Any existing elements at that location in the array are shifted up, and new elements are created and inserted into the specified location. Inserting 5 elements at index 3 will shift up (in index value) all elements in the array starting at index 3 and up by 5. The element previously located at index 3 will now be located at index 8, element 4 will now be element 9, and so on. Newly added elements are all initialized to their default values (zero/null for all types except structs containing structdefaultproperties).
  • Remove(int Index, int Count): where Index is the array index to begin removing elements from, and Count is the number of elements to remove. This allows us to remove a group of elements from the array starting at any valid index within the array. Note that any indexes that are higher than the range to be removed will have their index values changed, keep this in mind if you store index values into dynamic arrays.
  • AddItem(Item): adds Item to the end of the array, extending the array length by one.
  • RemoveItem(Item): removes any instances of Item using a linear search.
  • InsertItem(int Index, Item): inserts Item into the array at Index, extending the array length by one.
  • Find(...) - finds the index of an element in the array. There are two versions of Find: standard find for matching entire element values, and a specialized version for matching a struct based on the value of a single property of the struct
    • Find(Value): where Value is the value to search for. Returns the index for the first element found in the array which matches the value specified, or -1 if that value wasn't found in the array. Value can be represented using any valid expression.
    • Find(PropertyName, Value): where PropertyName is the name of property in the struct to search against (must be of type 'Name'), and Value is the value to search for. Returns the index for the first struct in the array that has a value matching the value specified for a property named PropertyName, or -1 if the value wasn't found. Value can be any valid expression.
  • Sort(SortDelegate): uses SortDelegate to sort the contents of the array in-place. SortDelegate should have signature matching the following:
    • delegate int ExampleSort(ArrayType A, ArrayType B) { return A < B ? -1 : 0; } // a negative return value indicates the items should be swapped

Length Variable

Dynamic Arrays also have a variable called Length, which is the current length (number of elements) of the dynamic array. To access Length, using our example array, we would say: IntList.Length . We can not only read the Length variable, but we can also directly set it, allowing us to modify the number of elements in the array. When you modify the Length variable directly, all changes in array length happen at the 'end' of the array. For example, if we set IntList.Length = 5, and then we set IntList.Length = 10, the extra 5 elements we just added were added to the end of the array, maintaining our original 5 elements and their values. If we decreased the Length, the elements would be taken off the end as well. Note that when you add elements to the array, either by Insert() or by increasing Length, the elements are initialized to the variable type's default value (0 for ints, None for class references, etc). It is also noteworthy to know that you can increase the length of a dynamic array by setting an element index that is greater than the array's current Length value. This will extend the array just as if you had set Length to the larger value.

OldLength = Array.length 
Array.Length = OldLength + 1
Array[OldLength] = NewValue

Array[Array.Length] = NewValue 

Array.AddItem(NewValue) 

are all equivalent forms of the same operation.

Note however that you cannot both increase the length of an array and access its members at the same time.

Array[Array.length].myStructVariable = newVal

does not work.

A word of caution - the Length member of a dynamic array should never be incremented / decremented by '++', '--', '+=', or '-=', nor should you pass Length to a function as an out parameter (where the function can change the value of it). Doing these things will result in memory leaks and crashes due to Length not being accurate any more; only setting the Length via the '=' operator (and setting an element at an index larger than Length) modifies the actual length of the dynamic array properly.

NOTE: array<bool> is not a supported type!

A final note - dynamic arrays are not replicated. You could get around this by having a function that replicates and has two arguments, an index into the dynamic array and the value to store there. However, you would also have to consider consequences of elements not being the same within a space of a tick on client and server.

Iterating Dynamic Arrays

Dynamic arrays now support the foreach command to allow simple iterations. The basic syntax is:

foreach ArrayVariable(out ArrayItem, optional out ItemIndex)
{
   ...
}

ArrayItem must be of the same type as the elements in the array. Each iteration will increment the index and write out the item as well as the index if a property is supplied.

function IterateThroughArray(array SomeArray)
{
    local string ArrayItem;
    local int Index;
    foreach SomeArray(ArrayItem)
    {
       `log("Array iterator test #1:"@ArrayItem);
    }
    foreach SomeArray(ArrayItem,Index)
    {
        `log("Array iterator test #2:"@ArrayItem@Index);
    }
}

Structs


An UnrealScript struct is a way of cramming a bunch of variables together into a new kind of super-variable called a struct. UnrealScript structs are much like C structs, in that they can contain variables, arrays, and other structs, but UnrealScript structs cannot contain functions.

For information on performance implications of using structs in UnrealScript, see the UnrealScript Structs page.

Struct Definitions

Before you can declare a struct variable, you must define the struct to be used. The definition consists of the struct keyword followed by the name to be given to the struct. Then, inside curly braces { and } the variables to make up the struct are declared using the same syntax as any other instance variable. The closing curly brace should be followed by a semicolon.

An example of a struct definition for a vector is shown below:

// A point or direction vector in 3D space.
struct Vector
{
	var float X;
	var float Y;
	var float Z;
};

Structs can also have default values specified for the variables they contain. This is done by adding a structdefaultproperties block inside the struct definition. For instance, if you wanted each of the variables in the Vector struct defined previously to start out with values of 1.0, you could define the struct like so:

// A point or direction vector in 3D space.
struct Vector
{
	var float X;
	var float Y;
	var float Z;
	
	structdefaultproperties
	{
		X=1.0
		Y=1.0
		Z=1.0
	}
};

For more information on default properties for struct members, see the Struct Defaults? section of the UnrealScript Default Properties page.

Struct specifiers

Structs may also have a few specifiers that affect all instances of the struct. Specifiers are placed between the struct keyword and the name of the struct in the definition.

atomic
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.
atomicwhencooked
applies the 'atomic' flag only when working with cooked package data.
immutable
Indicates that this struct uses binary serialization (reduces disk space and improves serialization performance); it is unsafe to add/remove members from this struct without incrementing the package version.
immutablewhencooked
applies the 'immutable' flag only when working with cooked package data.
strictconfig
Indicates that when the struct property has 'config/globalconfig', only properties marked config/globalconfig within this struct can be read from .ini (without this flag, all properties in the struct are configurable if the property is)

Declaring Struct Variables

Once you declare a struct, you are ready to start declaring specific variables of that struct type:

// Declare a bunch of variables of type Vector.
var Vector Position;
var Vector Destination;

Using Struct Variables

To access a component of a struct, use code like the following.

function MyFunction()
{
	Local Vector A, B, C;

	// Add some vectors.
	C = A + B;

	// Add just the x components of the vectors.
	C.X = A.X + B.X;

	// Pass vector C to a function.
	SomeFunction( C );

	// Pass certain vector components to a function.
	OtherFunction( A.X, C.Z );
} 

You can do anything with Struct variables that you can do with other variables: you can assign variables to them, you can pass them to functions, and you can access their components.

There are several Structs defined in the Object class, which are used throughout Unreal. You should become familiar with their operation, as they are fundamental building blocks of scripts:

Vector
A unique 3D point or vector in space, with an X, Y, and Z component.
Plane
Defines a unique plane in 3D space. A plane is defined by its X, Y, and Z components (which are assumed to be normalized) plus its W component, which represents the distance of the plane from the origin, along the plane's normal (which is the shortest line from the plane to the origin).
Rotator
A rotation defining a unique orthogonal coordinate system. A rotator contains Pitch, Yaw, and Roll components.
Coords
An arbitrary coordinate system in 3D space.
Color
An RGB color value.
Region
Defines a unique convex region within a level.

Enumerations


Enumerations exist in UnrealScript as a convenient way to declare variables that can contain "one of" a bunch of keywords. For example, the actor class contains the enumeration EPhysics, which describes the physics which Unreal should apply to the actor. This can be set to one of the predefined values like PHYS_None, PHYS_Walking, PHYS_Falling, and so on.

Internally, enumerations are stored as byte variables. In designing UnrealScript, enumerations were not seen as a necessity, but it makes code so much easier to read to see that an actor's physics mode is being set to PHYS_Swimming than (for example) 3.

Here is sample code that declares enumerations.

// Declare the EColor enumeration, with three values.
enum EColor
{
   CO_Red,
   CO_Green,
   CO_Blue
};
 
// Now, declare two variables of type EColor.
var EColor ShirtColor, HatColor;

// Alternatively, you can declare variables and
// enumerations together like this:
var enum EFruit
{
   FRUIT_Apple,
   FRUIT_Orange,
   FRUIT_Bannana
} FirstFruit, SecondFruit;

In the Unreal source, we always declare enumeration values like LT_Steady, PHYS_Falling, and so on, rather than as simply "Steady" or "Falling". This is just a matter of programming style, and is not a requirement of the language.

UnrealScript only recognizes unqualified enum tags (like FRUIT_Apple) in classes where the enumeration was defined, and in its subclasses. If you need to refer to an enumeration tag defined somewhere else in the class hierarchy, you must "qualify it":

FRUIT_Apple         // If Unreal can't find this enum tag...
EFruit.FRUIT_Apple  // Then qualify it like this.

Enumeration values can be used as the size of a static array. Additionally, a static array can be declared to be a size equal to the number of items in the enumeration by using the enumeration's type name in the declaration, for example:

var int MyIntArray[EFruit];

Constants


In UnrealScript, you can specify constant literal values for nearly all data types:

  • Integer and byte constants are specified with simple numbers, for example: 123. If you must specify an integer or byte constant in hexadecimal format, use i.e.: 0x123
  • Floating point constants are specified with decimal numbers like: 456.789
  • String constants must be enclosed in double quotes, for example: "MyString"
  • Name constants must be enclosed in single quotes, for example 'MyName'
  • Vector constants contain X, Y, and Z values like this: vect(1.0,2.0,4.0)
  • Rotator constants contain Pitch, Yaw, and Roll values like this: Rot(0x8000,0x4000,0)
  • The None constant refers to "no object" (or equivalently, "no actor").
  • The Self constant refers to "this object" (or equivalently, "this actor"), i.e. the object whose script is executing.
  • General object constants are specified by the object type followed by the object name in single quotes, for example: texture'Default'
  • EnumCount gives you the number of elements in an enumeration, for example: ELightType.EnumCount
  • ArrayCount gives you the number of elements in an static array, for example: ArrayCount(Touching)

You can use the "const" keyword to declare constants that you can later refer to by name. For example:

const LargeNumber=123456;
const PI=3.14159;
const MyName="Tim";
const Northeast=Vect(1.0,1.0,0.0);

Constants can be defined within classes or within structs.

To access a constant which was declared in another class, use the "class'classname'.const.constname" syntax, for example:

class'Pawn'.const.LargeNumber

Object and actor reference variables


You can declare a variable that refers to an actor or object like this:

var actor A;	// An actor reference.
var pawn P;	// A reference to an actor in the Pawn class.
var texture T;	// A reference to a texture object.

The variable "P" above is a reference to an actor in the Pawn class. Such a variable can refer to any actor that belongs to a subclass of Pawn. For example, P might refer to a Brute, or a Skaarj, or a Manta. It can be any kind of Pawn. However, P can never refer to a Trigger actor (because Trigger is not a subclass of Pawn).

One example of where it's handy to have a variable referring to an actor is the Enemy variable in the Pawn class, which refers to the actor that the Pawn is trying to attack.

When you have a variable that refers to an actor, you can access that actor's variables, and call its functions. For example:

// Declare two variables that refer to a pawns.
var pawn P, Q;
 
// Here is a function that makes use of P.
// It displays some information about P.
function MyFunction()
{
   // Set P's enemy to Q.
   P.Enemy = Q;

   // Tell P to play his running animation.
   P.PlayRunning();
}

Variables that refer to actors always either refer to a valid actor (any actor that actually exists in the level), or they contain the value None. None is equivalent to the C/C++ NULL pointer. However, in UnrealScript, it is safe to access variables and call functions with a None reference; the result is always zero.

Note that an object or actor reference "points to" another actor or object, it doesn't "contain" an actor or object. The C equivalent of an actor reference is a pointer to an object in the AActor class (in C, you'd say an AActor*). For example, you could have two monsters in the world, Bob and Fred, who are fighting each other. Bob's "Enemy" variable would "point to" Fred, and Fred's "Enemy" variable would "point to" Bob.

Unlike C pointers, UnrealScript object references are always safe and infallible. It is impossible for an object reference to refer to an object that doesn't exist or is invalid (other than the special-case None value). In UnrealScript, when an actor is destroyed, all references to it are automatically set to None.

See the Communication Between Scripts section for more details on references and how to use them to allow objects to communicate with one another.

Class Reference Variables


In Unreal, classes are objects just like actors, textures, and sounds are objects. Class objects belong to the class named "class". Now, there will often be cases where you'll want to store a reference to a class object, so that you can spawn an actor belonging to that class (without knowing what the class is at compile-time). For example:

var() class C;
var actor A;
A = Spawn( C ); // Spawn an actor belonging to some arbitrary class C.

Now, be sure not to confuse the roles of a class C, and an object O belonging to class C (referred to as an "instance" of class C). To give a really shaky analogy, a class is like a pepper grinder, and an instance of that class is like pepper. You can use the pepper grinder (the class) to create pepper (objects of that class) by turning the crank (calling the Spawn function)...BUT, a pepper grinder (a class) is not pepper (an object belonging to the class), so you MUST NOT TRY TO EAT IT!

When declaring variables that reference class objects, you can optionally use the syntax class<metaclass> to limit the classes that can be referenced by the variable to classes of type metaclass (and its child classes). For example, in the declaration:

var class ActorClass;

The variable ActorClass may only reference a class that extends the "actor" class. This is useful for improving compile-time type checking. For example, the Spawn function takes a class as a parameter, but only makes sense when the given class is a subclass of Actor, and the class<classlimitor> syntax causes the compiler to enforce that requirement.

As with dynamic object casting, you can dynamically cast classes like this:

// casts the result of SomeFunctionCall() a class of type Actor (or subclasses of Actor)
class( SomeFunctionCall() )

Type Casting


Type casting is the process of converting a value from one type to another, generally for the purpose of assigning it to a variable of the type being converted to. Casting a value from one type to another can be very useful with simple data types as well as more complex types like object references. Keep in mind that data can be lost during casting, though. Different types of data have different levels of precision and converting from a higher-precision type to a lower-precision type will result in the extra digits of precision being dropped.

Type casting can take one of two forms: implicit or explicit.

Implicit Type Casting

Some variable data types (generally the numerical data types - byte, int, float) support being converted automatically between one another. This is called an implicit type cast because you are converting the data type but not explicitly stating the type to cast to. An implicit cast is performed when you assign a value or variable of one type to a variable of another type.

For instance:

var int IntVar;
var float FloatVar;

...

IntVar = 2;		// IntVar holds the value 2
FloatVar = 4.25;	// FLoatVar holds the value 4.25

...

IntVar = FloatVar;	// IntVar now holds the value 4

FloatVar and IntVar are different types but you can assign the value of one to the other because int and float support implicit casting between one another.

Explicit Type Casting

While numerical types can be converted implicitly, other types require explicitly stating the type to convert to. Not all types can be explicitly cast to any other type. The type being converted must support being cast to the target type or the compiler will throw an error.

When explicitly casting a value, you must state the type to cast to followed by the value to cast in parentheses. The basic syntax is:

TypeToCastTo(ValueToCast)

Let's say you have a Vector variable that you want to display as a String. The Vector data type supports explicit casting to a String so the following would be completely valid:

var Vector Offset;
var String OffsetText;

...

Offset = vect(1.0, 2.5, 5.0);	//Offset now holds the values X=1.0, Y=2.5, Y=5.0
OffsetText = String(Offset);	//OffsetText now holds the value "1.0,2.5,5.0"

Explicit Casting Supported Types

String
The String data type supports being converted to the following types:
  • Byte, Int, Float - The number held in the String is converted to an actual numerical value. If the value of the String does not contain a number, the result of the cast will be 0 0r 0.0, depending on the type being converted to.
  • Bool - Converts the value of the String to either TRUE or FALSE. If the String contains either "True" or "False" (case does not matter), the text is converted directly to the equivalent Bool value. If neither of those values are present, the value of the String is first converted to a numerical value (following the rules described above) and then converted to a Bool value with a value of 0 converting to FASLE and any other value being converted to TRUE.
  • Vector, Rotator - Converts a String holding the text form of a Vector or Rotation (three numeric values separated by commas, i.e. “0.5,23.64,18.43”) to the specified target data type. For Vector conversions, the numeric values in the String will be converted to Float values with two decimal places of accuracy. For Rotator conversions, the numeric values in the String will be truncated, or have all decimal places removed, and converted to Int values.
Bool
The Bool data type supports being converted to the following types:
  • String - Converts the TRUE or FALSE value of the Bool to String values of "True" or "False", respectively.
  • Byte, Int, Float - Converts the TRUE or FALSE value of the Bool to numerical values of 1 or 0, respectively.
Byte, Int, Float, Vector, Rotator
These numerical data types support being converted to the following types:
  • String - Converts the numerical value(s) to text form. In the case of a Vector or Rotator, the text form is the three numerical values (X, Y, Z or Pitch, Yaw, Roll) separated by commas.
  • Bool - Converts the numerical value(s) to Bool values of TRUE or FALSE. Any non-zero value converts to TRUE, while a value of zero converts to FALSE. In the case of a Vector or Rotator, the value of each component must be zero to convert to FALSE. If any non-zero value is present, the result will be TRUE.
Name
The Name data type supports being converted to the folowing type:
  • String - Converts the text value of the Name to a STRING text value.
Vector
The Vector data type supports being converted to the folowing type:
  • Rotator - Converts the direction from the origin of the world to the location specified by the coordinates of the Vector to the Pitch and Yaw values of a Rotator that would correspond to that direction. The Roll value will always be 0.
Rotator
The Rotator data type supports being converted to the folowing type:
  • Vector - Converts the Pitch, Yaw, and Roll values of a Rotator to the coordinates of a Vector starting at the origin and pointing in the direction of the rotations.
Object Reference
Object Reference data types support being converted to the following types:
  • Int - Converts the Object Reference to a unique Int value.
  • Bool - Converts the Object Reference to TRUE if the variable holds a valid reference or FALSE if the value is None.
  • String - Converts the Object Reference to text form, i.e. the Name property of the Object or Actor being referenced (after casting the Name to a String) or "None" if there is no Object being referenced.
  • Object Reference - An Object Reference can be converted from one class to another provided the two classes are related. See Converting Object References for complete details on this type of casting.

Converting Object References

Just like the conversion functions above, which convert among simple data types, in UnrealScript you can convert actor and object references among various types. For example, all actors have a variable named "Target", which is a reference to another actor. Say you are writing a script where you need to check and see if your Target belongs to the "Pawn" actor class, and you need to do something special with your target that only makes sense when it's a pawn -- for example, you need to call one of the Pawn functions. The actor cast operators let you do this. Here's an example:

var actor Target;
//...

function TestActorConversions()
{
	local Pawn P;

	// Cast Target to Pawn and assign the result to P.  If Target is not a Pawn (or subclass of Pawn), then the value assigned to P will be None.
	P = Pawn(Target);
	if( P != None )
	{
		// Target is a pawn, so set its Enemy to Self.
		P.Enemy = Self;
   	}
   	else
   	{
	   	// Target is not a pawn.
   	}
}

To perform an actor conversion, type the class name followed by the actor expression you wish to convert, in parenthesis. Such conversions will either succeed or fail based on whether the conversion is sensible. In the above example, if your Target is referencing a Trigger object rather than a pawn, the expression Pawn(Target) will return "None", since a Trigger can't be converted to a Pawn. However, if your Target is referencing a Brute object, the conversion will successfully return the Brute, because Brute is a subclass of Pawn.

Thus, actor conversions have two purposes: First, you can use them to see if a certain actor reference belongs to a certain class. Second, you can use them to convert an actor reference from one class to a more specific class. Note that these conversions don't affect the actor you're converting at all -- they just enable UnrealScript to treat the actor reference as if it were a more specific type and allow you access the properties and methods declared in the more derived class.

Another example of conversions lies in the Inventory script. Each Inventory actor is owned by a Pawn, even though its Owner variable can refer to any Actor (because Actor.Owner is a variable of type Actor). So a common theme in the Inventory code is to cast Owner to a Pawn, for example:

// Called by engine when destroyed.
function Destroyed()
{
	// Remove from owner's inventory.
	if( Pawn(Owner)!=None )
    	Pawn(Owner).DeleteInventory( Self );
}