"Duration" Ability / AttributeModifiers and a weird collider issue

Laocoon7

New member
I have three mostly related topics.

Part 1:
Currently, the EnableModifier(bool enable) will only spend the Attribute if m_ValueChange != 0. When writing an ability which costs "Mana" setting the attribute's m_ValueChange in the inspector causes the mana to be removed as the ability starts. When making a targeted ability, one may fail to find a proper target and want to refund the cost. Can we get:


C#:
// The attribute can be refunded by a single value...
if (!enable && m_ValueChange != 0){
    m_Attribute.Value -= mValueChange;
}

Around line 318 of AttributeManager.cs?

While it's not so bad to m_AttributeModifier.Attribute.Value -= m_ValueChange;. We also need to perform checks ourselves to see whether or not the skill is setup to auto-update. By making this change, we would be safe just calling m_AttributeModifier.EnableModifier(false); to refund the mana / or reverse the autoupdate. Or maybe I'm missing a reason it was never implemented this way?

Part 2:

The Ability.Update:IsValid() function stops abilities that can be refunded/take time (Start- ButtonDown, Stop- ButtonUp with a one time cost). Take this example:

MaxMana = 100
MinMana = 0
AbilityCost = 10

Casting the Ability 8 times is fine. On the 9th time. CurrentMana = 20 CanStartAbility makes it's check and says all is good. It removes 10 from the cost. Update is called and makes it's check. CurrentMana is now 10, and 10 - 10 = 0 which causes IsValid to return false and stop the ability. As I am then refunding the mana, the displayed mana pool shows 20, yet the Ability costing 10 looks like it is un-castable. If I don't refund the mana, the ability will spend 90 mana and only "cast" 8 times. Perhaps a something like:

C#:
// The attribute has a chance to stop the ability if it reached the min value. An example use case for this is if the stamina ran out and the character
// can no longer run.
// Allow single cost abilities that have already paid.
if (m_AttributeModifier != null && (m_ValueChange == 0 && !m_AttributeModifier.IsValid())){
    StopAbility();
}

On line 604 of Ability.cs? Is there never going to be a reason to call base.CanStartAbility/base.Update as long as I'm handling the attribute costs?

Part 3:

I'm using a Physics.OverlapBox to get collisions around a ghost object inside of Ability.Update() before placing the real object. However, it doesn't seem to overlap the Character's CapsuleCollider until I release the button and it makes the same check in AbilityStopped as it did in Update. I'm using the same function for checking for a valid position in both places and update the Materials before actually placing the object. I properly overlap every other collider, including the other characters in the map which causes me to think there's some magic going on with the character while an ability is updating?
 
I've completely reworked how the attribute modifiers work in version 2.3 and overall it works a lot better. Let me know what you think after it has been released (should be any day now) :)

Having the single value amount along with the auto update amount made for some weird cases. In 2.3 I've consolidated this to just one value and it's working a lot better.

I'm using a Physics.OverlapBox to get collisions around a ghost object inside of Ability.Update() before placing the real object. However, it doesn't seem to overlap the Character's CapsuleCollider until I release the button and it makes the same check in AbilityStopped as it did in Update. I'm using the same function for checking for a valid position in both places and update the Materials before actually placing the object. I properly overlap every other collider, including the other characters in the map which causes me to think there's some magic going on with the character while an ability is updating?
If you are using root motion the ability is updated after the character has moved within OnAnimatorMove.
 
If you are using root motion the ability is updated after the character has moved within OnAnimatorMove.

I'll probably have to dig into this more... I was keeping a count of OnTriggerEnter/Exit and it was working then, but I had issues where if I clicked fast enough, the initial collisions wouldn't register and the item would be built in an invalid location. I may have to OnTriggerStay with a starting count of at least 1 to force it to update collisions at least once, but I'll definitely do a bit more research. Thank you.
 
Top