Create a RPG Battle system with Unity 3D – Part 2 – TurnManager.cs

TurnManager.cs : What should it do ?

This script is a component wich will handle all the turn batlle system mechanics. To resume it clearly, it will be in charge of :
  • Time Battle Management : run when no unit is acting, stop when a turn starts et resume when a turn ends.
  • Update elapsed time for all units
  • Start unit turn if is it’s turn
At the end of the tutorial, you will be able to handle battle like this kind of game (I hope you recognized it)
Final fantasy 9 – SquareSoft – 2000

Enums

We’ll use an enum for defining the turn manager state as following : 
#region Enums
public enum eTurnManagerState
{
    NOT_INITIALIZED,    //the turn manager has not been initialized
    INITIALIZED,        //Initialized !
    RUNNING,            //Currently running, no unit is acting
    PAUSED,             //The turn manager is paused, no time is elapsing right now...
} 
#endregion

Properties 

For handling all these features, we’ll need all these properties : 
#region Properties

/// 
/// List of all units in the battle
/// 
private List unitList;

/// 
/// State of the turn manager
/// 
private eTurnManagerState state;

/// 
/// Unit to have to begun its turn
/// 
private Queue unitTurnList;

/// 
/// Elapsed time since beggining of the battle
/// 
private float elapsedTime { get; set;  }

/// 
/// Current unit acting
/// 
public TurnUnit currentUnitTurn;

#endregion

I will not define all these properties because it’s cleary named and commented.

Functions

To sum up all the needed function for the turn battle manager system :
  • Init : Initialize the component 
  • GetAllUnitInBattle : Get all game objects with a TurnUnit.cs component (will be provided in the next article)
  • UpdateUnitTime : Update Unit elapsed time
  • CheckIfUnitCanStartItsTurn : Check if a unit can start it’s turn, if yes, start the turn !
  • Run : Run the timer
  • Pause : Pause the timer
Here is the Unity’s implementation :
#region Implementation

/// 
/// Use this function to initialize the component
/// 
public void Init()
{
    ////////////////////////////////////
    // properties
    GetAllUnitInBattle();
    unitTurnList = new Queue();
    currentUnitTurn = null;

    state = eTurnManagerState.INITIALIZED;
}

/// 
/// Get All the unit in battle
/// 
private void GetAllUnitInBattle()
{
    unitList = new List();

    foreach(TurnUnit turnUnit in FindObjectsOfType())
    {
        unitList.Add(turnUnit);
        //Suscribe unit events
        turnUnit.onTurnStarted += OnUnitTurnStarted;
        turnUnit.onTurnEnded += OnUnitTurnEnded;
    }
}

/// 
/// Update Unit elapsed time
/// 
private void UpdateUnitTime(float pTime)
{
    foreach(TurnUnit turnUnit in unitList.OrderBy(unit => unit.timeLeftUntilTurnBegin))
    {
        turnUnit.RemoveTurnTime(pTime);

        if (turnUnit.CanStartTurn())
            unitTurnList.Enqueue(turnUnit);
    }
}

/// 
/// Check if a unit can start its turn, if yes, start it
/// 
public void CheckIfUnitCanStartItsTurn()
{
    if(unitTurnList.Count > 0)
    {
        currentUnitTurn = unitTurnList.Dequeue();
        currentUnitTurn.StartTurn();
    }                
}

/// 
/// Use this function to start the timer
/// 
public void Run()
{
    state = eTurnManagerState.RUNNING;
}

/// 
/// Use this function to stop the timer
/// 
public void Pause()
{
    state = eTurnManagerState.PAUSED;
}

#endregion

Events subscription

As you can see, we’ve suscribded to unit’s events on the GetAllUnitInBattle() function. In fact these event are necessary to : 
  • Pause the timer when the unit begin it’s turn.
  • Resume the timer when the unit has ended its turn
Here is the code of these two function :
#region Events Suscribed

public void OnUnitTurnStarted(TurnUnit pTurnUnit)
{
    Pause();
}

public void OnUnitTurnEnded(TurnUnit pTurnUnit)
{
    currentUnitTurn = null;
    Run();
}

#endregion

Unity callbacks

Now we have all the logic implemented, we can just run the timer in the Unity Update() built-in function as below : 
void Awake()
{
    state = eTurnManagerState.NOT_INITIALIZED;
}

void Update()
{

    CheckIfUnitCanStartItsTurn();

    if (state == eTurnManagerState.RUNNING)
    {
        this.elapsedTime += Time.deltaTime;
        UpdateUnitTime(Time.deltaTime);
    }
}
At this point, we have a turn battle system totally functionnal but no unit… Of course, it will be provided to you the in the next article.
It will be a little more complicated, but not so much. Don’t give up !
If you have some review or questions, feel free to post it !
Thanks you for reading. All feedback is appreciated.
Posted in J-RPG Battle system and tagged .

2 Comments

  1. Pingback: Create a RPG Battle system with Unity 3D – Part 3 – TurnUnit.cs – MateriaGame

  2. Pingback: Create a RPG Battle system with Unity 3D - Part 3 - TurnUnit.cs - MateriaGame

Leave a Reply

Your email address will not be published. Required fields are marked *