This page describes the mechanics behind the Corgi Engine's weapons, and how to create and use your own weapons.

Introduction

The Corgi Engine includes a generic weapon system, allowing your characters to equip a weapon (projectile based, melee, or whatever you can think of), switch to another one, and use it. The engine also includes a few examples of weapons you can have a look at, and that you can use as a basis when creating your own.

The CharacterHandleWeapon Ability

To be able to equip and use a weapon, a Character must have a CharacterHandleWeapon component. From its inspector you’ll be able to optionally select a weapon for your character to start with, define if it can pickup new ones, and specify a Weapon Attachment. This is a transform on your character (or nested inside its prefab) for the weapon to attach to. If you don’t specify one, the weapon will attach to the root level of your prefab.

What the CharacterHandleWeapon component will then do is check for changes on the weapon use button, and if it gets pressed/released, transfer that information to the weapon currently equipped.

The Weapon classes

All weapons in the Corgi Engine derive from the Weapon class. You can of course divert from that, but that’s how all the examples work. The Weapon class is meant to be extended and will define a lot of things common to all or most weapons. Using it as a basis you’ll be able to create everything, from a shotgun to a rocket launcher, but also a katana or a grappling gun. In addition to providing a solid basis for animations, sounds, state management, it allows you to define in your child class what happens when the weapon is used, and build from there. You can look at the ProjectileWeapon and MeleeWeapon classes for examples of how you can create very different weapons from this very same script.

Creating a weapon

To create your own weapon, you can either reuse the ProjectileWeapon or MeleeWeapon scripts as they are, extend them, or create your own Weapon child class. In any case, you’ll then need to create a weapon prefab. To do so, you’ll need a gameobject. Basically you’ll have the choice to have a visible weapon or an invisible one. For example if you look at the BlueRobot enemies, they do have a weapon, but you don’t see it, it’s just an empty gameobject spawning effects and projectiles. The MinimalRocketLauncher on the other hand is visible, and even includes tiny (very minimal) hands. That way when it rotates as the player aims, the weapon is always facing the right direction. So decide on that depending on the kind of visual result you’re looking for.

Once you have your sprite, or model, or empty game object, just add your weapon (ProjectileWeapon, MeleeWeapon, or your own) script to it. From its inspector you’ll be able to setup animations, sounds, effects to trigger when firing, and specify how the weapon should flip when the character flips.

Here’s a step by step creation of a Melee Weapon for reference :

  • create an empty gameobject
  • add a MeleeWeapon component to it
Jekyll
Our empty game object with the MeleeWeapon component
  • in the MeleeWeapon inspector, set the following parameters : Trigger Mode to Semi auto, Damage Area Shape to Rectangle, Area Size to {1,1}, Area Offset to {2,0} (so that the damage area will activate in front of our character), Active Duration to 0.2 (it’s a short attack, a punch basically). Then set the Damage Caused Target Layer mask to Platforms and Enemies, and 10 damage.
  • rename this gameobject to MeleeAttackWeapon (or whatever you prefer)
  • drag this gameobject into your hierarchy to make a prefab out of it
  • select your character, and drag that newly created prefab into its InitialWeapon slot (or you can use the ChangeWeapon method via script to equip it)
Jekyll
Binding the weapon to our character
  • that’s it, you now have a working weapon. Press play, then E (by default), and you’ll be throwing punches around and damaging enemies/objects. But so far you’re probably not seeing anything when attacking. Let’s bind an animation to that attack.
  • select your character’s animator, drag your attack animation into it if it’s not already the case.
  • create a new animation parameter (the little + button at the top right corner of the Parameters panel), in our example we’ll call it “RectangleMeleeAttackStart”
Jekyll
Adding a new animation parameter
  • create a transition to that animation. You’ll probably want it to have the following settings (at least the fixed duration), but feel free to adjust to fit your particular animation.
Jekyll
Adding a new transition to our attack animation
  • go back to your weapon’s inspector, and fill the StartAnimation field with the name of your animation parameter. In our example “RectangleMeleeAttackStart”.
Jekyll
Binding our new animation parameter to our weapon
  • press play again, attack with your weapon, you now see your character attacking. You can add other animations, for when the attack is in progress, ending, etc.

Projectile Weapons

Projectile weapons will require an Object Pooler component attached to them. You’ll need to add either a SimpleObjectPooler, or a MultipleObjectPooler to your weapon, it won’t shoot anything otherwise. Object poolers are a way to recycle projectiles as they’re fired, that way you don’t instantiate/destroy objects as you go, which is much better for your game’s performance. Simple object poolers will allow you to shoot one type of projectile only (which is just fine for most weapons), but if you want to get fancy and have it shoot different type of stuff, go for a MultipleObjectPooler. In your object pooler’s inspector, drag the object you want to shoot in the GameObjectToPool field, define the pool size (the amount of items the game will store and reuse, how much that is really depends on your game, the level’s size, etc. Basically the idea is that you want your pool to never be used entirely, but not be too large either). Finally you can decide whether the pool can expand to accomodate for edge cases where all the pool’s been used but not recycled yet.

Projectiles

Projectile Weapons usually shoot projectiles (I know). The engine comes with two ready to use classes for that. The aptly named Projectile class will handle most common uses, from bullets to rockets. It’ll allow you to create projectiles that move in one direction (affected or not by the direction of the weapon), at a certain speed and acceleration. The MinimalMachineGunBullet prefab is a good example of it.

