In this post I will focus on shooting and reloading functionalities. Goals that I want to achieve:
- I want to have easy method for shooting with different weapons,
- If my weapon doesn’t have ammo it should reload automatically,
- I can reload my weapon whenever I want,
- I won’t be able to shoot if I’m changing weapon,
In this post weapon won’t fire any projectile yet but you will learn more about blueprint communication, creating animations in blueprints and doing recoil directly in animation blueprint.
<strong>This Tutorial has been created using Unreal Engine 4.8.2</strong>.
Make sure you are working on the same version of the engine.
Adding base variables to BaseWeapon. Basically BaseWeapon should have variables / functionalities that all weapons can share. Open BP_BaseWeapon and add those variables:
- CurrentAmmoInMag (int) It will tell us how much ammo we have in magazine,
- MaxAmmoInMag (int, default 6) How much ammo we can load to magazine,
- CurrentAmmoInBackpack (int) How much ammo do we have currently in backpack,
- MaxAmmoInBackpack (int, default 30) How much ammo we can have in backpack,
- RealoadTime (float, default 2) It will tell us how much time is needed to reload the weapon,
- WeaponType (ENUM WeaponType) It will tell us which type this weapon is. In this post we will use this information for recoil but it should be useful later as well,
Now let’s create functions that all weapons can use:
- Fire Basically all weapons will have ammo so let’s decrease ammo here,
- Reload All weapons need to have reload functionality. We will check how many ammo do we have in CurrentAmmoInMag and set CurrentAmmoInMag according to the MIN value. MIN will return MaxAmmoInMag if CurrentAmmoInBackpack >= MaxAmmoInMag. If CurrentAmmoInBackpack will be 3 or 4 or 1 it will Set those values to CurrentAmmoInMag. So we won’t be reloading full mag if we don’t have enough ammo in backpack.
- HaveAmmoInMag – outputs HaveAmmo (bool) and MagIsFull (bool) it can be pure function,
- HaveAmmoInBackpack – outputs HaveAmmo (bool)
That’s all in BaseWeapon.
BP_Weapon_Pistol We will be working on Pistol weapon in this post. You can overwrite MaxAmmoInMag and MaxAmmoInBackpack for this weapon if you like. I will leave it as it is. Now we need to call parent class Fire and Reload functions. To do so:
- Right click on your event graph,
- Find Event Fire and add it,
- Compile your blueprint,
- Left click on Event Fire,
- Chose “Add Call To Parent Function”
- Connect Event Fire with Parent: Fire
Basically Parent: Fire will execute everything that is in BP_BaseWeapon. We won’t be using additional functionality for Fire in Pistol but I wanted to show you how to call parent functions. Thou we can play reload animation in Reload function. Please find Event Reload and add it to the Pistol event graph like here: PlayAnimation will play already existing animation from Military Weapon Silver package. It contains muzzle flash FX and sounds as well! They are pinned to animation using AnimNotifies. That’s all here. Now the biggest part in GameplayCharacter!
GameplayCharacter It will be responsible for managing reloading and animations. Basically we don’t have any hands reload animations that will fit to our weapons so we are doing here lot’s of “hard coding” blueprint animations connected to Animation Blueprint. But it’s working and will work for all of the weapons. Open GameplayCharacter and add this variable:
- CanFire (bool),
- OnCharacterFireWeapon and it will take input WeaponType named WeaponType,
Now Custom Events:
- Reload. I’ve added comments to help you guys to understand this,
- Left Mouse Button and R button inputs,
That’s almost all but at this point equipping weapon will be broken because we will be able to start reloading while equipping different weapon and we will see animation glitches when equipping different weapon during reloading. To fix that we need to update EquipWeapon event. I’ve selected added nodes.
In earlier post we EquipWeapon event had branch for isReloading but nothing goes to TRUE. Added blocks are connected to True. Everything else stays the same. Basically what this is doing its checking if hands are still up. If yes – move them down but do this with FInterpt because we don’t know if the value will be 0.5 or 0.1 or 0.9 or 1. If hands are down we can change weapon normaly. Thanks to that you will have seamless changing weapon animation during reload! PullWeaponDown timeline is used as a Tick. It is 5 sec length to make sure that FInterpt will be able to reach Target 1.
USEFUL TIP: You can use timelines as spawning Ticks for your game. They will Tick only when they are active.
Now functionality is here but we don’t have any recoil animation. Let’s do that.
Creating custom recoil. Basically recoil should be done using hands animations but we don’t have any. That’s why we will create custom recoil using Animation Blueprint! Open HeroFPP_AnimationBlueprint and add these variables:
- PistolRecol (bool),
- DeltaT (float),
- CurrentRecoilTime (float),
Now in Event Graph let’s update Update Animation event:
What this is doing its waiting for PistolRecoil will be true. If yes it’s adding DeltaTime to CurrentRecoilTime and if it’s taking 0.2 seconds we are disabling recoil (PistolRecoil) and resetting CurrentRecoilTime to 0 so we can use it again. Now create new event Blueprint Initialize Animation – it’ something like Begin Play in other actors. We will use this to connect to CharacterFireWeapon dispatcher we created in GameplayCharacter.
Every time this Dispatcher will fire (so player will fire) we will set PistolRecoil to true. Now we need to drive PistolRecoil bool in AnimationGraph.
In earlier post you have learnt how to use Transform (Modify) Bone nodes. You can use them for recoil here. I won’t be posting screenshots of my Transform Bones nodes details. Try to create them by yourself. You will learn a lot! The most important part here is Blend Posses by bool. If PistolRecoil is true then we are doing modifications to animation if not – we are in PistolPose without any modifications.
That’s it! You can test it out using left mouse button and R keyboard input.
Implementing game is taking time but writing about this is taking much more effort!