Mostly Harmless

Legacy:Variable Type

From Unreal Wiki, The Unreal Engine Documentation Site
Jump to: navigation, search

This page lists the variable types in UnrealScript. For details on declaring variables, see Variable Syntax.

Simple Types[edit]

bool[edit]

Boolean values: True, False

Initial value: False

Boolean values can't be used for arrays or as out parameters of functions.

int[edit]

Numbers from -2147483648 to 2147483647.

Initial value: 0

byte[edit]

Numbers from 0 to 255.

Initial value: 0

Assigning a number that exceeds this range will wrap it at the boundaries (so setting a byte variable to 256 will actually set it to 0).

float[edit]

Floating point numbers (single precision with a 24 bit mantissa).

Initial value: 0

Maximum precision error free: 223 = 8388608

string[edit]

Any number of characters (including zero) enclosed in double quotes.

Initial value: Empty string ""

  • Escape characters by prefixing them with a backslash: \" for literal double quotes in a string and \\ for literal backslashes.
  • For a newline character use the Chr(13) function call (\n is just a (needlessly) escaped n)
  • Some Unreal Tournament classes have support for the n escape on UnrealScript level, for instance UWindowDynamicTextArea (which is, among other things, used to display the weapon description for TournamentWeapon, so you can use n – escaped as n in the Default properties block of a .UC file – to create line breaks in such a description).

name[edit]

An identifier enclosed in single quotes.

Initial value: 'None'

The identifier may only contain letters, numbers and underscores. Names are not case-sensitive, so 'RedeemerDeath' and 'rEdEeMeRdEaTh' are basically the same thing, but the first appearance of the name in UnrealScript code will be used when converting it to string. (e.g. for logging)

vector, rotator, etc[edit]

Other apparent variable types such as vector, rotator, color, etc. are in fact built-In Structs, enums or Objects. See Color Operators for more on colors.

pointer[edit]

There seems to be a new built-in type pointer which is used instead of int for C++ pointers as of build 2166.

Structs[edit]

A struct allows you to define a new variable type that is made up of several variables itself. A good example is the built-in struct vector, which is made up of three floats X, Y, Z.

Structs are defined at the start of a class. They can't be declared within functions.

 
 struct modifiers StructName {
     variable declaration 1;
     variable declaration 2;
     ...
 };

Variable declaration within struct declaration uses the same syntax as class variables. Using "var" instead of "var()" will hide those component variables in an editable variable that uses the struct.

All elements of the struct are initialized with their corresponding null values.

Like variable declarations, struct declarations can have modifiers. The following struct modifiers have been spotted in UT2003 code:

native 
export 

The struct's name can be used as variable type within variable and function declarations. A struct declaration can also be used directly as the type of a variable, e.g.:

var VariableModifiers struct StructModifiers StructName {
    variable declaration 1;
    variable declaration 2;
    ...
} name, name, ...;

Extending structs[edit]

You can build a new struct on the base of an old struct.

In object for example:

// A point or direction vector in 3d space.
struct Vector
{
	var() config float X, Y, Z;
};
 
// A plane definition in 3d space.
struct Plane extends Vector
{
	var() config float W;
};

So the Plane will get the X,Y,Z from Vector, but will also includes its own W.

Copying structs[edit]

When you use the equals assignment operator a = b; on structs, the data inside b is copied over the data inside a. In other words, a and b are still two separate structs that happen to contain the same data. This is different behavior from using objects. If a and b are objects, the above statement results in a and b pointing to the same object.

struct something
{
	var int anInt;
};
...
something a,b;
a.anInt = 3;
b.anInt = 4;
a = b;		//b and a both contain anInt eqaul to 4
a.anInt = 3;	//a.anInt is 3 but b.anInt is still 4

This behavior is standard for all variable types except objects.

Enums[edit]

enum EnumName { EnumValue1, EnumValue2, ... };

Enums can be declared within the variable's type like structs.

var enum EnumName { EnumValue1, EnumValue2, ... } name, name, ...;

Enums are internally handled as byte variables and show some strange behavior when you try to typecast them. The initial value of an enum is its first element.

There are some built-in enumerations in UnrealScript like the ERole enumeration used in the Role and RemoteRole variables declared in the Actor class.

If you want to know the number of items in the enum use EnumCount(ENumName).

To get the name representation of an enum value, use GetEnum(), defined in Object. It takes two parameters - the enum object, and an int corresponding to the value. The expected type for the object parameter is the name of the enum, explicitly casted to an enum. ex:

log("Logging my Role and RemoteRole - Role:" $ GetEnum( enum'ENetRole', Role ) @ "RemoteRole:" $ GetEnum( enum'ENetRole', RemoteRole ));

El Muerte TDS: don't know if this always has been like this, but in UT2003 I have to do the following to get the number of elements in a enum:

