Creating a new unit Ability =============================== RTS Starter Kit contains an API for ability creation. You can make your own abilities for units with custom logic. An ability is split into two classes: - A **data** class, deriving from ``AbilityData`` (a plain ``ScriptableObject``, marked with ``CreateAssetMenu`` so you can create asset instances of it in the Project window). It only holds config fields (icon, sound, etc.) - no gameplay logic. - A **logic** class, deriving from ``Ability``, where ``TData`` is your data class. This is a plain C# class (not a ``ScriptableObject``) - it is found and instantiated automatically at runtime by the asset, matched to its data class by the generic argument, so you don't need to register it anywhere yourself. Here is the built-in **Carry Out** ability as an example: .. code-block:: csharp using InsaneSystems.RTSKit.Core; using UnityEngine; namespace InsaneSystems.RTSKit.Data.Abilities { // Built-in ability data as example [CreateAssetMenu(fileName = "CarryOut", menuName = Globals.AssetName + "/Abilities/Carry Out")] public class CarryOutData : AbilityData { } } .. code-block:: csharp namespace InsaneSystems.RTSKit.Gameplay.Abilities { // Built-in ability logic as example public sealed class CarryOutAbility : Ability { protected override void StartUseAction() { if (UnitOwner.TryGetModule(out var carryModule)) carryModule.ExitAllUnits(); } } } You have 3 methods to override on your logic class: **InitAction** - called once when the unit spawns and the ability initializes. **StartUseAction** - called when the player clicks the ability icon and it is possible to use it (ability icon active, etc.). **UpdateAction** - called every frame (from the **AbilitiesModule** of the specific unit). You can also override **CanUse()** to add a custom usage condition - it returns true by default. Don’t forget to add a custom **CreateAssetMenu** to your data class, so you can create asset instances of your ability from the Project window. If you need to pass some extra data to your ability (for example, a custom transform or a value tweaked per-instance), just add it as a field directly to your data class - since it's a regular ``ScriptableObject``, you can set it up per-instance in the Inspector, and read it from your logic class through the inherited ``data`` field: .. code-block:: csharp namespace InsaneSystems.RTSKit.Data.Abilities { [CreateAssetMenu(fileName = "SomeAbility", menuName = Globals.AssetName + "/Abilities/Some Ability")] public class SomeAbilityData : AbilityData { public Transform CustomTransform; public GameObject CustomGameObject; } } .. code-block:: csharp namespace InsaneSystems.RTSKit.Gameplay.Abilities { public sealed class SomeAbility : Ability { protected override void StartUseAction() { data.CustomTransform.position += Vector3.forward; data.CustomGameObject.SetActive(false); } } } If instead you need something that comes from the specific unit instance owning the ability (not shared config), add a regular ``MonoBehaviour`` component to the unit's prefab and fetch it through the inherited ``UnitOwner`` property: .. code-block:: csharp using UnityEngine; // Just an example component for an ability which needs additional info from the unit's GameObject. // Add this component to your unit prefab and set up your fields as you need. public class AbilityAdditionalSettings : MonoBehaviour { public Transform CustomTransform; public GameObject CustomGameObject; } Next, in the ability, you can get this component using this code: .. code-block:: csharp namespace InsaneSystems.RTSKit.Gameplay.Abilities { public sealed class SomeAbility : Ability { AbilityAdditionalSettings additionalSettings; protected override void InitAction() { additionalSettings = UnitOwner.GetComponent(); } protected override void StartUseAction() { additionalSettings.CustomTransform.position += Vector3.forward; additionalSettings.CustomGameObject.SetActive(false); } } } It will fetch the component once from the unit owning this ability, and then you can use it in any of your ability's methods. So, you can make any abilities you want this way. .. toctree::