The other class you can use is the Thrown Object class. Useful for grenades, knives, or anything you want gravity to affect. To these, the weapon will apply an initial force and let gravity handle the rest.

To most projectiles you’ll want to add a DamageOnTouch component, so they hurt their target, and potentially a Health component if you want them to be destroyable before they hit.

Timing

Timing is essential when creating weapons, as you’ll want to sync your weapon’s component to its animation perfectly. All weapons come with two variables you can tweak directly from the inspector : DelayBeforeUse (the time between the input registration and the actual WeaponUse - the shot, axe sling, etc), and TimeBetweenUses (the time that needs to pass before you can have another WeaponUse (whether it’s in auto, or via repeated presses, etc). The weapon just won’t “shoot” during that time).

Additionally, the melee weapons have two more variables you can play with : InitialDelay (the delay between the WeaponUse and the activation of the damage area) and ActiveDuration (the time during which the damage area will stay active). These 2 last parameters are very specific to damage areas, and of course you’ll want to sync these values with your DelayBeforeUse / TimeBetweenUses to prevent conflicts.

Weapon Laser Sight

Jekyll
The lasersight component in action

You can add a WeaponLaserSight to your weapon. It’s of course more suited for a projectile weapon but there are no restrictions. What it’ll do is that it’ll cast a laser in front of the weapon, like a laser sight would. You can set a collision mask so that the laser stops when meeting a wall or platform. From the inspector you can also customize the appearance of the laser.

Weapon Aim

Adding a WeaponAim component to your weapon will allow you to control its orientation, allowing your character to shoot up, down, etc. From its inspector you’ll be able to define its control mode :

  • Off : no weapon aim
  • PrimaryMovement : the weapon will aim in whatever direction you’re moving your movement stick/keys to.
  • SecondaryMovement : the weapon will aim in the direction you point your secondary movement input to. That’s the right stick on an xbox pad by default, for example.
  • Mouse : the weapon will point in the direction of the mouse pointer

You can also define the Rotation Mode :

  • Free : full 360° rotation
  • Strict 4 directions : up, down, left, right
  • Strict 8 directions : up, down, left, right, and the diagonals (up left, down right, etc)

Finally you can define a maximum and minimum angle to constrain movement to allow only up shots for example, or prevent the character to shoot in its back.

The WeaponAim component also allows you to display a Reticle on screen for your weapon. You’ll need to specify a gameobject prefab for it (there’s one included in the asset, called TheHuntReticle, but you can use your own of course). You can set the distance from the character the reticle should be at, or if it should follow the mouse, if it should rotate as you aim your weapon, and whether or not the mouse pointer should be hidden.

Ammo

With the introduction of the InventoryEngine in v4.0, the engine now supports ammo and the possibility to create ammo based weapons. There are two types of ammo based weapons you can create : inventory based, and regular ones.

Inventory based weapons will require your character to have an Inventory attached to it (via the CharacterInventory ability), while regular ammo based weapons will just consume infinite ammo, but both will allow you to define a magazine size, reload or not, etc.

All these settings can be set on the weapon’s inspector. There you’ll be able to define the magazine size, whether the weapon auto reloads when the magazine is empty, or if the player needs to press the reload key, how long the reload should take (in seconds), as well as how much of that ammo each shot consumes.

Checking the “Magazine based” checkbox will tell the weapon that it should take its ammo from the character’s inventory. To do so, you’ll also need another component on your weapon, WeaponAmmo. There you’ll be able to specify the name of the ammo the system should look for in the inventory (“Bullets” for example), what the inventory’s name is (usually MainInventory but you can pick any name you prefer as long as it’s set that way on your inventory), the maximum ammo the weapon’s ammo indicator should go for, and whether or not the weapon should load itself with ammo from the inventory when equipped.

Weapons and Inventory

If your character is using an inventory, the Player can now switch weapons (cycling through all the weapons available in the inventory) using an input shortcut. By default this is bound to LB on an xbox pad, or t on a keyboard.

Additionally, if your character has a Weapon Inventory, and if that inventory contains a weapon when starting a level, this weapon will be automatically equipped.

Weapons IK

From the Weapon’s inspector you can define left and right hand attachments to use with Unity’s built-in animation IK system. This will attach the hands of your character to specific points of your weapon, detach them when you unequip the weapon, and allow your character to move and aim naturally as you move your weapon. The Soldiers demo characters in TheHunt are all setup like that if you want a ready to use example.

Weapon examples

The engine comes with a bunch of demo weapons you can build on (or reuse if you like them). Most of them are available as regular weapons and as inventory based ones.

  • Machine Gun : shoots bullets in automatic mode
  • Shotgun : shoots three bullets in semi automatic mode, and you’ll need to reload it after 2 shots
  • Melee Attack : an example of a sword/melee attack
  • Rocket Launcher : shoots a slow(ish) rocket
  • Grenade Launcher : shoots grenades that bounce on walls and stuff and explode after a while

Ammo Display

AmmoDisplay is a component you can add to a GUI rect to have it display a progress bar and text showing how much ammo you’ve got left in your magazine and inventory. Just add it to an empty GUI object, and in its inspector you’ll need to bind it to a ForegroundBar and a Text object, and specify for what player you want to display that info (usually Player1).