Mostly Harmless

Legacy:Variable Syntax

From Unreal Wiki, The Unreal Engine Documentation Site
Revision as of 16:35, 11 August 2008 by Tex23bm (Talk | contribs) (Discussion)

Jump to: navigation, search

Variable Declaration

Class variables

The var keyword is used after the class declaration to declare class variables. Using parentheses after the keyword var makes the variable appear in the Actor properties window for objects of that class. Using group makes them appear in a certain group like Display. If group is not specified the class name is used as group. See Displaying variables in UnrealEd.

var(group) modifiers type name, name, ...;
var() modifiers type name, name, ...;
var modifiers type name, name, ...;

Default values of variables are set in the Default Properties block. For the possible values of the 'type, see Variable Type.

Constants

Constants are just names for certain values and can be changed neither from UnrealScript nor from native code. Constants can be declared anywhere in a class, even inside functions, but they are always available in the whole class.

const name = value;

Note: Constants will not be evaluated in the default properties block. You will have to use literal values there.

Local Variables

Local variables are only available in the function they were declared in.

local type name, name, ...;

Function Parameters

See Function Syntax.

Arrays

Static Arrays

A static array has a length known at compile time and is not resizeable.

To create an array just specify its length in brackets behind the variable's name:

var/local type name[length], ...;

Type can be any of the built-in types (except bool) or a struct or an object. (Enums?) The length needs to be a constant integer value greater than 0, i.e. you can also use a constant instead of a number here. The array's size cannot be changed once the array has been declared. All elements are initialized to their null values. (see Built-In Types below)

Array values are accessed via name[0] to name[length - 1]. If you need to get the length of the array use ArrayCount(name).

Note: UnrealScript doesn't support multi-dimentional arrays of any kind. To fake multi-dimensional arrays you either have to use a larger array and write accessor functions for it that transform multiple indices to a the actual array index or use a declaration like this:

struct TMultiArray {
  var int Y[100];
};
var TMultiArray X[100];

Later, in a function you can access this fake multi-dimensional array with this syntax:

X[50].Y[50] = 31337;

Note on replication: The elements of a static array count as indvidual variables with identical replication conditions, so you can replicates arrays of any size you want as long as the individual elements obey replication restrictions.
However, as parameter of a replicated function only the first array element will arrive at the remote machine. To get around that, make the array part of a struct and use that as the function parameter.

Dynamic Arrays

A dynamic array is an array that can be lengthened or shortened to accomodate the number of elements in the array.

See Dynamic Array.

Variable Modifiers

Modifier keywords come between the var keyword and the type keyword. Any number of modifiers can be used, including zero.

//Example
 var transient int MyVar;
