Recent Changes - Search:

Triggered Script

TriggeredScript

(also see TriggeredScriptReference)

The TriggeredScript system is a method within BiA of scripting the creation, destruction, and behavior of pawns, controllers, and other actors within a BiA map.

Why TriggeredScript?

There are many different ways of creating behavior in BiA:

  • C++ - Powerful, but requires a lot of knowledge and specialized tools.
  • UnrealScript - Fairly powerful, but requires substantial knowledge.
  • ScriptedTriggers and ACTION_* arrays - Reasonably powerful but with a clunky interface.
  • Triggers/Events - Fairly weak but totally controllable from within UnrealEd.

The TriggeredScript was introduced to bridge the gap between UnrealScript and ScriptedTriggers, providing level designers with a powerful but relatively easy-to-use system for controlling in-game behavior.

Advantages

The TriggeredScript system has several advantages over previous techniques.

  • **Power.** TriggeredScript is, ultimately, UnrealScript and can do anything it can do.
  • **Generality.** TriggeredScripts can talk to the entire level: any actor, any pawn, any controller. TriggeredScripts are not tied to a particular pawn or controller.
  • **Within UnrealEd.** TriggeredScripts can be developed entirely within UnrealEd.
  • **Easy to Support.** TriggeredScript functionality can be easily extended by programmers as new features are needed. Debugging TriggeredScripts is relatively easy.

Disadvantages

There are some caveats to the TriggeredScript system.

  • **Requires Programming Skill.** TriggeredScripts are programmed. Level designers that use them have to have at least basic programming skills.
  • **Perhaps Too Powerful.** TriggeredScripts are powerful enough to do very bad things: delete important actors, crash the game, or seriously hurt performance.

Getting Started with TriggeredScript

Here are the steps to create a TriggeredScript within your level.

1. In the Actor Browser, find the TriggeredScript class.
2. Right-click the TriggeredScript class and select "New...".
3. In the dialogue that appears, enter MyLevel for the package name and a valid class name for your class name. **Class names may not begin //or end// with a number.** Click OK to continue.
4. You are shown the source code for your class. Currently the source code is almost empty.
5. Within the source editor, move the caret down below all the other text in this file and paste this source code, which will act as a kind of template for your TriggeredScript classes.

state Start
{
Begin:

// Your code here!
GotoState( 'Default' );
}

state Default
{
Begin:

// Your code here!
}

state Triggered
{
Begin:

// Your code here!
GotoState( 'Default' );
}

We'll talk more about writing actual TriggeredScript code in a minute. For now, we'll move quickly on to show the whole process of compiling, placing a TriggeredScript actor in your level, and testing the level.

6. Compile your script by clicking Tools->Compile Changed. The second icon from the left in the script editor toolbar does the same thing.

  • If the script has errors, this will be shone in a bright red band at the bottom of the script editor.** You must correct your script before it will compile. Uncompiled script will not run in the game!

7. You have now created a new subclass of TriggeredScript, but //no actual actor of this class exists in your map yet.// Place an actor of your new class by selecting your class in the Actor Browser and then placing one in the world in the usual way. It will appear in the world as a dragon head icon.

8. Simply run the map to test your script. Since we haven't actually written any script yet, this TriggeredScript actor won't do anything.

A Very Simple Test Script

Here's a simple test script you can use. All it does is print log messages in various places in the code. This will help you to see when different parts of the TriggeredScript code are run, and also introduce you to the ModLog() function and the log window.

ModLog()

You can use the ModLog() function to print text to the BiA log window. To see the log window, type showlog from the BiA console, or start the game with the -log command-line parameter (UnrealEd does this by default).

Here's an example of ModLog() in use:

	ModLog( "Hello World!" );

This line will cause a string similar to:

	TriggeredScript: MyTriggeredScript1<Default>: Hello World!

...to appear in the log window.

After the game has closed, you can review the log by opening BiA.log in the system directory.

The Example Code

Replace the text you copied into your TriggeredScript-derived class with this code:

state Start
{
Begin:

ModLog( "START HERE" );

GotoState( 'Default' );

}

state Default
{
Begin:

ModLog( "DEFAULT HERE" );

}

state Triggered
{
Begin:

ModLog( "TRIGGERED HERE" );

GotoState( 'Default' );

}

Note that you'll need to keep the first 5 lines of the file intact (the lines down through placeable;).

After entering this new code, **compile** again with "compile changed scripts". If you get errors, correct them (ask for help if this proves daunting). Then run the map and keep an eye on the log window to see ModLog() spitting out the messages from your code.

Scripting Basics

Here are some important basic facts about scripting with UnrealScript (which is what TriggeredScript is):

Case

UnrealScript, and Unreal in general, is **case insensitive**. This means that it cannot tell the difference between Gearbox, gearbox, and gEarBOx. It considers all of these to be the same. However, you should try to be consistent in your scripting and act as if UnrealScript is case sensitive so that your code will be easy to read.

