BULLETFISH

 

BulletFish was developed entirely using C# for Unity in 5 months.

TECH: Unity 5 | C# | WebGL | Paint.Net | Excel | Trello | Toggl

Everything other than the sounds and fonts is of my own creation.

I had to ensure my code was readable and concise as I was programming everything, including gameplay, AI, and UI.

The player controller code is a sparse 219 lines as a result.

Enemy Behaviour AI

The “spawnkill” nature of the game meant I could use a small pool of enemy behaviors to quickly put together interesting encounters.

Writing and employing a base enemy controller made quick work of implementing new enemies with thanks to the planned code reusability.

As you can see, the “Bomb Fish” AI component is only 83 lines as a result:

public class BombFish : MonoBehaviour
{
    public enum State { Enter, Attack, Exit };
    public State currentState;
    private EnemyController EC;

    public enum DropStrategy { DropOnPlayer,
                               DropOnDestination,
                               DropXCoordinate }
    public DropStrategy Drop;

The Bomb prefab, which is the payload of a BombFish, will only fall vertically. As such I use an enum to cover every conceivable strategy for the enemy to use.

Unity‘s editor provides a drop down menu with the options in the enum, hence they are named quite literally “DropOnPlayer” and so on to provide clarity. I ensured I never needed to revisit the code to know exactly what behavior to expect when designing new encounters.

    public float XTarget = 0f;

    private Bomb ourBomb;
    private Transform PlayerTransform;

    void Awake () 
    {
       EC = GetComponent<EnemyController>();
       ourBomb = GetComponentInChildren<Bomb>();
       currentState = State.Enter;

       PlayerTransform = GameObject.FindGameObjectWithTag("Player").transform;
    }
 
    void Update () 
    {
         switch (currentState)
         {
            case State.Enter:
                EnterUpdate();
                break;
            case State.Attack:
                AttackUpdate();
                break;
            case State.Exit:
                ExitUpdate();
                break;
            default:
                break;
         }
    }

    private void ExitUpdate()
    {
      // Fish keeps swimming. Additional behaviors can be added here.
    }

    private void AttackUpdate()
    {
        DropBomb();
        currentState = State.Exit;
    }

    private void EnterUpdate()
    {
        switch (Drop)
        {
             case DropStrategy.DropOnPlayer:
                 if (Mathf.Abs(PlayerTransform.position.x - transform.position.x) < .5f) { currentState = State.Attack; }
                 break;
             case DropStrategy.DropXCoordinate:
                 if (Mathf.Abs(XTarget - transform.position.x) < .5f) { currentState = State.Attack; }
                 break;
             default:
                 // Drop Destination
                 if (EC.atDestinationX && EC.atDestinationY) { currentState = State.Attack; }
                 break;
        }
    }

    private void DropBomb()
    {
         ourBomb.ActivateBomb();

         int xVector = 0;
         if (transform.localScale.x < 0)
         {
             xVector = -1; 
         } else
         {
             xVector = 1;
         }
         EC.SetMovementVector(xVector, 0);
         currentState = State.Exit;
    }
}

See my Enemy Controller AI implementation here!

BulletFishDIYWidget