EnumName.EnumCount

Tarquin: No way to typecast them at ALL? Not even to int?

Mysterial: I've never had any problems typecasting them either to or from ints.

Dark Ryder: Does anyone know how to make something like the following work?

var enum EList {
	LI_One,
	LI_Two
} List;
 
var string Text[List.EnumCount];
 
defaultproperties {
	Text(LI_One)="String number one."
	Text(LI_Two)="String number two."
}

I keep getting "Error, Variable declaration Text: Illegal array size 1" (also tried EList.EnumCount). If it can't be done, it can't be done, but that seems like a very strange error to get (count should be 2 and even if it's only 1, that should be a valid array length).

Wormbo: You can only use numbers in the array index in default properties. Also, the enum count is expressed as EnumCount(List) in your case, but somehow I doubt you can use that in declarations.

Dark Ryder: So it would seem. In fact, because the engine seems to be unable to see enums as anything but instance variables, they can't be used as array indices in static functions (e.g. FillPlayInfo and GetDescriptionText), which is the whole point of what I was trying to do. Oh, well, back to the old-fashioned way...

Objects[edit]

Object variables are specified in the form

class'package.name'

These might be actors in a level, or resources such as textures, sounds, or meshes. For example:

  • Texture'Engine.DefaultTexture'
  • Sound'WeaponSounds.ExplosionSounds.Boom123'
  • xPawn'CTF-SomeWeirdMap.xPawn9'

The initial value of Object variables is None. Unlike for name properties, this None is not enclosed in single quotes.

Copying Objects[edit]

When you use the equals assignment operator a = b; on objects, the object a points to is now the object b points to. In other words, a and b become references to the same object; changing one changes the other. This is different behavior from using structs. If a and b are structs, the above statement results in a and b containing the same data but as separate places in memory.

class something extends object
 
var int anInt;
 
...
 
something a,b;
a.anInt = 3;
b.anInt = 4;
a = b;		//b and a both point to the object b. a will be garbage collected (if nothing else references it)
a.anInt = 3;	//a.anInt and b.anInt is now 3. There is only one copy of something left in the code
Log(b.anInt);	//Prints "ScriptLog: 3" to the log file.

Objects are the only variable type that this is true for. Using any other variable type will leave two varibles in memory.

Classes[edit]

Class variables are actually just another type of object variable. The value of a class variable is a particular class. (This is because deep down in the engine even functions, enums, structs and variables are objects.)

You might use a class variable if you wanted a Spawn statement where the class wasn't fixed at compile time. Basically, you can use a class variable where you could also use a fixed class.

A class variable definition can specify a 'top-level' class, for example:

 var class anyClass< SEMI > // can be anything
 var class<Pawn> notAnyClass< SEMI > // can only be Pawn or subclasses

Specify the value of a class variable the same way as an object variable: class'xGame.xPawn'. Classes are just a special kind of Object reference, so their initial value also is None.

If you wish to find out whether an object is of the same type as a class type then you can use the Name property of the Class object you have.

var class<Weapon> biggerGun;
..
if ( someObject.IsA( biggerGun.Name ) ) {
  // Code here
}
..
default properties {
  biggerGun=Class'Botpack.WarHeadLauncher'
}

Daid303: IsA() doesn't seem to work with classes in UT2003. Atleast not for me. Anyone else having this problem?

Foxpaw: What exactly are you trying to do with it? If you are trying do something like SomeClassVariable.IsA( 'SomeOtherClass' ), that won't work. Reason being that class variables are all of type "class", and aren't derived from their superclass. Only instances of objects are derived from their superclass. The equivalent for class variables is to do:

  if ( ClassVariable == Class'SomeClass' || ClassIsChildOf( ClassVariable, Class'SomeClass' )

Daid303: If you hear a loud banging then that's my forehead comming on contact with my table. I feel so stupid. It's so clear... Anyhow, thanks. Now I can finaly take out that ugly hack.

Wormbo: Of course "class'xPawn'" isn't a real "Pawn" but only "a description of a pawn". However, "a description of a pawn" is a description, so e.g. class'xPawn'.IsA('Class') will return true like it's supposed to.


Guest: I'd like to ask here is there a way to convert a class variable into an actor variable and vice versa?

Mychaeel: Well, the term "converting" is a bit misplaced in that context... just as you wouldn't talk about "converting" a recipe into a meal. To get an Actor of a given class, spawn it. To get the class of a given Actor, read its Class property. Refer to OOP for general insights into object-oriented programming.

Xian: If you are referring to typecasting then Mychaeel pushed you in the right direction.

Here is an example (if this is what you asked:)

var Class <Actor> MyClass< SEMI >
 
function SpawnTestClass ()
{
    local Actor TestActor;
    local Class <Actor> TestClass< SEMI >
 
    // creating an instance of a Class - aka converting a class into an actor
    TestActor = Spawn(MyClass);
    Log("Here I am:" @ TestActor);  // same thing would be if you'd write Log("Here I am:" @ TestActor.Name);
 
    // converting an Actor to a Class
    TestClass = TestActor.Class;
    Log("Here I was:" @ TestClass);  // same thing would be if you'd write Log("Here I am:" @ TestActor.Class);
}

Word of advice, MyClass is by default None. So it is best to set it to a class value before using it. Because the variable type is a Class and the Class type is an Actor it means you can set it to ANY CLASS which is a child of Actor (but not Object). So Pawns, Weapons, HUDs, RIs, Mutators etc. Hope this clears it up :)


Dunge: using var() class<SomeClass> varName; display a drop down list in the editor with all sub-class of the specified class and set it to NONE by default, that's great but what happen if we change it and want to come back to NONE after? It just don't display in the list..

Xian: what do you mean ?

Dunge: I mean the dropdown list contain every sub-class, but not the NONE (empty) option so we can't unset something (at least not in our editor).

Xian: Try using an Object type not an Object class. If you'll check most Effects classes you'll see they use Object types instead of classes. Stuff like:

  • var () Sound Sblah;
  • var () Texture Tblah;

... and so on. Perhaps that might help although I am not sure what you want.

Tarquin: No, "var() class<SomeClass> varName;" defines a variable that holds a class, not an object. You'd use a variable like this if you wanted a Spawn statement where the class wasn't fixed at compile time: eg you might spawn a biorifle or a minigun depending on what the player already has.

Xian: That's what I said :) Maybe not using the best proper terms though...


SuperApe: I have this question on HelpDesk as well, but: Is there any way around the UT2004 class syntax HideDropDown? ShieldGun or Translauncher, for example, are Weapons that will not show up on the drop down list when you declare var() class<Weapon> myWeapon;. How can I get around this? Suggestions?

Xian: Perhaps not the best thought but might push you in the right direction; try using an enum. The downside is that it won't support 3rd party guns.

SuperApe: I thought of that, but not supporting 3rd party guns is too limiting for my purposes. If I have to, I may try again to use a string. But I'm having problems accessing it properly. This is actually an array<Weapon> property. When I try accessing values from an array<string>, I have problems with conditionals like if ( myString[i] != "" ) and statements like CreateInventory( myString[i] ), especially from another class, which is my situation. Not to mention strings can get messy if I'm asking mappers to type. ;) So, I'm trying to find another way. I'd really like a simple pull down to include those few hidden weapons. (btw, where the heck is the lightning gun?)

