Using the MagdalenaMonster as our base monster that we made in a previous tutorial this will show you how to make your monster fire projectiles. The magdalena base class can be downloaded from here:Magdalana Base Class
We need to set up the monsters RangedAttack function. This function controls how the monster attacks.
function RangedAttack(Actor A) { if ( bShotAnim ) { return; } bShotAnim=true; if ( Physics == PHYS_Swimming ) { SetAnimAction(IdleSwimAnim); } else { SetAnimAction('Gesture_Taunt01'); Controller.bPreparingMove = true; Acceleration = vect(0,0,0); FireProjectile(); } }
Here you can see that when the monster attacks it will play the animation “Gesture_Taunt01”. This animation is quite good for Magdalena. Look at your monsters animations and pick a suitable one to place here. Next we need to edit the FireProjectile function slightly and add two new global variables. Add these variable to the top of the class.
var class<Projectile> ProjectileClass; var int AimError;
Good, now add the FireProjectile function.
function FireProjectile() { local vector FireStart,X,Y,Z; if ( Controller != None ) { FireStart = GetFireStart(X,Y,Z); Spawn(ProjectileClass,,,FireStart,Controller.AdjustAim(SavedFireProperties,FireStart,AimError)); PlaySound(FireSound,SLOT_Interact); } }
This tells the monster to spawn its ProjectileClass whenever it stops moving. You can change the way this function works so the monster spawns projectiles whilst it is running, like the skaarj do, or when it gets within a certain distance or many other conditions. Just take a look at the Skaarj/Gasbag/Warlord/Brute/Krall code etc… We need to set the projectile class in the monsters defaultproperties next like this. We also need to set the AimError variable. This variable will be used in the Spawn() function of the FireProjectile function to determine how accurate the monster is. The FireSound is also played at this point. So don’t forget to include that in the defaultproperties if you havn’t done so already. Feel free to give this a lower value to make your monster a sharp shooter!
defaultproperties { ProjectileClass=class'SkaarjPack.KrallBolt' AimError=600 FireSound=Sound'WeaponSounds.ShockRifleAltFire' }
You can put any projectile class here. You can even make your own!
Your monster class should look something like this.
class MagdalenaMonster extends Monster; var class<Projectile> ProjectileClass; var int AimError; function RangedAttack(Actor A) { if ( bShotAnim ) { return; } bShotAnim=true; if ( Physics == PHYS_Swimming ) { SetAnimAction(IdleSwimAnim); } else { SetAnimAction('Gesture_Taunt01'); Controller.bPreparingMove = true; Acceleration = vect(0,0,0); FireProjectile(); } } function FireProjectile() { local vector FireStart,X,Y,Z; if ( Controller != None ) { FireStart = GetFireStart(X,Y,Z); Spawn(ProjectileClass,,,FireStart,Controller.AdjustAim(SavedFireProperties,FireStart,AimError)); PlaySound(FireSound,SLOT_Interact); } } simulated function PlayDirectionalDeath(Vector HitLoc) { local float Decision; Decision = fRand(); if(Decision < 0.25) { PlayAnim('DeathF',, 0.1); } else if ( Decision > 0.25 && Decision < 0.50) { PlayAnim('DeathB',, 0.1); } else if ( Decision > 0.50 && Decision < 0.75) { PlayAnim('DeathL',, 0.1); } else { PlayAnim('DeathR',, 0.1); } } simulated function PlayDirectionalHit(Vector HitLoc) { local float Decision; Decision = fRand(); if(Decision < 0.25) { PlayAnim('TurnL',, 0.1); } else if ( Decision > 0.25 && Decision < 0.50) { PlayAnim('TurnR',, 0.1); } else if ( Decision > 0.50 && Decision < 0.75) { PlayAnim('TurnL',, 0.1); } else { PlayAnim('TurnR',, 0.1); } } defaultproperties { AimError=600 ProjectileClass=class'SkaarjPack.KrallBolt' FireSound=Sound'WeaponSounds.ShockRifleAltFire' Mesh=SkeletalMesh'Magdalena.Magdalena' Skins(0)=Texture'MagdalenaTextures.magdalena_body' Skins(1)=Texture'MagdalenaTextures.magdalena_head' IdleWeaponAnim="Idle_Biggun" IdleHeavyAnim="Idle_Biggun" IdleRifleAnim="Idle_Rifle" TurnRightAnim="TurnR" TurnLeftAnim="TurnL" CrouchAnims(0)="CrouchF" CrouchAnims(1)="CrouchB" CrouchAnims(2)="CrouchL" CrouchAnims(3)="CrouchR" CrouchTurnRightAnim="Crouch_TurnR" CrouchTurnLeftAnim="Crouch_TurnL" AirStillAnim="Jump_Mid" AirAnims(0)="JumpF_Mid" AirAnims(1)="JumpB_Mid" AirAnims(2)="JumpL_Mid" AirAnims(3)="JumpR_Mid" TakeoffStillAnim="Jump_Takeoff" TakeoffAnims(0)="JumpF_Takeoff" TakeoffAnims(1)="JumpB_Takeoff" TakeoffAnims(2)="JumpL_Takeoff" TakeoffAnims(3)="JumpR_Takeoff" LandAnims(0)="JumpF_Land" LandAnims(1)="JumpB_Land" LandAnims(2)="JumpL_Land" LandAnims(3)="JumpR_Land" DodgeAnims(0)="DodgeF" DodgeAnims(1)="DodgeB" DodgeAnims(2)="DodgeL" DodgeAnims(3)="DodgeR" DoubleJumpAnims(0)="DoubleJumpF" DoubleJumpAnims(1)="DoubleJumpB" DoubleJumpAnims(2)="DoubleJumpL" DoubleJumpAnims(3)="DoubleJumpR" MovementAnims(0)="RunF" MovementAnims(1)="RunB" MovementAnims(2)="RunL" MovementAnims(3)="RunR" SwimAnims(0)="SwimF" SwimAnims(1)="SwimB" SwimAnims(2)="SwimL" SwimAnims(3)="SwimR" WalkAnims(0)="WalkF" WalkAnims(1)="WalkB" WalkAnims(2)="WalkL" WalkAnims(3)="WalkR" WallDodgeAnims(0)="WallDodgeF" WallDodgeAnims(1)="WallDodgeB" WallDodgeAnims(2)="WallDodgeL" WallDodgeAnims(3)="WallDodgeR" IdleRestAnim="Idle_Rest" IdleCrouchAnim="Crouch" IdleSwimAnim="Swim_Thread" IdleChatAnim="idle_chat" FireHeavyRapidAnim="Biggun_Aimed" FireHeavyBurstAnim="Biggun_Burst" FireRifleRapidAnim="Rifle_Aimed" FireRifleBurstAnim="Rifle_Burst" HitSound(0)=Sound'SkaarjPack_rc.injur1sk' HitSound(1)=Sound'SkaarjPack_rc.injur1sk' HitSound(2)=Sound'SkaarjPack_rc.injur1sk' HitSound(3)=Sound'SkaarjPack_rc.injur1sk' DeathSound(0)=Sound'SkaarjPack_rc.death1br' DeathSound(1)=Sound'SkaarjPack_rc.death1br' DeathSound(2)=Sound'SkaarjPack_rc.death1br' DeathSound(3)=Sound'SkaarjPack_rc.death1br' ChallengeSound(0)=Sound'SkaarjPack_rc.scuttle1pp' ChallengeSound(1)=Sound'SkaarjPack_rc.scuttle1pp' ChallengeSound(2)=Sound'SkaarjPack_rc.scuttle1pp' ChallengeSound(3)=Sound'SkaarjPack_rc.scuttle1pp' }
TIP – Some monsters are afraid of bright lights. By remembering to leave your fridge door open you can be sure to scare them away.
Recent Comments