Fursan al-Aqsa: The Knights of the Al-Aqsa Mosque® is a Third Person Action Game on which you play as Ahmad al-Falastini, a young Palestinian Student who was unjustly tortured and jailed by Israeli Soldiers for 5 years, had all his family killed by an Israeli Airstrike and now, after getting out from the prison, seeks revenge against those who wronged him, killed his family and stolen his homeland, by joining a new Palestinian Resistance Movement called Fursan al-Aqsa: The Knights of the Al-Aqsa Mosque®. Fursan al-Aqsa® is a Registered Trademark of Nidal Nijm Games © 2022, all rights reserved.

Post news Report RSS Fursan al-Aqsa Dev Blog #9 - Making-Off Weapons and Projectile Physics

In this article I discuss the technical details of how I created the weapons of my game, and how I did the physics simulations for the projectiles using Unreal Script.

Posted by on


Whenever you think First Person Shooter, or Third Person Shooter games, what is the first thing that comes to your mind? Badass Killer Weapons, right?

For a long time, shooter games tried to simulate real world warfare, but some games may multiply the reality by some craziness, which makes the gameplay experience fun, even though it is not very realistic.

In the end, I think that the most important thing for a weapon on a shooter game is to make the player feels a Bad Ass Super Hero killing all the bad guys :)

Thinking on this, I began to create the weapons for my game. But as my game is about the real war between Palestine x Israel, I tried to make these guns as most realistic as I could, and I opted to recreate real guns used by Israel Army and Palestine Resistance.

As everybody knows, and people keep asking me. No, I did not model the weapons myself, I did purchase model packs, but did make some slight changes on these weapons models, adding some details here, and there, changing textures, and so on. If I would model all the assets I am using on my game, being a solo dev, it would take for me 100 years to finish developing this game :D :D :D

I plan to have thousands of weapons in my game, however, as I will be releasing (and developing) this game into chunks (episodes), each episode will come with different weapons, character skins, maps and game modes.

For this Episode 0, which will be releasing in March 2020, these are the weapons which will be available:

Which are (in order): Combat Knife, Desert Eagle with Silencer, Makarov Pistol, AK-47 Rifle, M4A1 Rifle and RPG7 Bazooka.

Also being an old gamer (36yr), and a poor gamer :D :D :D which don't have money to purchase new games, neither purchase a PC capable of running these new games, I need to stick playing my old and retro N64 games for taking inspirations.

Being a Nintendo 64 Fanboy, I still play and love Goldeneye007 and Perfect Dark, which in my opinion, they are simply the best shooters of all times.

So I did play these on my old Project64 Emulator to try to dissect what makes the gunplay on these games so pleasant and fun.

After a while, I realized that what makes the gunplay so fun on these games are 3 points:

1- The feeling of power the gun has while shooting;
2- The reloading animations;
3- The hit reaction animations it triggers on the enemy characters;

Taking these 3 points into observation, I began to program (in Visual Studio 2008 with Nfringe plugin for Unreal Script) my weapons. I am proud because the programming I did all by myself.

The default UTWeapon class, the base code for weapons which comes outside the box with Unreal Engine 3 / UDK, is just a very basic system, which does not contain any reload system, just a basic bullet (ammo) count.

So the first step was to create a good reload system (a simple one) for each weapon, because each weapon has it's own reload animation time and other specific properties.