config 
The value of this variable can be saved to a *.ini file and is class specific. (see Config Vars And .Ini Files)
const 
The variable cannot be changed from UnrealScript, but only through native code.
deprecated 
(Only in v600+ builds of the Unreal Engine.) The compiler prints the warning "Reference to deprecated property variable name." when a variable marked as "deprecated" is used in the code.
edfindable 
(Only in v600+ builds of the Unreal Engine.) Can be read as 'Editor Findable.' If this property is selected in the actor properties window within UnrealEd, there will be a "find" button beside the property in question. If you click the "find" button, the cursor will change to the "finder" cursor. If an actor is clicked while the "finder" cursor is displayed, the currently selected property (in the actor properties window) will be set to the actor clicked upon. For an example, see Volume.DecorationList
editconst 
The variable cannot be changed in UnrealEd, even though it might be displayed there.
editconstarray 
Prevents users from changing a dynamic array's length in the properties window.
editinline 
(Only in v600+ builds of the Unreal Engine.) Allowes UnrealEd users to edit the object referenced by this variable within the property window of the object this variable belongs to. See editinline for details.
(no)export 
Whether or not this property should be displayed in the default properties of classes exported with UnrealEd or the BatchExportCommandlet. Just a guess, but export probably overrides a class' noexport declaration for subobject exporting.
globalconfig 
The value of this variable can be saved to a *.ini file and is also used for all subclasses. (see Config Vars And .Ini Files)
input 
<wiki>"Input" variables can be mapped to the console, by binding a key to a special console command. Only byte or float variables can be input variables. The appropriate console commands to bind an input variable to a keyboard/mouse/joystick input are:
  • Button <variable name>: The input variable is 1 if the button is pressed, 0 otherwise. Should be a byte variable.
  • Count <variable name>: This variable will increment every time the button is pressed. If it is an axis, this will increment every time a new input is recieved. This can be useful for checking to see if an input has changed since it was last checked. It will wrap around when it reaches 255. This should use a byte variable.
  • Axis <variable name> <arguments> The only one that takes arguments is also the only one meant for use with floats. This captures axis movement. Depending on the axis in question, this may be an absolute value (as with joysticks) or it may be a relative value. (as with mice) Arguments are specified in the format argument name=value and the valid arguments are:
    • Speed: Appears to be a simple multiplier for the input. Seems to be useful on mice.
    • SpeedBase: Appears to be an exponential multiplier for the input. Seems to be useful on joysticks.
    • Deadzone: Inputs within this amount of zero are not set into the axis variable and are registered as 0. This appears to be applied BEFORE speed or speedbase.
    • Invert: Interestingly, this appears to be a simple multiplier. Set to -1 to invert the axis.

Note that Interactions are better for most input capturing, as input variables require subclassing PlayerController. (or PlayerPawn in the case of UnrealEngine1) Axis input variables can also only be accessed within the PlayerTick function - outside of this function they will always be zero. (though the variable can be stored in another variable that will be accessible anytime.) The only real reason to use input variables in UnrealEngine2 is because Interactions do not capture joystick axis movement.

</wiki>

localized 
The default value of this variable can be located in a localization file (*.int, etc.).
native 
This variable is set by native code.
private 
The variable is only visible from the class it was declared in, but not from any of its subclasses.
protected 
The variable is only visible from the class it was declared in and all subclasses.
transient 
This variable will not be included when saving the current game. (in Unreal)
travel 
The value of this variable does not change when traveling between levels.

Related Topics


Discussion

Foxpaw: I have some variables that I could make private, but I'm curious - is there any advantage to having them private or should I leave them public on the off chance that a subclass might want to use them somewhere down the road? I don't see any reason why they would, but on the other hand there are some functions declared as final that Epic apparently didn't think anyone would want to override, whilst I very much do - so it's possible that sometime someone might want to use this variable for something. Is there a performance gain or anything like that to be had for using private variables?

Mychaeel: That's more a code design question than a purely technical one. While I'm very glad Epic followed a policy of leaving virtually everything public and non-final, my own code makes very frequent use of private or protected variables and functions.

At least during development my intent is to force others working with my code (and myself) to interact with my code only in a clearly defined, controllable fashion instead of messing with the internal state of my objects at will. That allows me to change the internal implementation of my classes without having to worry about what those changes do to others' code as long as I keep the interface true to its specification.

If you want to keep people from accessing variables or functions from outside a class but would still like to let them use those variables and use/overwrite the methods in subclasses, make them protected, not private.

Tarquin: I don't quite understand what "private" does. If I declare variable "Foo" to be private in MyClass, and I have objects A and B of that class, and C of a child class, can B read A's foo but C can't read A's foo? C has a foo variable of its own, with the same restrictions to its child classes?

Mychaeel: First part: Yes. Second part: C can have its own private (or public) variable called "foo," but that variable wouldn't be connected in any way to the "foo" variable from the base class. (Of course C has a piece of memory space allocated that the code in the base class would address as "foo," but the code in the child class doesn't know about the base class's "foo" at all.)


Tarquin: Can a constant be a boolean? eg

const DEFAULT_PROTECT_ARENA = True;

