January 9, 2018 at 22:29 #22620mvcurtissParticipant
In my game, AI units have access to several different skills and weapons. Its obvious that each weapon/skill should have its own scorer/targeting function (e.g. dagger attacks nearest enemy, heal will heal nearest ally, etc.), but I am at a loss as to how exactly I should implement this using Utility AI, considering these weapon/skill combinations can change in real-time. This seems like it should be a trivial task, it is a common use-case, but nonetheless the solution eludes me.
What seems easiest to do is to check the agent’s inventory for equipped weapons and skills, and then generate the AI tree in realtime from a library of weapon/skill AI scorers, however it is not very clear given the documentation available how I might accomplish this. Also, this solution might hinder performance, since (I assume) single instance AI’s would no longer shared amongst agents.
Alternatively, I could have a giant tree which evaluates every single weapon and skill scorer in the game, but first checks each weapon/skill scorer to see if the agent is actually wielding it. This option carries a bit of ‘code smell’, and could potentially become very unwieldy even with the editor provided, especially if a single weapon is capable of performing multiple different actions depending on different circumstances (e.g. “Reload Gun” and “Fire Gun” in the SurvivalShooter example).
I would probably be fine with the above solution if I could ‘wrap’ multiple qualifier/action pairs (i.e. a Selector) into a single qualifier. For example, wrap “Reload Gun” and “Fire Gun” into a single qualifier “Use Gun”. “Use Gun” would evaluate its child qualifiers, and return the score of the highest child qualifier. If that score is chosen by the parent selector, then the “UseGun” qualifier would execute the action of the proper child. It isn’t clear given the documentation provided how I might implement this. I see you can set the ‘action’ property of the QualifierBase class, but I am unsure how to use the editor to hook up this ‘SelectorQualifier’ class. All this being said, I can’t shake the feeling that I’m just trying to do things in the wrong manner.
Any help would be appreciated. Thanks!January 10, 2018 at 10:41 #22622RamiKeymaster
Thanks for your post.
First, I need to state that there are usually numerous ways to solve such a situation. The exact right solution sometimes take experimentation and actual in-game tests.
That being said, it sounds to me like you are overcomplicating the situation. As you start by stating, each weapon or skill should have its own scorer(s), leading to an action. Scorers can be reusable (e.g. HasHealth above or below X), and you can combine multiple scorers easily in the editor.
You probably do not need to write your own qualifiers at all. Most likely, you will just need to write scorers (IContextualScorer and IOptionScorer). The provided qualifiers usually suffice, e.g. “Sum of Children” and “All or Nothing” are the ones that I most commonly use.
If you find that certain weapons have more complex behaviours, e.g. Reload and Fire for a gun, you can – as you state – wrap this up in its own action. E.g. the “Use Gun” action checks for ammo, if none, then reloads first, otherwise just fires. Alternatively, you can visualize this in the AI as well. I recommend using “Sub AIs” (with AI Links) to hide the complexity and to facilitate having small, easily maintainable AI assets that form a more sophisticated network together.
Doing this would however require you to implement the needed scorers and set up AI nodes for each weapon/skill (or at least the ‘type’ of weapon/skill, if some can be treated equally). I do think this is preferable though, since everything is visual and easily tweakable through the editor. Breaking the AI up into smaller sub AIs will avoid having a huge, confusing AI tree.
Actually doing dynamic instantiation of AI nodes within an AI asset is not recommend. Dynamically adding or removing AI assets to an AI agent is fine though, if that helps your use-case.
You must be logged in to reply to this topic.