Worst-case scenario: the UEd Goblin wipes the map and burns down your house.
Legacy:VitalOverdose/VariableTimedMover
Part of Vital'sPMT
Overview
I was making a level one time where i needed to make a sort of cannon. Naturally i decided to use a Mover for the job but i couldn't get the 'Recoil' Effect looking right just by moving the cannon backwards and forwards at only one speed. What i really needed was something that first moved fast and then slowly reset to its original position.So i made the VariableTimedMover or 'Recoiler' By sub classing mover. This is not to be confused with the VariableTimedMover written at a later date by SuperApe using a different method.
Note:This custom class is not designed to work in any of the looping states already present in the mover class.
The Main Mover
The calculations for the new movetimes are done in PostBeginPlay and then assigned to global variables.This way the values don't have to be recalculated each time they need to be used.
I've chosen to alter the value used in the actual move rather than replace the the original movetime variable with one that the mapper can set. This makes cleaner code thats easy to spot/update at a later date.
The .SuperFunction effectively copies any code from the parent of this function and put it in on the next line... so you don't have togo to all the bother of writting it in your self. This also results in a very slimline script that's easy to understand/update ;)
Note:If you subclass mover directly in Unrealed youll notice 'Placeable' after the class name in the code. This is apparently wrong as movers shouldnt have Placeable for some reason.
//------------- VTM VariableTimedMover V1 ----------- // // By Fataloverdose Class VTM extends Mover Placeable; var() float Openspeed; // Open speed muliplyer var() float CloseSpeed; // Close speed muliplyer Function Postbeginplay() { Openspeed *=Movetime; // Calculate and assign new move time in PostBeginPlay. CloseSpeed*=Movetime; // This way the calculation is only done once. super.Postbeginplay(); } function DoOpen() { movetime=Openspeed; Super.DoOpen(); } function DoClose() // Close Mover { movetime=CloseSpeed; // Set MoveTime To new Close Movetime super.DoClose(); } DefaultProperties { Openspeed=0.5000000 CloseSpeed=2.000000 bBlockKarma=True }
After that i decided to add some FX
//------------- VTM VariableTimedMover ----------- // // By VitalOverdose Class VTM extends Mover Placeable; var() Array < Class< Emitter > > TheFX; // Dynamic array var() Float Openspeed; // Open speed muliplyer var() Float CloseSpeed; // Close speed muliplyer var() bool FX_Attatch; // Hard attach the fx to the mover var() Bool FX_bOnOpened; // FX spawn timeframe var() Bool FX_bOnClosed; // FX spawn timeframe var() Bool FX_bOnClosing; // FX spawn timeframe var() Bool FX_bOnOpening; // FX spawn timeframe Function Postbeginplay() { Openspeed *=Movetime; // Calculate and assign new move time in PostBeginPlay. CloseSpeed*=Movetime; // This way the calculation is only done once. super.Postbeginplay(); } function Spawnfx() // function SpawnFX { local Emitter Effect; // Define local variable of type Emitter local int MaxArraypos; local int Pickedno; local class< emitter> pickedEmitterClass< SEMI > if ( TheFX[0] == None ) { return; // Check to see if mapper wants any FX Spawned } MaxArraypos = TheFX.length; Pickedno = Rand(MaxArraypos); pickedEmitterClass = TheFX[Pickedno]; NetUpdateTime = Level.TimeSeconds - 1; // Quick Update Effect = Spawn(pickedEmitterClass,self,,Location,Rotation); // SpawnFX if ( FX_Attatch == True ) { Effect.SetBase(self); // HardAttachFX } } function DoOpen() // Open Mover { movetime=Openspeed; // Set Movtime to new OpenMovetime If ( FX_bOnOpening==True ) { Spawnfx(); // Call function Spawnfx } Super.DoOpen(); } Function FinishedOpening() // FinishedOpening { If ( FX_bOnOpened==True) { Spawnfx(); // Call function Spawnfx } Super.FinishedOpening(); } Function DoClose() // Close Mover { movetime=CloseSpeed; // Set MoveTime To new Close Movetime if ( FX_bOnClosing==True) { Spawnfx(); // Call function Spawnfx } super.DoClose(); } Function FinishedClosing() // Finished Closing { if ( FX_bOnClosed==True) { Spawnfx(); // Call function Spawnfx } Super.FinishedClosing(); } DefaultProperties { Openspeed=0.5000000 CloseSpeed=2.000000 bBlockKarma=True }
The array used for the FX is a Dynamic Array. The idea is that the mapper can choose as many emitter as hes like and the Game Engine will pick one at random at spawn time. There are 4 spawn times which happen at the same time as the Event triggers in the mover properties.Open,Opening,close,closing and there's options are controlled by the use of Boolean variables.
A dynamic array has no elements(blank spaces to hold info) defined at build time unlike a static array which mean the mapper can enter as many emitter fx as he wants and the editor creates a new element and add it onto the end of the last value stored in the array. If there are no elements used in the array anything added in go in at position [0].
To get our random number for our random FX we ask the game engine to pick a number between 0 and the the amount of elements used in the array. got get the elements used or the 'length' of the array we use;-
ArrayName.Length // Returns the number of elements in the array.
So to the the GameEngine to return a random Int number we use..
Rand(MaxIntNumber); //Rand (int Max) [static]: Returns a random number ranging from 0 to Max-1.
So rather than have to separate commands and to save using a variable we can combine two to come up with;-
Rand(ArrayName.Length); //will return a single int value. Max Possible Value = the length of ArrayName.