Here is just a small part of the reload code (it's big):

class WeaponReloadM4 extends UTWeapon;

//these variables are for handle the ammo quantity in the magazine
var int MaxMagAmmo, TransferAmmo;
var bool bIsReloading;

//these are the custom class functions that will overwrite the original functions/////////
//function consumeAmmo//////////////////////////////////////////
function ConsumeAmmo( byte FireModeNum )
{
	// Subtract the Ammo
	//reload system mod
	AddAmmoDefault(-ShotCost[FireModeNum]);
}
//function consumeAmmo//////////////////////////////////////////

//original add ammo function/////////////////////////////
function int AddAmmoDefault( int Amount )
{   
    //default add ammo count
	AmmoCount = Clamp(AmmoCount + Amount,0,MaxAmmoCount);
	
	// check for infinite ammo
	if (AmmoCount <= 0 && (UTInventoryManager(InvManager) == None || UTInventoryManager(InvManager).bInfiniteAmmo))
	{
		AmmoCount = MaxAmmoCount;
	}

	return AmmoCount;
}
//original add ammo function/////////////////////////////

//add ammototal function for reloading system////////////////////
function int AddAmmo( int Amount )
{
    //custom reload add ammo count
	AmmoTotal = Clamp(AmmoTotal + Amount,0,MaxAmmoTotalCount);
	
	// check for infinite ammo
	if (AmmoTotal <= 0 && (UTInventoryManager(InvManager) == None || UTInventoryManager(InvManager).bInfiniteAmmo))
	{
		AmmoTotal = MaxAmmoTotalCount;
	}	
	
	//custom reload variable
	return AmmoTotal;
}
//add ammototal function for reloading system////////////////////

//reload function to play reload animation///////////////////////
exec function Reload() {
  
  //this statement will prevent weapon reloading when ammo is full
  if (AmmoTotal > 0 && !bIsReloading && AmmoCount < MaxAmmoCount) {
    ForceEndFire();
    bIsReloading = true;
        
        //this will play the custom reload animation only on the half top body
		UTPawn(Owner).TopHalfAnimSlot.SetActorAnimEndNotification(true);
		
		                                          //AnimName, Rate, BlendInTime, BlendOutTime     
        UTPawn(Owner).TopHalfAnimSlot.PlayCustomAnim('reload_rifle_M4_UT3', 1.0, 0.5, 0.35);
		
		//this will call the function to play reload animation on the UTAttachment Mesh
        //UTPawn(Owner).AK47ReloadAnim();

		//this will set a timer to unload magazine in rifle
		setTimer(0.15, false, 'UnLoadMagazine'); 
		//this will set a timer to load magazine in rifle
		setTimer(0.85, false, 'LoadMagazine');
		
    WeaponPlaySound(WeaponReloadSnd);
	
    //this will play the allah_akbar sound
	PlaySound(SoundCue'dhikr.allah_akbar_1_Cue', false, true, true, vect(0,0,0), false); 	
	
	//this timer will be triggered after the duration of the reload animation which is 1.16 seconds
	setTimer(2.30, false, 'AddAmmoToMag');
  }
  
}
//reload function to play reload animation///////////////////////

I can't give an Unreal Script Tutorial (maybe later on), however I like to people see this stuff I am creating, because Unreal Script is very intuitive, and whenever I program, I like to write on my code small observations and comments, so I myself can remember and understand why I have done so and so. Imagine seeing a code you created 5 years ago? If there are no comments, you may forget how the code works (at least my memory is not that good neither strong :D :D :D)

So after the reload class, I needed to create another class for each weapon, however, on Unreal Engine 3, a weapon is composed of many classes, like the Weapon Class itself, the Projectile Class, the Damage Class and the Third Person Attachment Class.

There are basically two kind of weapons on Unreal Engine 3 (UDK Engine): Instant Hit Weapon and Projectile Weapon.

The marjority of games done in UDK, which use guns, they use the Instant Hit Weapon. However, I thought to my self: Why not make all my game's weapons projectile weapons? This way they will look more realistic.

I just needed to create a simple particle effect to represent the bullet trace (and to be used as the projectile which is shot from the weapon). I think there is a specific code on Unreal Engine 3 for bullet traces, however, I prefeer to MISS (Make It Simply Stupid) :D

By searching on default UDK Particle effects, I found the rocket launcher projectile. I duplicated it (to keep the original intact), then began to mess with the particle effect, removing some emitter here, and there, untill I stayed with the base light trace. Then I just changed the colours to a reddish yellow, and voila! Here I got my weapon trace effect:

Now I just had to play with the weapons properties, like these ones:

//The maximum amount of ammo the magazine clip can hold
MaxMagAmmo=50

//The current ammo count
AmmoCount=10

//The initial ammo count for this weapon if picked up from a weapon locker
LockerAmmoCount=10

//The maximum amount of ammo this weapon can hold
MaxAmmoCount=50

//We need to set an initial value for the reload function work and it must be the double of max ammo (it is extra ammo)
AmmoTotal=100
MaxAmmoTotalCount=200

CustomWeapName="RIFLE M4A1"
InventoryGroup=5

	//visual properties///////////////////////////////
    PlayerViewOffset=(X=-1.0,Y=0.0,Z=3.0)
	//x -> distance from camera
	//y -> horizontal position
	//z -> vertical position

    Begin Object class=AnimNodeSequence Name=MeshSequenceA
        bCauseActorAnimEnd=true
    End Object

    Begin Object Name=FirstPersonMesh
        SkeletalMesh=SkeletalMesh'M4.Mesh.M4'
        FOV=60
        //Animations=MeshSequenceA
        //AnimSets(0)=AnimSet'M4.Animations.M4_anims'
        bForceUpdateAttachmentsInTick=True
        Scale=0.7000000
    End Object

    Begin Object Name=PickupMesh
        SkeletalMesh=SkeletalMesh'M4.Mesh.M4'
        Scale=0.9000000
    End Object
	
	//ArmsAnimSet=AnimSet'WP_GOW.Anims.RA_ARMS'
	
	PivotTranslation=(Y=0.0)
	
	//this controls the projectile spawn position
	FireOffset=(X=-30,Y=15,Z=0)
	//x -> distance from camera
	//y -> horizontal position (negative value moves to left)
	//z -> vertical position	
	
	//visual properties///////////////////////////////
    
	//weapons in udk ultimate are ballistic, i.e, they trully shoot real bullets, projectiles which are controlled by physics properties
	//here the properties of the bullet are controlled by the class UTProj_Enforcer
    WeaponFireTypes(0)=EWFT_Projectile
    WeaponProjectiles(0)=class'UTProj_M4'
   
	//sounds
    WeaponEquipSnd=SoundCue'M4.Sounds.m4_draw_Cue'
    WeaponFireSnd(0)=SoundCue'M4.Sounds.m4_fire_Cue'
	WeaponReloadSnd=SoundCue'M4.Sounds.m4_reload_Cue'
    PickupSound=SoundCue'health_pack.Sounds.itempickup_Cue'

    //muzzleflash for 1st person model
	MuzzleFlashSocket=MuzzleFlashSocket
    MuzzleFlashPSCTemplate=ParticleSystem'WP_Enforcers.Effects.P_WP_Enforcers_MuzzleFlash_fix'
	
	//animations
	WeaponFireAnim(0)=WeaponFire
	WeaponFireAnim(1)=WeaponFire
	//WeaponPutDownAnim=WeaponPutDown
	//WeaponEquipAnim=WeaponEquip
	//WeaponIdleAnims(0)=WeaponIdle	

	//ammo fire speed functions///////////////////////////////
	FireInterval(0)=0.15
    FireInterval(1)=0.15
	//ammo fire speed functions///////////////////////////////
    
	//weapon icon for Canvas HUD Multiplayer
	//IconX=412
	//IconY=82
	//IconWidth=40
	//IconHeight=36

    //CrosshairImage for rifles
    CrossHairCoordinates=(U=320,V=0,UL=64,VL=64)

    //
    Mesh=FirstPersonMesh
    DroppedPickupMesh=PickupMesh
    PickupFactoryMesh=PickupMesh
    AttachmentClass=Class'UTAttachment_AIM4'
	
//custom zoom properties to simulate iron sights effect	
bZoomedFireMode(0)=0
bZoomedFireMode(1)=1

ZoomedTargetFOV=20.0
ZoomedRate=9000
//custom zoom properties to simulate iron sights effect	

Then also I had to play with the projectile properties and values:

class UTProj_M4 extends UTProjectile;

simulated function PostBeginPlay()
{
    // force ambient sound if not vehicle game mode
    bImportantAmbientSound = !WorldInfo.bDropDetail;
    Super.PostBeginPlay();
}

defaultproperties
{
    //this is the visual representation of the bullet, which is a particle system based on the rocket launcher
	//I just changed the mesh by a bullet mesh (case) and the trail effect to simulate a bullet tracer
    ProjFlightTemplate=ParticleSystem'WP_Enforcers.Effects.Bullet_fix'
	
    ProjExplosionTemplate=ParticleSystem'WP_Enforcers.Effects.P_WP_Enforcer_Impact'
    ExplosionDecal=MaterialInstanceConstant'WP_Enforcers.Decals.MI_WP_Enforcer_Impact_Decal01'
	ExplosionSound=SoundCue'M4.Sounds.m4_bullet_Cue'
	AmbientSound=SoundCue'M4.Sounds.m4_travel_Cue'

    DecalWidth=12.0
    DecalHeight=12.0
    Speed=6000.0
    MaxSpeed=0
    Damage=40.0
	MomentumTransfer=1250
    MyDamageType=class'UTDmgType_M4'
    LifeSpan=8.0
    RotationRate=(Roll=50000)
    bCollideWorld=true
    CheckRadius=42.0
    bCheckProjectileLight=true
    bWaitForEffects=true
    bAttachExplosionToVehicles=false

}

I will never be able to create a realistic ballistic physical simulation for my game, as it is hautingly hard for just one person (I consider myself a noob in programming yet). I just tweaked these values based on real life guns properties, not exact values, just an aproximation and comparison between guns (I have been reading some cool guns reviews on the web).

In example, in real life, the M4A1 Rifle's Projectile has bigger acceleration and causes more damage than the AK-47. So I did this on the projectiles properties, I made the speed and damage of the M4A1 projectile bigger than AK-47's.

The same for Makarov Pistol and Silencer Desert Eagle (which is the most devastating pistol available).

At the very least these properties are based on real guns properties and not random values from my mind.

Other detail to make my gun feel bad ass is the fire sound. The original sound which came with the weapons I purchased was not realistic. Because of that I decided to use real gun sounds from Youtube Videos, especially those who instruct how guns work. I edited the gun sounds in Adobe Audition, removed some noises here and there, until I got the final fire sound for the weapons.

Also other sounds, small sounds which make a big difference are the bullet impact sound and the projectile travel sound (that whoosh effect the projectile makes while transversing the air).

As for the Hit Reaction animations, I already showed on previous videos, however, I am creating many more hit reactions to give my game some kinda variation (avoid being repetitive).

I hope that you all enjoyed reading this new devblog, and untill next update.

Cheers!

Post a comment

Your comment will be anonymous unless you join the community. Or sign in with your social account: