|
|
Line 1: |
Line 1: |
− | This is a list of new UnrealScript features in [[Legacy:UT3|UT3]], compared to [[Legacy:UT2004|UT2004]]:
| + | #REDIRECT [[UnrealScript history]] |
− | | + | |
− | ==Interfaces==
| + | |
− | | + | |
− | Previously only some licensees implemented interface support in their games, but UnrealEngine 3 adds it as a default feature.
| + | |
− | | + | |
− | Interfaces are declared in separate .UC files, just like classes. The difference is, that they are declared using the keyword "interface" instead of "class". Interfaces don't have to extend from any other class, but if they do, the other class needs to be an interface as well.
| + | |
− | | + | |
− | Like in Java, you can only declare constants (not variables marked with the "const" modifier!), functions and delegates. It is currently unknown whether functions and delegates can have an implementation, but some stock interfaces declare native functions, which could be considered a kind of implementation.
| + | |
− | | + | |
− | ==Built-in Preprocessor==
| + | |
− | | + | |
− | The [[Legacy:UE3 Preprocessor|UE3 Preprocessor]] provides a powerful macro system, similar to that provided by elmuerte's [[Legacy:UCPP|UCPP]]. There are a few built-in macro functions and values. For example the type of compiler run can be determined by checking if any of the macros DEBUG, RELEASE or FINAL_RELEASE are defined.
| + | |
− | | + | |
− | Logging is preferably done through the `log() and `warn() macro functions now. They take the message string as first parameter and an optional condition as second parameter. The message is only logged if the condition evaluates to true at runtime.
| + | |
− | | + | |
− | There are no instances of user-defined macro functions in the downloadable UnrealScript sources, but several instances of macro definitions for code snippets. An example is located in Object.uc:
| + | |
− | | + | |
− | <uscript>
| + | |
− | `if(`isdefined(FINAL_RELEASE))
| + | |
− | `define prevent_direct_calls private
| + | |
− | `else
| + | |
− | `define prevent_direct_calls
| + | |
− | `endif
| + | |
− | </uscript>
| + | |
− | | + | |
− | it is used further down in declaration of the LogInternal and WarnInternal functions, which now should be called through the `log and `warn macros:
| + | |
− | | + | |
− | <uscript>
| + | |
− | native(231) final static `{prevent_direct_calls} function LogInternal( coerce string S, optional name Tag );
| + | |
− | native(232) final static `{prevent_direct_calls} function WarnInternal( coerce string S );
| + | |
− | </uscript>
| + | |
− | | + | |
− | The `{''macroname''} syntax apparently means the macro value should be omitted from the imported source code, but still be used by the compiler. If the macro value should be inserted into the imported source code, use the `''macroname'' syntax instead.
| + | |
− | | + | |
− | ==No More #-Directives==
| + | |
− | | + | |
− | There's no replacement for #[[Legacy:Exec Directive|exec directive]]s, you have to use UnrealEd to import resources now.
| + | |
− | | + | |
− | The (admittedly, very infrequently used) '''#include''' directive has been replaced by the '''`include()''' preprocessor macro.
| + | |
− | | + | |
− | ==New Default Properties Features==
| + | |
− | | + | |
− | In addition to the defaultproperties block of the class file you can now also specify a structdefaultproperties block for every newly declared struct type. Members of a struct variable are initialized with the specified values, no matter where the struct is used.
| + | |
− | | + | |
− | Default dynamic array values can now be added or removed with special macros. (see '''New Dynamic Array Features''' below)
| + | |
− | | + | |
− | [[Legacy:Subobject|Subobject]]s can now be modified by subclasses. For this, the subobject needs to be redeclared in the subclass's defaults block with the same name, but without a class specification. The following is an example from [[Legacy:PathNode|PathNode]] changing the sprite component's texture:
| + | |
− | | + | |
− | <uscript>
| + | |
− | defaultproperties
| + | |
− | {
| + | |
− | Begin Object NAME=Sprite
| + | |
− | Sprite=Texture2D'EngineResources.S_Pickup'
| + | |
− | End Object
| + | |
− | }
| + | |
− | </uscript>
| + | |
− | | + | |
− | The "Sprite" object was originally defined in the [[Legacy:NavigationPoint|NavigationPoint]] class:
| + | |
− | | + | |
− | <uscript>
| + | |
− | Begin Object Class=SpriteComponent Name=Sprite
| + | |
− | Sprite=Texture2D'EngineResources.S_NavP'
| + | |
− | HiddenGame=true
| + | |
− | HiddenEditor=false
| + | |
− | AlwaysLoadOnClient=False
| + | |
− | AlwaysLoadOnServer=False
| + | |
− | End Object
| + | |
− | Components.Add(Sprite)
| + | |
− | GoodSprite=Sprite
| + | |
− | </uscript>
| + | |
− | | + | |
− | Note that <code>HiddenGame</code>, etc. are inherited by the PathNode Sprite. If these classes were in different packages and the NavigationPoint's Sprite properties were changed, all changes (except those to the Sprite property, which was overridden in PathNode's Sprite) would propagate to the PathNode Sprite without recompiling its package as well.
| + | |
− | | + | |
− | ==New Dynamic Array Features==
| + | |
− | | + | |
− | [[Legacy:Dynamic Array|Dynamic array]]s are now a lot easier to handle, both in regular code and the [[Legacy:Default Properties|default properties]] blocks. In UT200x dynamic arrays only had the property Length and the functions Insert and Remove and they were only available in regular code, not in the defaults section.
| + | |
− | | + | |
− | Now the following additional functions are available in regular code:
| + | |
− | | + | |
− | ; Add(''number'') : Adds empty elements to the end of the array. <code>ar.Add(x)</code> is the same as: <uscript>ar.Length = ar.Length + x;</uscript>
| + | |
− | | + | |
− | ; AddItem(''value'') : Adds the value to the array. <code>ar.AddItem(value)</code> is the same as: <uscript>ar[ar.Length] = value;</uscript>
| + | |
− | | + | |
− | ; RemoveItem(''value'') : Removes all occurrences of the value from the array. For example <code>ar.RemoveItem(none)</code> removes all empty elements from an object array, which would otherwise require code similar to the following snippet but is likely to perform faster: <uscript>
| + | |
− | for (i = ar.length-1; i >= 0; i--)
| + | |
− | if (ar[i] == None)
| + | |
− | ar.Remove(i, 1);
| + | |
− | </uscript>
| + | |
− | | + | |
− | ; InsertItem(''value'', ''index'') : Inserts a value before the specified array element. <code>ar.InsertItem(x, i)</code> has the same effect as: <uscript>
| + | |
− | ar.Insert(i, 1);
| + | |
− | ar[i] = x;
| + | |
− | </uscript>
| + | |
− | | + | |
− | ; Find(''value'') : Searches for a value and either returns the index of the first array element containing that value or -1 if the array doesn't contain the value.
| + | |
− | | + | |
− | ; Find(''property name'', ''value'') : A special version of '''Find''' for dynamic arrays of structs. The first parameter must be a name value matching the name of the struct member to compare to the specified value.
| + | |
− | | + | |
− | Additionally, every dynamic arrays automatically serves as an [[Legacy:Iterator|Iterator]] function. If an actual iterator function existed, its declaration would probably look similar to the following:
| + | |
− | | + | |
− | <uscript>
| + | |
− | // The array would be declared as "array<ArrayType> ArrayName"
| + | |
− | // NOTE: No actual code!
| + | |
− | native iterator function ArrayName(out ArrayType Value, optional out int Index);
| + | |
− | </uscript>
| + | |
− | | + | |
− | Note that, unlike "real" iterator functions, there's no way to limit the output to certain classes.
| + | |
− | | + | |
− | And finally, UnrealEngine 3 also adds dynamic array macros to defaultproperties and the new structdefaultproperties blocks. These are different from the functions available in "real" code.
| + | |
− | | + | |
− | ; Add(''value'') : Like AddItem in real code.
| + | |
− | | + | |
− | ; Remove(''value'') : Like RemoveItem in real code. This makes it easier to remove specific inherited values from a dynamic array without having to know the exact index.
| + | |
− | | + | |
− | ; Empty : Removes all inherited values from the dynamic array. You don't have to add any parentheses after this one.
| + | |
− | | + | |
− | ==Metatags for Variables and Enum Elements==
| + | |
− | | + | |
− | After the name of class and struct variables and enum elements you can now add metadata in angle brackets. Various fields are comma-separated.
| + | |
− | | + | |
− | Syntax:
| + | |
− | var() ''usual modifiers'' type name<tag1=value1,tag2=value2,tag3>;
| + | |
− | | + | |
− | The following tags have been spotted in the UT3 UnrealScript source code:
| + | |
− | | + | |
− | ; Tooltip=''text'' : Displays the specified description as tooltip for the variable in UnrealEd's property window. Note that it's usually easier to use a doc comment, i.e. <code>/** ... */</code>, but if you already have such a comment and want to use a different text for the tooltip, you need to use the tag to override the displayed text.
| + | |
− | | + | |
− | ; DisplayName=''text'' : Displays the specified text instead of the variable or enum element name. Note that UnrealEd already automatically removes enum name prefixes in ALL-CAPS followed by an underscore '_' character.
| + | |
− | | + | |
− | ; EditCondition=''boolean value'' : ''(needs confirmation)'' Similar to the editconst variable modifier, but applied dynamically based on the specified condition.<br />All occurrences in stock code refer to bool variables at the same scope, i.e. for class variables it's a bool variable in the same class and for struct members it's a bool-type member in the same struct.
| + | |
− | | + | |
− | ; AllowAbstract : For variables of type Class this tag allows the user to select abstract classes. Without the tag, only non-abstract classes can be selected from the drop-down list. Always use this tag if you don't intend to create instances of the specified class. For for example it is absolutely essential to use this class for [[Legacy:DamageType|DamageType]]s or [[Legacy:LocalMessage|LocalMessage]]s, since those classes are always abstract.
| + | |
− | | + | |
− | ; AutoComment=true : Apparently this tag only works in [[Legacy:SequenceObject|SequenceObject]] classes and also only if the class's bSuppressAutoComment property is set to false. The effect of this tag seems to be that the tagged variable's value is displayed in the sequence object's comment in the [[Legacy:Kismet|Kismet]] editor.
| + | |