Skip to content

Machine Gun

Creating Machine Gun class

We want to provide several weapons to the player to make clearing waves of enemies easier and on top of that we also want to arouse excitement when a new weapon drops from a defeated enemy which will help you clear a level.

This time we’re gonna create a machine gun to let our player rapid fire at enemies, which will hopefully result in obtaining more score points.

We begin with creating a new C# script which we’ll call MachineGun and connect it to the Projectile class. In here we specify that this machinegun can deal damage with the IDamageable interface.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MachineGun : Projectile
{
   public float damage; 

    protected override void Hit(IDamageable damageable)
    {
        damageable.Damage(damage);
        base.Hit(damageable);
    }
}

Next, we create another class called MachineGunFactory which will create our bullets. As shown underneath here, we use override to provide a new implementation of a method inherited from a base class. In this case IWeaponUser. We can adjust things such as size,rotation, forward speed etc. However, variables as lifetime and ammo will be changed in the player script.

public class MachineGunFactory : ProjectileFactory
{
    public float damage; 
    public float speed; 
    public LayerMask hitMask;
    public float lifetime; 
    public int ammo;

    public override Projectile CreateProjectile(IWeaponUser user)
    {
        GameObject bulletObj = new("Projectile MachineGun");
        bulletObj.transform.position = user.Position;

        Rectangle rectangle = new("Projectile rectangle");

        Transform rectangleTransform = rectangle.GameObject.transform;
        rectangleTransform.parent = bulletObj.transform;
        rectangleTransform.localPosition = Vector3.zero;
        rectangleTransform.localScale = Vector3.one * 0.1f;
        rectangleTransform.Rotate(Vector3.forward, 45f);
        rectangle.CreateCollider(bulletObj, true);

        Vector2 aimDirection = user.AimDirection; 

        MachineGun bullet = bulletObj.AddComponent<MachineGun>();
        bulletObj.AddComponent<Rigidbody2D>().velocity = aimDirection * speed;
        bullet.transform.up = aimDirection;
        bullet.damage = damage;
        bullet.hitMask = hitMask;
        bullet.lifetime = lifetime;

        return bullet;
    }
}

Input Bindings changes

Now that we’ve created our new Machine Gun, we want to acually shoot with it as well. Within our player’s inputBindings we navigate to the public KeyCode, which is used to let the player shoot. In here we create a new variable to let the computer know we want a secondary- or even a third shooting function in order to fire our bullets and ofcourse specify with which key this can be activated.

        shoot = KeyCode.Mouse0;
        shootSecondary = KeyCode.Mouse1;
        // temporary third shooting function (shoot by pressing mousewheel)
        shootThird = KeyCode.Mouse2;

public KeyCode shoot, shootSecondary, shootThird;

Creating third Shooting Method

Now that we’ve specified a second and third shooting variable we can acces these in the player script. Under player._bindings we specify our MachineGunFactory and create a new thirdFactory from it to setup our weapon projectiles specifics. We set this thirdFactory equal to new() since we want a new bullet created everytime we want to shoot. In these curly brackets we can specify the components of our bullets such as the speed, damage, hitmask & lifetime. Next, we want to be able to shoot with this third Factory/third Weapon. In order to do this we must let the player script know we want a secondary/third shooting option and with which key this shooting can be activated.

Note: Make sure to read through AmmoWeapon first! (to understand why AmmoWeapon is created)

 player._bindings = new InputBindings();

        BulletFactory mainFactory = new()
        {
            damage = 1f,
            speed = 20f,
            hitMask = IWeaponUser.EnemyMask,
            lifetime = 10f
        };
        player._weapon = new BasicWeapon(mainFactory, 0.2f);

        // Canon Weapon   
        // CanonFactory secondaryFactory = new()
        // {
        //     damage = 5f,
        //     speed = 15f,
        //     hitMask = IWeaponUser.EnemyMask,
        //     lifetime = 5f,
        //
        // };
        // player._secondaryWeapon = new AmmoWeapon(secondaryFactory, 0.5f, 20);

        // Machine Gun weapon
        MachineGunFactory thirdFactory = new()
        {
            damage = 1f,
            speed = 20f,
            hitMask = IWeaponUser.EnemyMask,
            lifetime = 3f,   
        };
        player._thirdWeapon = new AmmoWeapon(thirdFactory, 0.1f, 50);

        return player;
    }

As shown underneath within the private void Update() function we create a new input by using an if-statement to check whether our second or third shooting method is triggered (methods created under Input Bindings Changes) Next, within the curly brackets we want to try to fire. We do this with _thirdWeapon.TryFire(this);.

    private Weapon _weapon, _secondaryWeapon, _thirdWeapon;

    private void Update()
    {
        _moveInput = GetMoveInput();
        _aimInput = _camera.ScreenToWorldPoint(Input.mousePosition);

        transform.up = _aimInput - (Vector2)transform.position;

        if (Input.GetKey(_bindings.shoot))
        {
            _weapon.TryFire(this);
        }

        // Second shooting method weapon (right mouse click)
        if (Input.GetKey(_bindings.shootSecondary))
        {
            _secondaryWeapon.TryFire(this);
        }

        // Third shooting method weapon (shoot with mousewheel)
        if (Input.GetKey(_bindings.shootThird))
        {
            _thirdWeapon.TryFire(this);
        }
    }

Last update: May 23, 2023