Foxpaw: That seems to work for me. I believe that constants in UnrealScript are closer to #DEFINE in C rather than a variable that can't be changed. (Only for constants, not const vars.) Unfortunately, however, you can't set a constant to be a statement or an expression like you can with a #DEFINE. Booleans should work, though.


Evolution: regarding the noexport modifier: this is only used by the GUIDesigner - it tells the GUIDesigner that this property shouldn't be included in the subobject definition that will be generated when you hit Ctrl+X while you are in design mode and have a control highlighted. The fact that it prevents those properties from appearing in the defaultproperties block for the class when you use batchexport is in fact a bug  :) It's fixed in the first patch, but I completely forgot about exporting classes from UnrealEd! so it will only correctly export those properties if you use batchexport to create the .uc files.


Devi: Is there a way of declaring member variables as static? I was wondering because I wanted to use the singleton model in one of my classes (The singleton model is where you declare a class in such a way that there can only be one instance of it, that instance is usually a static member variable of the class and is accessed via a static method of the class) in C++ I would do it like this:

class MySingleton

{

  private:
     int some_data_or_other;
     static MySingleton my_singleton_instance;
  public:
     inline static MySingleton &GetInstance(void) {return my_singleton_instance;}

};

Then, whenever I needed to get access to the class or it's functionality I can do:

MySingleton::GetInstance().DoSomethingWonderful();

I normally use this technique for big manager classes and such that get referenced all over the place and am wondering how I'd deal with the same kind of situation in UScript...

Wormbo: There are no static variables in UnrealScript. There are default class variables, though. You could store objects in them, but it's not a good idea. You will very likely mess up garbage collection by assigning dynamically generated objects (i.e. not within the editor) to default class variables, because they might still reference the level even after a map change. You should store the reference to your object in another central object that can easily be accessed.

Foxpaw: You can use default variables for the same purpose. In many instances I have done the following:

class SomeClass extends Whatever;
 
var SomeClass Reference;
 
function PreBeginPlay()
{
  default.Reference = Self;
}
 
function Destroyed()
{
  default.Reference = None;
}

However, default properties don't get "cleaned up" in the same way that dynamic references do, so you have to make sure you manually clean up these references like I've done above.

Devi: That seems to make sense, I'll give it a try... For extra protection you may like to use code like this:

function PreBeginPlay()
{
  if (default.Reference!=None)
  {
    if (default.Reference!=Self)
    {
      Log("There's more than one SomeClass class placed in this level, one named: "$Name$" the other: "$default.Reference.Name$"...");
    }
  }
  else
  {
    default.Reference=self;
  }
}
function Destroyed()
{
  if (default.Reference==Self)
  {
    default.Reference=None;
  }
}

This way your code is protected if something accidentally generates a second instance of your singleton class...


Jimboh: Are newly declared variables GUARANTEED to be zero?

Wormbo: Yes, however, only local variables and new array elements can be considered "newly declared".

Skrilax: What string is a 'coerce string'? (for example used in BroadcastMessage function)

Mychaeel: The "coerce" isn't part of the variable type; it tells the compiler to accept non-string arguments at that place as long as they can be auto-typecasted as strings. The Log function also coerces its argument to string, so you can write Log("foo") or Log(123) or even Log(Pawn.Location) without having to bother with writing an explicit typecast.


Juxtapose: I added new information to constants as pertaining to default properties. I haven't investigated the situation further than the information used above (using constants from classes compiled before the current default properties block, e.g.) so if anyone else has run into this, please add what you know. Also, are there any suggestions on where this should go? I linked the default properties page, but maybe all this information needs to be there instead. Should Default_Properties link back to here for use of constants?


MM: Is there a limit to the [length] of a static array? (In Unreal Engine 1) Such as

var string testtxt[1000000]

Tex23BM Is there a way To declare C++ member variables in Unreal? AKA: I want a C++ fstream (not a FileLog).