Cookbook 🥣

Here we describe the recipes for some common mechanics. We can see how simple it is to implement them with GASify.

Dash

Create a duration GE with a multiply modifier to MovementSpeed attribute. Hook the MovementSpeed attribute to your movementSpeed variable on the controller. Drag the GE to an ability (GA) and activate it.

public class PlayerController : MonoBehaviour {
        public AbilitySystemComponent asc;
        public AttributeName movementSpeedAttributeName;
        public float moveSpeed = 10f;

        private void Awake() {
            asc = GetComponent<AbilitySystemComponent>();
            asc.OnAttributeChanged += (attributeName, oldValue, newValue, ge) => { if (attributeName == movementSpeedAttributeName) moveSpeed = newValue; };
        }
}

Constant Health regeneration

Create a GE with infinite duration. Add a period value, and a BasicModifier that targets Health. Set it to Add and put a value. Attach it to a passive ability the ASC is initialized with OR Apply the GE on start manually.

Constant Health regeneration based on a HealthRegen attribute

Create a GE with infinite duration. Add a period value, and an AttributeBasedModifier that targets Health and uses your HealthRegen attribute. Attach it to a passive ability the ASC is initialized with OR Apply the GE on start manually.

Stun

Add a GameplayTag named "Stun" to the stunning GE. Make a listener for ASC.OnTagsChanged event on your player controller. If the Stun tag is present when the event is triggered, disable the control, else enable it.

public GameplayTag stunTag;

private void Awake() {
    asc.OnTagsChanged += (tags, source, target, applicationGuid) => {
        if (tags.Contains(stunTag)) DisableController();
        else EnableController();
    };
}

Custom Damage Formulas

Extend the Calculation base class and make a DamageCalculation that implements your custom formula.

    public class DamageCalculation : GameplayEffectCalculation {
        public string name = "DamageCalculation"; //this is just to have it display on inspector
        
        public override List<Modifier> Execute(GameplayEffect ge) { //Example of default mechanic using Calculations
            minDmg = ge.source.GetAttributeValue("DamageMin");
            maxDmg = ge.source.GetAttributeValue("DamageMax");
            damage = UnityEngine.Random.Range(minDmg, maxDmg);
            
            var damageModifier = new BasicModifier() { attributeName = AttributeNameLibrary.Instance.GetByName("Health"), modifierOperator = ModifierOperator.Add, value = -damage };
            return new List<Modifier>(){damageModifier};
        }
    }

Create a ScriptableObject class that holds it.

[Serializable][CreateAssetMenu(menuName = "GAS/GameplayEffectCalculationSO_DamageCalculation", fileName = "GameplayEffectCalculationSO_DamageCalculation")]
public class GameplayEffectCalculationSO_DamageCalculation : GameplayEffectCalculationSO {
    public GameplayEffectCalculationSO_DamageCalculation() {
        calc = new DamageCalculation();
    }
}

Create a SO instance of the Calculation (GEC) via the assetMenu, and attach it to the damage GE.

OnDamageHit VFX/SFX (Cues)

Select the GE ScriptableObject that contains your Damage calculation or modifier. Add a GameplayTag "OnDamageHit" to its CueTags Go to your CuesLibrary, register a prefab (VFX/SFX) and assign its tag to the GameplayTag (OnDamageHit) you just added on the GE CueTags.

Inventory item consumption on ability activation

(e.g. Ammo consumption when using a Shoot Ability)

Create a new class that inheritis from any GameplayAbility class. On the new class, override CheckCost and Activate, respectively, to include a check for the cost on your inventory and pay the cost when activated.

Bonus Damage depending on Weapon Type

Create a tag for you weapon type e.g. "Weapon.Type.Ranged.Bow".

Whenever you equip/unequip the weapon, apply/remove an infinite durationType GE 1 with "Weapon.Type.Ranged.Bow" on GrantedTags

Create an GE 2 with Multiply Modifier (with the bonus value) for MinDamage and MaxDamage attributes.

Add "Weapon.Type.Ranged.Bow" to the GE 2's ApplicationTagRequirementsRequired

When the GE 2 is applied, the modifiers will only be applied if the target has "Weapon.Type.Ranged.Bow" on its tags.

Global Cooldown

Create a tag for it "Ability.Cooldown.Global" Assign it to the SourceTagsForbidden of every ability that shares the global cooldown, OR extend GameplayAbility's CanActivate() method to always check for that specific tag for all abilities. Add it to the cooldown effect on the abilities that should trigger it, OR extend GameplayAbility's Activate() to always apply the tag for X seconds when the ability is activated.

Hit Position

If you are doing a shooter game and/or require exact hit positions to trigger cues: 1 - Add a position vector to your GE.

public class GameplayEffect {
	public Vector3 positionalData;
}

2 - Pass the GE on the GameplayCue and move it to the desired position:

AddCue(... , GameplayEffect ge) {
    ...
    instance.position = ge.positionalData;
}

More?

Hit me up at feliperoddd@gmail.com and tell me what you want, and I'll give you a recipe for it ;)

Last updated