#Combat System managing problems

1 messages · Page 1 of 1 (latest)

vapid bone
#

Im a unity beginner and im trying to make a combat oriented game, though i feel my 'CombatManager' is spaghetti code and i cant EXACTLY seem to figure out why, any advice? (ANY advice will be helpful)

#

heres the code

#

heres the 'pipeline' (if u can call it that):
the check in update is done and the subclass of the entityCombatManager (in this case playerCombatManager) updates the "pressedLightAtkbutton" or wtv button he pressed, then it sees if theres a weapon equipped in the first place and if that attack exists (as if there is a light attack in the first place).

#

then when all checks are passed, it calls the "CombatManager_OnCombatStart" with the corresponding atk type

#

it then invokes an event called OnCombatStart which is there for the entityanimatorscript and so on

#

then through animation events in the atk clips, it does these in this order:
1 - SetAttackDirection();
2 - CheckForNextHit(); (To create a sort of attack buffer)
3 - TurnOnHitBox(); (Still working on this)
4 - TurnOffHitBox();
5 - StopCheckingForNextHit();
6 - GoToNextHitIfAchieved();
7 - AttackEnded();

#

if theres any inquires abt the code/other scripts tell me and ill send them too

#

and yes, it works, but if this is spaghetti code thats glued together then it doesnt work, it works FOR NOW

#

by the way this is an entitycomponent, i attach it to an entity and if i wanna override it i js make a new script and inherit from this base script. In this case, playerCombatManager inherits from entityCombatManager and barely does anything except manage input (cause ive generalized most of the heavy lifting in the base class)

sick cloud
#

First of all, share the !code correctly.

#

!code

mint nexusBOT
vapid bone
#

aight

sick cloud
#

So, the first thing that comes to mind is that you can't decide what this script should be doing. It seems to be managing all kinds of unrelated logic a little bit. For example, you mentioned that input is controlled by a subclass, but then you have stuff like PressedHeavyAttackButton = false;. If this should be a generic component applicable both to players and npcs it should definitely not do anything input related.
Another example is handling equipment logic. This should definitely not be in a "combat manager" class.
Then it seems like you have multiple separate mechanisms for controlling combos, like the combos string but also light and heavy attack counters.

You need to decide the single responsibility that this component should be dealing with. Rather than combat manager it seems to be mostly responsible for combos.

Maybe think about extracting logic into dedicated classes, for example, having a Combo class that would know the key/attack type sequence that is required for the combo to succeed/continue. Then you could loop a list of available combo objects and evaluate those that are still valid in the current sequence. And if all combo evals fail, fallback to light or heavy attack.
The attack types could also be separate class objects that handle the specific attack logic.
If these are specific to a weapon, they could live on the weapon instance so you could just do weapon.EvaluateAttackAction(attwckContext) or something. Basically, strip down responsibilities from your class and delegate them to specific classes/objects. That should make it cleaner, easier to debug and extend.

vapid bone
# sick cloud So, the first thing that comes to mind is that you can't decide what this script...

yeah when i said that input is controlled by subclass i meant like this:

using UnityEngine;

public class MainPlayerCombatManagerScript : EntityCombatManager
{
    public WeaponScriptableObject tempTest;
    protected override void Update()
    {
        if(Input.GetMouseButtonDown(0))
        {
            PressedLightAttackButton = true;
        }
        if (Input.GetMouseButtonDown(1))
        {
            PressedHeavyAttackButton = true;
        }
        base.Update();
        //temporary
        if (Input.GetKeyDown(KeyCode.G))
        {
            EquipWeapon(tempTest);
        }
    }
}

this is the mainplayercombatmanager for instance.

#

but i get what you mean, the combat manager is managing more than js combat

#

i wanna seperate it into more classes as u suggested but im afraid thatll lead to more event clutter

#

since its already bad enough i feel

sick cloud
#

Well don't use events when you don't need to use events.

#

If the combat manager manages these class instances, it can call methods on them directly.

vapid bone
#

but that isnt really that modular tho is it

#

cause if an entity can attack and has a combat manager but cant do combos then i cant seperate them

#

or ig i can js add a null check

steep island
#

I use scriptable objects to handle combos. Each SO contains a combo route that I basically treat as a state machine. I'll have an input system that will save inputs to an input buffer(list/queue). The ComboSystem will then read the inputBuffer and evaluate combo list to see if the combo continues or is dropped.

sick cloud
vapid bone
#

how many inputs does the input buffer take?

#

i only really have one 'buffer' that js buffers the next continuation of an attack

vapid bone
#

i dont know exactly what i wanna do

#

honestly lost on what exactly i wanna do but im trying to ig 'prototype' to find something that feels nice and satisfying cuz thats what i wanna achieve

#

are combos a part of that or not? im not sure but imma try adding them anyways and see what happens

#

i use scriptable objects for combos too but theyre a bit different

#

i store the actual combo in a scriptable object and then store that in the weapons SO, that means a weapon can have more than one combo

#

and in runtime i analyze the 'currentComboString' (basically seeing what the player has done so far in terms of combat) and, on the fly, see if he achieved a combo

#
{
    foreach(ComboString comboString in WeaponCurrentlyEquipped.WeaponScriptableObject.ComboStrings)
    {
        if (comboString.Combo.Count > CurrentComboString.Count || comboString.Combo.Count < CurrentComboString.Count) continue;
        for(int i = 0; i < comboString.Combo.Count; i++)
        {
            if ((int)comboString.Combo[i] != (int)CurrentComboString[i]) break;
            if (i == comboString.Combo.Count - 1) return comboString;
        }
    }
    return null;
}```
#

this runs in update while InCombat

#

what yall think

sick cloud