SuperApe: I see the LightningGun is actually xWeapons.SniperRifle. But, I'm still hoping someone can help with a method to list all the Weapon classes in a listbox, even those defined with the class syntax HideDropDown.

Xian: I thought of a compromise but I am not sure if you'll accept it. Try writing a var descriptor for any class, and simply use the Actor browser to set a weapon (how you'd, for example set sounds, textures etc. effects in explosion chains in UT/U1). Although this is not the best method as I assume you wanted a simple way to do it, this is just something I thought might help. Good luck though :)

SuperApe: var descriptor? I'm not sure what you mean; I'm just not familiar with that phrase. I'm up for any suggestion. If I'm not able to get a simple listbox for the mapper to use, I can probably resort to using a string array, if I can figure out what I'm doing wrong when I access that array in another class. (problem described above)

Xian: Nevermind it was late :P Guess the best way would be just to use a string and then load it dynamically.

SuperApe: Thank you. Loading it dynamically was the trick to working with the string array property. I also just had some lame typos in my code that prevented it from working during my tests. Thanks again. :)

Xian: Hey, you did it all :) So the kudos go to you, I just pushed you in the right direction (I hope) :)

BTW I thought of an exotic way to do it as well... You could use special localization files to write in all Weapon classes and a name for each. Say, how in UT you had Botpack.UT_EightBall. You could write the class string and a name, i.e. "Rocket Launcher". Then the mapper would just have to write "Rocket Launcher" in the map actor (instead of the class) and you'd use the int parse functions (GetNextIntDesc() in UT) and check the corresponding class string. This might be easier and more fun since it's easier to remember "Bio Rifle" instead of "blah.stuff_blah_ut_bioriflez0r". And the names could be anything you want them to be, as simple and easy to remember as possible. The only drawback would be again, that it wouldn't support 3rd party weapons unless they'd use int files (although you could say make it easy for them by writing a readme on the syntax) as "plugins". Although the dynamic load using input strings does the trick, just thought of giving you a "different" idea. :) Not too many use this and the best part is that it's easy to implement :)

Related Topics[edit]