#gameplay-ai
1 messages · Page 69 of 1
Sight is blocked by the visibility channel by default
So either your walls collision profile has visibility disabled or you changed the sight settings somehow
Yep that's it
Hello !
The newb question: in 5.3/5.5, in your opinion, is it still relevant to use the regular behavior trees over state trees ?
I played a bit with state trees in 5.0, and was very impressed. I played with BT too, and found it very cumbersome, with some very annoying limitations, and quite poor performance out of the box (had to use cooldowns etc).
Anything you would recommend reading (apart from the obv documentation, and pins 🙂 ) / using ?
Gonna start implementing our own "player" AI soon.
For the fun: I was contemplating trying to train a real AI, but at the end, I kinda wonder if it is really worth it, and if it will be practically usable for several AI characters ... (like 20-40). Probably not ... but who knows.
Thanks !
So i figured it out.
I make mostly 3 states of AI.
1- Reinforces/Defends territories.
2- Attacks enemies territories.
3- Gather armies to attack.
Now i have no idea how am i supposed to do this in terms of structure? Should these be components?
I have my CampaignAIController. How do i manage the AI different types of behavior?
I can make it all with if statements and enums.
Either can be used depending on which you like. BT performance should be entirely fine, but depending on things you might need to use C++ - ST can have similar performance problems with BP based nodes in some circumstances. ST is likely to require some manual digging through engine code to better understand it as it still has some rough edges that aren't documented very thoroughly
You could probably use BT/ST's or some custom solution for this just fine whichever fits your purpose better. It doesn't really matter
I would argue that controlling performance in Bt's is easier than in St's as for right now
If its was my gsme, I would build a Utility System for Bt's (in 5.5 there is one provided for state trees) and handle the state through that. The weights can be handled by your Campaign AI Controller. My other advice is to handle things with gameplay tags rather than enums. There is a lot of documentation on how to use untility system for that type of games
How do games normally handle pedestrians?
Should I just abuse plugins or make my own logic or both?
You could always use mass the same way Matrix demo does. The code is available
🫡 danke
Though im using c++. should i do the behavior tree in c++
i find behavior trees very confusing, i only worked with them twice
I failed to see the advantages of it for a turn based strategy game
At the time it just seemed more bloat. Though they seem useful for a real time game
Wouldnt it be better in this case to just use a component in my CampaignAIController, called ArmyMovementAIComponent
and there i just manage all the movements of the AI. What regions to attack/move to, or instead if just defending what regions to defend.
Could also create child components of the ArmyMovementAIComponent, for different AI strategies
Anyways my game is 90% in C++, so i dont know if i can do this in Behavior Tree blueprints, could be just a bit clumsy, right? Why not do it fully in C++?
Everything you are describing can be a bt where each branch dies what it's needed and decorators check for the conditions to do X or Y. Doing c++ is good, but that doesn't mean you can't use bp's or any other form of visual scripting. The bt's are nice to work with in editor once you understand them. But in the end is your decision. In my experience, I would do tools and whatever in c++ so designers can use them in bp/bt/st because it's faster, the can be autonomous and debugging and itereting is much faster
But if you don't need any form of AI approach to handle your decision making due to it being very very simple... Then just do what you need. I find it strange you don't need it tough
Any talk about AI in strategy games I have seen/read had something, Age of empires, starcraft, guild wars...
The way you describe it sound like your complicated stuff will be in the decision about what to do and where and then just move to/do some attack action in a very simple tree.
The decorators, the tasks, etc.. which i dealt with in the past. Why not just use Enums, bools, and structs in C++ ? Is there any disadvantage to using the C++ instead of the bp?
i say this because my C++ classes have everything there. The BT is a degree of abstraction that i cant see the value in it. Maybe im wrong
Where would the BT help here? exactly?
Then just do what you need. I find it strange you don't need it tough
ITs because the blueprints especially the BT can be overwhelming too. They create little files everywhere. Tasks, Decorators, BB. Harder to manage, harder to find certain functions.
C++ gives you more freedom. But im saying this maybe im just wrong.
In C++ i can just create enums and check stuff there.
Okay i will try behavior trees one more time today.
Also Behavior trees are less performant
thats another thing to take into account. even though its a turn based strategy game that doesnt require much performance
You can't be wrong or right. I feel like what you say depends on you, your preferences also on how you work with different tools. As also Bruno said, it seems like you could do what you describe with bt too. You can use them as state machines. Then if it's worth it, really depends on what you need from it. Just try. Make a draft, play around with it a bit and hopefully you can feel if it's good for you
If you think bools etc fit your needs, go for it. In the end, unreal offers tools and it's up to you what to use
Disadvantages: iteration speed mostly
The rest, it's all OK the code side
On the other hand, you might end up with a miriad of bools in a class and you will have to develop debug tools for your system. That said, I'm not saying you need bt's, just suggestin thinga
Depends on how you use them
I would research a bit on how other similar games handle AI first
Usually strategy games use weights for their decisions etc
🫡 so its easy to iterate in bt. because you are seeing things graphically humm
doesnt have to be bools. Could be just checking the armies of the enemy, the numbers of enemy soldiers. If they have more than me, then move my armies to the regions in the back to consolidate and defend
if they have less than me but are spread out in the provinces then move through them and defeat in detail, encircle, choke them, make small caldrons
if they have a big strong army in just one province, than concentrate all my armies and attack this army
or split my armies and go around pillaging many regions with small armies
in all of these im checking the enemy numbers, and the regions for the most
then i use enums to set the current AI strategy the AI player is following
And instead of checking every x seconds interval or on tick, like you would do in BT. i check by turns
So like every X turns check if i need a new strategy, or if i should continue the same strategy
im saying this but im noob, and never tried this one
I did very basic ai in the past with characters moving around looking for enemies based on who is weaker, that was an rts...
This is one currently is a strategy turn based game, its more like chess.
🫡
this is so complicated im with analysis paralysis. im just going to play some games or go to the gym to see if the dust settles
can someone help me, I need to switch to static nav mesh because dynamic nav mesh and invokers cause significant performance issues. the only issue is that my levels are connected via level streaming and some of the levels overlap. my nav mesh is currently in the persistent level and spread across the whole map, this doesn't work because it needs to be built with all the levels visible and like i said they are overlapping. does anyone know how i would go about fixing this?
You just gotta pick an approach if you're stuck like that. Something that can help is writing down a "Plan B", eg. if your initial idea doesn't work, what are you going to do then. This way you don't need to worry about picking the perfect solution since you know what you need to do if the choice doesn't work
And you don't need a programmer to change code (like adding variables), recompile etc
- place a small volume (default when you drag it at 000 is good enough) in persistent level to guarantee the recast object is always in the Persisten level. Recast object will hold your nav data
- then in each sub-level, add the necessary nav volumes for it.
- to build nav, you need to show all levels and then build. Each sub-level will save its nav data in the level that contains the nav volumes (in our game, each sub-part in the game is a mic of sublevels with different info (art, sound, gameplay). Our nav volumes are in the gameplay level, so the nav data is in the nav chunk within the gameplay ULevel object. It's not until that level streams when the nav chunk is added to the nav data in the recast object
The problem with unreal approach of showing all levels is that you need lots of ram if your game is big. But there's a workaround: use a commandlet. Not loading the editor or anything visual at all, saves LOTS of ram. For us it would have been impossible otherwise (machines with 192gb of ram couldn't handle showing the entire world in editor)
The second problem you will have is this
#gameplay-ai message
hey all, how do i make an agent completely ignore certain kinds of collision? i have meshes that affect the navmesh, but it'd be nice if i could make the static meshes affect some navmeshes and not others. do i have to do something with collision in order to make the static mesh affect some meshes and not others?
the context: i have a lot of actors that normally avoid trees around the world (because they have blocking collision), but i have one big actor that can literally plow through trees (no blocking collision on trees). i want that second big actor to be able to navigate using the nav mesh system but ignore trees.
Thanks I’ll try it
That you handle with nav filters and nav areas. You make your trees to generate a NavTreeArea in yellow for example. Then when enemies that path around, use a nav filter that avoids NavTreeArea while the other just paths through it as if it was default nav
Ok Plan A: Make an AI Component that is MainAIComponent, Then make child of these components like, AttackerAIComponent, ConsolidatingAIComponent, BoomerAIComponent.
Plan B: Just make it all in the same CampaignAIController, with enums for each AI behavior style?
😵💫
You might benefit from a data driven approach. We use data assets that define everything in an enemy: all the bt's for combat/idle/patrol etc, tags, values for stats (imagine strength, defense etc). Many other things too like navigation capabilities etc etc. We spans units using spawner objects located in the world. When a enemy spawns we do it deferred and we set all the data from it's data asset before calling finish spawning (some other data will happens in specific components in post Initialize, begin play etc)
So have a data asset for each type of AI, and assign it that way. Spawn it deffered, get data table, set stuff up, done <-
Yeah. Then you have 1 controller, 1 of everything common and all your data comes from the data assets. We have things like DA_AI_Grudge. Same approach is used for everything: animation, ai, audio... Then a main DA that collects all of them. There it's just "which data asset for AI?" + the class of the enemy. Our spawner use that main DA to spawn enemies
🫡
One piece of advice: soft references for everything, then load things when needed
Otherwise your memory goes brrrrr
🫡 yes i do that, though for components that are mostly data, too ?
i mean i do it for meshes and stuff
Everything: actors, bp's, components, data assets, montages, bt's.... Everything
yeah, i wonder why this is not set as standard
shouldn't the engine load it always soft
as a standard
Well... Everything depends.
in AI MoveTo, is Destination supposed to be the exact world location for the AI to move to? My AI seems to be unreliable or to move locations far away, usually to a room upstairs above the desired location, even thought the Z value never changes. Are there any glaring issues that can be spotted in this blueprint? Should I be reseting the location and redo MoveTo when MoveTo fails?
Most of the times he stays in the room, but there are a few rooms where he just leaves. I tried increasing the acceptance radius to 100. Don’t know if the location is too close to the wall or in the middle of a table. it will make the AI go somewhere else. I’m so confused why he would go upstairs. For example, the first floor rooms has a Z location of around 200, but upstairs is probably 800. I spawn a sphere before AI MoveTo so I can see where he is suppose to go, but then he walks for 10 seconds to go upstairs. Then 10 seconds to come back when the next MoveTo is set
I would try using project point to navigation
Sometimes if it attempts to path to a point that isn't on the navmesh it will go into weird places
In my project it was problematic as items they want might not be in predictable locations, so I projected several points around each item to navigation, and chose the best out of them for it to navigate to
Is the nav mesh the green parts of the level when you press P or the whole box? I put one whole nav mesh box over the entire house
The green parts
The box is the nav mesh bounds, it's the boundaries inside which the nav mesh generation code will run
I’ll take a look at project points
Is it recommended to also change the settings of the nav mesh to make the green parts closer to the walls? I only changed some height settings to make the ai able to go up stairs.
Not unless your nav agent radius is actually lower than the default
They can walk all the way to the edge of the nav mesh, so that their center point is at the very edge of the green, so if the radius of the agent is the same as the radius configured to the mesh, they will be as close to the walls as they can
fantastic, thank you
I'm having a tough time finding tutorials on how to use the node project point to navigation. I tried using is Valid AILocation, but seems like the locations I set at Valid for the AI. Guess Valid AILocation doesn't mean if the location is not on the green part of the nav mesh
QQ on this. the trees are part of an instanced static mesh component. would i need to switch to actors to do this?
can some one help me am making a game where i have the navmeshbounds dynamic but am wondering if there is a way in blueprints to switch it back to static does anybody know if its posible in blueprints to do this ?.
@misty wharf in the end I used project point to navigation, and I got the location of the projected point and I check if it's nearly equal to my random location. If it's false, I set a new random location until the random location is nearly equal to the projected location. Seems like it's working and the AI doesn't just randomly decide to walk all over the house and go upstairs.
anyone know a good way of managing a bunch of enemy soldiers, for example taking cover in positions that threaten the player the most
I was thinking a subsytem but I dont know if theres a more reliable way of doing it?
I want to create a manager who directs commands to multiple actors in the scene. The manager is not going to have a mesh or be rendered, it is strictly a manager class that makes decisions and gives commands to the members of the squad. I would prefer to do this with C++, as that’s where I’m most comfortable. I’m not sure how to go about this...
kindof like this
You should be able to do it in the static mesh editor
Nope. The configuration of the nav mesh (whether it is dynamic or static) is soemthing that can't change at runtime
For covers you can post process the nav to create cover points, add them to an octree (so it's fast to search) and with an eqs look for the right ones (min/max distance to target, type of cover etc etc).
There are examples like this one. This one says runtime but nothing prevents you to make that a post process in your build pipeline and store is statically to save lots of frames in runtime
https://www.freecodecamp.org/news/real-time-dynamic-cover-system-in-unreal-engine-4-eddb554eaefb/
In a game I was part of, what I did was to analyse the nav edges and do traces every Xcm, trace outwards the nav (towards the objects/walls) at different heights and define if the cover was half body (ie low barriers, explosive barrels etc) or full body (higher elements like walls). Then I had a special type of object (cover point) that had the location, type flag (low/high) and if it was reserved (so 2 AI's wouldn't try to use the same cover point). I also had the custom type for the Black Board so we could use it in behaviors. Eqs would look in the octree for a point in a radius checking the type desired, that it was free, not closer than X (so it didn't look stupid), not further than the weapon range, nav-rechable and in between the target and the AI (including the path) so you wouldn't see and AI run pass the target in its face to cover (this happens all the time in Star Wars Outlaws and pisses me off to see it)
Now, if you have several enemies and you need squad behaviors, you can have a director AI calculating this and driving where the AI's should go. Left 4 dead is a famous example of this, but there are many others
More examples here
https://modl.ai/the-ai-director-of-left-4-dead/
is there a maximum amount of ongoing AI state trees that are supported?
if i load up enough actors with state trees, eventually some stop working
Umm good question. No idea. Do they stop ticking completely or do they fail some condition and stop doing what is expected?
Nice! Thanks for sharing
Is it possible to detect path blockers that are actors of a specific class/can be interacted by AI? I'd like to make my AI open/break doors if it's making the path to a location shorter
One way to do it would be to make them not affect navigation, and then if you collide with one, you would handle it then
But not sure if there's some better way to do it
So I should check if the pawn has a door in front of it within some range?
That's enough for me as I'm just learning about AI. But I'm curious if there would be a different approach for a game that would be shipped
Well at least with doors you could use navlinks
Yeah I'm actually looking to implement a AI director, but how would I create that? Would it be a subsystem? Or maybe a component with a event dispatcher?
Or would it be something completely different?
up to you and your game architecture. A subsytem would be, for me, the best choice since it will be always present without the need of having an actor in the game for it, easy to access from components, auto-initializes and finishes too
I see , is there a good resource on making an AI director using a subsystem? I couldnt find much on them and it would be my first time implementing my own
You just make a world subsystem and then start coding things that you think should be in there.
It is up to you to determine how you handle the things that are influential to the AI Director's decision making
Like, maybe if the total health of the group is less than 40% of the potential total health, you spawn less
Ah I see
Or maybe if you find that someone is too far from the group you spawn a boss that targets them
So like the subsystem kinda tells the whole team what to do
Subsystem tracks certain things about the players and then makes decisions based off that
Well it's more strategic like mgs but I get what your saying
I thought subsystems only initialize and deinitialize
No. They're UE's version of singletons
Oh I see
Think of it as a general commanding troops
The general is the subsystem and the commands are sent to the different AI's there (usually AI's would resigter into some collection (like an array) within the subsystem on spawn etc
Posting this pic about a problem I've been talking about in #ue5-general. Basically, I want the enemy to always be running the rotate task, shoot whenever it can, and if it's unable to shoot do the move task. On the move task, I have an AIMoveTo function.
Problem is that I need to put a StopMovement function somewhere, if I want the enemy to stop moving once it starts shooting. But it's bad practice to run the StopMovement function every frame, if I were to just put that in my shooting task, right?
Use the built in Move To node
A Simple parallel node might work well here (for the rotate)
Any reason you're not?
Because I have more specific needs (for example, it stops moving once it's close enough to the player)
That is what the acceptance radius is for
And what I'm saying is use the built in "Move To" task in the BT
The acceptance radius is specifically for a range check pretty much
Both the AI Move To node you have right there and the Move To task in the BT do the same thing
As for rotating - you can do the parallel node like Neo said or make the rotation a service and put it on the shooting task
Depends on how you want it to behave
IE - Stop and rotate and then shoot
Or rotate while shooting and all that jazz
When I do that, it doesn't rotate and move at the same time
If you need the acceptance radius to be configurable though - that is something that the Move To node lacks.
You can always be using the "rotate towards velocity" property (or w/e it is called) on your character
Huh?
sorry, I don't understand :3
There is a property in the character (might be on the character movement component) that will rotate your character based on the direction it is supposed to be going.
So if you send it a move to command - it'll rotate towards that direction
The rotation I want it facing is independent of the direction it's moving
The Rotate BT Task I made makes the AI rotate towards the target at a preset speed, unless the target is within a minimum distance in which case that preset speed increases
The problem is that if I use the built in Move To BT Task, the Rotate BT Task doesn't work properly :(
If you want to always be running the rotate task - make it a service and put it on the root selector
Just like how you have your "Update Blackboard Values" service
Or if you only want it to be running only when the player is perceived - just put the service on the selector that is below that sequence node with the "Has perceived player" decorator
Anyone here doing async navmesh generation in 5.5? It seems completely broken and I can make the engine hard crash on a fresh project just by setting the nav mesh generation to dynamic with a lazy/async gather. (I have submitted an issue with repo to epic, but curious if anyone here has worked around it).
We use async with dynamic with modifiers only (which is static with nav modifiers) and all good in 5.4. We don't use world partitioning
yeah works just fine in 5.4, but there was a bit of a refactor/rewrite to navmesh generation in 5.5 and it seems like async is busted
guess we are sticking in 5.4 until a hotfix or 5.6 which sucks cause there are many other 5.5 features we could really use
Could do a source engine build, but keeping the team in sync is a hassel i want to put off as long as possible
We are not upgrading versions until hot fixes are published generally. But if that bug requires changing header files, will not be fixed until 5.6
welp then its probably 5.6 as part of the issue is a one line inline function in a header (getting a weak ptr)
forgive me for being dense here. so i went ahead and created a new NavArea called NavArea_TitanIgnore and gave it to the mesh (it's the red box). i would expect to start seeing pink all over the nav, but unfortunately that's not happening
restarting the engine seemed to have done the trick. added a nav filter and voila
hey everyone, im having an issue where characters that are enemies are not sensing each other. they're both AI characters. is there a specific collision setting that i need to enable in order for characters to sense each other?
You need to add, not only the AI Perception component to their controllers, but also the AIPerceptionStimuliSourceComponent.
i can look thank you! btw my AI perception is on my characters. should i not do this?
Honestly, not sure. I have always put the Perception in the AI Controller and the stimuli in the character, but at this point not sure if it's a force of habit or if there's a good reason for it that I forgot... I know... Terrible orwctive
here's what i've got set up, let's see if it works
i have it on my character because my character has a data asset that provides its "line of sight" and then on PossessedBy i set up the sense
I guess that works too?
damn, even setting a source is not working
could it be a collision problem?
ETeamAttitude::Type ABastionEnemyCharacter::GetTeamAttitudeTowards(const AActor& Other) const
{
const auto ASC = GetAbilitySystemComponent();
if (!ASC) return ETeamAttitude::Neutral;
if (const auto OtherCharacter = Cast<ABastionCharacter>(&Other))
{
if (const auto OtherASC = OtherCharacter->GetAbilitySystemComponent())
{
auto TagContainer = FGameplayTagContainer();
TagContainer.AddTag(TAG_Gaia);
TagContainer.AddTag(TAG_Titan);
TagContainer.AddTag(TAG_Player);
for (const auto& Tag : TagContainer)
{
if (ASC->HasMatchingGameplayTag(Tag))
{
if (!OtherASC->HasMatchingGameplayTag(Tag))
{
return ETeamAttitude::Hostile;
}
}
}
}
}
return ETeamAttitude::Neutral;
}
i've confirmed that ETeamAttitude::Hostile is being hit
If you open the gameplay debugger and enable the Perception category, any data that might help?
oh, let me look!
AIPerception->OnTargetPerceptionUpdated.AddDynamic(this, &ThisClass::OnTargetPerceptionChanged);
🤷♂️
literally nothing. WTF. it's so weird that it works for players and not for other AI characters
Dude it says on the log
You need to put your AI Perception on the controller or bind manually the event
XD
Look at the log line below
i'm binding manually to the event
AIPerception->OnTargetPerceptionUpdated.AddDynamic(this, &ThisClass::OnTargetPerceptionChanged);
it's working for player characters, not for other AI characters
If you open the gameplay debugger (what you show is the visual logger, I'm talking about a different tool) and open the Perception category (usually 5), does it show any debug?
is it because my mesh is too big?
maybe something about it needing to be at eye level?
there's collision
but yeah no perception
he's clearly in the cone there too
You will need to debug the AISense_Sight to check why the sight traces are not hitting
what game trace does it use by default btw?
Can't think what else could you try, aside moving the component to the AI Controller as a sanity check
is it visibility?
anything obviously wrong here?
detect Friendlies. Enemies are friends of other enemies
not quite:
there are different factions in the game
the titan just detected some enemies btw, but not the other way around
could be a potential clue
let me check the gameplay tags...
ah... that's a good start yeah
Is Run Behavior in a BT just to split the logic into smaller graphs and keep it tidy or is it possible to implement generic behaviors like roam around and use it inside other BTs?
no dice 😦 the tags are correct... sigh
i'm debugging now
ohhhhhhhhh
i think it's because the pawn is too large
yep
as soon as i make the pawn smaller, the AI system perceives it correctly
maybe i need to adjust the eye level for the titan
Yeah... If you don't tweak it, it's at centre capsule level, which for big enemies is way too high
It's to use any other bt that uses the same bbk (or a child) of the host tree. So to your question: yes to both
If you use dynamic run bt, you assign a tag to the node and you can inject bt's dinamically with that tag. Useful to have a node "attack", but each enemy has a different attack BT you inject there based on your enemy data
So if I can implement a base BB and generic BT's using that BB and create my other BTs using a child of that base BB, I can run them on any BT, is that correct?
Yes
Got it, thanks!
i had to adjust the point of view backward offset. figured it out by debugging. thank you!
Awesome! Well done dude
Good news: i see the single-line fix in github, in fact they fixed it 2 weeks ago on main. Bad news, its in a header and it doesn't look to be in the 5.5.1 hotfix that is out this morning, so looks like dynamic/async nav mesh won't work until 5.6 in the spring unless we roll our own build 😦
Although i see lots of header hotfixes in todays patch, so maybe 5.5.2
Honestly, it's very worth to compile the engine yourselves. Distribution can be a PITA y you never did it before, but quite easy if you use p4 and UGS in sync with your build machine (Jenkins or team City)
yeah, we're going to have to for dedicated server reasons, but we have no automated build process right now (6 person remote studio)
This seems pretty moronic tbh. "If we break stuff we can't fix it until a new major relase" ???
I would assume if they broke something that is clearly a bug then it would be fine to include it in a fix release
I think its more about breaking API compatability and if you change a header its breaks existing 5.5 games... potentially.... but his one wouldn't as its a bad check() so maybe it will make it in
Yeah
This may be a stupid question, but how do I return out of a custom BTDecorator? Tasks have a Finish Execute node, but I'm not seeing anything in editor or in documentation that would be an equivalent for a Decorator
Ah, found it. I have to override functions to get the input and output nodes.
I'm only interested in running my State tree at certain events. I've got it working but not sure if this is the intended workflow, ideas?
This is for the root component:
Does anyone have recomendation for state trees? Like how do they compare to the behavior trees, once you learn them, are they easier to use?
i'm using state trees right now. they have their own challenges. but i like them infinitely more to behavior trees.
behavior trees were always confusing to me. once you become proficient with how they work it becomes easier, but for someone doing indie game dev where you have to wear a lot of hats, it can be hard to reconcile how they work after not working with them for a few months
state trees i like more because they have a debugger out of the box and they record all of the state and why their state is changing
i also really like the way their data binding works. it's different and much less esoteric than the blackboard. you can bind your properties directly to something called an "evaluator" and it makes it so much easier to work with
ah right the debugging, yeah you have to have a lot of set ups with behavior trees,
you mind showing me some work that you did with them?
funnily enough though, i am struggling right now with a state tree problem
like what
my full gameplay loop is on a state tree
like anything really
one of the reasons i find state trees better to work with. they have tons of detailed messages about what's going on
having an issue right now, anyone know what this could mean? and how do i give my transition a priority?
i just wasn't looking in the right place. the debugger was telling me exactly what was happening. a condition was failing. i fixed the condition and all is well
so do Behavior Trees.
- Visual Logger debug
- BT Editor shows the flow (which you can pause), the values of the blackboard and you can add breakpoints
- Gameplay Debugger also has an AI category that shows the BT's execution flow
Both lack debug in builds though
I'm losing my mind here. In my test level I have multiple NPC pawns that share the same AI controller. You can see on the screenshots of vislog that BP_NpcController_C_0 is possessing BP_Npc_C_0 at one moment and in the next moment (literally next tick judging by the time gap) it's already controlling another pawn. What can cause it and how do I prevent it? It kinda messes up with a few parts of my AI code that does some things with AI controller and it expects a pawn to be fixed for a controller 🤔
ok, nvm, i think I figured it out. It seems that for whatever reason I just have multiple AI controllers (which are spawned on PiE start for NPCs placed in world) with the same name, so no controllers manages multiple NPCs at the same time. I'm not sure if thats a good sign or not, but it does kinda mess up reading vislog data since it groups data by vislog data provider name and it is the same for multiple controllers. Any ideas how can I prevent it? 🤔
- bt's are vastly more solid, they have been running in games since ue4.0 (state trees are experimental and constantly changing to add basic features)
- lots of tutorials and learning material online. And since they follow the BT "standard", any documentation about bt's more or less applies to unreal and the other way around
- easier to control performance than with state trees (state trees run on tick constantly as for 5.4)
If I was a teacher, definitely Bt's because that can be translated to any engine with similar approaches. St's are unreal only) altoguh they are HFSM)
For State trees, just curious, what sort of naming Conventions have you all been using for Tasks?
Dang. Must be hard to find the actual task if they're all named "without the STT" in your editor.
You do you boo
:D
And if you were teaching, say, an undergraduate class in Unreal/AI which would you pick?
sir this is a wendy's
Yeah I just got the joke.... Time for a coffee
I have a general question for AI move to, if I have lets say 10 of the AI moving to a single point they clump up, how can i prevent this, I know about nav modifiers but You have to manually place them into the world and etc, what are some tips any of you guys reccommend?
Crowd control will handle the "clumping up". But you will benefit form better logic to choose the final point (you could store it somewhere and have an eqs pick points nearby that are not picked already
but lets say this AI is a zombie and this point is the player location, how would you go about it then? what do you mean by croud control? if i have 100 zombies running to the player what do you do then?
this ai is a melee ai too
so basically while using a parallel tree run an eqs query to adjust the movement?
- you will never get 100 AI's running with decent framerate using Unreal Character Movement Component as is, it's too expensive on cpu.
With that out of the way:
- crowd control is the Engines Flocking behaviour. It will prevent AI's to get stuck against each other but, if they run behind a player, they will end up in a single line.
My eqs suggestion was for a static location.
Alternatives for chasing: something like what Sunset Overdrive does but unreal version: each AI follows an actor that is not the player but an actor that gets it's location updated in tick. It's location will be the player location + some distance to the right/left of it. That way they will run chasing the player but not collide (or fall in single line).
That or implement your own flocking behavior (will post links if I can)
No this is not a good idea. You can try with that, but using a location in move to causes issues. You want to set it to an actor (updates are more natural because it doesn't stop the movement when the actor changes locations. If you use a location it will stop and start the movement every time you update it)
GDC talks cover a range of developmental topics including game design, programming, audio, visual arts, business management, production, online games, and much more. We post a fresh GDC video every weekday. Subscribe to the channel to stay on top of regular updates, and check out GDC Vault for thousands of more in-depth talks from our archives...
Look for avoidance behaviors (unreal has 2 versions, RVO and Crowd control. First one doesn't care about nav and can push AI's outside , the second one will keep AI's in nav but AI's can't collide against static/dynamic objects, which can cause them yo go into walls in extreme cases (you need to change the movement mode to nav movement mode in your Movement Component)
interesting take, I see what you mean any other approaches that you recommend and that you like?
Not really. If you check videos of the ascent (top down rpg shooter) and you see gameplay where there are several melee enemies running to the player, you will see they do exactly that acotr approach. With a twist: the closer they get to the player, the closer the proxy actors are to the player too. If they get far (because the player is fast) the proxy actors move further (whit a limit). Or so I have been told
Do that, add crowd control on top and you should get something quite decent
thats actually clever and is really easy to do as well, im just trying to think on how I can make the actor approach work, because its one actor right that they go to, or each enemy will have an actor instance they will go towards?
Some people prefer to do custom avoidance/flocking logic. There are some plugins available too
or instead of the actor would eqs work as well? the perferred point is controlled by the distance
so basically the distance shrinks the area of points the closer it gets to the player
One actor per AI moving. You can have a pool and re-assign them. Proxy actors are super simple: just a scene component. You can even disable tick and make the AI update its location. Once the proxy actor is super close to the player, you can snap it to the player location or straight target the player and forget about the proxy (skip updates) until the AI is far or needs to move somewhere else (once you have the proxy actor approach you can use it for every movement thing. Just place it at the desired location, like a patrol point, and go there)
But with points you will run into the start/stop problem. Do a test: chase the player with one AI. Then do the same with a point you update in tick that you pass to move ai. You will see each time you call move ai there's a stop of the movement. It's not fluid
Ok im going to experiment with both thank you for the help, I always wondered how to go about it
It's one of those things that are a known secret. Watch the talk I posted at the timestamp marked in the link, so you get an idea of what you can achieve. They use forces and angles but same end result
Thank you
Good luck!
That talk is quite good
but they dont use the actor approach though, just a flank manager that calculates theta right ?
Yeah. Different engine and solution. You can do that too. For me it's much easier the proxy actor approach, but it's just a choice.
and as long as they are pooled performance wont be affected
If anything, spawning them the first time. But you can do that during the loading screen and keep them in your pool, no need to do it on the spot when they are needed
So for the actors you spawn them in per zombie in the level, if there are 100 zombies across the entire map then spawn in 100? or only when the zombie engages with the player you spawn them in?, then when the zombie needs to move to the location, set the actor's location to the player's location, after all of the calculations i want to do then offset it to my liking, correct?
oh wait since its a scene component then its already on the zombie
so just set the scene component location to the actor location then perform the calculations right?
ProxyActor->SetActorLocation([here you put your calculated location during the AI tick])
Then, since move to is to an actor, your proxy actor, your AI will seemsly follow until reached
Ok I see what you are saying, im going to have to do a few things in terms of setup different because of my current system structure, thank you for your help
No worries. Maybe someone has a better approach, but I shipped games with that and I can vouch for it
Thank you again, ill keep you updated on how it works out
hey all, in my CPP code i'm calculating the target position in which my actor needs to be in (it's a dynamic combat system) in order to cast spells. i'm using an evaluator to take this info from CPP and store it into its own variable in the blueprint.
is there an easier way to do this? it'd be nice if i had access to this directly in the state tree without going through the evaluator. this delegate is called on tick, so i can't imagine this is performant at all
Evaluators are about to be deprecated by Global Tasks.
You are facing the same problem I have with state trees: they assume you will do everything in ticks. Making things event driven it's a bit difficult
i'm actually about to move to an event driven system. the challenge is that the combat position needs to be handled in real time. the target (usually the player) can move in any direction so the position needs to be recalculated when that happens
but calling a delegate on tick feels wrong and wasteful
would you happen to know where i have to raise the event? i mostly raise the event on the ASC but do controllers allow you to send gameplay events?
when you make an EQS cone it says generate in front of querier. Anyway to inverse this? I want the point set behind
@slow bobcat im not sure how to go about the proxy location algorithm
im having a hard time, im trying to account for the angle and distance and at the end of the day they still clump
Currently have a problem where my BasicAttack task is being selected, but is getting interrupted by the StepDodgeBackwards node. Confirmed the BasicAttack node is actually triggering, I get output off the 'interrupted' exec branch of that task's underlying PlayMontageAndWait call.
What I don't understand is, why? Shouldn't the behavior tree wait until the task has completed before it moves onto the next thing in the sequence?
cant you just invert the Cone Degrees?
get th opposite angle
read what a sequence is, it breaks execution when something fails
WIP
The goal isn’t just to manage a large number of AI but to craft a beautiful, fully functional ecosystem.
I’ve been working on something that’s easy to use and debug: a multithreaded AI system. Hornet features a custom behavior tree and state tree for creating unique behaviors. The whole system is multithreaded, allowing you to implement things like flocking algorithms with 4,000 birds alongside zombies, essentially creating a fully functional ecosystem.
Oh, and it also supports Utility AI
I got low - mid gaming pc 8 cores, 8gb vram and about 150 fps on shipping
What do you guys think of this?
that doesn't work how you'd expect, it always starts from the faceing direction. I just ended up making a 'donut' line from the target past the querier
worth a shot 😦
the basic attack isn't failing. its starting to play the montage and then the BT is instantly moving on to the next thing, and the basic attack montage gets interrupted by the dodge backwards montage. If I remove the dodge backwards node in the BT, the basic attack works just fine
that's one flat donut, but it works
haha
I just needed a point behind the enemy after he attacks
what is inside that task?
have you checked the distance
because you have a decorator for entering the sequence
the reason I would like to see inside that task is are you calling the play montage function, then dragging off of completed and finishing the task?
on the same idea tho, how would you make a mob back away as you progress forward, common with the knights in smth like dark souls 🤔
I actually have that
oh you got a dot product in there ey? interesting thanks!
Task itself is very simple. The underlying function it calls in turn calls a GAS ability, which is where the PlayMontageAndWait is
yes it works at a basic level if the enemy is facing the player and the player facing the enemy
that behavior is probably why, put a break point on that finish execute and see if it executes before or after the task
if it executes before try some delay
nice, I'll try something like that, might eliminate the need for a flat donut
haha, im still stuck on crowd control for my zombies was talking with bruno and I have the pooled actors but I dont know how to approach the location algorithm
probably what its doing is executing that animation on another thread then while it started the thread it then goes to finish execute
alright yeah, its getting to the finish execute before it plays the animation. Something isn't documented properly here, because nothing I'm using is Async. So I shouldn't get to the Finish Execute node until the Basic Attack function completes....
yea as a temporary thing im doing this
the point of PlayMontageAndWait is for the ability to not complete until the montage is done though, right? Unless I'm misunderstanding
im not sure I dont use that node
That's impressive. That's actually a low/mid pc, which makes it even more impressive. Great job
Ping me in 10/12 hours (it's 23:21 here), going to sleep now. I will try to help
I got the object pooling actors set up but the further I get away from the zombies the closer those actors get to one another, thank you and will do
Love that you can have more than one tree in the editor. How do you handle the MT for actors movement etc? Is it custom logic everywhere?
Ah. Abilities are inherently async. That's the problem
While cool - in my experience, the BT/ST haven't been the bottleneck. So this isn't as attractive imo. The bottlenecks are rendering and CMC mostly. Plus the 4k birds - that is a long solved problem. Just use particles.
ok
@harsh storm while you are hear, whats your approach to mob crowd control?
Bruno is helping me but want another perspective
I'll answer in a bit. I was just browsing - but about to eat dinner
ok
While the bird project was a fun side project, primary goal was to develop a framework that would allow anyone to easily expand upon threaded content. This framework includes custom VATs/Flipbooks in the editor.
My next step is to create something more dynamic, such as a well-functioning survivor AI to complement that zombie vid. Also aiming for better VAT support within AnimBp and improve animation workflow to efficiently handle VATs across numerous actors.
also, we got custom CMC and custom Physics in place :)
Hope this helps!
do you have a crowd control system in place? Wondering what you did
Anywho - are you talking about like, having a lot of mobs chase the player or something like that?
Sounds good 👍
yea but right now they chase in a straight line towards the player, like a conga like
You can give them an offset
So it looks more natural-ish
Can use EQS to also find a location.
But Bruno said that moving to the actors are better
like a move to actor is better then a move to location
Try both. See which one you jive with more
I was going to do that but didnt think it would be correct
which do you do
Correct is what works and meets your perf requirements
I don't often have mobs, so it has been years. I do w/e is simplist. So offset
then when they get in a specific distance they will have to move to the player's location then
I'll see what I can whip up thank you
hey all, a bit of a dumb question. where do i send gameplay events to be caught by the state machine?
looks cool but idk what im looking at
looks awesome
SendStateTreeEvent
is it possible to assign a parameter based on a payload from a event in a state tree?
i'm a bit confused by this whole thing. can we receive events for state trees inside of global tasks? seems like parameters simply cannot be set
so do we just have a single global task that holds all of the state we want to store for the AI?..
any chance anyone can point me in the right direction here? any docs potentially for state trees that use global tasks for info? i'm using an evaluator right now but it'd be nice to determinisically set parameters instead of doing it on tick
State tree events are events sent through the state tree component to a specific tree. In 5.5 they support a payload to be passed alongside. I only use them in transitions, not sure you can listen to them in tasks (whether it's a global or a local state task). My first time using then I got confused because I through they were like any other delegate you could subscribe to, but nope, they are an internal thing (to state trees I mean)
That said, if you want to do things in a event driven way (like the AI God intended), you can make your tree task FInstanceDataType a class instead of a struct. Then, it being a class, you can have Ufunctions to be used as callbacks when subscribing to delegates. You can subscribe in Start and un subscribe in End.
Your global task can listen to delegate broadcasts / executions and set paramenters then
Here @misty wharf did a guide on how to do it
https://zomgmoz.tv/unreal/State-Tree/StateTree-InstanceData
You don't need to listen to event in tasks, the tree is listening to events constantly. You define a transition with the event you want and you're good. I see they also introduced an entry condition event thing. But don't know how that works, have not found a use case for it yet. Using them in transitions should cover a lot of common cases
Is it a bad idea to give AI skills (not GAS, simple custom components) that requires aiming (with GetActorEyesViewPoint) and use focus to aim before activating the skill?
As state trees are right now in 5.5, is there any way for them to not tick and be purely driven by events? And is creating a schema for the tree to work with UObjects a huge hassle? Any insight is much appricated 😄
For NPC's, sometimes it's missing when the player jumps or makes sudden movement change, when I want it to succeed %100. Should I just skip aiming part if the player is a bot and use target BB value?
Yes but it listens only to State tree events. What I mean was for cases where you want to listen to other type of events (like some component delegate like a trigger on enter etc)
I'm in 5.4 and all the events are handled in the Execution Context tick.
There's an event queue where events are added, tick in the context process them, then the queue is emptied
But no idea if 5.5 has changed that much
About schemas, no idea. Never did one
I use the default for AI (same as the base one, but with the AI Controller in it too)
But the transition needs to be set on the root, correct? Also, the point is that I want data from those transition events, which is where the complexity comes in
Nope, on whatever state you want to transition from
Unless you want it to always be relevant then I guess root is ok
@slow bobcat Are you available currently to talk about the crowd control approach
yeah i still don't understand. i just want something like a blackboard where i have access to it and i store information in it that is accessible to the entire state tree...
i already have tasks that are backed by UObjects (appreciate that advice, it helped me create a deterministic task) but let me give you an example.
say that my character is idle. and then they move to in combat because they have a new entry in their threat container. i'm sending that new threat in the event payload. it's clear to me that the event payload is freaking useless (i basically can't do anything with it but apply a conditional on top at the state tree level).
so now what do i do? the only thing that i can think of is to set a shared field in the character somewhere, grab it at the global task level, and then bind to that value in the following tasks (like, "move to threat" for example)
Hey, just left the office. I'm running errands and stuff for the next few hours but I will try to talk with you after
You just described output parameters in a global taks
so i have this right now in an evaluator
and i'm going to switch it to use global tasks
Isn't there a way to use the payload to set variables in the tree? Aside the tree component I mean. I'm still in 5.4 so I don't have payload
but the evaluator is subscribed to a delegate and that lives outside of the state tree
Isn't there a way to use the payload to set variables in the tree? Aside the tree component I mean. I'm still in 5.4 so I don't have payload
unfortunately no, not through the UI. i looked for a CPP API but i have no idea where to start
this is the whole point of what i'm saying btw
i can't find how to get the payload output variable to set a parameter in a global task
so the payload is basically useless
In 5.4 events are handled in the State Tree Execution Context tick. Check there. Might still be there and maybe you can see where the payload ends or if it can be passed to task somehow
ok if you can ping me if you dont mind that would be nice, dont want to ping at a wrong time
Anyone else run into issues with a nav mesh working fine in one level with a landscape but go to another with the same settings but using static meshes for the floor and it refuses to generate tiles
Using dynamic + invokes (same actor with invokes across both maps).
5.4.2
Placed navmesh/ build navigation
Are State Trees bugged in packaged builds? using 5.5.1, they don't even start. run fine in editor
how are you running the tree? are you storing it as a field in the controller?
or is it in your developer settings?
State Tree component in the AI Controller
I've assigned it static inside the component
you assigned it in a blueprint?
Yeah in the AI Controller class, inside the State Tree component
the reason i ask is because if you renamed the asset there could be a chance that in a packaged build it's not finding the asset at all and that's why it doesn't load
I see, i'll quickly test with a fresh tree
Yeah seems to run fine on a fresh tree, must be corrupt somehow
Quick question, is crowd avoidance ai or rvo avoidance more performant?
again, it's probably not corrupt if it works in the editor
it's purely a path problem
you need to correct the path
however i'm glad you're unblocked
Ah it wasn't the asset, it's that Get Property Reference doesn't work in shipping, since it failed and it went back to root it looked like nothing was running
I think rvo is more perfomant because it doesn't do nav checks, but better to check with insights. It's an educated guess
I actually got it working with objects and for the tree tick should be rather easy to solve, thanks for the pin pointer 😄
What do you mean by "with objects"? I'm interested
UObjects, instead of using components
I got some FSM in cpp logic, but can become quite large, so i want to try replacing them with state trees. But my data and logic is containe within UObjects so i couldn't use the state tree stock schemas
Sorry, instead of actors i meant
You mean as using a uobject as some. Sort of blackboard for the state tree? Not sure I understand where the Actor part fits
Not to familiar with blackboards. The stock state tree component takes a Context actor class so you can interact with it's variables. I've just created a state tree object schema that can use a context object for variable interaction.
Is it difficult to create your own schema? How do you return the extra objects inside?
I'm only doing early crude testing, no huge blockers so far so take it with a grain of salt.
-
You basically just copy the content of the component schema, change actor references to object along with string params.
-
Copy the state tree component, copy the content and do the same here, this is parented to the BrainComponent so you need to remove some of the conditional checks for it to initialize properly.
-
Swap schema references in your new component to your custom UObject schema.
I'm going to probably reparent the custom state tree component and strip out all the unused Ai-related stuff. Right now it's just functioning in a hacky way 🤣
Just debug the component initialization stage and setup sequence and you'll see what's needed and not.
Hackity hack woooosh (swings the magic wand)
Hey dude, I have some time now. Wanna chat?
Trying to get my ai character to be able to walk backwards when using the MoveTo function in the behavior tree. Things I've tried so far:
- Turning off Orient Rotation to Movement and turning on Use Controller Desired Rotation
- Setting focus in the AiController to the player actor
- Doing a parallel sequence with a constant rotate towards the player during the move to
- Setting Allow Strafe on the AiController to true
- Setting UseControllerRotationYaw to true
None of these have worked, and the ai character continues to turn around and face the direction of movement instead. Any suggestions on something else I can try?
Try disabling Orient Rotation to Movement in your character, then try avgain your solutions
Yeah, let's. What's the problem?
already tried that
Ah sorry, just read it again. I thought you tried that but not combined with the other things
Nah at this point I'm doing all of them in one big long chain lol. Nothing's worked so far
I tried your recommended approach with the proxy actors but im having a hard time witht the spreading, i tried to take into account the enemy angle and the distance but that wont work
Dm (let me know here if you can't see my mesagges in private.)
Is this why this doesn't work? Ugh
Umm maybe. I would need to check how do we handle focus. That was written years ago and we have our own priority stack for it.
Ok ill dm
had a bug where bool I input into my toggle focus task wasn't negated for the branch that set or cleared focus. So while I was properly setting Orient Rotation to Movement and Use Controller Desired Rotation, I was clearing the focus instead of setting it to the desired target
It's always the stupid thing lol
What is the general consensus on using marketplace 'AI' packs that contain pre-configured logic for common behaviours? More hassle integrating than they're worth or geniune timesave? Would like to use Perception system + GAS for more complex combat behaviour
I'd say an overwhelming majority are way more hassle than they are worth. With no guarantee that they even actually do what you want.
How do I abort a tree immediately when a decorator condition becomes false? Currently the character is completing the current action before swapping. I want it to interrupt
specifcally, aborting MoveTo. I see multiple different solutions out there, not clear on what is the correct way
easier than I thought, just needed a decorator to abort self on it
@slow bobcat i figured it out
i figured out how to assign to Parameters in state trees
FStateTreeRunEnvQueryInstanceData has an example:
UPROPERTY(EditAnywhere, Category = Out, meta = (RefType = "/Script/CoreUObject.Vector, /Script/Engine.Actor", CanRefToArray))
FStateTreePropertyRef Result;
auto [VectorPtr, ActorPtr, ArrayOfVector, ArrayOfActor] = InstanceData.Result.GetMutablePtrTuple<FVector, AActor*, TArray<FVector>, TArray<AActor*>>(Context);
if (VectorPtr)
{
*VectorPtr = InstanceData.QueryResult->GetItemAsLocation(0);
}
else if (ActorPtr)
{
*ActorPtr = InstanceData.QueryResult->GetItemAsActor(0);
}
the api is balls, but at least i can go fully event driven now
StateTree randomly crashing when compiling, when playing, when stopping the game, when binding context, thats literally unusable as of 5.5
I can't even open my asset sometimes
Sometimes can
Sometimes it crashes
Sometimes not
It even crashes if I press compilation button 2 times in a row (first time is successful, the second crashes)
The most recent one crashed on StateTree compilation phase when it tried to compile Enter Condition if (Abs(MyParameter) > 5.0)
Just recreated the crash on like 5th attempt
I can understand bugs which are stable, it happens and unreal engine is a big engine
did you make that struct?
StateTreeCompareFloat?
or is that a system struct?
seems like you're trying to compare a nullptr
Its a part of an engine
thus the 0xffffffff
Yeah its a global parameter
in the UI, are you binding to a float?
Cant be nullptr
for some reason, Parameters seems to be nullptr here
that really sucks though 😦
i'd probably make the state tree again
It happens when I open an asset
yeah i'd just recreate the state tree asset
So I dont even get how it ever remotely can be related to my code
unlikely to be related to your code
If it was the only problem
Theres lots of random problem occuring at random time, tedious to recreate lost progress all the time
you should try 5.5.1 to see if that's fixed
Its 5.5.1
or look at the release notes for 5.5.1
oh
yeah i feel you with unreal. every once in a while i get a crazy bug like this
Oh, 5.5.0
it's rare but it happens
But theres no StateTree fixes in 5.5.1
if i were you i'd set up version control
so that when something like this starts happening you can revert the asset
Bruh ofc Im using it
Im thinking of getting back to BT
do it, it's much more stable
At least its a bit more stable
i've also debated switching back to BT
but now that i'm unblocked on events i'm gtg
i haven't had any bugs with state trees at all, you should try recreating your state tree asset from scratch
How do I recreate event stuff in BT?
That was 3rd one
No
wow, that's surprising
might be worth opening a bug report
does it only happen with this operation?
Ive stopped counting after 5th different stack trace
?
I liked you can interrupt StateTree, can I recreate it in BT?
Like Aggro state -> Attacking -> on event target lost -> switch to state PlayOnTargetLostAnimation -> OnFinish return to Root (which will eventually lead to idle)
everything you can do in state trees you can likely do in BT
it's just a different paradigm
BTs have decorators and tasks IIRC
But Idle -> on event target appeared -> do different stuff -> aggro state
yes you can do all of that
Like, not mirrored
and significantly more
Different transitions
BTs are the standard way of developing AI in Unreal
but there's a bit of a learning curve, i would recommend watching this: https://www.youtube.com/watch?v=iY1jnFvHgbE
In this presentation, Epic's Paulo Souza uses Unreal Engine's built-in AI features to build smart enemy behaviors for a game with stealth-like mechanics.
By relying on the Gameplay Framework in Unreal, we're able to quickly create convincing AI using Behavior Trees. Behavior Trees are great for creating complex AI that can be presented in a way...
from start to finish
I've been researching a lot
So far not a single enterprise-level game using barebones BT
They all seemingly use a mix of Utility + BT or just Utility or hierarchical fsm
one thing i don't like about BTs is that i very often ended with something i call a "doom loop" where the brain is stuck evaluating endlessly until a condition is triggered
you making an enterprise game?
I've described the behaviour here
Even that simple thing doesnt go well in BT or I dont understand something
lol
Theres lots of sphagetti when youre doing non 2-way conditionals
what do you mean?
^
i literally have this exact thing working on another project with BTs
and i set this all up again in STs like last week
Thats an example, transitions from and to attack are different
With a bunch of linked decorators with NOT logic on them?
No, I mean the logic inside decorators
it's just a blackboard, BTTask and decorators
i don't know what you're asking i'm just letting you know it's possible, it's not as convoluted as you might imagine, it just takes getting used to the engine
You cant even subtree that stuff anymore
that way
Sorry for being harsh, just kinda sad of StateTree and its like a month of work lost
youre good, such is game dev
it gets easier
easier is probably the wrong word, but for me it definitely got significantly easier after a certain point
just takes time
and you didn't lose your work if you're able to figure out why the engine is crashing
i would open a bug report
Not true. I have been in projects that use Bt's as they are (with custom decorators, services and tasks of course).
My preferred approach is to have:
- a state tree on a very high level just to decide if idle, combat, patrol etc
- bt's for each of the aforementioned states.
I my previous game the state tree assigned g.tags to the character that are read by decorators in a main tree that runs the corresponding subtree.
Utility is good if you have a heavy use of decision making (ie while in combat the AI has 8 different attacks) or rpg's where many things have to be considered before making the call
This happens in st's: they tick endlessly until a condition or event happens (unless you disable it's tick and control said condition externally)
not sure if you saw but i figured out how to get parameters set through tasks. so the next step would be to see if it's possible to do this from within the event
Tree with 2 branches hanging from a Selector
- left branch is a sequence with a decorator that listens to an event and can abort the Flow. To listen to an event you register in Become relevant and unregistere in cease relevant (you need to enable the flags bNotifyBecomeRelevant and bNotifyCeaseRelevant in its constructor). Create a memory struct in the decorator and Initialize it. Within that memory you will keep the handle to your delegate (the event you listen to). The memory is kinda your Instanced data in St's, a way to keep data specific to that decorator instance without actually making instances for each usage of it. Or you can instance it (you need to enable the flag in the constructor) and keep your delegate handle as a local class member (I don't recommend instancing due to it "wasting" memory). When the delegate broadcasts, in your callback, call abort on lower branches (which will be your idle) and set a flag to true. That flag is the one you have to return in your decorator evaluation function (can't remember the real name of it).
- the sequence above has your "do different stuff" and your "aggro state" (I understand that last one is the attack itself. That can be a separated tree you run as a sub tree.
- idle: an infinite wait with a loop animation. Right branch of the tree.
Yeah! Thanks! Funny enough everything ring bells
i'm actually having a weird problem atm. for some reason my character is not seeing this wall in the EQS query
whoops forgot to include the stimuli source setup
I don't recommend doing that. Perception system is very limited in terms of how many things can handle at one. I was part of a game that could have more than 30 enemies alive at once. Many of them (after the 30th) would never react. Turns out the Perception system was not processing them. It works by looping through all the stimuli sources and checkign how long it took to process them. If budget used (ms), continue the next frame. It got into a situation where the Perception array would change and new entries added at the end would never be processed
It's a system that need tweaking for large numbers of enemies. If you start adding walls and what not you might end up having the same problem
damn ok. but eqs doesn't provide me a way of checking if something is visible to the actor or not. i wanna do a raycast between the pawn and the target to see if it's visible.
so, check if see center. if not see center, hit wall until gone. loop
If walls are important I would recommend have a system to manage them where the wall register to it (so they are all in a collection) and you can query them without needing the Perception system
if i use actors by class then i can always "see" the center
i guess i could make my own custom EQS query
and do the raycast myself
i'm okay with the target knowing about all walls and then measuring based on distance, not a problem at all. i have a state tree that manages this, somewhat (and again, it works when i do "get all actors of class")
Actors by class is slow if you have many of them. Even though unreal categorizes actors by class etc, in the end, there's a lot of looping within the actors collections. And you will retrieve all of them in the map. Create an Environment Subsystem (a subsystem class, your friendly singleton in unreal). Make each wall register as "wall" so the subsystem puts them all in an array for walls (then you can do the same with houses etc). Your eqs can then check which ones are closer within the Eqs Walls Generator (you probably will need a way to grab the points in a wall since they can have different forms) by simply looping your array of walls. From those in range, discard the ones that are not within an angle of your view (within what would be a view cone). Then trace for the rest of you need it (traces can be done async so they ran outside the game thread. Same for path checks, which is usually something you need)
My 2cts
You have to give that to ST's: waaaay easier to read what's going on than BTs
Sorry I'm joining abruptly and maybe this has been answered but a new AI learner so I want to confirm my thoughts. Isn't this (interrupt) basically having decorators on your nodes?
This is how I setup my first basic AI, a player target (aggro) is needed to hunt (use the skill/kill the player), a location is needed to investigate (received from sight or hearing perception or last seen location of target player if got out of sight) and roam is just the basic (walking randomly + idle) default state in case there is nothing logical to do
Losing the player aborts hunt and failed execution continues from investigation. Losing also the perception location fails the execution and just continues to randomly walk
This is probably providing state changes from high to low priorities but reverse should fail (which I haven't tested yet), like starting to hunt once a player is seen while roaming, since there is no decorator to abort that task (MoveTo)
Does anyone know the implications of this sentence?
I only need tick in very specific State Tree tasks, but I have no idea what Property Copy means in this context.
Does that mean that I can't modify the instance data or anything like that?
How are we supposed to get the Context Actor from the context when you are in EnterStater within a task (or any other function that retrieves the context). Since I use the AI Schema, I always get the context owner, which is my AI controller, and then I grab the pawn from there.
But I couls simply grab that actor.
Can't find how
If your state tree component is in the AI Controller, then setting context actor class to your pawn class should make it assign the pawn instance to it
It has special cases in the code that populates the context to deal with that
Yeah my question is more basic as in "how do I actually access that variable in code?" is there a function or something I can call in the context?
Ah, I mean you'd just do an InstanceData which has a property AActor* Context (actually not sure if we should be using TObjectPtr on these also now)
Then you can just read it off that same as any other instance data
My AI Perception for Parasite type zombie Didn't get updating..
Updating Fast is not printing
What's the reason for this ?
What's the difference between these two screenshots besides the text? Are they in different controllers?
they are different AI controllers
This one is not triggering..
Okay, have you compared the perception settings on both controllers to see if there are any differences?
The most common reason for this to not trigger is the detection by affiliation setting
Aaaaaaaah.... Dude...
OK it's obvious when you see it.
I was reading Context so I was just doing "context->" with the Execution Context. Didn't occur to me to look inside the Instanced data.
OK ol thanks for clarifying it
Or the missing stimuli component in the AI character. 50/50
Oh GOD how can I forget this 🥲
Thanks btw
Well if the other one works it's probably not that, since UE does default to pawns autoregistering as stimuli sources
heh :) yeah it happens, I guess it's kinda hidden in the configuration menus
I got depressed about an hour for this 😂
Aaaaah true true. My bad
Sounds like the average experience with unreal
It's kinda weird it autoregisters the pawns, but then auto-configures the component to not detect any of them by default :P
It's like... Yeah we'll make it half-work
We have disabled the auto register so we can control when things happen, hence my assumption
Unreal in a nutshell. Makes it more fun
I must be blind or not understanding you (definitely because there's something I don't know), but I can't see what you mean
That's a ref by default isn't it?
Yeah I'm on 5.4 also... let me check what the code was I used
Oh, yeah I'm not sure what that particular overload does, but the one I'm using is called using FInstanceDataType& InstanceData = Context.GetInstanceData(*this);
Then it would let you just go InstanceData.Context->Whatever
ah right... that gets the instanced data of the state itself. Ok ok. Let's try that
I also have some code using external data for getting the character, I don't remember if that required some special setup or if the character was already handled by the default code for that
but... I'm confused... FInstanceDataType... isn't that only for conditions? or can it also be used in tasks?
I was under the impresion that you can only define your instance data types in conditions.
That one is usually defined with a using FInstanceDataType = FYourInstanceStructType;
ah yes... the only decen documentation done by that person you can't trust... XD
There's an example of using external data here https://zomgmoz.tv/unreal/State-Tree/StateTree if you want to try that approach
I'm not quite sure how these two are intended to be used tbh. The external data approach doesn't require defining the context actor in the instance data so it can be a bit more convenient in some cases I guess?
so... I'm stupid basically. I just realized that (obviously) you can define your own InstancedData type struct anywhere, whether it's a Condition or a Task.
Why was I assuming it was a condition only thing? because potatoes
but just so I'm clear (to not assume things again).
If I do this
FYourInstanceStructType
{
}```
What exactly do I need to put inside?
Is that Context automagically added somehow?
Or do I need to do this
FYourInstanceStructType
{
UObject* Context = nullptr;
}```
And the code will set my Context variable to my Actor type?
Because if I have to bind it myself (Adding a bindable parameter in my custom struct type) I don't get the point of the schema for AI
You have to manually set it up every time
I've been considering having a shared struct type which just has the context actor in it since it's pretty common to have nothing else than that
(Also it needs to be set up as UPROPERTY(Category=Context) AActor* Context; )
It might require the edit accessor for it to show up in the editor but I'd imagine it can bind the context automatically even without it
yep, that's what I have for conditions
I vaguely recall it uses the Category=Context to determine which ones to bind using the context data, but the name still has to match the name of the context data
aaaah I see. Damn that's obscure
good call. Thanks a lot for the help. This removes 1/99999 questions I have about this system
👍
has anyone ever made use of the AI learning agents beyond simple navigation?
Another State Tree question.
I want to Finish task based on a State Tree Event. Basically in the task tick I'm checking if the event exists in the event queue (context->GetInstanceData()->HasEventToProcess()), I do some stuff and return Succees.
But that's not how trees work. Execution Context will obliterate the Events Queue after evaluating transitions. So, this happens
- I send the event from an object
- Execution Context evaluates transitions, deletes all the events (call Reset on the array)
- My task never sees the event in tick
So I tried a different approach: I set a transition in the state running the task (on event transition) thinking that would call the ExitState function. But it doesn't. Transitions do not call exist state.
How can I handle this? I need to finish a task only if I get certain callback and I'm trying to avoid indirection where some object calls a function in the state tree component, so this one executes a delegate to which my task is subscribed.
Sounds lke there must be an internal way to handle it
Not sure but it feels like there should be a way to trigger ExitState on transition 🤔
I vaguely recall there are a number of bools you can set to adjust... some?... behaviors of the task maybe in relationship to these. Those might be worth checking if they did anything useful for this
Ok I can check. Please ping me if you suddenly remember anything that might be relevant. Ty
I don't see any bool that can help. I will debug code to see when/how is exit state being called
Yeah maybe the flags were more about copying some data or something 🤔
But it definitely seems a bit peculiar Exit wouldn't get called on transition, if you listen to any events or such how are you gonna clear those if you don't get exit
No idea. I saw that transitions have types and based in that exit calls. But that's a problem for Monday now
did you ever figure this out? i have code that does this so i can send it over
We talked about it here :) #gameplay-ai message
Is there some static method to find the nearest navigable location on navmesh from non-navmesh location? I want to simply teleport my NPC after it finishes using smart object which can be a bit off the navmesh to the closest navigable navmesh location (as a temporary solution)
Grab the nav system and look for project point on nav. You can pass an extension (imagine a cylinder) used to know how fsr to seek for the nav
do you mean this method? UNavigationSystemV1::ProjectPointToNavigation
Yeah.
ok, thanks, i'll try
Thanks I'll try
What would be a good approach to getting the AI to maintain a 'combat distance' from the player within a radius? (e.g. if the player gets too close to the AI, it backpedals. If the player gets too far, the AI moves towards)
At the moment I'm just using a Move to Location or Actor which works fine for getting close, but then the player can stand-on the AI which I want to not happen
you could probably use distance related decorators in your BT
In your case, for me, the key question would be: do I want to interrupt what the AI is doing to keep it's distance to the target or do I want it to finish what is doing (ie and attack) and then keep the distance?
- no: just a decorator in a priority branch (a branch on the left of your tree) that checks distance to the target and if < than the min distance, allow for moving away (this can be just a node or an entire subtree that calculates directions, takes obstacles into consideration etc. Depends on how advanced you need it). Whenever the tree re-evaluates, it will check your "keep distance" decorator/branch
- yes: then you need something like above, but your decorator should also abort low priority branches (it being the highest prio will cancel whatever the AI is doing). On top of that, you will need a service checking periodically the distance to the target and writting it to a bbk. Your decorator in this case will check that bbk value and abort on result changed. That will make your keep distance branch react at any time and abort the current action to favour it.
The other thing is what you mentioned about the player standing on the AI: it's not only about reacting at the right time, you need to move away from the target's movement trayectory (jumping to the side to dodge the train rather backwards if you know what I mean). But if you still want to move just away (like when a boxer dodges a punch stepping backwards), if the AI's velocity is lower than the player's, the player will always catch up. You might want to consider playing a root motion animation and use Motion Warping to modify the end point (so it moves away in the desired direction). You will need to add checks so the AI doesn't move outside the nav, or into a cliff etc (that is, if you don't want that). You could also try applying a force to the AI to achieve the same result or modifying the movement velocity temporarely. Root moton is more controlable and the results are nicer, but it's less flexible
hey, does anyone knows some plugins or source-code for nodes to handle AI moving with root-motion? as I see, default AIMoveTo cannot handle moving with root motion. Or I miss something?
Moving with root motion does not require calling anything but playing the animation that moves the root bone
Well, it's good if I control the pawn directly, but we're talking about AI
Yeah, doesn't matter. Root motion movement means that the character (ai, player.. Doesn't matter) moves because the root bone of its skeletal mesh is displaced. Based on that, you can use unreal's Motion Warping to choose where the end point of said root bone would be and manipulate the results
So, if you have a montage with root motion, your character plays it, the montage will displace the root bone, causing the entire skeletal mesh to be displaced
In said montage, each animation sequence will have root motion in the enabled (it's a flag you can toggle in/off)
So your node is simply Play Montage
yes, but the problem is that the standard nodes for moving AI move the pawn on their own and they are not designed to use root motion
That's why I'm asking if there are ready-made solutions for AI using root motion
Nope, either you build your own (we have our own stuff so root motion characters can follow a nav path) or you use motion warping plugin (included in unreal) to achieve the same
Oof. Guess if I want my AI to climb ladders that is an issue
I was hoping to make it a SmartObject task
I don't see why not? 🤔
You can. Smart object to handle the slot, a nav link to handle nav and the trigger of the anim...
Has anyone encountered issue with state tree triggering twice on the task it goes into the moment it triggers "Event Enterstate" ? I tried with only just one simple print msg task
Perhaps related to the multiple enterstates "feature" discussed here https://jeanpaulsoftware.com/2024/08/13/state-tree-hell/
I see, thanks for the information
I have a box for every room (some rooms have 2 boxes if its an odd shape). When the AI is suppose to stay in a room and not leave, I get a random location in the room box, I Project Point to Navigation and see if it is nearly equal to the random location (this fixes a problem where sometimes the AI walks to a floor above the room). If it is then AI MoveTo. This seems to work for most of my rooms. There are a few problem rooms where the AI walks to an adjacent room. The only problem I can think of is that the random location is choosing a place off the nav mesh, and the closest location is in an adjacent room, but then why wouldn't my logic work? Wouldn't Project Point to Navigation then be placed in the other room and it wouldn't be nearly equal to the random location?
I might have figured it out. I need to test it, but it seems like there were some spaces inside the walls that had a nav mesh, like under the stairs even though there is no room under there. I'm assuming the project point to nav was getting set there, and the closest point to that location was a different room
any easy way to offset the Z value of a move to location for a flying mob? tried doing this in a task but its a bit jittery and keeps re running the task before the move to finishes
the animations hiccup with an EQS too, if I have 'move directly to actor' everything is smooth but I need to offset the Z which I can do with a Post Project vertical offset. The issue seems to be it keeps rerunning the query and for a split second the animation returns to idle while chasing
I added on tick to the service and that fixed it, runs smoothly now.
That's because the code when using move to actor is different form move to location. With move to actor, the engine detects if the actor moved (there's a tolerance value) and corrects the end point within the same move request. When using a location, if you move the point, the engine creates an new move request. When done in a bt, the move task running will finish, which doesn't happen with move to actor
A good way to handle movement in unreal is to have movement proxy actors. Basically an empty actor that only has a scene component in it. It doesn't tick or have any type of update or physics. Each AI has a ProxyActor assigned. You place the actor wherever you need it (you can set its location to the player logic within your AI tick while moving) and always use move to actor using said proxy actor. That will give you a smooth movement always. If you need to move to a location, you set the proxy actor there and don't change it's location. If you want to chase another actor, match the proxy actor location to the chased actor.
For your Z issue it would be an easy solution.
Umm isn't your move to task re-running constantly?
Is it logical to use decorators as
- First node under sequence
- A is set
- B is not set
- Second node under sequence
- A is not set
- B is set
in order to abort tasks as soon as the desired state is ensured?
Yep. That's quite common to do that as an "if/else" check. But under a sequence makes no sense. If the 1st check is true, it will run, the second check fails, sequence exists. But if the 1st is false, implying the 2nd is true, the second node will never execute since the sequence will abort when it fails on the first.
You need to put that in a selector. That way it will work
Is debugging tools ready for state tree based NPC's ?
ST's log a lot into the visual logger and there's a state tree debugger also, so I'd say mostly yeah. There are a few edge cases where the logs are not useful though
Hmm, ran into a scenario where being able to drop a perception component on a regular actor would be useful... but I guess I'll just hack something else together
You can do a hack which is to implement the CanBeSeenFrom function in your characters and, from that actor, call the function in them. It implies knowing which ones to call, but you can always grab every actor with a perception component in a radius of X meters, then iterate and call CanBeSeenFrom
Actual function name might be different, can't recall the exact name
Not in builds. Same flaw as with BT's
Yeah I ended up just calling FAISystem::IsTargetInViewCone or whatever it's called from some other code :)
Sufficient for now
I checked and the AI controller is not used for anything but logging and calling this 2 functions in the Perception component (images).
I think you will be fine (aside the damn ensure)
You will probably need to create custom logic to initialize the perception in some other place since there's no AI controller but... should be fine I think
Anyone know if Smart Links on child actor nav proxy links are working or bugged? Trying to create a door with a child nav proxy actor and it's never firing off the "smart link reached" event. any work arounds appreciated! (I also tried making a door that is a child of the nav proxy link actor class but that just makes my mesh door collision get ignored?)
Yeah I don't want the nag in the logs lol
It's fairly simple what I'm doing currently with it so I think it's fine without it, just woulda been a tiny bit less work if I could have dropped that in there :D
yeah... you would need to create your own child of PerceptionComponent, override OnRegister, copy paste evertying from the engine but the ensure parts (or anything related to the AIOwner). That ensure will be the only thing messing with the logs
the smart link is a UNavLinkCustomComponent. You can add that to your actor and get the same functionality with a component. It's not recommended by Epic to use Child Actors. It's considered a bad practice due to the amount of issues you could face.
If you eant the nav link to control navigations when the door open/closes, that's probably your best bet
Ooohh I didn't know about a custom component! I suppose ill have to add it in c++ right? the nav link component i saw didnt have smart link functionality
the class is set with MinimalAPI, not sure if that also exposes it to BP's or not. You can try adding a new component in BP's and inherit from it. If not, c++ it is (I use it in c++)
Thank you Bruno for your detailed response! Yes I would almost like two 'thinking' streams for the AI with actions that can overlap;
- Movement, checking range to target and adjusting positioning as necessary, maybe random movements in-between
- Combat, attempting to attack and respond to player attacks
- Character can move and attack at same time
At the moment I'm just using one Behaviour Tree Task that manages these two things on-tick. Would you approve of that approach or recommend an alternative? Utilizing decorators I would need to split that up?
I recommend to use whatever works for you. If one task for everything works, go for it. In the end... It's gonna be a personal choice combined with whatever the gameplay needs
How to subscribe dynamic delegate in BT Task?
Memory->DelegateHandle = Perception->OnTargetPerceptionInfoUpdated.AddUniqueDynamic(this, &ThisClass::OnPerceptionUpdated, &OwnerComp, NodeMemory);
^ This doesnt compile (tho it works for non-dynamic delegates)
Any alternative? I want it to be usable with non-instanced task, the core of a question is how to forward OwnerComp and NodeMemory into dynamic delegate methods? How to forward arguments into dynamic delegate at all?
That's exactly what you need to do. Let's start with the basics: did you create your own memory struct etc?
Of course
tho it works for non-dynamic delegates
Ummm I can check tomorrow (heading bed) but I could swear we subscribe to then too. Ummm but they need ufunctions right? Will check tomorrow
Yes its UFUNCTION
non-dynamic example in my code
dynamic (MemoryWrapper because you can't pass uint8* into dynamic UFUNCTION)
Theres a hacky solution I don't like: https://forums.unrealengine.com/t/function-arguments-within-adddynamic-call/384580
Too much boilerplate for a single line of code
Easier to just make a task instanced that way
But I don't get something... You are passing the memory to that delegate. Isn't that an engine delegate? Does that match the delegate signature?
Probably you don't know, you can add extra arguments into a call for non-dynamic delegates
E.g. signature is DELEGATE(name, arg1, arg2)
Subscribe like AddUObject(this, MyMethod, arg3, arg4)
Called like void MyMethod(arg1, arg2, arg3, arg4)
Aaaah right. Yeah always forget about that. I handle things in a different way (sometimes using a lambda for the binding)
Yeah but you can't use lambda for dynamic delegates either :)
Yep
So far object wrapper is the only viable solution Ive found
But you have to write a separate object for every delegate and then store the created object for lifetime somewhere and it becomes messy
Out of curiosity, what are you trying to achieve?
UBTService_Perception::OnBecomeRelevant subscribes to stuff
UBTService_Perception::OnCeaseRelevant unsubscribes
UBTService_Perception::OnPerceptionUpdated changes BB value for a current threat
I've just made it an instanced task, it would work, not a big deal
With instanced task I can store owner as a plain UPROPERTY
But.... Why do you need to pass the memory of the node into the callback function?
Yeah.. The only few times we've been forced to use Instanced nodes have been due to delegates and callbacks to keep shit alive
Was a generic example when you need both memory and owner (e.g. you wanna compare current threat and previously cached threat or something)
In my example you only need an owner, but you can't pass owner either
E.g. in my DoAbility task I also pass memory into a callback, that way I'm using CachedSpecHandle from memory to check stuff
Aaah right... Of course. I hate that. I hate when you need info from the tree but... Oooops... You are in a callback, so you don't have the memory pointer nor the owner
Btw in StateTree its solved by using Class instead of Struct as a memory (you can do it there). You're writing a callback inside the memory class
In your delegate... If you get anything from the owner (ankther component, or a component in the controller) anything that can lead to the owner, you could try grab the memory from the Known Instances in the behavior tree component
Yeah perception doesnt give
What does it pass to the callbakc?
info about detected actors
Any chance you can add another callback and call it at the same time? Hacky because you have 2 callbacks for the same thing but...
Its possible to make a child class from PerceptionComponent and make a custom delegate with extra info there but not worth it
I'll just make it instanced, apprx the same performance-wise
I always handled things different with perception. Everything goes through a Target a component that digest the Perception info and handles/delivers it to others. Just because of this kind of problems, it's just too rigid
Yeah I've handled OnPerceptionUpdated in AIContoller
Now experimenting with moving it into BT because AIController kinda doesnt need any of that data
I can't imagine not having my own child of perception but that's me any needs. Then fuck it, Instanced it is. That ram is expensive, better use it
I've paid for 64gb, gonna use it
Exactly. I can recommend a target component for all this bullshit
It's a way to centralise anything target related: perceived ones, aggro weights, temporal target swapping, you name it. An layer of indirection to handle everything in a central place for each AI
I say target component but I don't mean the one in the engine, I mean one custom you make for this
hey guys have anyone seen a behavior tree do that? It switches between setmovementspeed node and simple parallel with move too, AI is not moving to target and standing still. Dozen times per seconds, on video it much slower. I don't really understand why it works like that. https://i.gyazo.com/8b7aec3724ec52e9943066bd66b5c5b2.mp4
even with a simpler tree it still works like that, flickers to moveto node and nothing helps https://i.gyazo.com/9181acf3a8cc0d1089942c24263d291c.mp4
Flickering like that usually means a node is failing which is resetting the tree and it keeps rerunning the tree over and over again
You can use the BT debugger to look at what nodes are being activated and which are failing - it seems likely to be the MoveTo in this case
The visual logger usually has information on why moves are failing so you probably need to look there
hm, visual logger only says "trying to find path resulted in Error", but I don't see any possibility to understand what kind of an error. NavMesh is fine
Your path end point could be outside the navmesh, or the actor you're trying to move isn't on the navmesh
Or it's impossible for it to find a path from start to end because no valid path exists
well it's strange cause it's flat area
so it seems the end path is outside navmesh which I thought will result in AI trying to move to the closest point on the existing navmesh, but yeah it's not possible
but I don't understand how to fix this then, I don't want a turret to ignore navmesh
Try using project point to navigation
hm, where I can find this setting?
Oh, it's a node, you can use it on the location to project it into a point that's on the navmesh
oh I see, so I need to redo behavior tree so moveto nodes moves not to actor, but to location, and then that's location is getting from actors project point to navigation
thank you will try to
Oh, there might be some settings on the MoveTo also that might allow you to adjust this if you're moving to an actor
But yeah if that doesn't work then you can try projecting it manually and see if that helps
honestly cant find any to allow this on moveto node
it's even trying to project it already as I can see
oh actually there is something, I was able to fix this with turning off "require navigable end location"
so AI try to move as closer as possible and my code is set the way it checks is there any targets in proximity radius for attack and even with that checkbox off, it still able to get to the proximity range and it works
@misty wharf thank you for the help 🙂
Can someone tell me if the Move To node in a Behaviour Tree can be used with Navigation Invoker Components or does it have to have a Navmesh please?
Never used them but, doesn't the nav invokers always have nav around it?
I thought so tbh but wasnt sure. also getting some weird results with them
Ie.. Not sure why it has a chunk of nav mesh missing when moving the actor around
this is the settings.
Also dont understtand that I can move the actor outside of the invoker when it is the owner of the invoker component
Can you show this showing the tiles too? The nav recast object has flags to show different things
lol X marks the spot apparently
Is the component attached to the root of the actor?
Show this one showimg the times too please. I have a theory
Where do i show the tiles?
I,ve not used these Invokers before sorry. 🙂
"Draw Tile Bounds"? This what you mean ?
Yeah
I was trying to use a Navmesh on a landscape but it took forever to generate so figured there must be a better way to have NPC,s wander around the landscape. 🙂
Can your draw a sphere at your invokers location with your invoker's radius? No idea if there's a debug for it already, just to see what's being considered. I think what you see might be right
It makes sense because it can't draw partial tiles and, if filling the missing ones you get more nav than expected
This is a radius of 500 from it,s locaiton
Yeah then you are seeing what is expected
The calculus is aporxymated when generating nav tiles
Ah so its generated from a Sphere shape and not a square , I thought it was a box around the character 🙂
My bet is that your nav config and resolution also matter a lot to define what kind of nav is created
didnt know, That makes more sense now though
No idea, you might be right but the result will be the same I guess
Ye i changed the Tile Generation Radius to 1000 from 500 and gott this result
Either they make a cube with your number or a sphere, they will more or less have the same "coverage"
Which looks like what I kind of expected.
There must be some debug to show your radius provided by the engine somewhere
No worries! Good luck!
In State Trees, I would like to separate Information retrieval about the world (Beliefs) and Decision.
I started making a Global task gathering beliefs constantly in parallel of what the State Tree does to take decision and act on them. On some rare case, this setup causes trouble because I need to update a belief from an action really fast to avoid ending up in the wrong state (race condition between the Global Task update and the State Task). For instance if an AI can shoot only once per turn (Tennis for instance), I need to immediately register that it cannot shoot and that it is not its turn to play when the Task Shoot is successful.
This leads me to a theoretical question and a practical one :
- Is it that easy to completely decouple Belief gathering from decision taking (Belief-Decision-Intention in artificial intelligence) ?
- If I accept to couple them from time to time what is the best way to deal with this kind of immediate updates in a State Tree ?
I have tried several options like making a component in my controller that acts as a Blackboard for my Tree or using ST Parameters (those can be updated since 5.5) and allowing both my global task and States tasks to updates those Blackboards-like objects.
But it always feel bad. With the component it looks like the problem I had with blackboards : Tedious to set/get variables + often need to have a copy of the same variables in the Controller + in the "Blackboard". With the parameters it is straightforward to get variables but a bit ugly to set them and it looks like it was not really meant to be used this way + I might need to share knowledge between bots and I do not see how to do it with parameters.
The race condition... How come? When a estate tree updates, the very first thing is the global talks, then the rest of the tree. If you update your values from a state task, that's before the global task runs again
For the second part: you need some form of blackboard. We run Bt's from our state tree tasks and we use the blackboard in them for conditions and what not in the state trees. We have a mixed approach. I don't think you can have "static" info (available to every AI) and handle everything in params, the same way you can't do that with blacboards either (unless you use the static bbk's). You always need some level of indirection and (generally in different components)
I know it's been a few days, but thank you so much! I actually didn't know Visual Logger existed before you mentioned it, and it's extremely helpful
If you haven't yet, watch this. It's great to give ideas on how to use it in intersting ways
https://youtu.be/hWpbco3F4L4
The Visual Logger, built into the Unreal Editor, is an incredibly useful tool for recording, visualising and tracking objects, locations and data in gameplay, but it’s rarely used outside of AI. Let’s change that!
In this talk by Rare's Principal Gameplay Engineer Andy Bastable, you'll discover practical tips and examples from Sea of Thieves, ...
Thanks! I'll have to watch that later
@slow bobcat Thanks for the answer.
I was not clear I thing for the first part: The global task is at the moment the only one setting variables that will be used in conditions to decide which state to got to. And I have one case where a Task should do it too because the action of the task (hitting a ball) is important to know because it changes the conditions of other tasks. Hence my question on how to have a common blackboard between the tasks and the Global Tasks (In my particular case, the Global task has a way to get the info that the ball was hit anyway but it seems to get it too late and I get stuck in another state before it happens).
OK, interesting for the BT part, so you have the state tree deciding high level Tasks and BT doing the more linear sequences of tasks?
I am a bit new to this but already ran into BTs that gets more and more difficult to maintain/modify and I am looking a way to decouple more the different actions of my AI. I tried FSM for higher level tasks (Goals) + BTs for straightforward sequences of actions (Plans) + some utility. It worked fine for my use case but I was lacking a good method to package everything I needed for one Sequence of action (Conditions, Groups of Sequences of actions etc. ) and State Tree have almost everything I need now that they feature utility scores so I try to move to it.
@slow bobcat where did the inspiration for your current system come from btw ? I found some pieces of information here and there, but except for one book ( Game AI uncovered) and the videos from Bobby Anguelov, I did not find a lot of useful tips to develop a framework with better flexibility when adding new behaviors than the vanilla FSMs/BTs/STs.
and if not secret of course, why was it developed this way in your case, for what type of AI ? What property are you looking for for it ?
Precisely the article of Paul Roberts in Game Uncovered AI. That reaction approach is soemthing we needed because our Bt's were big an very difficult to maintain whenever we wanted to introduce a new reaction. We already had a state tree deciding high level: pretty much just setting gtags on the AI that the main bt will read to know if it should go to combat etc. Our game is very reactive: AI's can dodge, block, parry, get stunned, react to the player going too far, or going outside the nav and many other things. Having a bunch of state trees in parallel checkign for this things helps a lot. We execute a main state tree now, it's states run Bt's (idle, patrol, combat...) and, if a reaction St says it can run, we run it (a different bt for each) and continue with the previous bt. It's all a WIP but so far, it's working decently. Our biggest hurdle is debug tools because st's debug system sucks a bit, but getting there with the help of epic
Based off of this image should this behaviour tree work please?
Tree
RandomLocation is being set multiple times but the npc never actually moves.
This might show it better. 🙂
How are you getting it? Is it being proyevted onto the nav? Why does the movement fail? You can check visual logger to see what's going on
using GetRandomPointInNaviagableRadius node
OK I will go back to it then (the article), this is exactly my problem. Thanks a lot for the detailled answer !
and a radius of1000.
as the tile generation of the invoker is 1000 so it should never generate a spot outside an active tile from the invoker (I think)
I'm not entirely sure you can use a global task like that unless the in/out params can be set from outside (another task) and not depend on the global task to be updated by the Execution Context.
The tree runs in a very specific way. It think it goes this way (not 100% sure so take this with a pinch of salt)
- first global tasks
- evaluators
- decide a state
- check it's conditions
- check transitions (which evaluates State Tree Events)
The thing is that, when you call set param on your global task, no idea if that's immediate (like it would be for a class property) or if that's something pending the next global task update (which will happen the next frame and, in between, some other task will run needing that value)
If I'm getting you right.
There's another one next to it from Call of Duty. Paul's approach is based on that one. Worth reading both. I also strongly recommend chapter 20 😏
I would draw debug that point with a sphere just in case. Also check visual logger to confirm why the movement fails
As you can see the ball spawns within the nav area but the character fails to move and it never stays on the Move To node
what is the best way to catch a situation when my NPC can't pass through some narrow navmesh spot because there is another NPC is standing (not moving) in the way? Is there some virtual AAIController:OnNpcPathBlockedByOtherNpc or something like that? I wouldn't really want to make NPCs capsules ignore each others and it's not always possible to adjust level design so I guess if I could catch such moments I could just launch some montages like pushing/letting pass through or something 🤔
haha I see 😏, did not read it yet, 2 more chapters to go !
iirc there are functions that get called if colliding with stuff during movement, that's about it
might be C++ only if that's a concern
I think I fixed my issue I didnt have a Character Movement Component so I guess thats why it wouldnt move and the parent class wasnt a Character, Once i recreatted it as a Character it works. 🙂
anyone know how to overcome this? 🙂
basically, i have a really huge character and for some reason the nav mesh is saying that the endpoint is not on the nav mesh. i'm guessing it's because the actor it's trying to go is an obstacle?
i could technically do a raycast to the wall and then go to the point of the raycast, but i thought the path following component already handles this?
there's like a tiny gap where there is no point on the navmesh
The nav mesh will stop before the wall/go around it, I believe. What is the huge character supposed to be doing?
Ohhhhhhh, I see. What I've done in similar situations is subtract a little bit from the actual location of the end point actor so that it gets a little distance away from it. That way, it's not right up on it either
Maybe that would work for your situation?
true i'm thinking about doing a raycast
this is tricky 🤔 let me think about this
i could set the origin of the actor to be offset
so that the mesh is not at the origin of the actor
Ohh I think I see what's happening too, it looks like the end point is ending up in the middle of the wall, since that's the technical position of the actor. A raycast could work to get the hit position
yeah the only problem with the raycast is that there's a very real chance that the actor could spawn behind some mountains in the back, and then the raycast would never get hit, which is why i wanna rely on path finding to find the wall
no matter though, i think i got it
i can set the wall at an offset from the origin
it worked!!
i'm getting some new weirdness now. invalid navigation data? o_O
i removed the mountains as dynamic obstacles and it fixed it, but for some reason i'm still getting invalid navigation data?? o_O 😦
seems like crowd following component does not support multiple agents 😦 let me disable it
Ohhhhh, interesting
the next challenge is that the character does not understand it can traverse through all of these trees
is there any way to make this agent completely ignore certain actors on a nav mesh?
You should be able to set the tree actors collision to ignore the player character (I think it's the pawn layer)
Hmmmmm 🤔
yeah i'm actually at a bit of a loss here
the collision settings are correct (this actor has correctly navigated through trees in the past)
although, maybe it was navigating through trees because it had the wrong agent
what's weird is there's no error anywhere in the visual logger or log
looks like this is unrelated to the navigation system as the character is not moving at all 🙂
well that'll do it 😄
Hello
Question on Visual Logger, I have a Designer who tried to use it but the visual logger record only when its computer is not focusing on the viewport.
ex: play, launch record on visual logger. it will record no frame or one frame then nothing. then Alt Tab on other window, it will record normally but Alt-Tab and go back on the PIE Window, it stop recording at all
I try to look its Visual Logger settings in editor preference but Its the same as me and my visual logger work normally.
realtime is also set to true in the viewport options
Someone has encounter the same issue ?
edit: I found a solution but I don't know why it fixed it. My designer was putting its viewport in fullscreen (F11 base shortcut). when viewport is in fullscreen, VL doesn't record.
I'm having issues with MoveTo BT Task. It seems to complete the task with success (according to visual logger) even though there is still distance to the target location (acceptable radius is 5, ends between 500-1000 units remaining). It's a plane without any blocks so target location should be reachable. How can I get more information about what's going on, or is MoveTo task reliable/has any difference than running the AI MoveTo node in a task myself?
Any idea how I could add actors to the RVO system so that my npcs could avoid more than just other npcs?
is it possible to get UEnvQuery or FEnvQueryRequest from FEnvQueryResult?
doesn't look like it
in my test state tree i added multiple break points on the root and child states, as well as debug texts in various states (and also asa a global task)
i tried using the "auto start" option and also calling "start logic" function on the state tree component, but i dont have any feeback and it seems like its not running.
if this matters i am using the AI derived class of the state tree component on my AI character
If I can't, I have to write different functions for each FEnvQueryRequest->execute I wanna call for creating unique logic
which sucks
What are you trying to achieve?
Cant tell what i wanna do entirely but I run multiple eqs in cpp each with a looping timer. Each timer has its own looping time and after the execution, I need to create unique logic for the eqs I ran.
ah yeah, then you can create a TMap with all your QueryID and whatever data you need as the value. When getting a call to OnQueryFInished, just match the queryID passed with your map to obtain the data. The up to you what to do
.execute returns an int32
if it is QueryID, then I can use it.
as a tmap you suggested
just make sure you remove the entry from the map before you run the same query again, since the ID's will be re-used
yeah... part of those things only people looking at code can know (sorry for BP people)

Ahha, apparently this was due to a sphere collision I added on to the pawn. So the acceptance radius is calculated to the distance to the outmost collision?
Ah, ReachTestIncludesAgentRadius toggles this, yay
How does PerceptionComponent senses pawns with sight sense by default? An actor should be considered as a stimuli source/have the stimuli source component to be sensed according to what I understand but pawns/characters don't have that by default as far as I can see. Is there an exception for the pawns?
Yeah pawns get registered as stimuli sources by default
You can disable it from DefaultGame.ini or whichever it was
Is it possible to register/unregister on runtime to give temporary invisibility?
So should it be disable auto register -> add stimuli component -> call functions on demand kind of a setup?
If that's the behavior you want yeah. If you use C++ you don't really need the stimuli source comp as you can just directly call functions on the perception system
Not what I want right now but the question "what if I want the pawn to be invisible to specific AIs" arises. I guess these functions make the actor undetectable by all perceptions right?
The senses you register/unregister them with yeah
Is there a functionality to specify "unregister this source from those perception component(s)" then?
Not from specific perception components but specific senses yes
I see, thanks!
Hi, any update on that? We upgraded from 5.3 to 5.5.1 and the same crash ocurrs. I've chcked your main branch but havent seen any fixes. I am thinking of creating a UDN post about it
Authorities have been notified. The authorities are not in the office yet so I'm unable to ask, but I don't think any of 5.5 will have the fix - the changes that can go into hotfixes are very restricted (no API changes for example) so even if the fix has already been submitted (you'd need to check ue5-main on github) I wouldn't expect it before 5.6.
I am checking on p4 ue5-main. Thanks for the update. Really appreciate it
/** State Tree asset to run on the component. */
UPROPERTY(EditAnywhere, Category = AI, meta=(Schema="/Script/GameplayStateTreeModule.StateTreeComponentSchema", SchemaCanBeOverriden))
FStateTreeReference StateTreeRef;
why StateTreeReference property in protected?
how to set the reference statetree runtime in c++?
Inherit from the component to make your own version and you can then use it. You will need to do some extra steps to initialize etc, but you can see what to do by checking what the engine does
I have a Sequence that get "stuck" on the first node, even though it's set as Force Success; what am I missing here?
thanks, it work
is your rotation finidhing? it might never bee finishing due to the tolerance of the rotation (look at) and stuck forever
yeah after a bit of debugging I got that, although honestly I don't care about it; I want to continue either way.
I went with parallel node for now, Melee Attack is the main, Rotate is the "Background".
Not sure if it's the correct way or how good it will work, but for now it seems fine
does anyone know how to use this decorator properly? im not able to query the gameplay tags from the actor from it
why cant i save the out vector in a state tree parameter ?
i would like to reuse this out value at other places
Does that use gameplay tags in the Ability System Component of the character owner or is it using the old "tags" that were FNames?
Edit: never mind, yeah, gtags. You will have to debug its code to know why it fails
seems like because it needs to be added in cpp the igameplaytaginterface
ugh
Maybe you can add the interface in Bp's too? No idea if it's exposed, I would asume it is
It isn't
All the builtin gameplay tag related nodes in BP, BT, EQS, etc. require the IGameplayTagAssetInterface
They do absolutely nothing without
For real? Man that sucks big time. G.tags are incredibly useful. Why wouldn't they make that interface blueprint implementable?
Good question. I always assumed it was for performance reasons, since the BP plumbing has an impact on that on BlueprintNativeEvents
It seems they thought about this for GAS, since the GAS-related code all gets the Ability System Component via a function which can use either IAbilitySystemInterface or FindComponent
Where the interface is not implementable in BP's either
Anyone have experience with vehicle AI? Making it nav a navmesh and not a set path? I'm thinking I may need to look at the Nav Agent source code for UE5.
Seeing as things like automobiles, tanks, etc tend to take up the space of a rectangle and all.
Im assuming you cant get a specific curve from a curve table in bps
there is no functionality, but in c++ there is
am I right anyone?
Q: Is there a way to stop AI from detecting and following other AI ? I have 4 enemy units and 1 player and the enemys can watch each other and the player but I only want them to follow the player using the SIght Sense. I have seen that you have to do some pretty hacky stuff in C++ to use the Detection By Affilition checkboxes. So wondered if theres a BP way of doing this?
detecting I think its some work in a specific ini file, but chasing thats simple, either on your target perception updated check the sense, == sight, then Sensed Actor.has tag = player, or run an eqs percieved actors query with the actor being the character
Ok thanks ! I,ll try the tag route for now, Not used EQS too much yet
eqs is actually easy, each time your perception gets updated, make sure its sight then run an eqs query and bind a dispatcher to on finished
then you can get the percieved actors, Lyra uses the same query for their ai
hi all, im trying to create mass unit ai for moving to the target and then attacking. i run into the problem of ai perception giving really fast wrong false (for the sensed enemy). how can i fix this?
i have tried tweaking tick interval for the aiperception component but its like its not reliable
(i am using sight config)
@misty wharf yo thanks for the website, i found it by just googling around. https://zomgmoz.tv/unreal/AI-Perception/Debugging-AI-Perception-Sight-problems you have some of it covered which is about aiperception and whilst i knew the issues im still looking for answers. what is your stance on Pawn Sensing component? I remember it was better for sight but i could be wrong.
IDK why tree is getting stuck at rotate to face BB_Entry task
I've found the source code, partly.
I've discovered it uses recast navigation, interestingly.
Adjust the angle to fix it
What do you mean?
how?
Pawn Sensing is pretty much superceded by AI perception, there is no reason to use it
A reference
No but what do you mean form the table? As I you have a table with different curves and you want one?
Why can it be, that BT service node memory, initialized in OnBecomeRelevant, is not persistent (all zero) on first service tick? I have all required parameters set: bNotifyBecomeRelevant set to true, GetInstanceMemorySize overriden. What am I doing wrong here? 🤔
Are you initializing your memory?
Also: check if tick runs before become relevant
A curve table with multiple curve floats,and I wanted to get the row of that curve table and it return a curve float object, i know you can do it in c++ but bps i dont think so, so i just made up a data asset containing an array of curve floats
so they can act as proxy spreads as you recommended
that was a really good idea actually, everything is more dynamic, i just assign a random spread curve to the proxy
on begin play
No, should I? Also I did check, on become relevant is called before first tick
Check other decorators like the one that checks Gameplay tag query on actor. They Initialize the memory. There are others.
Maybe you are missing it? Worth a shot
nevermind, the problem was that, as always, the programmer is irredeemably stupid
i was casting node memory to the service instead of the service memory in the OnBecomeRelevant and IDE's autocomplete filled in the variable that has a very similar name to the variable I wanted to initialize in the node memory
Isnt this which way npc is facing?
I'm experimenting with the smart object plugin, and am currently trying to get my AI to be able to navigate to a slot by the instance tags provided via EQS

