Sprint using stamina

Haytam95

New member
Hi I wanted to share with you the first ability that i wrote, it's called "Sprint".

It extends from SpeedChange, I wanted to start with something simple, but connecting other components like the AttributeManager and trying Coroutines.

So, this new Ability allows the character to run until he/she runs out of stamina (declared by dev). Also it's possible to prevent the character start running again after minimal regeneration, using "MinimalStaminaStart" variable.

Here is the Ability:

C#:
using System;
using System.Collections;
using Opsive.UltimateCharacterController.Character.Abilities;
using Opsive.UltimateCharacterController.Traits;
using UnityEngine;
using Attribute = Opsive.UltimateCharacterController.Traits.Attribute;

[Serializable]
[AllowMultipleAbilityTypes]
[DefaultInputName("Change Speeds")]
[DefaultStartType(AbilityStartType.ButtonDownContinuous)]
[DefaultStopType(AbilityStopType.ButtonUp)]
public class Sprint : SpeedChange {
  
    [Tooltip("Minimal stamina to start ability")]
    [SerializeField] protected float m_MinimalStaminaStart = 20;
  
    [Tooltip("When stamina value is below this number, the ability will stop.")]
    [SerializeField] protected float m_MinimalStaminaExecute = 1;
  
    [Tooltip("Rate of consumption of stamina")]
    [SerializeField] protected float m_ConsumptionRate = 1;
  
    [Tooltip("Amount of stamina consumed in each rate")]
    [SerializeField] protected float m_ConsumptionAmount = 1;

    public float MinimalStaminaStart { get { return m_MinimalStaminaStart; } set { m_MinimalStaminaStart = value; } }
    public float MinimalStaminaExecute { get { return m_MinimalStaminaExecute; } set { m_MinimalStaminaExecute = value; } }
    public float ConsumptionRate { get { return m_ConsumptionRate; } set { m_ConsumptionRate = value; } }
    public float ConsumptionAmount { get { return m_ConsumptionAmount; } set { m_ConsumptionAmount = value; } }
  
  
    private Attribute m_AttributeStamina;
    private Coroutine m_ConsumptionCoroutine;
    private AttributeManager m_AttributeManager;
  
    public override void Awake() {
        base.Awake();
      
        m_AttributeManager = GetComponent<AttributeManager>();
        m_AttributeStamina = m_AttributeManager.GetAttribute("Stamina");
    }
  
  
  
    public override bool CanStartAbility() {
        if (!base.CanStartAbility()) return false;
      
        return m_AttributeStamina.Value > m_MinimalStaminaStart;
    }

    protected override void AbilityStarted() {
        m_ConsumptionCoroutine = m_AttributeManager.StartCoroutine(ConsumptionCoroutine());
        base.AbilityStarted();
    }

    protected override void AbilityStopped(bool force) {
        if(m_ConsumptionCoroutine != null) m_AttributeManager.StopCoroutine(m_ConsumptionCoroutine);
        base.AbilityStopped(force);
    }

    private IEnumerator ConsumptionCoroutine() {
        while (IsActive) {
            m_AttributeStamina.Value = m_AttributeStamina.Value - m_ConsumptionAmount;

            if (m_AttributeStamina.Value < m_MinimalStaminaExecute) StopAbility(true);
          
            yield return new WaitForSeconds(m_ConsumptionRate);
        } 
    }
}

And here is how the AttributeManager was configured, so the Stamina can be regenerated automatically.

1569969443350.png

Feel free to play with this or use it for whatever you want, I just coded it to practice extending the controller


Last but not least, about the Coroutine i had to use the AttributeManager, because i couldn't start it from Ability. If someone knows a better way of doing this, i'm all ears!
 
Last edited:

Justin

Administrator
Staff member
Thanks for your contribution! There was actually a bug in the attribute system which prevented you from being able to do this without needing a new ability. This post has the fix:

 

Haytam95

New member
Thanks Justin, actually i didn't saw that Speed Change ability had that! (And it was kind of excuse to try coding a custom ability)
 
Top