Struggling with a Resource Drain type ability

AKB

Member
So what I am trying to accomplish is an action that, when I walk up to some resource, I can hit a button which equips an item and starts draining from it - like a mining tool would. When the button is released, the mining stops. So far I have some stuff working but others are hair-pulling and I need some help.

I have an ability that can chain an equip and a use. Letting go of the button stops the entire thing. All good.
The ability uses an Energy attribute and if that gets to zero, it stops as expected.
I was leveraging Magic Item to sort of take care of some basics but I've noticed a couple of issues I'm struggling with

1) The Cast actions seem to be one-shot so it's not continually called to do what I want (I made a DrainResource cast action that takes health from target and adds an item to inventory)
2) I can't find the best way to cancel the action if I decide, for instance that the thing being drained is dead (Assuming I can get it to continually drain). in my tests if I kill the target and it's removed (It has a Health component on it) the action continues.

I had made a script on the Magic Item (For my mining tool) to try and test to see if I could cancel the action but I can't find the API to get there from an Item object. i.e. The current action running with that item so I can cancel it (somehow).

Have I gone about this the wrong way? Should I write my own Item from scratch in this case or is there a better choice? If my mining tool was a "shootable" would that be better and should it operate without "bullets" that need to be consumable but fire and when hitting the target, damage and then give the player a resource?. I'd still want some continual particle system that starts when the action starts and stops when it stops but should I just use the concept of "bullets/projectiles" to do the things I need?

Any help really appreciated.
Cheers
 
Last edited:
What approach you take really just depends on the specifics of your use case. E.g. I wouldn't really recommend ShootableWeapon based on what you've said, unless there is a way in which having the mining be aimed or projectile-based makes sense. (But even then, you can get the majority of that functionality within MagicItem, so it's unlikely that would be a good reason.) MeleeWeapon would make sense if the mining should require some kind of physical collision with another object. You'd also need to consider whether the feature will have variations in the future, e.g. different types of pickaxes that modify gathering speed or whatever.

But just based on what you've said, I'd say MagicItem would be the most straightforward option. If you set the "Use Type" for a MagicItem (under "Magic") to "Continuous", then the Cast Actions will fire every Update tick. The ParticleStream item in the demo uses this to continually spawn particle effects, impact targets, play audio and drain an attribute.

For manually stopping the action, you should be able to just call TryStopAbility on the Use ability (see this page for an example script, under "API" near the top). To know when to actually call that though, you could just add a callback to the "On Death Event" in the target object's Health component. You can even add listeners to the OnDeathEvent during runtime (Health.OnDeathEvent.AddListener/RemoveListener). Alternatively, the Health component executes the "OnDeath" event when it dies, which you could listen to. (More info on how to listen to events here and names of all the built-in UCC events here).
 
Thanks Andrew.

A couple more things if I may

Regarding the OnDeath event, would the best place be to monitor that be my custom action (Given it is an action that uses DetectObjectAbilityBase so has a detected object. And then if that object is dead, stop itself?

Second, if I wanted my actual item to monitor for killing its target and stopping any actions on it, is there a way to do that. I couldn't see a way to get any "current action" from the MagicItem (Or base) classes. i.e. From a script that has access to an Item object can I get any current action that's running on my character with that item?

Thirdly, is there a concept of a current target for running actions? My DetectObjectAbilityBase obviously has a target for deciding whether to start the action. However, once the actions starts it's the items that do the work (MagicItem in my case most likely). Now I can can hook events to do things as the magic happens but I've lost the target at that time? I obviously don't want to couple my Item to mandating the character has an abvility with DetectObjectAbilityBase to access the m_DetectedObject but if there's some concept of "target" for things that would be great. I see in the UI sometimes things are mentioned like "Face Target" etc but these targets seem to be hooked to mouse pointing, which I don't want - this will be a controller game.

ThirFinally, it seems continuous isn't working or I've set something up wrong. I have mine set up like this below but I only get Cast() called once. Here DrainAttribute is my own CastAction.

1635966124672.png
 
Last edited:
Just to follow up. What I found was because I was chaining abilities in a custom ability of mine, what happened when I fired the use button was that even though my outer ability was still running, the use ability stopped, because the normal Stop condition (Fire button up) was positive so it just lasted a very short while.

So, happy I found this and my stuff seems to be coming together now finally.

I would love for UCC to add ability chaining some how - maybe having an overall start/stop condition that gets applied to the child actions.
 
You could listen to the OnDeath event from within your custom item action, yeah. You could also have a custom Use ability that stops itself, but unless you'd need it for other reasons too it's probably not worth it.

Item.ItemActions will return an array of all the ItemActions on that Item. ItemActions themselves don't have a concept of whether or not they're "active" since that's all controlled by abilities (i.e. the Use ability), so if you want to check that too you'd need to find the matching Use ability (you could compare the Action IDs) and check if it's active (Ability.IsActive).

The Use ability or item actions in general don't have a concept of a "target" built-in, since their functions can vary wildly (e.g. it wouldn't make sense for a grenade or teleport to have a "target object"), so that's something you'll need to add to your custom item action. But it should be easy enough to get the detected object and store a reference to it in your custom item action?
 
Top