Pyreal
Pyreal

Reputation: 517

How can I make my Attack Combo System more modular?

Working on a beat em up. I've fleshed out a basic way to handle attack combos. I'm looking for a better way to handle modularity when adding new moves and making the logic more concise.

public class Attack : AbstractBehavior
{

public bool attack1;
public bool attack2;
public bool attack3;

public int currentAttack = 0;
public float lastAttackTime;
public float attackDelay = 0.2f;

private void FixedUpdate()
{
    var canAttack = inputState.GetButtonValue(InputButtons[0]);
    var holdTime = inputState.GetButtonHoldtime(InputButtons[0]);

    if (canAttack && currentAttack == 0 && holdTime < 0.1f)
    {
        attack1 = true;
        currentAttack++;
        lastAttackTime = Time.time;
    }

    if (canAttack && currentAttack == 1 && holdTime < 0.1f && Time.time - lastAttackTime > attackDelay)
    {
        attack1 = false;
        attack2 = true;
        currentAttack++;
        lastAttackTime = Time.time;
    }

    if (canAttack && currentAttack == 2 && holdTime < 0.1f && Time.time - lastAttackTime > attackDelay)
    {
        attack2 = false;
        attack3 = true;
    }
}

Upvotes: 0

Views: 1161

Answers (1)

tsvedas
tsvedas

Reputation: 1069

I would just use a "tree" of AttackComboUnits, where you nest what comes after what. Then, in main Attack script, you hold the initial attack combo unit and the one that's currently active.

NOTE: it's just a concept idea, script might not work as they were writen inside Notepad++ and I haven't tested them.

public class AttackComboUnit : MonoBehaviour
{
    [SerializeField]
    privaet bool baseComboUnit;
    [SerializeField]
    private AttackComboUnit nextUnit;
    [SerializeField]
    private float maxDelay;

    private Animator animator;
    private float enableTime;





    private void OnEnable()
    {
        enableTime = Time.time;
    }




    public AttackComboUnit Attack()
    {
        // Player didn't use attack for too long and this is not base attack unit, so delay must be applied
        if(!baseComboUnit)
        {
            if(Time.time - enableTime > maxDelay)
                return null;
        }


        animator.Play("myAwesomeComboSkill");

        // // // // // // // // // // // // //
        // Do some damage or something else //
        // // // // // // // // // // // // //

        return nextUnit;
    }
}





public class Attack : AbstractBehaviour
{
    [SerializeField]
    private AttackComboUnit initialAttackUnit;

    private AttackComboUnit currentAttackUnit;





    private void FixedUpdate()
    {
        if(canAttack && holdTime < 0.1f)
        {
            AttackComboUnit comboUnit = currentAttackUnit.Attack();
            SetAttackUnit(comboUnit);
        }
    }

    private void Start()
    {
        currentAttackUnit = initialAttackUnit;
    }





    private void SetAttackUnit(AttackComboUnit attackComboUnit)
    {
        currentAttackUnit.enabled = false;
        currentAttackUnit = attackComboUnit;
        attackComboUnit.enabled = true;
    }
}

Now just place all the AttackComboUnits on the GameObject, ant assign what goes after what. Adjust delays. Delay is counted from when the script is enabled. Disable all attacks except the initial one.

You could also add field for name of animation that should be played, so that your AttackComboUnit script becomes more generic.

Upvotes: 1

Related Questions