Adding your own logic
The core of TBE’s API is the RtUnitBhv. Please - even if the API allows it, do not directly modify any values herein.
TBE is already extensible just because of Unity’s component-based architecture.
But here we want to talk about some points where and how to best hook into TBE:
Regarding Units
Programmatically instantiate a Unit:
The following code creates a Unit PLUS gives you a place to add your post init logic.
var createdUnit = UnitManager.CreateUnitForPlayer(unitPrefab, player, position);
createdUnit.UnitReady += unit => {
Debug.Log($"Unit {unit.DisplayName} ready.");
};
CreateUnitForPlayer has an additional overload where you can (additionally) specify the UnitBase. This is the method that enables using one prefab for multiple different unit types, and thus it will override the UnitBase configured in the prefab.
|
Listening for created Units:
In order to get informed of ANY created Unit make a MonoBehaviour and add:
private void Start() {
MessageBus.Singleton.OfType<UnitInitialized>()
.Subscribe(OnUnitSpawned).AddTo(this);
}
private void OnUnitSpawned(UnitInitialized message) {
Debug.Log($"Unit: {message.Unit.DisplayName} Initialized.");
}
Adding your own logic to a runtime Unit (RtUnitBhv)
If you want to add your own component (MonoBehaviour) to one or more of your Units, and it requires the Unit to be fully initialized, you can write:
private void UnitIsInitialized() {
unit = GetComponentInParent<RtUnitBhv>();
}
The initialization logic uses Unity’s BroadcastMessage to call the UnitIsInitialized method.
Unity hint: Other than the name may imply, GetComponentInParent also searches in its own GameObject and not only in its parents. The same is true for GetComponentInChildren.
|
Add a UnitMotionMapper
Read about Motion Mappers here.
Use custom unit Actor messages
The UnitActorMsg can take a custom string. (Here: "open")
var openEvent = new UnitActorMsg(unit, UnitMsgSubType.Custom, "open");
MessageBus.Singleton.Post(openEvent);
When doing this, you can define an Actor that acts upon this message and e.g. plays a sound.
Regarding Buffs
See: CustomBuffContextCfg
Damage Response:
Extend the class RtDamageResponseImpl to create your own Damage Response. TBE has the example class SacrificeResponse which is also used in the Sacrifice Demo.
Special Enumerations
TBE has the following special Enumerations:
-
DamageKind -
UnitAttributeFlag
Changes to these enumerations
While changing these Enumerations cannot be officially supported, the system is abstract enough to handle changes to them, and also the Editor will adapt.
| If you want to change them, (e.g. if you need Fire, Water, Air, etc. damage,) you must define that at the beginning of your project and then stick to it. If you change that midway through your project, all serialized data in which they appear will be corrupt. |
Do not change these enumerations themselves as such changes would be overwritten by updates to TBE. Instead, you deactivate them in TBE and then make your own versions in your project. To this end you have to define the scripting define symbols TBE_CUSTOM_DAMAGE_KINDS and/or TBE_CUSTOM_UNIT_ATTRIBUTE_FLAGS.
Of course, the enumerations that you define must be in the same namespace as they were before.
Listening to GameMessages
This page already mentioned how you can listen for UnitInitialized messages but some more info is available on Game Messages.
Initialization Logic
Users can extend SystemManagerPlugin to get the chance to execute their initialization logic.
SystemManagerPlugin s must be added to the TbeSystemManager.
|