CHAPTER ONE: Introduction to OOP and UnrealScript
Code: Select all
//=============================================================================
/*
> [x.x] Preface
How to navigate:
> Search [>>] or >> to find important teminology or highlighted notes covering specific
concepts.
> Search [x.x] or x.x, x = any number to move between chapters and sections.
Credit goes to the Unreal and UT development team, and the community for providing the
information going into this guide.
Credit goes to everyone that has posted information on unrealwiki, especially the person or
persons helping host this website.
Credit goes to Higor, his help has made it so I understand (somewhat) what I am doing.
Thx m8
> [1.0] Object Oriented Programming In A Nutshell: How You Can Into UnrealScript
First of all a program is a file (data) that changes other data. Your operating system
(perhaps DOS) is a program. An example of the data that it might change would be the
data that the computer is sending to your monitor. Your program might change that data from
being no data sent to the monitor (resulting in blank screen) to data being sent to the
monitor telling it to light up certain pixels on the screen in a pattern resembling letters that
spell out "Hello World". An image file is data but it is not a program. While its data is a pattern
of pixels to light up on the monitor, which will resemble a picture of something, that data
alone changes nothing, therefore the image file is not a program. A program would change
the data sent to the monitor to be the data that the image file contains. In an OOP program,
subclasses of class objects change (override) data in their parent class and act as extensions
of the program itself. This will become clearer as you read on.
Programs execute one line of code at a time in a linear fashion. Starting from the first line of code
the program will continue to the second line of code and then the third, unless one of those
lines of code instruct the program to jump to another line and execute it. If perhaps the fourth
line of code instructs the program to execute the 27th line of code, the program will do so and
then resume execution of its code from line five. Line 27 of the program's code may be the
beginning of a block of code that consists of 5 or 6 lines of code. All 5 or 6 lines would be
executed before the program returns to line 5 to continue from there. One of those 5 or 6
lines of code may instruct the program to jump back up to line 14. The program will then
execute line 14 and all lines that follow within the block that begins at line 14 and then
return to the next line of the block that began at 27 and finish that block before returning
to line 5. Think of a picture of Mario or Luigi being printed by a printer, the printer printing
each pixel of the individual character starting from the top of the picture, moving from left
to right as the picture is printed from the top to the bottom. As the printer reaches the end
of a single layer of Mario or Luigi's pixels, the print head (how ink is applied) moves from
the last point ink was applied to the newest point. While a shakey analogy, this is similar
to how programs are executed: one line of ink (or code) at a time, however the only
difference is that sometimes our print head (or program) can move from one line to another
through calls done in ink (code).
Rather than bounce around up and down a list of instructions, an Object Oriented Program will
jump a lot of the time to code within a separate modular piece of the program. This modular
piece of the program, perhaps a class file, is compiled and embedded into the program and
becomes kind of a file inside of a file. An Exe file that appears to be one file that is the
program may actually be made up of individual modules and compiled into one file. Just as
the program would jump to line 27 of its code, a line of code in an OOP program may call
(tell the program to jump to) code within another module. That module is kind of like one
of the blocks of code mentioned earlier. Now when you look at the code you can see the
core of the program in one module, and specialized sections of code contained in separate
modules that might be extended even further other modules that hold even more specific
code related to the module that they are extending.
Use your imagination. Depending on the type of program you are writing, you might imagine the
modules representing different "real life" objects. For example, if you are writing a business
program you may imagine different modules being different departments within the
same office, each having specific duties where all departments work on modulated aspects
of the office's one project. If you were writing a game some of the modules would be items
and some would be players. Still yet some other modules in a game would be physics of
world the game takes place in and some would be smaller components of one module that
is an item in the game (like a bullets for a gun or guns for a player). If all of the code in the
program was one long list of code to be executed in linear fashion it would be very hard to
keep track of while you were writing it and almost impossible to fix or change the code later.
That's how it used to be done, but we know better now. Another reason for programs
being OOP is that you can actually use these modules in other programs that you write and
save a whole lot of time for yourself.
UnrealScript is a form of object oriented programming (OOP). OOP is the concept of not just
writing one massive piece of code, written to run everything, but instead several different
pieces of code all working together discretely to form the greater whole. This means that
all code is not depending on large chunks of code, making it easier to read, translate, or
debug for coders. Unreal and Unreal Tournament both use Unreal Engine 1, which uses
UnrealScript (which uses C++ for it's low-level, performance-critical code) to allow for the
interaction and modification of game objects. Writing UnrealScript is not possible without
writing classes and using objects. Every player, vehicle, weapon, pickup, and light is an
example of an object. Even abstract things like the game rules and scoreboard are objects.
Every object belongs to a Class, which describes what data and functions are applicable to
that object. For example, each player has an Enforcer. These are all of the same class: every
Enforcer has primary and secondary fire, and has a number of bullets. The Enforcer, its ammo
and and any projectile it may fire are all seperate Objects (for example, each Enforcer in a
game is a seperate object class of a class).
[>>] class - the 'blueprint' for objects.
Defined on Terminology as: "abstraction that typically is assigned clearly specified
characteristics; in other words, a chunk of data with a certain class associated to it; the
class describes the data structure and contains the code that deals with objects of that class".
[>>] object - an actual thing in the world.
Defined on Terminology as: "type of an object, an object's class defines how an object is
implemented; derived from or instantiated by an object, from which it inherits clearly defined
attributes. A class can contain: static data members, objects of another class, pointers and
references to types and objects of the same or another class, declarations of another class,
member functions, and friend classes. All Classes are listed in the Actor browser".
PROTIP: If you want a visual example of what is being described as "class objects", make a
new map in either UnrealEd 2.0/1. Subtract enough space that you can put a player on the map.
Go into your actor browser and you will see the "Actor" tree, or a visual example
of how a simple single-inheritance class graph works. In this class graph, each class
that is revealed as you open the sub menus is a "child class", meaning it is a class
that inherets properties/functions/states from it's parent class. Each of these classes
are examples of how OOP is meant to function - inheritance of code from parent classes,
as well as being easily attachable "modules" ("modules" being a hypothetical visual term).
[>>] Here is Unreal Tournament's Class Tree hierarchy from Actor in all its beauty and
glory. The Actor class inherits from Object (UT) (not seen here, but viewable in UnrealEd).
While some subclasses exist purely to customise data rather than behaviour, this is generally
frowned upon as most if not all duplicate functions can exist in one actor with multiple
functions. When it comes to creating classes, do not create classes if you can just modify
properties of existing actors through their class objects in editor or game:
Actor (UT)
+- Brush
| +- Mover (UT)
| +- AssertMover
| +- AttachMover
| +- ElevatorMover
| +- GradualMover
| +- LoopMover
| +- MixMover
| +- RotatingMover
|
+- DamageType (UT) Not used
| +- UnrealDamageType
| +- Burned
| +- Corroded
| +- Decapitated
| +- Drowned
| +- Fell
|
+- Decal
| +- FadeShadow
| +- PlayerShadow
| +- Scorch
| | +- BigEnergyImpact
| | +- biomark
| | +- BlastMark
| | +- BloodSplat
| | +- DirectionalBlast
| | +- EnergyImpact
| | | +- BoltScorch
| | +- ImpactHole
| | +- NuclearMark
| | +- Pock
| | +- RipperMark
| | +- UTBloodPool
| | | +- UTBloodPool2
| | +- WallCrack
| |
| +- TargetShadow
|
+- Decoration (UT) How many classes!
| +- ut_Decoration
|
+- Effects (UT) >>
|
+- HUD (UT)
| +- ChallengeHUD
| | +- ChallengeTeamHUD
| | +- AssaultHUD
| | +- ChallengeCTFHUD
| | +- ChallengeDominationHUD
| |
| +- UnrealHUD Not expanded
|
+- Info (UT)
| +- AssaultInfo
| +- BotInfo
| +- ChallengeBotInfo
| +- ClientScriptedTexture
| | +- ScrollingMessageTexture
| +- CodeMaster
| +- EndStats
| +- FontInfo
| +- GameInfo (UT)
| | +- TournamentGameInfo
| | | +- DeathMatchPlus
| | | | +- ChallengeDMP
| | | | +- ChallengeIntro
| | | | +- LastManStanding
| | | | +- TDarkMatch
| | | | +- TeamGamePlus
| | | | | +- Assault
| | | | | | +- TrainingAS
| | | | | +- CTFGame (UT)
| | | | | | +- TrainingCTF
| | | | | +- Domination
| | | | | +- TrainingDOM
| | | | |
| | | | +- TrainingDM
| | | |
| | | +- UTIntro
| | | +- LadderLoadGame
| | | +- LadderNewGame
| | | +- LadderTransition
| | | +- TrophyGame
| | |
| | +- UnrealGameInfo Not expanded
| |
| +- InternetInfo Not expanded
| +- Ladder (UT) Not expanded
| +- LocalMessage (UT)
| | +- LocalMessagePlus
| | +- CriticalEventPlus
| | | +- CriticalEventLowPlus
| | | | +- ControlPointMessage
| | | | +- KillingSpreeMessage
| | | | +- LMSOutMessage
| | | |
| | | +- CriticalStringPlus
| | | +- CTFMessage
| | | +- DeathMatchMessage
| | | +- FirstBloodMessage
| | | +- TimeMessage
| | |
| | +- CTFMessage2
| | +- DeathMessagePlus
| | | +- EradicatedDeathMessage
| | +- DecapitationMessage
| | +- ItemMessagePlus
| | +- KillerMessagePlus
| | +- MultiKillMessage
| | +- PickupMessagePlus
| | | +- PickupMessageHealthPlus
| | +- StringMesagePlus
| | | +- RedSayMessagePlus
| | | +- SayMessagePlus
| | | +- TeamSayMessagePlus
| | |
| | +- VictimMessage
| |
| +- MapList Not expanded
| +- MeshActor
| +- Mutator (UT)
| | +- Arena
| | | +- FlakArena
| | | +- impactarena
| | | +- InstaGibDM
| | | +- MinigunArena
| | | +- PulseArena
| | | +- RocketArena
| | | +- ShockArena
| | | +- SniperArena
| | |
| | +- ChainsawMelee
| | +- DMMutator
| | +- FatBoy
| | +- InstantRockets
| | +- JumpMatch
| | +- LowGrav
| | +- NoPowerups
| | +- NoRedeemer
| | +- Relic
| | | +- RelicDeath
| | | +- RelicDefense
| | | +- RelicRedemption
| | | +- RelicRegen
| | | +- RelicSpeed
| | | +- RelicStrength
| | |
| | +- Stealth
| |
| +- NewGameInterimObject
| +- RatedMatchInfo Not expanded - no plans to at this time
| +- RatedTeamInfo Not expanded - no plans to at this time
| +- ReplicationInfo
| | +- GameReplicationInfo
| | | +- TournamentGameReplicationInfo
| | | +- CTFReplicationInfo
| | +- PlayerReplicationInfo
| | +- BotReplicationInfo
| |
| +- SavedMove
| +- ScoreBoard
| | +- TournamentScoreBoard
| | | +- LMSScoreBoard
| | | +- TeamScoreBoard
| | | +- AssaultScoreBoard
| | | +- DominationScoreBoard
| | | +- UnrealCTFScoreBoard
| | |
| | +- UnrealScoreBoard
| | +- UnrealTeamScoreBoard
| +- SelectionDude Not expanded
| +- ServerInfo Not expanded
| | +- ServerInfoTeam
| | +- ServerInfoAS
| | +- ServerInfoCTF
| | +- ServerInfoDOM
| |
| +- StatLog Not expanded - no plans to at this time
| +- TeamInfo
| +- TestInfo Not expanded - no plans to at this time
| +- VoicePack Not expanded - no plans to at this time
| +- ZoneInfo (UT)
| +- CloudZone
| +- KillingField
| +- LavaZone
| +- LevelInfo (UT)
| +- NitrogenZone
| +- PressureZone
| +- SkyZoneInfo
| | +- RockingSkyZoneInfo
| +- SlimeZone
| +- TarZone
| +- TeleporterZone
| +- ToggleZoneInfo
| +- VacuumZone
| +- WarpZoneInfo
| +- WaterZone
|
+- Inventory (UT)
| +- LadderInventory
| +- Pickup (UT)
| | +- Ammo (UT)
| | | +- ASMDAmmo
| | | | +- DefaultAmmo
| | | +- FlakBox
| | | | +- FlakShellAmmo
| | | +- NullAmmo
| | | +- RazorAmmo
| | | +- RifleAmmo
| | | | +- RifleRound
| | | +- RocketCan
| | | +- ShellBox
| | | | +- Clip
| | | +- Shells
| | | +- Sludge
| | | +- StingerAmmo
| | | +- TournamentAmmo
| | | +- BioAmmo
| | | +- BladeHopper
| | | +- BulletBox
| | | | +- RifleShell
| | | +- FlakAmmo
| | | +- Miniammo
| | | | +- EClip
| | | +- PAmmo
| | | +- RocketPack
| | | +- ShockCore
| | | | +- SuperShockCore
| | | +- WarHeadAmmo
| | |
| | +- Amplifier
| | +- Armor
| | +- Dampener
| | +- Flare
| | +- Flashlight
| | | +- SearchLight
| | +- ForceField
| | +- Health
| | | +- Bandages
| | | +- NaliFruit
| | | +- SuperHealth
| | |
| | +- Invisibility
| | +- JumpBoots
| | +- SCUBAGear
| | +- Seeds
| | +- Shieldbelt
| | | +- PowerShield
| | +- Suits
| | | +- AsbestosSuit
| | | +- KevlarSuit
| | | +- ToxinSuit
| | |
| | +- TournamentHealth
| | | +- HealthPack
| | | +- HealthVial
| | | +- MedBox
| | |
| | +- TournamentPickup
| | | +- Armor2
| | | +- RelicInventory
| | | | +- RelicDeathInventory
| | | | +- RelicDefenseInventory
| | | | +- RelicRedemptionInventory
| | | | +- RelicRegenInventory
| | | | +- RelicSpeedInventory
| | | | +- RelicStrengthInventory
| | | |
| | | +- ThighPads
| | | +- UDamage
| | | +- UT_invisibility
| | | | +- UT_Stealth
| | | +- UT_JumpBoots
| | | +- UT_ShieldBelt
| | |
| | +- Translator
| | +- VoiceBox
| | +- WeaponPowerup
| |
| +- TrapSpringer
| +- Weapon (UT)
| +- ASMD
| +- AutoMag
| +- DispersionPistol
| +- Eightball
| +- FlakCannon
| +- GESBioRifle
| +- Minigun
| +- QuadShot
| +- Razorjack
| +- Rifle
| +- Stinger
| +- TournamentWeapon
| +- Chainsaw
| +- Enforcer
| | +- DoubleEnforcer
| +- ImpactHammer
| +- Minigun
| +- PulseGun
| +- ripper
| +- ShockRifle
| | +- SuperShockRifle
| +- SniperRifle
| +- Translocator
| +- ut_biorifle
| +- UT_Eightball
| +- UT_FlakCannon
| +- WarheadLauncher
|
+- Keypoint (UT)
| +- AmbientSound (UT)
| +- BlockAll
| +- BlockMonsters
| +- BlockPlayer
| +- ClipMarker
| +- DynamicAmbientSound
| +- Earthquake
| | +- CH_Earthquake
| +- GuardPoint
| +- HoldSpot
| +- InterpolationPoint
| +- LocationID
| +- MakeNaliFriendly
| +- ObjectPath
| +- OEMEnd
| +- PathPoint
| +- RockSlide
| | +- MagmaBurst
| +- SpectatorCam
| | +- QuakeCam
| +- ThingFactory
| | +- CreatureFactory
| +- ThrowStuff
| +- TriggeredAmbientSound
| +- WayBeacon
|
+- Light (UT)
| +- ChargeLight
| +- DistanceLighting
| +- FlashLightBeam
| +- OverheadLight
| +- QueenTeleportLight
| +- SightLight
| +- SpotLight
| +- TorchFlame
| +- TriggerLight There are two identical TriggerLight actors in Engine and UnrealShare.
| +- TriggerLightRad
| +- WeaponLight
| +- EffectLight
| +- PurpleLight
|
+- Menu Not expanded - no plans to at this time
|
+- NavigationPoint (UT) >>
|
+- Pawn (UT)
| +- Bot (UT)
| | +- HumanBotPlus
| | | +- FemaleBotPlus
| | | | +- TFemaleBot1
| | | | +- TFemaleBot2
| | | |
| | | +- MaleBotPlus
| | | +- TBossBot
| | | +- TMale1Bot
| | | +- TMale2Bot
| | |
| | +- SkaarjBot
| |
| +- Bots Not expanded
| +- FlockMasterPawn Not expanded
| +- FlockPawn Not expanded
| +- PlayerPawn Not expanded
| +- Scout Not expanded
| +- ScriptedPawn Not expanded
| +- StationaryPawn Not expanded
|
+- Projectile (UT) Not expanded
+- ShareSounds
+- SpawnNotify
+- Triggers (UT)
There are many ways to think of classes and objects: you can imagine a class as a "recipe" or a
"blueprint" for making things. It defines properties that every object of this class will have
(even if the values may differ), and functions (or methods) that every object of this class
can perform.
A basic principle of object orientation (OO) is that two classes shouldn't be doing the same thing.
For instance, both the Enforcer and Bio Rifle in Unreal Tournament do very similar things -
consume ammo, fire an instant shot, do damage to a target, etc. There are so many
similarities that much of the basic functionality can be done with the same lines of code.
Instead of duplicating this between the two classes, they share a parent class which handles
most of the basics. They then extend that class, assume all of it's properties and functions
(unless said properties and/or functions have been overridden, but that will be described later)
and then only add or edit what they need. This has many advantages. It makes it much
easier to maintain the basic functions for all three classes, since they share code.
With the Unreal engine, the hardest thing new modders need to grasp is how object oriented it is.
Unreal's OO design is what makes it possible to create a whole new game without having
to actually touch any of the original code. It's what allows for mutators to alter an entire
game with only a few lines of code. It makes the engine remarkably versatile to play with,
but also somewhat easy to break.
The main problem most people have with OO is unxpected behavior. Since you are usually not
staring at all the relevant code at once, it can be easy to misjudge the end result.
Modding games in such a manner used to be left up to those with enough knowledge to know
how to really hack into somebody else's binaries and change them all around. In reality,
game modification probably has a lot to owe to piracy and old school code demos as those
were the early 8-bit hobbies of doing something with somebody else's technology. Now,
the developers of the game give you access to their code, tools to edit it and programs to
recompile it.
*/
//=============================================================================
/*
> [1.1] Design Goals of UnrealScript
UnrealScript was created to provide the development team and the third-party Unreal developers
with a powerful, built-in programming language that maps naturally onto the needs and
nuances of game programming.
The major design goals of UnrealScript are:
[>>] To support the major concepts of time, state, properties, and networking which traditional
programming languages don't address. This greatly simplifies UnrealScript code. The major
complication in C/C++ based AI and game logic programming lies in dealing with events
that take a certain amount of game time to complete, and with events which are dependent
on aspects of the object's state. In C/C++, this results in spaghetti-code that is hard to write,
comprehend, maintain, and debug. UnrealScript includes native support for time, state, and
network replication which greatly simplify game programming.
[>>] To provide Java-style programming simplicity, object-orientation, and compile-time error
checking. Much as Java brings a clean programming platform to Web programmers,
UnrealScript provides an equally clean, simple, and robust programming language to 3D
gaming. The major programming concepts which UnrealScript derives from Java are:
> a pointerless environment with automatic garbage collection;
> a simple single-inheritance class graph;
> strong compile-time type checking;
> a safe client-side execution "sandbox";
> and the familiar look and feel of C/C++/Java code (such as upper/lower case insensitivity).
[>>] To enable rich, high level programming in terms of game objects and interactions rather
than bits and pixels. Where design tradeoffs had to be made in UnrealScript, execution speed
was sacrificed for development simplicity and power. After all, the low-level,
performance-critical code in Unreal is written in C/C++ where the performance gain
outweighs the added complexity. UnrealScript operates at a level above that, at the
object and interaction level, rather than the bits and pixels level.
*/
//=============================================================================
//=============================================================================
/*
> [1.2] Example Program Structure
The following examples illustrate a typical, simple UnrealScript class, and highlights the syntax and
features of UnrealScript. Pizza, a child class of Meal (Pizza.uc would be it's file name):
*/
//=============================================================================
//=============================================================================
// Pizza
//=============================================================================
class Pizza expands Trigger;
var int NumberOfParts;
var bool bHasCheese;
function postbeginplay(); /* This is inherited from Actor, Meal's parent class. */
{
local Pizza MyPizza; /* That's where I'm going to hold the pizza. Like a dish. */
MyPizza.Slice(8); /* Cut into 8 parts */
log("Slice executed, pizza slices:"@NumberOfParts);
}
function AddCheese()
{
bHasCheese = true;
}
function EatCheese()
{
bHasCheese = false;
}
function slice(pieces)
{
NumerOfParts=pieces;
}
function EatParts(int number)
{
local Pizza MyPizza;
NumberOfParts -= number;
if ( NumberOfParts <= 0 )
Destroy();
}
event Touch( Actor Other)
{
if ( Other.IsA('PlayerPawn') && !IsInState('EatPizza') )
{
Guy = PlayerPawn(Other);
GotoState('EatPizza');
SetCollision( false );
}
}
else
{
GotoState('');
}
}
state EatPizza
{
local Pizza MyPizza;
event EndState()
{
Guy = none;
}
Begin:
Guy.PlaySound ( Sound'Test.Munch');
Sleep( 1 );
Guy.PlaySound ( Sound'Test.Munch');
Sleep( 1 );
Guy.PlaySound ( Sound'Test.Munch');
Sleep( 1 );
MyPizza.EatParts( 8 );
Sleep( 1.5 );
GotoState('');
}
defaultproperties
{
NumberOfParts=1 // Semicolons AREN'T required for default
}
//=============================================================================
/*
> [1.3] UnrealScript Key Elements
The key elements to look at in this script are:
[>>] The class declaration:
Each class "extends" (derives from) one parent class, and each class belongs to a "package,"
a collection of objects that are distributed together. All functions and variables belong to a
class, and are only accessible through an actor that belongs to that class. There are no
system-wide global functions or variables, just functions or variables inherited from parent
classes.
Defined on Terminology as: "type of an object, an object's class defines how an object is
implemented; derived from or instantiated by an object, from which it inherits clearly defined
attributes. A class can contain: static data members, objects of another class, pointers and
references to types and objects of the same or another class, declarations of another class,
member functions, and friend classes. All Classes are listed in the Actor browser".
[>>] The variable declarations:
UnrealScript supports a very diverse set of variable types including most base C/Java types,
object references, structs, and arrays. In addition, variables can be made into editable
properties which designers can access in UnrealEd without any programming.
Defined on Terminology as: "memory location with a symbolic name where a program can
store information for future retrieval".
[>>] The functions
Functions can take a list of parameters, and they optionally return a value with the "return" type
("return;"). Functions can have local variables. Some functions are called by the Unreal
engine itself (such as BeginPlay), and some functions are called from other script code
elsewhere (such as Trigger). Basically, a section of code within an object that is
declared (created and defined) and does nothing until it is called from somewhere else.
Defined on Terminology as: "piece of code with a defined entry point and one or more exit points".
> That exit point may be reached upon completion of every line of code in the function or
as the result of a test within that function that indicates in the event of a negative
result the program should skip all the rest of the code in the function and exit.
[>>] The code
All of the standard C and Java keywords are supported, like for, while, break, switch, if, and so on.
Braces and semicolons are used in UnrealScript as in C, C++, and Java.
[>>] Actor and object references
Here you see several cases where a function is called within another object, using an object
reference.
[>>] The state keyword
This script defines several "states", which are groupings of functions, variables, and code which
are executed only when the actor is in that state.
Note that all keywords, variable names, functions, and object names in UnrealScript are case-
insensitive. To UnrealScript, "Demon", "demON", and "demon" are the same thing.
*/
//=============================================================================
//=============================================================================
/*
> [1.4] The Unreal Virtual Machine
The Unreal Virtual Machine consists of several components: the server, the client, the rendering
engine, and the engine support code. The Unreal server controls all gameplay and
interaction between players and actors. In a single-player game, both the Unreal client and
the Unreal server are run on the same machine; in an Internet game, there is a dedicated
server running on one machine; all players connect to this machine and are clients.
All gameplay takes place inside a "level", a self-contained environment containing geometry and
actors. Though UnrealServer may be capable of running more than one level simultaneously,
each level operates independently, and levels are shielded from each other: actors cannot
travel between levels, and actors on one level cannot communicate with actors on another
level. Each actor in a map can either be under player control (there can be many players in
a network game) or under script control. When an actor is under script control, its script
completely defines how the actor moves and interacts with other actors.
With all of those actors running around, scripts executing, and events occuring in the world,
you're probably asking how one can understand the flow of execution in an
UnrealScript. The answer is as follows:
[>>] To manage time, Unreal divides each second of gameplay into "ticks." A tick is the smallest unit
of time in which all actors in a level are updated. A tick typically takes between 1/100th
to 1/10th of a second. The tick time is limited only by CPU power; the faster machine, the
lower the tick duration. Some commands in UnrealScript take zero ticks to execute
(i.e. they execute without any game-time passing), and others take many ticks. Functions
which require game-time to pass are called "latent functions". Some examples of latent
functions include "Sleep", "FinishAnim", and "MoveTo." Latent functions in UnrealScript
may only be called from code within a state, not from code within a function. While an actor is
executing a latent function, that actor's state execution doesn't continue until the latent
function completes. However, other actors, or the VM, may call functions within the actor.
The net result is that all UnrealScript functions can be called at any time, even while
latent functions are pending. In traditional programming terms, UnrealScript acts as if each actor
in a level has its own "thread" of execution. Internally, Unreal does not use Windows threads,
because that would be very inefficient (Windows 95 and Windows NT do not handle thousands
of simultaneous threads efficiently). Instead, UnrealScript simulates threads. This fact is
transparent to UnrealScript code, but becomes very apparent when you write C++ code
which interacts with UnrealScript.
All UnrealScripts execute in parallel. If there are 100 monsters walking around in a level, all
100 of those monsters' scripts are executing simultaneously and independently.
//=============================================================================
/*
> [1.5] Class Overview
Before beginning work with UnrealScript, it's important to understand the high-level relationships
of objects within Unreal. The architecture of Unreal is a major departure from that of most
other games: Unreal is purely object-oriented (much like COM/ActiveX), in that it has a well-
defined object model with support for high-level object oriented concepts such as the object
graph, serialization, object lifetime, and polymorphism. Historically, most games have been
designed monolithically, with their major functionality hardcoded and unexpandable at the
object level, though many games, such as Doom and Quake, have proven to be very
expandable at the content level. There is a major benefit to Unreal's form of object-
orientation: major new functionality and object types can be added to Unreal at runtime, and
this expansion can take the form of subclassing, rather than (for example) by modifying a
bunch of existing code. This form of extensibility is extremely powerful, as it encourages
the Unreal community to create Unreal enhancements that all interoperate.
[>>] Class (expands Object) is a special kind of object which describes a class of object.
This may seem confusing at first: a class is an object, and a class describes certain objects.
But, the concept is sound, and there are many cases where you will deal with Class objects.
For example, when you spawn a new actor in UnrealScript, you can specify the new actor's
class with a Class object.
[>>] Object is the parent class of all objects in Unreal. All of the functions in the Object class are
accessible everywhere, because everything derives from Object. Object is an abstract base
class, in that it doesn't do anything useful. All functionality is provided by subclasses, such as
Texture (a texture map), TextBuffer (a chunk of text), and Class (which describes the class
of other objects).
[>>] Actor (extends Object) is the parent class of all standalone game objects in Unreal. The Actor
class contains all of the functionality needed for an actor to move around, interact with other
actors, affect the environment, and do other useful game-related things.
[>>] Pawn (UT) (expands Actor) is the parent class of all creatures and players in Unreal which
are capable of high-level AI and player controls.
With UnrealScript, you can write code for any Object class, but 99% of the time, you will be writing
code for a class derived from Actor. Most of the useful UnrealScript functionality is game-
related and deals with actors.
*/
//=============================================================================
//=============================================================================
/*
> [1.6] The Class Declaration
Each script corresponds to exactly one class, and the script begins by declaring the class, the
class's parent, and any additional information that is relevant to the class.
The simplest form is:
*/
//=============================================================================
class MyClass extends MyParentClass;
//=============================================================================
/*
Here I am declaring a new class named "MyClass", which inherets the functionality of
"MyParentClass". Additionally, the class resides in the package named "MyPackage". Each
class inherets all of the variables, functions, and states from its parent class. It can then add
new variable declarations, add new functions (or override the existing functions), add new
states (or add functionality to the existing states).
The typical approach to class design in UnrealScript is to make a new class (for example a
Minotaur monster) which expands an existing class that has most of the functionality you
need (for example the Pawn class, the base class of all monsters). With this approach, you
never need to reinvent the wheel. You can simply add the new functionality you want to
customize, while keeping all of the existing functionality you don't need to customize.
This approach is especially powerful for implementing AI in Unreal, where the built-in AI
system provides a tremendous amount of base functionality which you can use as building
blocks for your custom creatures.
The class declaration can take several optional specifiers that affect the class:
[>>] native
Says "this class uses behind-the-scenes C++ support". Unreal expects native classes to
contain a C++ implementation in the DLL corresponding to the class's package. For example,
if your package is named "Robots", Unreal looks in the "Robots.dll" for the C++
implementation of the native class, which is generated by the C++ IMPLEMENT_CLASS macro.
[>>] abstract
Declares the class as an "abstract base class". This prevents the user from adding actors
of this class to the world in UnrealEd, because the class isn't meaningful on its own. For
example, the "Pawn" base class is abstract, while the "Brute" subclass is not. You can place
a Brute in the world, but you can't place a Pawn in the world.
[>>] guid(a,b,c,d)
Associates a globally unique identifier (a 128-bit number) with the class. This Guid is currently
unused, but will be relevant when native COM support is later added to Unreal.
[>>] transient
Says "objects belonging to this class should never be saved on disk". Only useful in
conjunction with certain kinds of native classes which are non-persistent by nature,
such as players or windows.
[>>] config(section_name)
If there are any configurable variables in the class (declared with "config" or "globalconfig"),
causes those variables to be stored in a particular configuration file:
> config(system) – Uses the system configuration file, Unreal.ini for Unreal.
> config(user) – Uses the user configuration file, currently User.ini.
> config(whatever) – Uses the specified configuration file, for example "whatever.ini".
*/
//=============================================================================