AI Controllers usually are implemented as State machines. Unrealscript has a state construct that makes this easy. Code enclosed in a named state block is executed only when the object enters that state. The controller has an explicit method for switching state called GotoState(). As this is a simple example I have not overridden any methods inside the state block, but have written short fragments of code that can be executed latentley. Latent functions are Unrealscript speak for functions that run in the background. There are a small group of these available to you (grepping through the Controller, Actor and Pawn classes should reaval them), mostly related to Pawn movmement. Here, the rising state sets the Pawn velocity when it is etered, and then periodically checks to see if the bubble has risen too far. When it has, it enters the Popping state, wherein it stands still for a second, and then is destroyed.
The Destroy() function brings us to another point. Objects derived from actor have a special property in that they are spawned rather than created with the new() operator. In our BubblePawn class we called a base method called SpawnDefaultController(), and set ControllerClass to class'LavaLamp.BubbleController'. SpawnDefaultController will then create an instance of that controller class, and ensure that the controller Poseses (ie controls/owns) the Pawn by calling Posses. It is perfectly theoretially possible to pass a pawn around different controllers to implement different behaviours - although the state mechanism makes this less useful than it might sound.
class BubbleController extends AIController; var float RisingDistance; var float ExtraVelocity; simulated Event SetInitialState() { ExtraVelocity = FRand() * 1.25; bScriptInitialized = true; GotoState('Rising'); } state Rising { Begin: Pawn.Velocity = vect(0.0, 0.0, 0.85); Pawn.Velocity.Z += ExtraVelocity; RisingLoop: if (Pawn.Location.Z > RisingDistance) { StopLatentExecution(); GotoState('Popping'); } Sleep(1); goto 'RisingLoop'; } state Popping { Begin: Pawn.Velocity = vect(0.0, 0.0, 0.0); PoppingLoop: Sleep(1); Pawn.Destroy(); Pawn = None; Destroy(); goto 'PoppingLoop'; } defaultproperties { RisingDistance = 2048.0 }
No comments:
Post a Comment