Handle Faction Defeat Conditions
1. Default Defeat Condition Options
By default the RTS Engine offers two options for when a faction slot is considered defeated. The defeat condition can be set through a field in the Game Manager component's inspector.
Eliminate All: A faction is defeated when all of its unit and building entities are destroyed.
Eliminate Main: A faction is defeated when all of its main unit and building entities are destroyed.
A main faction entity (unit or building) has the field Is Main Entity in its Building or Unit component (on the Faction Entity tab) enabled. You can have this field enabled on faction entity prefabs or the initial pre-placed entity instances in a map.
Both the singleplayer and multiplayer lobbies allow to choose the defeat condition for a game before starting it, which would overwrite the Defeat Condition chosen through the map scene's Game Manager component. Check the corresponding manual guides for more information on that.
2. Create Custom Defeat Condition
When the Defeat Condition field in the Game Manager component is set to Custom, then you will be responsible for triggering the defeat condition through logic in your own separate components. Go ahead and set the Defeat Condition condition to custom and let's start.
In this guide, we will create a defeat condition that renders the local player's faction slot defeated after a certain time from the game start. The handling of the custom defeat condition will be through a custom game service. To learn more about creating custom game services, please refer to this guide.
Start with creating a new C# component and class. Let's call it CustomDefeatConditionHandler for example. Attach the component to one of the children objects of the Game Manager object.
Below is the logic used in that component that triggers the local faction slot to be defeated after X seconds (can be set through the inspector through the timeTillDefeat field).
using UnityEngine;
using RTSEngine.Event;
using RTSEngine.Game;
public class CustomDefeatConditionHandler : MonoBehaviour, IPostRunGameService
{
[SerializeField]
private float timeTillDefeat = 3.0f;
protected IGameManager gameMgr { private set; get; }
protected IGlobalEventPublisher globalEvent { private set; get; }
public void Init(IGameManager gameMgr)
{
this.gameMgr = gameMgr;
this.globalEvent = gameMgr.GetService<IGlobalEventPublisher>();
}
private void Update()
{
if (timeTillDefeat > 0.0f)
{
timeTillDefeat -= Time.deltaTime;
if(timeTillDefeat <= 0.0f)
TriggerDefeatCondition();
}
}
private void TriggerDefeatCondition()
{
globalEvent.RaiseFactionSlotDefeatConditionTriggeredGlobal(
gameMgr.LocalFactionSlot,
new DefeatConditionEventArgs(DefeatConditionType.custom));
}
}
The class here implements the IPostRunGameService interface that provides the OnInit() method. The latter provides a reference to the IGameManager which we can use to fetch other game services.
The game service we want to fetch here is the IGlobalEventPublisher that includes the RaiseFactionSlotDefeatConditionTriggeredGlobal method that allows us to raise a defeat condition. As parameters, it takes:
- A IFactionSlot instance (event source): This is the slot that will defeated. We fetch the local player's faction slot through the LocalFactionSlot property.
- Event arguments: This is where we specifically set the DefeatConditionType to custom. The defeat condition type raised in the event here must match with the one assigned in the Game Manager component for the defeat condition to take effect.
The rest of the logic in Update() is simply a timer that runs until it triggers the custom defeat condition.