Whitespace

Whitespace (blanks, tabs, and newlines) is generally ignored in UnrealScript. Said more accurately: a lot of whitespace is treated as a single whitespace character. That means that:

if(failed){GetJiggyWiddit();}

...compiles just the same as:

if( failed )
{
GetJiggyWiddit();
}

(But the latter is easier to read and so is considered good style.)

End of Statement (;)

Most statements in UnrealScript end with a semicolon (;). See the example above.

Curly braces

Curly braces {} are used to enclose a section of code that should all be run together. Technically, this is called a "scope". You'll see them in for loops, if...else statements, and lots of other places. You saw one a moment ago used with if.

Good formatting style with curly braces is to keep the opening and closing brace on the same line, as in these examples:

function Foo()
{
if( vomiting )
{
// You can ignore this complicated-looking expression for now.
for( i = 0; i < 10; ++i )
{
DoStuff();
}
}
else
{
DoOtherStuff();
}
}

Generally speaking, you do not need a semicolon after your closing curly brace. The above example is a good indication of where semicolons are needed or not.

Comments

There are two styles of comments in UnrealScript. Namely:

// Single line comments start with "//" and end at the end of the line.

/* Multi-line comments
begin with slash-asterisk,
can go for many lines,
and then end with asterisk-slash. */

Functions

Most of what you will do in your TriggeredScripts is to **call functions.** Function calls always have this form:

FunctionName( parameter1, parameter2, ... )

The name of the function comes first. Then the function parameters (or "arguments") come next, separated by commas and enclosed in parentheses. The parentheses are required even if the function takes no parameters, as in:

IsTodayTuesday()

Here are some examples of function calls:

ACTION_OrderMove( 'SquadUSA', 'SquadDest' );

Sleep( 3.0 );

GotoState( 'Default' );

if( IsPawnDead( 'Mac' ) )...

Strings

Some of the functions you call in your TriggeredScript take **strings** as arguments. In UnrealScript, strings are always enclosed with double quotes ("). Here's an example of a string being used in context:

ACTION_SpawnActor( "gbxEffects.gbxLandmineEffect", 'LandmineEffect' );

Since ACTION_SpawnActor() expects a string as its its first parameter, "gbxEffects.gbxLandmineEffect" is enclosed with double quotes.

Names

Some TriggeredScript functions take **names** as arguments. A name is similar to a string but is always enclosed with //single// quotes ('). In the example above, 'LandmineEffect' is a name rather than a string.

In the Triggered Script Reference, each function specifically indicates whether it wants a string or a name.

Unlike strings, names cannot contain spaces. They must be less than 32 characters. These restrictions make them less flexible than strings, but they are used because they are vastly more memory- and performance-efficient than strings.

Next Steps

Now that you've created a basic TriggeredScript-derived class that logs messages to the Unreal log window, the next step is to make something in the world actually happen. This is a simple matter: all you have to do is consult the Triggered Script Reference for functions you can call, identify functions that look useful and then try them out!

Here's a simple script to get you started. But note: this script references actor tags that you probably don't already have in your map. To make this script actually work you'll need to make sure that the tags specified in the script are actually present in the world. If you run the script as-is, it won't hurt anything at all but it will merely print out log messages complaining that it can't find actors with the specified tags.

state Triggered // Here we are declaring a state called "Triggered"
{
// The Begin label is where the state code starts executing.
// Every state needs a Begin label.
Begin:

ACTION_TriggerEvent( 'Mover' ); // We trigger the 'Mover' event.

// We teleport an actor with the tag 'Pawn' to the
// location of an actor with the tag 'SomePathNode'.
ACTION_TeleportToActor( 'Pawn', 'SomePathNode' );

Sleep( 5.0 ); // Wait for 5.0 seconds.

ACTION_TriggerEvent( 'Mover' ); // Now trigger 'Mover' again.

Sleep( 3.0 ); // Wait another 3.0 seconds.

Goto( 'Begin' ); // Now go back to the Begin label where we started.
}

If you place a mover (with its initial state set to TriggerToggle) in your map, a pawn, and a pathnode, and you leave all their tags as the default, this script will cause the following behavior:

1. The mover will begin moving.
2. At the same moment, the pawn will be teleported to the pathnode.
3. Five seconds will pass.
4. The mover will begin moving again back toward its original position.
5. Three seconds will pass.
6. Go back to step 1.

For more information on all of the functions introduced in this script:

- ACTION_TriggerEvent()
- ACTION_TeleportToActor()
- Sleep()
- Goto()

...as well as many other useful functions, consult the Triggered Script Reference.

Miscellaneous Notes

  • ALWAYS COMPILE YOUR SCRIPT** before running the game. Otherwise the map will still be running the old script.

Edit - History - Print - Recent Changes - Search
Page last modified on December 29, 2005, at 03:50 PM