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

In the previous article, we’ve created the turn based battle manager “TurnManager.cs“. The last step is now to create a script that will be attached to an unit. This script will be in charge of starting the turn of the unit.

Unit state

One more time, i will use an enum to handle the unit state. All the explanation is in the as usual :
#region Enum

public enum eTurnUnitState
{
    INACTIVE,       //The unit is not concerned by the battle right now
    IN_BATTLE,      //Currently in the battle
    SLEEPING        //In the battle, but the timer will not affect the unit
}

#endregion

Properties

We don’t need so much properties for the TurnUnit.cs component. Let me explain the properties.
  • timeLeftUntilTurnBegin : This is the time the unit need to wait before it’s turn begins
  • originalTurnTime : This is the original time that the unit need to wait AT THE BEGINNING of the battle. Imagine the unit has a speed up power and we need to recover the original turn time, we need to store it.
  • currentTurnTime : This is the time that the unit will wait for the next turn. If the unit has a speed up power, this is that properties that will be modified.
  • state : the current state of the unit
  • turnNumber : store the turn number if needed
#region Properties

/// 
/// Time left until the unit turn begin
/// 
public float timeLeftUntilTurnBegin;

/// 
/// This is the time the unit need to act.
/// More the action time is high, less the unit will act
/// 
public float originalTurnTime;

/// 
/// current turn time
/// 
public float currentTurnTime;

/// 
/// State of the unit
/// 
public eTurnUnitState state;

/// 
/// current turn number
/// 
public int turnNumber;

#endregion

How to notify the TurnManager.cs that a turn starts or ends ? 

The TurnManager will run its timer once the Init() and Run() function are called. But we need to stop the timer when a turn starts. For this, i will use delegates and events. 

Events and delegate

Using events and delegates will make our turn battle system very powerful and usable easely with external components. (I used delegates and not UnityAction. But feel free to replace it with UnityAction if you want)

Delegate

Simple delegate with one parameter :
#region Delegates
public delegate void TurnUnitEventHandler(TurnUnit pTurnUnit)
#endregion

Events declaration

I have implemented onUnitTurnStarted and onUnitTurnEnded. You can customize it with more events if you want.
#region Events declaration<br><br>        
    public TurnUnitEventHandler onTurnStarted, onTurnEnded;
    public TurnUnitEventHandler onActionPointAdded, onActionPointConsumed;        #endregion

Trigger events

I always create functions to trigger events. Here is the unity’s implementation :
#region Events

public void OnTurnStarted()
{
    if (onTurnStarted != null)
        onTurnStarted(this);
}

public void OnTurnEnded()
{
    if (onTurnEnded != null)
        onTurnEnded(this);
}
#endregion

Initialisation of the TurnUnit.cs component

As you can see, all my scripts have an Init() function. That’s the case for this script too :

/// 
/// Use this function to initialize the unit turn
/// 
public void Init(
    float pOriginalTurnTime,
    eTurnUnitState pState
    )
{
    ////////////////////////////////////
    // properties
    originalTurnTime = pOriginalTurnTime;
    currentTurnTime = pOriginalTurnTime;
    state = pState;
    turnNumber = 1;
}

Remove time from the unit timer

To reduce the wait time before the unit turn begin, we need a function for modifying the property. There is a little subtility. We only remove time if the unit is in the battle 
/// 
/// Remove time from the unit turn
/// 
public void RemoveTurnTime(float pTime)
{
    if (state == eTurnUnitState.IN_BATTLE)
        timeLeftUntilTurnBegin -= pTime;
}

Check if the unit can start its turn

The way to know if a unit can start a turn is very simple. If the property “timeLeftUntilTurnBegin” is lower than 0, it means that the unit can start.

Start and End turns

These functions are simple too but don’t need to forget to trigger events :
/// 
/// Use this method to start the turn
/// 
public void StartTurn()
{

    //Trigger event
    OnTurnStarted();

    //Increase turn number
    turnNumber++;
}

/// 
/// Use this method to end the unit turn
/// 
public void EndTurn()
{
    //Add time for next turn
    timeLeftUntilTurnBegin += currentTurnTime;

    //Trigger event
    OnTurnEnded();
}

And that’s all ! We finally created our unit turn based component. In the next article, i will add 1 extra feature : Action Points

These feature are used on tactic game. Our turn battle system can be used on this kind of game too. So it’s interesting to implement it.

Hope you’ve appreciate this article.
Let me know if you have some trouble or if you have some question.

See you soon,
D.

Posted in J-RPG Battle system and tagged .

Leave a Reply

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