[META] When use Abilities? When use custom Gameobjects?

Haytam95

Active member
Hi !

I've been having this doubt since day one, about how to separe things that should be in an Ability and things that should be in their custom gameobjects and work outside character solution.

The Ability system is extremelly powerfull, and that is also a risk of having a character that does "Too many things" that aren't actually related to it.

I've three examples of Abilities that I've created:

Terror

Terror detects if the character is facing some kind of ugly thing (or enemy or whatever) and updates the terror value in the AttributeManager (That is used by another system then to update the sound).

While this is somehow related to the character, is more related to the player actually... The character doesn't change it's behavior because of the terror thing (Just some camera effects) and if the character is an AI then it really is worthless.

Health Visualizer

It just updates an Animator param based on the character current health. With that value, the animator changes the character idle animation.

Aggro

Aggro detects if some enemy is discovering the character and starts chase music. (Again, related to the player not the character).


These examples are pretty easy to separate, but: What would be the golden rule?

How are you managing Abilities vs custom gameobjects? You use always abilities? Always gameobjects? :)
 
I think all of these would be better handled with states and animation parameters. I wouldn't use abilities for any of them, unless they need to ever override other abilities.
 
What would be the golden rule?
There isn't one - it's whatever makes the most sense within your game structure. With that said, if you take a look at the abilities included with the controller you can see that they do one of three things:

- Modify the character's position
- Modify the character's rotation
- Modify the character's animator

Out of the three abilities that you listed I personally would only make the Health Visualizer its own ability if it updates one of the built-in parameters. With that said, if it works for your use case then I wouldn't change it just because I personally would do things a little bit different. In the end it's the end result that matters.
 
Out of the three abilities that you listed I personally would only make the Health Visualizer its own ability if it updates one of the built-in parameters

Hi Justin

Right, actually the only ability that I kept was the Health Visualizer because it updates an Animator param. I've refactor the others and make them work as "Player Monitor" in their gameobject.

if it works for your use case then I wouldn't change it just because I personally would do things a little bit different. In the end it's the end result that matters.

Yeah, I'm asking because at first it worked okay. But then the game growed up and now I'm facing some problems (for example on character swap).

So I'd like to have a clearer vision about how the abilities were designed to. (i.e I've been seen people using prefabs as "ScriptableObjects" just because they can, and even if that works isn't correct)

- Modify the character's position
- Modify the character's rotation
- Modify the character's animator

This, this is a nice summarization actually


I think all of these would be better handled with states and animation parameters. I wouldn't use abilities for any of them, unless they need to ever override other abilities

Hi David, actually the Health Visualizer updates an Animation Parameter so I kept it as an Ability.

But I'm curious, how would you implement the other two using states? I've used states for other things, but not for this
 
Hi David, actually the Health Visualizer updates an Animation Parameter so I kept it as an Ability.

But I'm curious, how would you implement the other two using states? I've used states for other things, but not for this

I would activate the state on the enemy related to agroing on the player. Like, if "agro" activates a "chase" ability that makes them follow the player and/or speed change ability. The state is just a textbox you write in the name of the state on.

On the player, you'd subscribe to "OnStateChange" event and filter for that new state you made (agro). If the state becomes active, increase an int, if it becomes inactive, decrease the int. This int represents the number chasing you (you could even play more intense music or speed it up). If the value is 0, you turn off the music.

For terror, I'd give the player an overlap sphere (or add to an existing one if you have one of the same size doing somethign else). Filter it for the things that instill terror (if statements and a loop). Get the terror value off of the object(s). If it's directional, calculate the angle to the enemy and filter by angle. Then update the player's attributes.

You could flip it so the terror enemies have the sphere and instead apply it to the player, I don't know if there's any reason to do it one way or the other, so if enemies already have a suitable sphere (like agro radius), then you could use that.

I hope that makes sense! If not, lmk what I need to clarify.
 
There isn't one - it's whatever makes the most sense within your game structure. With that said, if you take a look at the abilities included with the controller you can see that they do one of three things:

- Modify the character's position
- Modify the character's rotation
- Modify the character's animator

Out of the three abilities that you listed I personally would only make the Health Visualizer its own ability if it updates one of the built-in parameters. With that said, if it works for your use case then I wouldn't change it just because I personally would do things a little bit different. In the end it's the end result that matters.
I like that a lot. You should add a note to the ability scripting section of the documentation for "3 different things an ability usually does."
 
I would activate the state on the enemy related to agroing on the player. Like, if "agro" activates a "chase" ability that makes them follow the player and/or speed change ability. The state is just a textbox you write in the name of the state on.

On the player, you'd subscribe to "OnStateChange" event and filter for that new state you made (agro). If the state becomes active, increase an int, if it becomes inactive, decrease the int. This int represents the number chasing you (you could even play more intense music or speed it up). If the value is 0, you turn off the music.

I really like this idea of using the State System as an empty textbox without actually making it modify anything in the controller or camera.

(And thinking out of loud, would be very nice to check if an state is active in the animator)

For terror, I'd give the player an overlap sphere (or add to an existing one if you have one of the same size doing somethign else). Filter it for the things that instill terror (if statements and a loop). Get the terror value off of the object(s). If it's directional, calculate the angle to the enemy and filter by angle. Then update the player's attributes.

Yes that could be (Actually this is the way the ability worked before).

But I found out that it's adding complexity to the character that shouldn't be there. If the same character in another scenario can't raise terror at all, then I would need to have two prefabs of the same character (One with the ability and another without it) or accept that every frame it would be checking: "It's something scary nearby?; It's something scary nearby?"

I think that "Terror" is more related to the player, than actually the character. Because of that, in the current implementation I've created a GameObject that lives (or dies) with the scene and accepts a character and a list of things that are scary (using SO architecture) .

Then that Gameobject is responsible of making the raycasts and funny stuff. If for some reason I want to disable the terror thing or change the current player at runtime, I could do it just by disabling the gameobject or changing the reference and everything would continue working.

Let me know your thougths about this one, nice debating with you!
 
But I found out that it's adding complexity to the character that shouldn't be there. If the same character in another scenario can't raise terror at all, then I would need to have two prefabs of the same character (One with the ability and another without it) or accept that every frame it would be checking: "It's something scary nearby?; It's something scary nearby?
Just disable the script/component or whatever that does the terror effect, on spawn, for the ones that don't use terror. Sometimes you need to do things like what you mentioned, every frame.
I think that "Terror" is more related to the player, than actually the character.
You mean different players are afraid of different things?

Let me know your thougths about this one, nice debating with you!

I didn't realize we were having a debate, lol. I was just giving you solutions based on what you've told me about what you need.
 
You mean different players are afraid of different things?

No, just that a Character depending on some factors could or could not raise terror (For example difficulty level). And because that's a mechanic that doesn't affect the character, but the player (heartbeat sound), for me it should be a separate gameobject rater than an ability :)

I didn't realize we were having a debate, lol. I was just giving you solutions based on what you've told me about what you need.

Hahaha yeah, I solved these problems but I wanted to know how the community would handle this cases. I would like to see other opinions as well but I'm happy that at least you explained me how would you do it. A few things come out here, use "States" as blank states (lol) and justin's vision about abilities
 
Top