#gameplay-ai
1 messages · Page 76 of 1
So I just create the custom component class and add it to my door actor and i can just use the smart link then?
If all else fails i'll probably just make it so that AI either can't use doors or the door is a physical hinged thing that can just open and doesnt affect nav 😭
I really appreciate your reply though, i needed the insight
Actually well... I told you to inherit etc but you can just add that component straight I think
I couldn't I had to create a component that came from NavLinkCustomComponent, otherwise there's only just "NavLinkComponent" which doesnt have the smart link stuff
On another note, even though I've made the new class that inherits from NavLinkCustomComponent, I cant set the smart link variables like if the link is enabled or what direction
NVM I found this;
/** change state of smart link (used area class) */
NAVIGATIONSYSTEM_API void SetEnabled(bool bNewEnabled);
bool IsEnabled() const { return bLinkEnabled; }```
I was trying to look for a term more specific like SetSmartLinkEnabled lol
has anyone had a problem with recast navmesh actor going crazy with rebuilding dirty areas in places where there is even no navmesh? it floods my vislog which causes FPS drop to 3-5 from 60-90 but also i think it's bad enough on its own that recast actor is doing all this every frame, but I have no idea what to do with it 🤔 I'm using world partition if it matters and I checked that physics is disabled on static meshes that are mentioned in vislog
to add on, i can't access ``` /** delegate to call when link is reached */
FOnMoveReachedLink OnMoveReachedLink;
you have your own child. Just add a getter to expose it in your child class
that said, this is how you set it up
SmartLinkComp->SetMoveReachedLink(this, &ANavLinkProxy::NotifySmartLinkReached);
Whenever OnMoveReachedLink broadcast, NotigySmartLinkReached will execute
The smart link comp can't be accessed weirdly enough, i have to use UNavLinkCustomComponent::OnMoveReachedLink
ah
that's your component
SmartLinkComp is the UNavLinkCustomComponent the ProxyNavLink uses
OH LMAO hsdjkfsdkfj man running my brain at 4am is just not it
in your case, it's your custom implementation
go to sleep. Resting is your best resource when programming
Yeah haha Thank you lots for your help again 😵💫
Hey has anyone here encountered the warning on the State Tree Reference that outputs when it calls "conditionally sync parameters" and the parameters aren't synced at that point? I tried tracking down where it should be syncing before then, but the only occurence I see is a deprecated call in the state tree component? Am I missing something?
Well there's one more occurence when the State Tree Reference itself is loaded in the editor for editing, but that isn't guarenteed to happen 🤔
not sure what could happen but rebuild happens for two reasons:
- a nav relevant object is added or removed to the map. This could be an actor or a nav modifier volume for example
- Something that can affect the nav moves.
If you eject whille playing and show the navigation, do you see that part going red or anything? That part on the right, is that a nav mesh bounds volume? if it is, why isn't there any nav?
If you eject whille playing and show the navigation, do you see that part going red or anything?
that's the point - there's no navmesh anywhere near the region where vislog reports dirty areas happening. There's only 1 navmesh bounds volume which I showed on 3rd screenshot, all the other areas are just game-related volumes that do not affect navigation in any way and neither is there any nav modifier volume.
probably some shennanigans with the world partition navchunks
navmesh isn't world-partitioned though 🤔 at least I did all I know possible to have it not being affected by WP
Out of interest, how do people deal with the implications of potential data duplication by using blackboards? Say I store something like a list of locations for a patrol route on the ai controller and want to access those for a move-to on the behaviour tree, seems like I would need to duplicate those locations onto the blackboard? Or is there a way to guarantee the 2 stay in sync?
You can create your own bbk type as a struct and put the array of points inside
Would that be a reference to the original data or still a duplicate?
The other thing is "where from the BT do you need to access it? Because if it's a decorator, task etc... You can just call a function in the AI Controller that returns said points from within the node
All the data would be your bbk
Yeah mostly about reusability of existing nodes with said data, otherwise you'd need to write a duplicate node for every different way of accessing data
Then just have a function and call it from the nodes code. Unless you need some logic that can take different arrays of locations, no need to have it in a bbk
What I mean: BTTask_FollowPoints and a designer can pass an array of patrol locations or an array of last know player locations or an array of "steps visible on the snow within X meters"
If you have that kind of logic and said point arrays can be different things up to the designer, then a bbk would make sense. Otherwise... You can just store them anywhere in code and have the task retrieve them calling the internal function
Also is it possible to use a blackboard key selector from an actor that isn't the blackboard? I tried doing it the same way as it works in the behaviour tree by referencing the correct asset on load but that didn't seem to quite work
No, the bbk selectors offers you a list of bbk's owned by the BB
As very well pointed by @keen crow below, you can have BBK's in any asset implementing IBlackboardAssetProvider
A link to an example is provided below.
If I have a reference to the blackboard asset itself?
Then yeah... But I'm not following. What's exactly do you want to do? Reference your BB somewhere and select a bbk from it?
Avoid having direct string references to blackboard values
I do that because I have a conditions tate tree that can check values from a BB (we use both, Bt's and St's)
You could define enums too if that's easier
Well the issue is if the name of a key changes you are basically screwed unless its a direct reference to the key via id
Not sure how an enum would solve that? Wouldn't it just translate to a string for the blackboard key?
So... Yeah. This is an old problem.
The enum basically ensures 3 things:
- all bbk names are available everywhere for everyone
- you don't commit misspelling errors since you don't have to write the string.
- if a bbk is renamed, you only need to fix the enum, not every single use of that string in your project
But the inconvenience is that you need to maintain the enum
Ah I see, so the crux is that everyone that wants to modify the blackboard key name would need to know to also change the enum name?
Yep. It's a minor price tbh. Bbk renaming doesn't happen that often
At least in my experience
it is
#gameplay-ai message
But you are picking the BBK from a BB.
"Also is it possible to use a blackboard key selector from an actor that isn't the blackboard?"
no, I am specifying a BB on whatever I implement IBlackboardAssetProvider on to be able to make FBlackboardKeySelector work, but since it's just an interface you need to implement you can have it on whatever actor/component/data asset you want
aaaaah
So if you implement IBlackBoardAssetProvider in any actor, you can then use it as if it was a BlackBoard (an asset with bBK's)?
ooook completely missed that
you don't use it as a blackboard, you are just able to use FBlackboardKeySelectors on whatever you put it. So sometimes I have to immediately throw something from AI controller into blackboard. I have a data asset that implements that interface and contains some FBlackboardKeySelectors which I use to get BBK name instead of hardconding it or having in some named constant
yeah, moddified what I meant.
That's cool. Funny how I never realised that
Ah the trick was inheriting from that interface, i guess there's some editor code that runs somewhere to populate the keys
Why is the blackboard key type for objects non-const? 🤔 Its not like its modifying the underlying object (hopefully)
Is it a bad idea to have thousands of smart links? (I can’t use simple links because I need my ai to jump at the start of the link)
What is the purpose of a BT Task's Blackboard Key? Just a preset variable easily accessible?
To reference a key from the BT's blackboard.
Blackboards are how you handle a decent chunk of data from outside the BT overall.
.SelectedKey
So you can more easily reuse the BT
Is this any different functionally or performant than just calling the blackboard and saying. Give me value for key "Name"
I see a lot of people storing public variables of type BlackboardKeySelector, why not just pass the "Name"
Because the BB key selector removes the possibility of typos. As well as supports refactors.
If it was just an FName - it'd be ripe for errors.
Makes sense. So if the name of a key changes, you dont need to fix all BT code
Correct.
Im seeing the vision now. Ty
So its a struct with the goodies inside. It gives you the class too. Very pack a punch.
Just need to figure out where to declare these. Would this be a top level service with public vars
Just declare them in the service/task/decorator.
I see the problem of maintaining them, since there are lots and finding an error with one will be difficult (ie: someone moves the assets and not your nav link end is not on the ground). Imoact on performance when using dynamic nav mesh would probably something to consider if high numbers of nav links are processed per frame to build nav
Ah teh other thing is the actor count. The more you have, the worst for level streaming. But I haven't used world partitioning so no idea how it's for it
short answer: yes. long answer: you will run into issues with performance due to the actor count. Unreal has recently added autogeneration of navlinks without the use of one actor per link. The way it works is by simply using a single instance that contains the logic (the cdo) and just run that logic with additional info provided by the start/end locations of the navlink and the info of the actor using it, its a bit limiting but a lot more performant
are you guys using behavior trees or no? asking because im not sure there is any gap in the same way blueprints have gaps that only c++ can fill
Any ideas why my navmesh isnt generating or navigation is showing? The setting is literally blurred
I built a tool to automatically generate nav links everywhere I want, so maintenance shouldn't be too bad at least
Exactly, actor count is the thing I'm worried. I did look briefly at the automatic nav link generation in 5.5 (I can't use it since it's too simple, my own generation tool works better for my use case) but I'll look a bit more at the code to see how they handle multiple smart links per actor, thanks
DDoes any one know why nav mesh is not complete in that flat area, no collision, no nav modifier. Command RebuildNavigation has no effect.
Having an issue with using the trace test env query, it doesn't seem to be working. Trying to create a query that generates cover by finding a spot not visible by enemy locations, but a query to find a spot not visible by the querier isn't even working. Any reason why?
This query only returns the furthest point, it doesn't cull points visible by the querier
Aaah is that how it works? I thought it was adding actors! Oooh that's neat. I got a request to check this from the design team just yesterday
Absolutely everything in Unreal has gaps that can only covered in c++. In the end, it's a c++ engine with a visual scripting layer on top
What's oyur setup for it? How are you generating it?
Do you have levels below or on top?
try setting bool value to true in trace test params. its bool value means "do you want the trace to hit something from item to context", so in your case you have it set to false so it will provide you points where there's nothing blocking from item to querier, and from what i understood you want the opposite
That level is a sub level of empty level.
not sure I understand. The image you show is within a sub level with nothing but a floor in it you mean?
Yeah, It has some collision for boundary but it is correct.
and the nav we are seeing is all within the collision boundaries?
also this doesn't answer my question: are there other levels below or above the one we are seeing?
It is not inside. But surround play area.
I am checking.
this might be the issue. Difficult to say without seeing more of it with the collision volume visible
I don't see anything above it.
and below? just to confirm. Unless you have verticality in your game (levels are on top of each other) ignore my question.
One test you can do is delete objects and rebuild paths. Delete one, rebuild, see if anything changed, continue.
It's a crudre way to deal with it but...
You could also run "show collisions" command see if any collision matches the shape you are seeing
Our game is top down so, there is no level on top other.
I already check the collision. No collision show up in that area. And this issue only happen on build.
How it look on UE.
ufff I had this problem in the last game we released and it was a pain to figure out.
We had to hack a bit the engine to print the volumes of the bounds considered for nav building in a build, dump them in a json and load them in editor through visual logger.
What kind of nav do you use? I'm guessin Nav with modifier only?
We use Nav bound volume. I also check the bound volume, and it is cover whole area.
The actor for boundary has nav modifier to avoid nav mesh is gen inside collision.
and you don't have this problem while PIE, only in game builds?
Yeah, Nav mesh in UE like this:
There's a chance that you have nearby sub-levels that are being loaded/unloaded due to level streaming (or WP) that are affecting this. It will depend on the order.
What I mean is this.
You can probably repro it in editor if you load/unload levels in the same order you do in the build
https://github.com/mbrpistoni/UnrealHowTo/tree/main/FixForOverlappingStreamingVolumes
the videos in that github explains what I mean
it talks abour overlapping streaming volumes, but that can happens with nav modifier volumes that are shared between two sub-levels
My guess is that some sub-level is streaming out taking the nav generated in shared tiles with it
Thank a lot. I will take a look.
I will try to turn on sub level to check if any level match that area.
a quick test is to play in the editor the same way you would play in the build, so you can cause the sub-level streaming to happen in the same order
and print in the log which ones are streaming in/out
The capsule is always squeezed out
Is there any way to prevent the character capsule from being squeezed away?
What? What do you mean?
@slow bobcatThe character capsule encounters the AI capsule and spins and flies away
Are you using RVO or Crowd manager? How are you moving your characters? Sounds like you are just forcing forces upon them
I was around the AI and let it spin around and push me away
Ufff difficult to help without knowing how are you handling movement, rotations etc
I solved it by setting the AI's capsule so that the character can step on it
hey can someone help me with state trees?i want to make the AI choose a random point in a radius and then go to it
i read the documentation and watched 2 h of tutorials but cant figure it out
Try making move to location a child of get location
Get location and move location, being siblings, will run at the same time. Whoever finishes first will trigger the transition logic for it and/or the parent
also does not work
@slow bobcat do u know state trees well?
if yes ,can we make a call today?
Hi All, not too sure why my Task isn't working. It should focus the attack target (the player character) but they just seem to look ahead instead. Could this be because they are registering themselves as an attack target as they are children of the player character (Needs to be this way due to another mechanic in the game)
ok- I have found out that this is the issue, but I'm not sure how to fix it. Any ideas?
So you're saying the problem is that your NPC is targeting itself, rather than the player, because it inherits from the player character class?
that would appear to be the case, yes
How are you selecting the target?
As in, where does the value in the blackboard key come from?
Can't do calls sorry, but we can have a private chat
- how are you reading the selected location from move to?
- is the selected location in the nav mesh?
- what is it failing in the logic? Difficult to say by the picture
It comes directly from the AttackTarget key in the blackboard. It works perfectly fine for the boss character (who is not a child of the player character), and with the fact that the enemies are shooting each other, this is the only thing I can think it to be
Yes I mean what is the code that puts the value into Attacktarget
If it ends up targeting itself, then that would indicate the AttackTarget value is set to itself, rather than the player, so the problem should be in the code which is assigning a value to it
ok, having taken a look at it and using print strings to make sure it is registering the attack target as the player, I can confirm that the attack target is working fine.
I have no idea what is causing this now
I don't remember for sure how the focus thing works, but it could be affected by the character movement component
You might need to turn on "use controller rotation" for it to work, or some other setting like orient rotation to movement might affect it
i wrote u a private message
guys ,how can i use the team agent perception in blueprints?
i read the documentation for state trees and the section below is c++,but i dont know it
The interface can only be implemented in C++
hmm.so i just skip the c++ part of this document?
Maybe, it depends on how the perception stuff is intended to be used
Without the interface, you can't use the builtin detection by affiliation system to determine who's on which side
But if this isn't a problem then you don't need to use the interface
if i dont have a numpad,how can i turn this debugging tools?
Virtual keyboard in Windows or remapping the buttons in the engine settings. My advice: buy a USB numpad. They are cheap, easy to find second hand and it will ease your life
If you are rich, 8bitdo retro numpad (cheff kiss)
those who made this tutorial ,why does danger not work properly?
AI agent does not run when it sees threat
i repeated all like in tutorial
Any help here would be appreciate, I am trying to learn AI and setting up a state machine. I have a find farm task that finds a closest farm that works and i have a move to task. Right now the move to task never works, even if i hard code the destination in what am i missing? I will say i have an initial setup without state machine and is just blueprints with AI moveTo that does move the NPC
For "report noise event" as well as the sight sense how would I configure it such that the strength returned is based on distance to the recipient? Right now it's just a constant 1 (or loudness for report noise)
I guess I would have to determine that after the fact during processing the stimulus
Could it be because of the part in c++ that you skipped?
Is the state with the taks to move running? Does the taks run? If you open the state tree debugger, what do you see?
Hi @slow bobcat do you know the command RebuildNavigation work on package build. It used to work in 5.0.3 but after upgrade to 5.5 it seem does not work.
No. This is how the nav build works:
- Dynamic: builds on demand PIE/Builds at runtime. Either around an invoker or within affected nav volumes entirely
- Dynamic with Nav Modifiers: you can only build it PIE (command or Build Paths tool) or during cooking time if specified (this I'm not very sure since we have a separated commandlet to build the nav in our pipeline). Tiles will re-build in runtime if affected by a nav modifier. No new tiles will be added
- Static: can only be built PIE or through the cooking process (same thing, not sure if you can specify in the cooking pipeline or needs to be a separated step as we do). It never changes at runtime.
Maybe if you use Dynamic or Dynamic with Modifiers it will work, I have no idea. I never called rebuild on demand within a build at runtime. Sounds like a bad idea to me
That is how our project setup. And it is bugging me.
but why would you call re-build navigation at runtime instead of leaving it to the system to decide when to do it?
Our project use run time procedural dungeon. I am not the one dev it so I am not sure why is the reason.
AFAIK there are two ways to handle procedural generation:
- either you construct your dungeons like Diablo3, where you have a set of "dungeon parts" you combine, like model kits (hallways, curves, rooms etc). Each of them has it's own nav baked and you streaim in the nav (this is the same as you would do using the old streaming levels system in unreal if you wanted to stream in navigation)
- Or you use Dynamic Nav and you generate navigation around invokers (this could be the player, the AI's or certain actors that are streamed in when you construct the dungeon)
You shouldn't need to call rebuildnavigation, which will force building the navigation on the entire game at runtime. You can of course (Whatever logic that command is calling you can access in c++ at any moment), but I think it would be better to use Dynamic around invokers and let the system build just the parts it needs.
Our project use pure random, there is no dungeon part. 
random is still running over a set of assets etc
You still pick a random floor etc right?
Among that logic, how are you handling the nav? You should be bringing in some nav bounds volume no? or are you creating one at runtime and adjusting it to cover whatever you generated?
Each dungeon is in sublevel and has a nav bound volume that cover whole dungeon.
ah ok I see. So you have an empty sub-level with a defined size and a volume and you add stuff inside. Then Dynamic Nav around invokers should work just fine
but if that's too expensive on cpu for you (it was for us for example), you will need to indeed call the build nav process before presenting the level to the player. I think Nav Generation has multi-thread support (it's definitely async, but not sure if threaded right now). If that's the case, you should be able to prepare everything ahead of time with little impact to the game thread (except for the streamin part of the level)
Our game release on mobile so that could be an issue. I am finding a method to replace for RebuildNavigation command.
I would try with Dynamic around nav invokers and use the players and the AI's for it as a performance test. Then check with insights in a Test Build. Might be fine, it will depend a lot on the size of your level, the complexity, the invokers' radius...
hey ,i succeded to make the AI go to random point,wait,go to arena while a timer runs,wait and repeat
but how do i make the strafe state?
i have no idea
i will have a boss on the map and it should strafe him
AI that i worked on is marked green,and the selected collision will be the arena
when AI will enter the arena,boss will spawn and the AI will need to switch the state to strafe
Focus
boss will also have its logic ,so i should strafe him,not the arena
yeah
I haven’t dabbled, but someone should know
so many people dont know 😦
my teacher does not know,everyone in voice channels does not know
Focus is a separate system not related to behaviour trees directly. Unreal just provided a node to set a focus from a behaviour tree, but probably not from a state tree. You could relatively trivially write your own "set focus" task
If you just want it to strafe towards the thing it is moving to, enabling the "strafe" flag on the move-to task should suffice
You can call "setfocus" on the AI Controller from any blueprint or code path you want
my teacher does not know
My advice about this: if you teacher hasn't work and released a game in unreal in a commercial way, look for another Unreal teacher if you can
look for another teacher?
haha
tell this to the university,not to me)
hahah yeah... I added the "if you can" because of it
then... no other than to be better than the teacher
this dude heard about state trees for the first time yesterday when i asked him for help
Just dont forget to clear the focus when you dont need it anymore, otherwise itll be stuck there forever
Tbh state trees are an Unreal thing while Bt's is an industry standard. But the lack of refreshment on his part is bad
state trees are relatively new ,and are ready for production ,but because its new,it means less tutorials and information online
ahah,i just started describinfg by problem here and saw that one execution pin was not connected,this one
poor excuse for a teacher (or a senior dev if you ask me), specially in an engine where you have the code
Anyone know how to make AI avoid each other? currently they walk into each other
The two builtins for that are crowd avoidance and RVO avoidance, you can probably find info on them by googling those terms
on ai controller i have this send gameplay events
one for help and anther one for combat state
i have the event watchHP on AI character to check the percentage of hp
if its less than HP percentage variable i call help event from the controller(previous screen)
here i store the player variable in a state tree evaluator to further access its location
and here is seek help task
i dont know why ,but the transition to seek help does not work
here is the transition event
The transitio event would only work if it's set on the running state. For things that fit the description "I want to interrupt my tree to X state", you can put said transitions in the root state, since that one is always running
Hey there. I've got a topic I'm having trouble finding information about. I have an Open World environment with Level Streaming set up, and my AI actors moving around and doing stuff in it. They are loaded in and out when the player gets close and far from them, that's fine.
But here's the issue: If they follow the player far enough from where they started they seem to just unload even though they are currently close to the player.
When I search for this topic I find information about persistence on loading and unloading in world streaming, which is fine, but I think its a different topic. I'm trying to figure out how to not unload these actors when they are right next to the player but far from where they started. This is why I'm bringing this up in the AI section, but if you recommend I take this somewhere else, please let me know.
I've not done a lot of level streaming stuff, but are the NPCs loaded/unloaded as part of the streaming level? If the level they are part of unloads, it seems they would then also unload, so if that's the case, you would need to somehow move them out of the level so they don't get unloaded like that
You're right, they are part of a level partition cell that is getting unloaded, but they aren't in the cell at the moment, they have moved beyond it. I don't know how to update which cell they are part of right now.
Yeah not sure about that either. My first guess would be using the Rename function which despite its confusing name changes the outer of the actor - the outer by default should be the level it's in, so if you were to change the outer to the persistent level, that could affect it. But not sure since I've not really done much with streaming levels as mentioned :)
Hello. Does anyone know why navmesh lost when changing level? I have NavMeshBoundsVolume in outliner but there is no RecastNavMesh
I must be doing something wrong because I've tried both of them, I also cant find any videos or anything guiding
Edit: basically Zomg already replied, I read it after writing this
Hello!
I have done this in 2 projects I'm different ways with the old level streaming, not with World Partition. The issue seems the same though: the owner of your actor is the level where it spawns. When the level streams out, it takes everything it owns with it, your AI in this case.
You have different approaches but, ultimately, it will depend on your game implementation.
If you want the enemies to be able to chase the player forever, you have two options:
- either spawn them in the persistent level. This is done by passing the persistent world as the owner of the actor in the spawning function.
- or you can change the owner as they go. This is trickier because it entails two things: one is to track on top of which level the AI is and, when on top of a level that is not the outermost owner... Do the second thing: change the owner. IIRC that's done in the same function where you set the name of the actor. Yep... You read that right. Unless it changed in ue5... That's still the case (I can check if you want, I know we do this somewhere in the game). Just bear in mind: that ownership change used to be quite expensive in ue4, no idea now.
If, on the other hand, you don't want your AI's to chase the player forever, you need to dive into the concept of Leashing/Anchoring. Basically design a system that controls how far form a location they can go. This is a deeper topic that entails many things like: should it be a radius or a volume? How do they come back? How to avoid exploits where the player runs just enough for the AI to run backwards back home and shoot it? How do I deal with a player far enough to be outside the leasing volume but close enough to hit the AI with a sniper? The topic is a headache and it depends a lot on the game. With that I can help a bit too.
The recast needs to be in the persistent level always or that can happen. One trick is to add a small empty nav bounds volume at 000 in the persistent level. That way the recast object will always be present
Does this sound rational:
- Place spawners in the world that when the level partition is loaded they spawn AI Actors.
- The AI Actors are not "Spacially Loaded" or managed by world partitioning so they won't disappear when the area/spawner they are from gets unloaded.
- Use something like the Level Streaming Persistency plugin to save the state of the spawners spawned actors so that for example it doesn't just spawn another one every time it gets reloaded.
- Have the AI actor itself despawn (and record to it's spawner) when it's far enough from the player.
I watched this but it has no guide on how it's set up
Hi all, I have no idea why my AI is getting stuck on this task, any ideas?
this image as well
does this tree look ok?
it just does not look right
but i dont know how would it look right
Posted it so you can look for similar videos using the terminology shown there
Yeah, sounds reasonable. I would add a small detail which is to spawn character when the player is nearby the spawner, not when it shows up in the world
Maybe the event is not being called? Who calls that event?
Sorry, I should have said I fixed it, but thank you!
But in world partitioning the cell is being loaded because the player is nearby. Or am I missing something?
Yeah but... How big is a cell? Isn't it massive? Could it be you enter a cell in the south to never pass the middle point toward north? Why spawning anything in the norden part?
It's quite configurable. Right now I have moderately granular cells with a large loading radius so that stuff is loaded in a bit at a time rather than large chunks.
I have some issues where my agents seem to be entering non-nav areas and then get stuck, trying to find a point out. I made the agent radius even larger then the actual capsule radius to allow for this but it hasn't helped
seems given the agent radius they should never be getting that close
Could be your steering logic pushing? Did you validate if you issue a move command outside the navmesh?
Ah I see. I haven't use WP yet. Very curious about it, specially about how would one handle a vertical game like Dark Souls for example
The grid is 3d, so things will load and unload when you get far enough above or below them.
But they unload entirely right? What I mean is: if I have 5 in column A and I'm at the bottom, the entire column A is loaded no? Or can you control the loading vertically too?
Hmm, I'm not sure the use case you are proposing. I'm suggesting there is a 3d grid of cells and the actors in each cell are loaded when a level streaming source is in range. In your example there is a vertical column, is it a single actor? Or a stack of actors? It might not matter much because when they are unloaded they can be replaced with an HLOD.
Oh sorry I meant a column as a grid column. A vertical stack of cells in the 3d grid you are describing
Was the 3d grid always supported or is it a new thing from 5.5?
Ah I see it was introduced in 5.4
yes the state tree is working, i have another task running to find a different object in the game that works correctly. I also can move the ai in that task using the blueprint ai moveTo. Its just specifically the statemachine moveTo does not move the npc
Thank you, but trick didn’t work
Is anyone familiar with State Trees and why the run EQS query fails to return a valid actor? The correct Classes are assigned for the actor and controller class. Even making my own State Tree task returns the actor as invalid.
Then I need more info to help.
How's your setup for the nav and levels?
The task using the move to from a BP, is it using the same location as the failing move to?
ST tasks run in parallel, so since you placed them on the same state your MoveTo is trying to run before your EQS task has finished running. Its best to have your MoveTo task on a separate state that is a child of the current one, and transition over when the EQS task returns the results.
However in 5.6 we are adding new patterns to how tasks run that make async patterns like this much easier to deal with 🙂
oh hell yeah Thank you!
when i run the underlined decorator only the wait 0.1 and next yellow task
if i move the decorator higher in the chain same thing
but i want to abort the whole move to arena when hp is less than 0.5%,how can i do so?
if i put the decorator on the task,it executes only this task
What's the typical approach to having low cover areas that require a crouch or some other change in nav agent size to traverse? I've seen Unreal has the concept of "low height areas" that can be marked on the navmesh, is that whats used for this kind of functionality?
A sequence node will run each of its branches from left to right in sequence as long as they succeed. If the decorator fails, so does the sequence
Does anyone use Detour Crowd Controller frequently? It works out of the box, but even with some tweaks I found online, my agents are still "sticking" to each other.
Any hints as to what Detour settings may improve this?
I'm trying to set something up similar to the crop out sample project. They use floating movement component but the pawns still stay on the ground. I use the same settings but seems the 'move to' in the behavior tree moves the pawns off the ground, even if I restrict the Z in my search nav task to 0.
If you are seeing something like this, that's what it should look like
https://youtu.be/MwQzDkrs0fI
This was exactly it, that and it appears setting the vector parameter with the EQS doesn't update in the move to task when it reads from that variable. It is giving a value from the EQS but giving a 0.0.0 value to the move to task. I just put them together instead of separate tasks and it works now.
Yes, I wish it just was more smooth consistently like RVO. But I don't like the idea of introducing the "push" mechanic RVO implements. I'll keep trying to improve Detour.
RVO alwasy sucked for me. Pushing AI's out of nav, inside meshes... Crowd is nice. You can tweak it a bit to get more distance but it will look bad in narrow corridors. You will see if you play with it.
Takes some work to get actual avoidance with anticipation that doesn't look bad.
Crowd control is more a "do not get stuck" rather than "avoid each other"
I probably need to rework capsule size and potentially introduce velocity compensation during these moments. I implemented a custom velocity compensation system into my instant pawn possession mechanic and it worked decently.
I'm developing a patrol system, where you can build splines with waypoints. And I'm wondering how to decide how to handle loading/creation with world partition? Given that a patrol may potentially cross multiple cells. And Because the actor is only associated with a single wp cell, how could I set things up so that I guarantee that I'll have a patrol that may go across multiple cells?
Not using WP, but the way we handle this is:
- designers place a special type of actor that consist in a patrol point.
- said points are added to an array within a patrol component in the spawner actor that will spawn the AI. We also draw a spline and numbers at it so designers can see quickly how the patrol looks. The patrol component also has flags to define, loop path, start reversed and some other flow control flags
- upon saving the level, those actors are processed and internally we serialoze an array of objects that have the location and couple other things (we can tú actions like "look at X direction for N seconds" in patrol points so the AI patrolling does cool stuff to decorate it
-the patrol actors placed in the level are Editor only, so they are never cooked or saved into a build - when a character spawns, the spawner passes to the character that data into its own patrol component (patrol component in the spawner is a data holder, patrol component in the AI is what has the logic to get the next point, to know if an action is to be done at certain point etc. Functions a bt will use)
That way you are not constrained to levels being loaded or need to increase your actors-in-level count or have more cpu work to stream this extra actors in.
Ahh, that's really interesting. So the information and the patrol points are ultimately stored in the spawner, which is itself loaded when it makes sense.
Thanks, that's very sensible.
I guess extending off that though, when a player approaches this patrol/spawner, is there a reference point (the spawner actor) that you check against to know when to activate it? Or are you taking into account the bounds of the patrol to ensure you can spawn it at the extreme closest to the player the earliest it may make sense to. Not sure if my question is clear
Yeah we check proximity to spawners to spawn AI's when needed. Unloading is a bit more complicated since we check the state of the AI, proximity to the player and other stuff.
The patrol part: no, we don't use the patrol boundaries for anything
Cool, makes sense. Thanks for sharing all that, super helpful as usual
Anytime. Sharing is caring and all that
Usually you would want some kind of persistent state thats not an actor but contains some extra data about how to re-spawn streamed actors
Depends a bit on the game implementation. Ours spawn back in idle form their spawner and let the AI to deal with the world context and it's fine. But if you need to spawn them back at the last location, or with the last behavior etc then yeah. You need soemthing.
Ugh, I was under the impression that if you triggered gameplay tasks from BT tasks, they would get canceled if the BT task gets canceled but nope doesn't happen
Is it normal for the navmash to be represented as long thin shards of glass?
Hello, is anyone used to UAITask_MoveTo in C++? I'm trying to use it, but anytime I try to start a new one while another one is running, it'll pause the first one, and run the second one.
The main problem I have is that when it pauses the first one, it forces the velocity to be nullified, making the AI start accelerating during a movement from scratch.
My AI is investigating a location using the first AI MoveTo task, spots a player, starts a second AI MoveTo task pausing the first one, and setting the velocity to 0.
void UAITask_MoveTo::Pause()
{
if (OwnerController && MoveRequestID.IsValid())
{
OwnerController->PauseMove(MoveRequestID);
}
ResetTimers();
Super::Pause();
}
Can you share an image of it?
You can't run 2 move ai taks at the same time because each of them calculates a path to the goal and you can't follow 2 paths at the same time.
The Pause thing makes little sense to me. You should simply stop it and start the new one because you will not come back to the first one, you can simply run another one when needed.
The acceleration can be two things:
- you are using acceleration based path following. That's a flag in the CMC. I'm almost sure it only affects the AI for stopping (deceleration) but worth giving it a try
- the other reason might be you have a low acceleration value and it takes a while for the AI to catch up to max speed.
Even though you can fix both, you will still have that frame of 0 velocity in between move task and it will look bad.
There are 3 approaches I have tried myself that can mask the problem
- #1. you can keep the walking animation happening X frames after the movement task finishes in a Timer. If another movement task starts, cancel the timer and skip the animation playing. If no movement task after, the timer will finish and stop the anim. This is easier done when your game uses montages (you call play montage)
- #2. Movement works in 2 ways that can happen at the same tine (all happen in CalcVelocity within the CMC): there could be a movement request that comes from the path following component (as a consequence of the move AI task calculating a path and requesting the path following component to move the AI through it) or there can be an input added to the AI (the function is called Add Movement Input or something like that). Well, one thing you can do is something similar to option #1, but instead of keeping the anim alive, you keep the movement alive by adding an input every frame at your current velocity within a timer. Same concept canceling the timer upon having a new move task etc. The call velocity will start the deceleration and as soon as there isn't any move request or Inputs (acceleration within that function).
- option #3 (my favorite): you always move to an actor. Basically you assign an actor to each AI (you can have a pool for performance). The actor is invisible and all it has is a scene component. When you want to move to a location, you place the actor there (set locsiton) and move to it. When you want to chase your player, you place the actor at player location and "glue it" to the player (this can be simoly enabling the tick in your actor and make it set it's location to the player locsiton). That way, you will only use one movement task and everything will be handled organically inside, allowign5you to swap between moving to locations and actors seamlessly, without pauses or anything, no "weird" timers to keep things alive. Also, you can get advantage of the path observer and do your stuff in the path events (like enabling/disabling the tick if the actor)
One thing that can happen is that, if you have deep complicated AI where deciding what to do next takes several frames (it will never take less than 1 because bt/st evaluation takes 1 frame minimum, but 1 frame is not an issue), you will still need to combine option #3 with #1 or #2 in cases where you approach your target and then decide things that imply another movement
Hi, guys: I want to write a subclass of UStateTreeTaskBlueprintBase in C++. Is there any repo that I can learn from.
I wonder how to create variables ,as in blueprint, letting the designer to bind specific objects to them in the editor
You wouldn't do the BP Base in C++
Oh I figured out :
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Context", meta = (AllowPrivateAccess = "true"))
TObjectPtr<AUnitAIController> AIController;
just like this in the declaration of the subclass
Look at how something like the MoveTo works.
I think it could be done to inherit the UStateTreeTaskBlueprintBase in C++
I know it can be done, but you shouldn't because you lose some of the biggest benefits of being in C++
The only reason I can think of where you should is if you want to make a new BP Base that all of your BP tasks will inherit from instead.
But if you're writing tasks explicitly in C++, you don't.
Tasks in ST are structs. If you do the BP Base, you're now doing it with UObjects. Which are heavier. If there is the concept of instanced tasks like there is in BT, you also don't get that.
So you take a performance hit for no good reason.
what if I want to write some generic task like : go to the nearest thing which is "some kind".
and I can configure it in the blueprint by assigning a class to the "kind ref"
That is still a struct. You would expose the "kind" property to be bound to. Then you would have some other task be responsible for actually finding it.
Or you just use the built-in Move To task.
And don't write it at all
But if you did, you still wouldn't need to inherit from the BP Base class.
Look at how the built in tasks are written.
It depends on your IDE, but you just search for the terms. Not by manually clicking around. Use the actual search feature of your IDE.
Okay when you said not using bp based class, did you use FStateTreeTaskBase as the parent class?
I don't recall the exact name. Again, just look at the built in tasks.
okay thank you very much
Why is this your favorite?
class UAITask_MoveTo : public UAITask
{
GENERATED_BODY()
public:
AIMODULE_API UAITask_MoveTo(const FObjectInitializer& ObjectInitializer);
the built in moveto task is itself a UObject?
AITasks (and gameplay tasks, etc.) are all uobjects
Look at how the built in state tree tasks are written. Not AI Tasks.
For the most part, right now, you don't need to worry much with AI Tasks.
Because it's super flexible:
- moving to a location, towards an actor or to chase it? No problem, it's all the same: move your lightweight invisible actor and off you go.
- want to do spread behaviors for your group of enemies chasing the player? Easy: 3ach assigned lightweight actor it's at a player location + some offset (Sunset overdrive did a similar approach)
- want to do a movement pattern like zig zag? Ez: calculate the points and move the actor to each point before the AI reaches the point. All handled within the same MoveTo Task, no velocity changes or stops while moving like you would have when using move to location
It's flexible and opens a door to squad movement formations and movement patterns in a very easy manner
Couldn't you achieve the same effect by lerping to the new location? I'd imagine the move to location has the issue due to teleporting more or less.
Never really noticed so never looked.
So like, if you're target actor teleports to a different place, would the issue still persist (the one this solves that is)
sorry I have searched but I can not find one
MoveTo ai task doesn't support changing the goal when it's to a location. You could handle it, build the code etc but... It's easier to always move to an actor
Well...that sounds like something that should be fixed imo.
Search harder. They exist.
some clue?
"Move To" and look for stuff around state tree.
They'll generally be like StateTree*Task where the * represents the name of the task.
SoStateTreeDelayTask or StateTreeMoveToTask or StateTreeDebugTextTask
I find it
True it is not a uobject
struct FStateTreeMoveToTask : public FStateTreeAIActionTaskBase
Is the recommendation for complex AI at this point to use the new StateTree system?
<@&213101288538374145>
ah its fine
Yesn't.
BT is still more stable and far more resources
But ST is what Epic is heavily pushing
And BTs are to be deprecated in the future possibly.
I've got no experience with either - I've always just written my own stuff entirely
i doubt they will deprecate BT
Mieszko said the plan is to deprecate them.
its a key AI feature, and diff to ST
But for the first time will be tackling something that's going to end up complex enough that I doubt that's a good idea 😄
I agree
both different
And I like BT more than ST
But even if they don't deprecate them - they'll just be on life support.
5.6 is supposed to have a lot of goodies for ST as well
Right, that's a thing. So might make sense to kick the AI can down the road until 5.6
ST confuses me sometimes though
like so many things can influence and its kinda awkward
They've come in here and asked a few times what are some of the pain points and why we may be using BT instead of ST
But async stuff is supposed to be getting a lot better in 5.6 for ST
only time i would consider ST is if performance was good
ST Debugging is actually quite fine if you use that record tool.
but when i last compared BT was still faster for me than ST for my ai
Would be nice if they would integrate ST into the RewindDebugger directly if they haven't already.
ST should be faster than BT 🤔
again it depends
my simple AI test with BT was faster than ST
but this was back in 5.3?
maybe 5.2
I also don't really like the property ref stuff all that much in ST to be honest. Gimmie my blackboard 😠
I think ST from 5.0 to 5.2 is hard to compare to BT. It seems to have gotten a lot of love in terms of UI and debugging tools up until now.
I think they are similar in many ways
Yeah, ST is getting a lot of attention
Sure they are similar, they are both State Machines in the end.
i do like the visual style of BT better though
yeah much better to debug now
BT is a bit nicer to look at when talking about AI, yeah.
^ that quickly becomes as easily readable as a nested struct array.
but grrr it annoys me
Yeah we had to use it for Mass too. Never used it for anything else.
And for Mass it's extra annoying.
but UBTTask_WaitBlackboardTime will keep existing until last dying breath of BT in Unreal (so roughly until UE6).
#gameplay-ai message
(Where Mieszko said BT is planned to be deprecated)
Well - 5.6 is also supposed to bring the ability for STs to still be functional without having to tick.
Don't you think it is more readable than BT
UE6 might become quite the shit show
no 😦
haha
BTs are nice layout wise because they're dense and concise
If the claims from #verse are true as well...yeah.....
ST has all the condition stuff so it needs to be turned into a vertical list which is much worse for space utilization
BTs laso work differently.
BTs have flow control nodes and leaf nodes that execute or do things.
And then with Conditions and Services on top of any node that wants it.
To be entirely fair - you can still model the BT behavior in the ST to a certain degree.
STs are nested states, where each State in the Path can execute/do things. Almost like a Tunnel (vs Bubble)
That's also why sibling states can't share input/output
At least iirc.
Have the highest priority stuff at the top of the ST. Enter Conditions can serve as your decorators that gate accessing the state. Then services are just another task on the state that never completes. Only let the states transition to the next state. This pretty much models how the BT works.
With some quirks of course.
Yeah, I think the biggest quirk for me remains what can use the Output of what.
Not that this is different to BT, but it still confused me.
Iirc it was this is wrong:
- Root
- FindWaypoint
- MoveToWaypoint
And it should be this:
- Root
- FindWaypoint
- MoveToWaypoint
Eh - I think BT's data handling is far more clean personally. Data management happens through the Blackboard. Simple.
So that MoveToWaypoint can use the result of FindWaypoint.
Yeah, but then MoveToWaypoint may not even be able to run because FindWaypoint hasn't completed yet 🙃
Yeah there was a way to resolve that. SmartObject stuff had an example for that.
Siggi showed some improvement to async stuff in 5.6 a little bit ago
I think you just notify the ST or so.
It generally started to make more sense to me thinking about the nested States as Scope instead of Children.
I'd rather be able to run the tasks on a state sequentially.
For situations exactly like this.
Yeah, that's what I expected and I was confused when my "Waypoint" variable wasn't avaible on the next task xD
Yeah, they can only access stuff on the parent states and global tasks.
And modifying the global stuff is pretty painful.
In BT, I'm pretty sure you'd handle that differently. You'd have:
- Root
- Sequence
- FindWaypoint
- MoveToWaypoint
Or maybe a parellel somewhere.
Yeah and FindWaypoint would write to the BB
Yus!
That's probably one of the key differences. I also think BTs can't jump to states iirc.
Which STs can do I think.
They can but you really really really really shouldn't 😅
Well let's say it's not intended at least.
BB is definitely the most missed part from BT for me.
fwiw, you can probably add a BT like feature to ST.
Well - the global params or global tasks is what is a quasi-BlackBoard
But writing to it is nowhere near as simple.
Property Reference - that's what I was thinking of. (For the BB)
does ST has something like Sequence?
I can not find a reason why they should not have one
Sequence? Like in behavior trees?
yeah
Not really because the execution model differs from BT's execution model. What are you trying to do?
- Root
- FindWaypoint
- MoveToWaypoint
then we can easily get way point from the first task\
then how do they handle the sequential tasks?
Sequential tasks which use data from the previous tasks would have to be nested in order to be able to access the data so it's a bit clunky
I think there's a property reference type which might allow another way to set them up though but I've not had a chance to look at it much so can't say for sure
Oh right, Siggi's on State Tree now
Yeah - he has talked a bit about what is coming in 5.6
And it is definitely a step in the right direction.
We worked with him at the startup he was at previously, so it's a weird context-shift for me 😅
Yeah sounds like it will improve some cases like what piggy was just asking about
which is kind of a pain esp with async tasks currently
Isn't that Context usable?
Iirc there was some context that was passed around. At least in Mass.
We even made our own for it at some point to have more data in it.
Is there any way to cancel all the other MoveTo tasks though? I always need the most-recent one, I will never continue the one I previously had
it is still Engine.RecastNavMesh or they changed it?
seems like not effecting the world
Unfamiliar with ST with Mass to be honest. I haven't had a need for Mass yet. I'm just talking about non-nerd gameplay stuff. So you have a global param and then in the state, you'd have a StateTreePropertyReference and that would bind to the global param you made. Then you can do some gets/sets on that.
Haven't tried modifying it from outside of the state tree yet though (I found a way to do that way back in 5.0/5.1, before all this extra fancy stuff)
If you keep the task object, yeah. You can just have a pointer to it
And what if I don't? 😛 It's called from different states which
And the task themselves are wrapped with a latent awaiter (ue5coro)
If Task_A finishes immediately and you want to use the result in Task_B,
The problem can be solved by simply placing Task_A and Task_B in the same State and giving Task_A a variable whose Category is Output.
But this can only be used in the limited case where Task_A terminates immediately.
It's much more common for this not to be the case, so I'll write it below.
If you need sequential tasks, where the next task uses the result of the previous task, you can do the following:
- Parent
- Child_A
- Child_B
- Let Parent own StateParameter.
- Child_A updates the StateParameter of Parent. Once the update is complete, Child_A will transition to NextState.
- To do this, Child_A's Task must have
TStateTreePropertyReforFStateTreePropertyRef.The built-inFStateTreeRunEnvQueryInstanceData::Resultis a good example.
- To do this, Child_A's Task must have
- Child_B uses StateParameter of Parent.
For example, in the StateTree in the image, Strafe State has a StateParameter called StrafeLocation_EQSResult.
This is updated by the FStateTreeRunEnvQueryTask that EQS State has, and used in StrafeMove State.
I have no idea how the default task works for st's. I use my own stuff for movement
I don't use State Trees for that, I was referring to other states, e.g. different pieces of code that don't know anything about each other
Sorry, I wasn't writing about your question, but about an earlier topic (#gameplay-ai message , #gameplay-ai message).
@slow bobcat random Q - any ideas for how to deal with canceling gameplay or aitasks launched inside BT tasks when the BT task gets canceled? This seems kind of a pain to track
Current idea is maybe I can have a C++ baseclass for the BT Task which would somehow be able to track when you launch the tasks from it (eg. through the task owner interface) or just shove the currently active task into a variable and check if it needs to be canceled 🤔
This is how I keep GA and BT in sync. I haven't touched BT for a while so please excuse me if I'm wrong.
We use gas for this. The flow is bt-task launches a GA and listens to onGameplayAbilityEnded. If the tasks ends, the ability is canceled. If the ability ends, it finishes the BT task.
The trick is that all our bt_tasks inherit from our own base class called BTTask_Action and, from that, we derive everything: movement, attacks and others
Interesting, I'll check how GAS handles this because I'm noticing BT tasks can be owners for tasks but it seems to just delegate it directly to the AI Controller which might make canceling only the ones from the BT task kinda iffy - thanks
Although come to think of it, I don't think they would ever be running any gameplay tasks besides the ones from the active BT task at the same time anyway 🤔
The move-to task is an ai task that is spawned from a bt task. This handles it correctly, all you really need to do is override the functions the same way it does it there. Its a bit of a pain to get running but it certainly works
Yeah BTTask_MoveTo basically uses the "shove it in a variable and cancel it" approach
I just have a couple which are implemented in BP's and wanted a kind of "don't have to think about it" solution to it :)
You can write a generic "run gameplay task" bttask, that has worked for me
Yeah that could be an option I guess, I just have a few which are more elaborate and do more logic
There's just a lot of little edge cases that need to be handled because it goes together with smart objects which could be removed while the NPC is using it and other sorts of fun shenanigans :)
I mean yeah, if you make it a base class you can always add functions to it, I have something like "run eqs then run a task on the result", but you can do it however you need it
So anything where I can have something get done automatically for me (like the tasks getting canceled) is helpful because otherwise I might forget and have bugs lol
You can inherit from the instance data, so you can have a base class with a base gameplay task pointer stored in it and have the base class handle all of that, while a subclass could still add instance data while keeping previous functionality
Hi everyone, I am fairly new at state trees and making bosses. I am currently making a game for a game jam with a boss fight in it, and i was wondering how to do different attacks using state trees. I was thinking of a few attacks, a basic attack, a charged dash attack, a ranged attack and an AoE attack. What i would like to know is how to implement the changes between attacks, I was thinking of some sort of percentage based system (like 50% of the times it will be a basic attack and so on), but i would gladly hear any other ideas that might be easier or faster for my game
some sort of percentage based system
PerhapsTry Select Children at Random Weighted by Utility( https://dev.epicgames.com/documentation/en-us/unreal-engine/state-tree-selectors-overview#tryselectchildrenatrandomweightedbyutility ) is what you're looking for.
One thing to note about this is that only specifying a value for Weight will not work, you also need to add Selection Utility.
StateTree is a lot faster than BT, its the only way we could do CitySample with the amount of characters there.
Performance is the main reason to use ST over BT 🙂
I'd love to hear more about what you like more about BTs, UX/UI is something we do want to improve in the future.
I'll take a look at this, it does seems that it will work for my goal
You can still do this in ST with a selection on Sequence, but you'd have to declare the parameters on the Sequence state to be usable by both children states.
Good discussion here btw 🙂 more of this! (still catching up)
yes, you can use "Try Select Children in Order". See:
https://dev.epicgames.com/documentation/en-us/unreal-engine/state-tree-selectors-overview
@harsh storm Can you tell me a bit what exactly you love more about BB? I actually prefer the scoped nature of property bindings, it makes the order of operations and expectations a bit clearer to me. Using a BB is more like using a bunch of global variables and there are very little guarantees the properties there will have the data you need at the time you need it.
it might be under certain situations but i tested a very simple AI and back in 5.2 (i think) the BT was faster
but it might work better now or maybe it works well cause CitySample used mass processor and it was all batched together?
A lot can factor into the perf yeah, including how much you use tick in ST tasks. Usually the perf limiting factor is what you do outside of the behavior, like interop with other systems.
In 5.6 you can make complete ST behaviors with no ticking
Hi Siggi, meaning I have to create several states to be executed their tasks in order?
I got another question: the built in state tree tasks are not uobjects, like StatetreeDebugTextTask.
How can they be found by the editor? Since there is no reflection?
I don't mind the typesafety portion of the property bindings - but BB made it clear how to give the BT data and pass it around. So even outside systems had an easy way to give the BT data.
As for data guarantee - I'm not sold on that in regards to property bindings. Because the data you actually need may not be filled out as well. As in, like the move to vector being filled out. It isn't guaranteed that the property on the actor is filled out by the time you need it. It just exists. Same with the BB in my eyes. It just exist. Timing for both systems still come down to the dev. Unless I'm not understanding what you mean by this. (Maybe you're talking about binding from one state to another state - where as I'm talking about the global params, as that is the closest ST has to an actual BB)
They are USTRUCTs
So there is absolutely reflection
Oh thank you very much
Excellent explaination Thank you very much
Makes sense. It's not so much about how to achieve it, but more about how the tree works vs how the tree works (or rather how I expected it to work originally.
They are all structs that inherit from a base FStateTreeNodeBase.
Thank you very much
correct, the data guarantees of the bindings is broken when doing async work currently
Im with you on that, we are working on improving some UX there to make it more intuitive and in line with what people first expect
but The state tree sequence by order would guarantee the order of execution of async work, I think this is good enough
correct 🙂 but as pointed out above, you need separate states setup for it
Okay
in 5.6 you can also chain tasks together 😉 almost like a mini task graph within one state
ie triggering a task when another one is finished
Even better
ooh
that sounds exciting lol
I wonder when is 5.6 coming out then hmm, I was just thinking I kinda need to redo at least some of my AI because it's getting kinda janky lol
....although it's probably gonna be broken and buggy at 5.6.0 so gonna have to wait til .1 or .2 as usual :P
Have some faith😅
I'm speaking from experience lol
the .0 releases always seem to have a few weird bugs but they do tend to get fixed pretty quick
Good to know
The hell did I even write there. I meant to write:
how the tree works vs how the user expects the tree to work (or rather how I expected it to work originally).
Note: Don't type stuff on your phone if you haven't had a coffee yet.
its fine, I got your meaning 🙂
Most likely UE fest or right before it.
So about a month
Good guess :)
A lot of the stuff Siggi has been saying is coming to ST does indeed sound really nice.
@chilly nebula btw do you have any knowledge about the smart object system? I need to support multiple activities from same slots, where each activity has its own behavior (eg. "take a thing from this" vs "place a thing into this" as separate activities)... and this is kind of clunky to support right now. So I wonder is this something that nobody thought of, or is there some actual intended way for this to work because I'm not sure :)
I know we do some stuff for this but that's the other AI programmer in the gsme. He's coming back from holidays tomorrow, I can ask if you are interested
Sure, that'd be great
I know you can have per-slot activities and behaviors which is one solution to this, but it feels not so ideal because if you have multiple slots where the object can be used from, you would essentially have <number of slots> x <number of possible activities> slots in the object at the end, and you would need a solution that claims all the slots in the same position when one of them is being claimed/occupied which seems a bit complicated as well.
So instead I have some custom things I've built around it to make it possible with one set of slots... but would be good to know if there might be something I've overlooked, especially if there's an "intended" way for it to work so any future changes to the system won't be problematic
I still haven't used the smart object system 😅
It works fairly well other than the multi-activity thing
Another small thing with it is that the builtin tasks and some functions also feel a bit like "here's a basic example" type of deal and to really fully take advantage of it, you have to make your own ones
Sounds like anything in unreal then
Haha, maybe :)
We use them in our patrol system to do stuff at certain patrol points. Also for what we call "first encounter" which are scripted actions for the first time a player encounters enemies in certain spots
I'm making a video store simulator so as a general system it fits it quite well. A shelf with videos is a SO, which can be interacted with in different ways. For example, customers can browse or take a video from a shelf, and employees can place videos on them. A cash register is a SO, and employees will use it to process customers in the queue, etc.
Is this a game or a proper simulator?
Game
Oh, yeah a game, I don't know what would be a proper simulator for something like this :D
It's basically like one of those job simulator games but I hope to make it a bit more in-depth since they feel like they often fall short on that
Although there is currently a bit of a gameplay loop problem that I need to solve, or change it to a more traditional top down tycoon style game which would immediately solve the gameplay loop problem :P
Don't you hate when that happens?
"Man - if I was just in a different perspective...."
lol yep
Oh I remember this... You posted pictures once about it
"I can solve it with a bit of transparency around the character"
Shit storm
I dont have a clear answer for you no, but Ive seen teams build something on top to support this. I think most just do the duplication approach you mentioned. I guess in your case you want the reservation to block other types, so you dont try to take something out of a container while someone else is putting something in.
Thanks :)
And yep that's pretty much it
Is this a normal shape for NavMesh separations?
Hey everyone I've been testing some stuff with state trees and so far I'm really liking them! However I haven't been able to find equivalent functionality to "Inject Dynamic Subtree"
The closest thing that I've found is a component level ability to override linked state trees by tag. However this wants static asset references in a dictionary and looking behind the curtain it seems unsafe to alter at runtime.
Is there a way to dynamically inject state tree behavior, or is there some decidedly different pattern to utilize to dynamically inject behavior at runtime? I've previoulsly handled things like "dynamically equipable weapons" by having a weapon optionally provide a dynamic injectable behavior. For example if an enemy was unarmed and saw they could get a pistol the pistol would provide them a behavior that describes how to position and use this item. I was hoping to do something similar here.
Currently it looks like I would need to handle all cases in a monolithic state tree or I would need to swap out the entire state tree with the new weapon (including ambient and non combat behaviors).
In this case am I best served just going with behavior trees or is there some way to get state trees to behave in the way that I desire?
yea, its the poly under the pawn + avoidance radius and ...
anyone could guess why my navigation raycast (the black line) returns hit (there is not wall in front of it). retuned TimeOfImpact is 0.999999999
it happens ranmoly in weird cases. im raycasting to the center of edge/portal
My chicken doesn't move at all. Also on begin play of my chicken BP I have my logic started via the ai controller bp
-
Your tasks are backwards. You have them running away and then finding a location that they should run to. So even though this is running in parallel - it reads very odd.
-
Your Move To Location or Actor node has no goal vector or goal actor to move to.
-
You're not binding the random location from the 3rd screenshot to anything in the state tree
So overall - nothing is even hooked up really. I would also advise to split out the tasks to be two sequential sibling states. So you find the location and then move to it. Easier to follow the flow of logic and more reliable of an outcome of behavior. I am also curious why you're not using the built-in move to task.
Even though it is extremely simple - but finding a random location that the AI can actually reach. Pretty sure everyone has implemented this at some point 😅
And exporting the c++ state tree AI components
I remember having to copy paste it myself to make a c++ subclass
(Also having a sort of global theme colors would be nice, creating the same theme on all my state trees asset is kinda annoying)
I ended up unchecking RequestedMoveUseAcceleration and setting up a longer (non-zero) interpolation time on the walking blendspace, which pretty much masks the 0 velocity on task switch
I have a little monster character that moves around from target point to target point...I added a timer that makes him stop every 5 seconds and face the character and shoot. I've been able to get the shoot action to happen (even the rotation, which flashes quickly) but nothing I've tried regarding the ai controller or the movement component (floating pawn movement) can seem to cancel the "move to location or actor" node...
here's one of the things I've tried.
Yep, very well known "bug" in unreal. I had this in every project. My advice is that you do what I do: start your nav traces 1 unit away from the nav edge.
Hi! I want to run an eqs query in a class that inherits from UObject (in blueprints), but the node RunEQSQuery is not available. Does anybody know why?
Nodes which require a world context won't work in UObjects unless your UObject implements GetWorld
There's an explanation plus example here https://zomgmoz.tv/unreal/UObject
Thank you so much! You're a life saver, it works now!
np :)
Hello, I am working on a project which is I need navigation mesh around 50 character. Their duty is just pick random location and then go there, then repeat. When I spawn all them of them performance is very poor for my case
they are not doing anything other than walk around
is there any flag or option I can play for tweak performance (I am okay with tradeoff with nav mesh performance)
Use Unreal Insights to determine what is causing the performance problem. Chances are it isn't navigation
If you have 50 characters, possible reasons include CharacterMovementComponent and skeletal animation
When I disable navmesh collision it works well
Where is that setting? Never heard of it :)
Is navmesh generated repeatedly inside of a packaged project or is it cooked in the level
Hey there ! Im going crazy with something and before I yeeted my project out of the window i thought i would ask here: So my ai in the landscape with navmesh doesnt move anymore, but if i put it in a level instance move, anyone know what the problem could be ?
Mention: When placing it works, When spawning it doesn't, AI seems to have a controller in both modes, AI works on a simple test level
Hey, I'm wondering do you guys have any method for merging/diffing state trees? Outside of diffing the raw serialized conent? (I'm currently using 5.4 and can't really make the jump to newer version).
Cooked by default but it can be set on dynamic from project settings which allows it to be generated at runtime or changed at runtime
Hi, Have you guys ever send a FStateTreeEvent to a running statetree in c++?
I have a basic Behavior Tree set up. Each AI has a Behavior Tree tick happening, but what is the ActionsComponent tick doing?
AI Controller > Get Current Path Points is only returning the start and end point. Does crowd detour break this functionality?
^This appears to be the case. Visualizing nav paths + detour avoidance appears to be unsolved.
Check with Visual logger what is going on. The navigation and path finding categories should have some clues
I do. What's the issue?
It is more about GameplayTags
https://dev.epicgames.com/documentation/en-us/unreal-engine/gameplay-tags?application_version=4.27
Did you config the gameplay tag for FstateTreeEvent in the project settings like the link above?
I think If I put all the gameplay tags in here, there would be a big fat configuration here.
and it is difficult for people to understand and to use
so How do you manage your gameplay tags?
we can add tags from code or from the editor. We use hundreds of them. Everywhre and for everything.
We have a macro function that, when you use it, look like this
CreateNativeGameplayTag(AIStateTreeEventReaction, "AI.StateTree.Event.Reaction");
That way we can use tags in code doing things like
SendStateTreeEvent(AITagsStruct::Get().AIStateTreeEventReaction);
We are quite thorough with our tag categories and hierarchy but, if we need a function to only use specific tags, we rely on the Uproperty macro to filter them
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category="Discord", meta=(Categories="AI.StateTree.Event"))
that way, only tags under AI.STateTree.Event can be selected
There's also the gameplay tag filter if you have different lists for gameplay tags
UPROPERTY(EditDefaultsOnly, Meta = (GameplayTagFilter = "YourTagFilter"))
that's just documentation on gameplay tags work. Yeah, we do that + de c++ thing. We can say we use them in every possible way
You use a AITagsStruct (A unique_ptr singleton to hold all the ai related tags)
to dynamically add a gamplay tag
and use filter when you wanna choose from a huge amount of tags
Is that correct?
when using dynamically added gameplaytags, How could the blueprint of statetree configure the transition of "On Event"
because the tags are not generated by then
Thanks a lot
dynamically added tags? Tags are static data.
Not sure what do you mean
CreateNativeGameplayTag(AIStateTreeEventReaction, "AI.StateTree.Event.Reaction"); did you create a gameplay tag here?
Like this guy
You create a tag at runtime
When I use editor, I could not find it
Is that true?
no no, that's never at runtime. I don't think it's even possible
Or all this kind of tags creation are written in the Constructor?
When I use editor, I could not find it
it's a custom function we have
CreateNativeGameplayTag(AIStateTreeEventReaction, "AI.StateTree.Event.Reaction"); do you create a tag by this code?
I mean you can not find the tag created in code when editing blueprints in editor
So, the way this works.
This is the code we call
const FNativeGameplayTag TagName = { UE_PLUGIN_NAME, UE_MODULE_NAME, FName(TagString), TEXT(""), ENativeGameplayTagToken::PRIVATE_USE_MACRO_INSTEAD };```
This is how our struct look like
```struct AITagsStruct
{
CreateNativeGameplayTag(EventTriggerAIAttack, "X.X.X.X");
static const AITagsStruct& Get()
{
static const AITagsStruct tags;
return tags;
}
};
#define GAITags AITagsStruct::Get()
So what happens is that, as soon as you use any of the tags in code, the tags will be added if they don't exist.
yeah, if you add the tag in Editor, you can't find it in code.
When we find that case, we add the line to create the tag in code. If it exists already, it's fine, it will not be created again.
If it doesn't exist, it will create it
go for it
I wouldn't share it if you couldn't.
Sharing is caring.
Just ask if you plan to give a talk about it. I want to mention it in a talk in September (if selected)
We have several of these structs depending on the feature/system
No I will not give a talk
I just want to use it in my code
Looking forward to your talk
will see if it happens. Scares the shit out of me to prepare it.
Hey guys,
I created a custom AISense for combat so each time there's a battle (using detection radius) it will trigger this sense.
Everything seems to work but I don't want this sense to be received more than once for each battle.
I tried adding
NotifyType = EAISenseNotifyType::OnPerceptionChange;
Which partially working, it does call it once but that's it.
Can someone explain how does the AI sense knows the perception is changed? by what parameters?
If you haven't looked at the sight sense, perhaps that's worth looking at, since I think it's the only builtin sense where the perception state can change, everything else is just "this event occurred" type senses
Hey sorry for the late reply here, I had to fact check a few things before responding to you. You can do most of this currently if you inherit the component and add C++ methods to modify LinkedStateTreeOverrides. Just be careful you dont change the overrides during a tick.
We are hoping to get a few changes in for 5.6 that will make this easier, and ideally a post/docs/sample to show how to do this. I agree its currently too complicated to setup correctly.
I have my detour crowd working much smoother around corners, but they always try to walk through eachother when stationary. How could I add a navmesh modifier to stationary actor locations dynamically?
has anyone had any success getting root motion montages to work on actors (no CMC)
You can. Might impact performance a bit since you will rebuild the affected tile upon activating the nav modifier, so try to avoid situations where they go in/out idle constantly
Ummm no idea if this is posible tbh. As far as I can see the root motion is translated to Movement by the CMC. I guess you will need to implement that logic on your own?
I found some code to consume root motion myself but it looked really janky - like the enemies were on a conveyor belt
But were they moving at the expected pace and playing the animation? Or what was janky about it?
sort of. it wasn't perfect and felt more like a guess based on the root motion and not actual root motion
Yeah no idea how the engine handles it low level with the cmc. I looked at it last year to fix some stuff but I immediately erased from my memory.
ya, on that note im happy not using root motion anyway since this is for a horde
Hi Bruno, got a question when I dig deeper to the UE' code:
why not do it like this:
in the .h:
UE_DECLARE_GAMEPLAY_TAG_EXTERN(StateMinerIdle, "X.X.X.X");
UE_DECLARE_GAMEPLAY_TAG_EXTERN(StateMinerGathering, "X.X.X.X");
UE_DECLARE_GAMEPLAY_TAG_EXTERN(StateMinerDepositing, "X.X.X.X");
in the cpp:
UE_DEFINE_GAMEPLAY_TAG(StateMinerIdle, "X.X.X.X");
UE_DEFINE_GAMEPLAY_TAG(StateMinerGathering, "X.X.X.X");
UE_DEFINE_GAMEPLAY_TAG(StateMinerDepositing, "X.X.X.X");
If that's what you like, go for it. There are no wrongs here.
Okay Thank you very much
how do you grab the tag later? is your macro creating the variable as a static/global variable in the same header?
This is the declaration in AIEventTags.h:
#pragma once
#include "NativeGameplayTags.h"
// The miner's AI event tags
namespace AIEventTags
{
UE_DECLARE_GAMEPLAY_TAG_EXTERN(EventResourceEmpty);
};
This is the way I use it:
if (StateTreeAIComponent)
{
//Send an event to the StateTree
StateTreeAIComponent->SendStateTreeEvent(
FStateTreeEvent(
AIEventTags::EventResourceEmpty));
}
and definition is in a cpp file:
#include "AIEventTags.h"
// miner's AI event tags
namespace AIEventTags
{
UE_DEFINE_GAMEPLAY_TAG_COMMENT(
EventResourceEmpty,
"AI.Resource.Empty",
"The EventTag that notifies the resource node is empty.");
}
I have to include the .h that declare the tag like "AIEventTags.h"
Aaah OK you have it within a namespace. Nice
This macro seems to be Epic's suggested way to declare native gameplay tags btw - wasn't sure if you were aware of this as you said "your macro" :) It creates a variable in the current scope, so it becomes a global unless it's namespaced somehow.
ah wasn't aware that's an Engine Macro. I'm not fully-in with GAS since I joined my current company and I'm a bit out of the loop.
Thanks for pointing out. I'm going to ask my peers why we don't use that
My project declares them in three different ways currently because it's been around so long lol
yeah I think we might be suffering the same issue. The project started 4 years and something ago. The first one at least. The second is being built on top of the first so... these legacy things will happen
I asked just in case, but it seems that we just want to declare things in the .h, so we don't have to also write the definition in the cpp with another macro
Yeah I guess that can make sense
True
I need a tip how to implement sometihng like Stun/Stutter Animation (stop movement etc) on damage with state trees.
- I have a state tree with many different states
- I have a global task that detects damage
What i think would be the best is something like Global Transition that will allow my state to go into Stun State no matter which state is currently active. I imagine that adding transisition to every of my leaf right now is not a smart solution. Addition transisition to main parent (like root) doesnt work also. So what can i do? Anyone got it implemented somehow?
Put it higher up. And dont use task for checks, use decorator or service.
decorator in state tree?
im not using BT
You can put the transition into the root state to have it be active for all the sub states
This should work I think?
At least I have a number of transitions I've used like that and they did work correctly, so if it isn't working the issue might be somewhere else
i was trying with some state under root and it didint work, but if you say it works for you then i need to make more tests, thanks, thats some good tip
Yeah it should. Transitions in parent states affect child states as well
ok i think i see the potential problem but i dont understand why its happening
it will be easier to show it
When my AI is in state MoveTo (Pink) the debugger is not updating it's state in real time, and when this state ends AI is going into the state i wanted it to (Stun - light blue/green)
I don't recall seeing any cases where a state wouldn't immediately react to a transition like this so not sure what's up with that 🤔
How are you triggering the transition?
its reacting immediately if its not in this MoveTo State, so i guess there is some problem with this state
I'm not on 5.5 yet, I wonder if they made some kind of option for tasks to block transitions because that's the only thing I can think of
yea, i know its some edge case, so thank you very much for your help anyway, i will try to test some cases and find solution
jesus
i found it
i had this one shitty thing enabled
thanks man, you got me on the right track
when this is enabled, state tree debugger will not update in rela time and it doesnt react to transitions
Ooh right, I forgot that is even there :)
Lock AILogic basically just stops all AI-related stuff from doing anything for the duration, state trees, behavior trees, everything
When in doubt, Unreal has some flag that is totally unnecessary just to mess with you
Also when in doubt, Unreal has some flag that is crucial to have enabled and that you haven't heard about ever and that is hidden in some weird settings menu
Does BT depend on frame rate?I think I'm noticing some services are executed less often with low frame rate even though the frequency is specified in seconds
How low are we talking about?
It seems as long as the service's tick rate is >=1 then you would have to hit single digit fps for it to be affected
About 15-25
I guess at 15fps if the tickrate is 1 second it could be delayed by 66ms
But it seems it would fire after the delay though and not get skipped
Because services can only run on tick right?
Yeah they would run on the gamethread
I see, I'll investigate further, thx!
Hi guys, Have you done something like setting property to the binding actor in state tree?
Do I have to create the state tree task to do the job
If so, it's really annoying. Because I have to create multiple setting tasks depending on how many kinds of properties I need to set
Hey, if you work with State Tree AITask, what do you use to store inter state - state. Do you use the Blackboard of the AI, hoping it has the keys, or is ther a smarter solution? (Like use one state to find & allocate a smart object and have another state to use this SO)
It really depends on how your tree is set up
I'm smoothbrain - so I keep my state tree kind of like a behavior tree honestly.
And that's also how I do my tasks
They are small - singular focused things
I want to trigger state trees from BTs as Sub routines, so I have a BB
So one state would be get the SO
Another would be to interact with it
So on and so forth.
@slow bobcat Does a hybrid of BT and ST. So he may be able to shed some light on how they approach it.
yeah, that's what I plan to do, I just wonder whats a good way to hand the SO handle from one state to the other. If I write it to the BB I can just use Fnames I think, as I can't use the BBKey things I could use for BT Tasks, so I can't bake the resolved key
We rely on the BB because we use st's for high level decisions and bt's for low level. You can have a BB without the whole st stuff if you inherit form the black board provider interface.
The in st's you can create conditions and tasks to read/write from/to BB. It's not very difficult if you look into the Balck board decorator to mimci it for example
Will have a look, thank you 🙂
Hey all. Working with state trees. I have a task that causes an enemy to attack. Should I place the montage, (and with that the notify begins) inside the task, or should I place the montage in the task and call a custom event (on the enemy character) to handle the hit/trace/notify logic after the montage plays ?
Hello! When people talk about 'Finite State Machine,' are they referring to 'State Machine' when it comes to NPC AI?Is 'Finite State Machine' the same thing as 'State Machine'?
Also, is using a Finite State Machine for NPC AI considered outdated, as it is generally recommended to use Behavior Trees or State Trees now? Thank you very much! 🙂
Not sure what you mean here? The actor the ST component is attached to is available via the context and available as a tree level parameter.
There are many ways to do this, a lot of people trigger a Gameplay Ability from a ST task and use that to trigger the animation and the trace logic. Depending on your needs, you usually need to time the hit trace with the animation so makes sens to do that outside of the ST (via anim notify and logic in a GA).
The "finite" in FSMs refers to the fact that there is a finite number of pre-defined states setup.
FSMs are often used to make NPC behaviors, and State Tree is a tool to write state machines in Unreal (it can even be used for other things than NPCs).
You could even say that an enum type + a class member is a simple form of an FSM, or any kind of field + if/switch statements.
State Tree is also what is called a hierarchical/nested state machine, which means it has a parent/child setup of states and the whole path of states is active at one.
So if you have for example:
Root
Idle
Combat
Attack
Chase
Or something like that, if leaf state "Attack" is active then its parents "Combat" and "Root" are also active and can be running tasks in parallel to what is setup on the Attack state.
This setup is very useful to enable code re-use, since otherwise you'd have to repeat a lot of setup that is common between states.
I am writing the custom state tree tasks in c++ for our AI.
There is a state in the AI where the miner find the resource node and set it as its target.
Then go for it.
So I have to write a ST task called "Set Current Mining Target" to use.
And There is also a state that set the Deposit site for the miner to deposit.
Then I have to write a ST task called "Set Current Deposit Site".
The 2 tasks are almost same
And There are plenty of similar tasks to implement like: Setting the current attacking target for a soilder.
Thanks! So, in this Reddit post, 'finite state machines' refers only to a specific implementation of FSMs, which involves creating a State Class for each State in C++ and defining enter/during/exit functions within each State. It doesn't mean using a State Tree or implementing it with enums, class members, and if/switch statements in C++. Am I right?
https://www.reddit.com/r/unrealengine/comments/1eskk42/should_i_use_behavior_trees_or_finite_state/
hello all, i've been trying to do some research on this but i'm not finding anything. it's a niche subject i think. basically i'm trying to get an ai actor to navigate around the player in a smooth circle or arc. any ideas on how i would achieve this?
Best way would be to move the AI to a point near the player. That would be your radius. Then set the focus to the player and add an input to the AI to it's left or right. Since the focus will be fixated on the player, the AI will move in a circle.
If you need the AI to follow a path, you can construct one calculating the points of the circle with an eqs and using them constructing an FNavPath. The create a move request with it and make your Path Following Component use it
thanks! i'll give it a shot!
Yes currently this is the pattern you have to follow. The issue is that output parameters from tasks are new parameters, and you cannot give it a reference to an existing parameter to write into instead.
However, you can question whether you need to "Set Current Mining Target" and instead just bind to the output parameter of the find task directly.. but I dont know the specifics of how you are using the "Mining Target".
There is no standard way to implement a FSM, so it can mean multiple things. All it means is you have a finite list of possible states, and you somewhere keep track of what the current state us.
Everything else on top of it is extra, but often implementations do transitions, conditions etc etc.
Thank you siggi. Helps a lot
I appreciate you Siggi for contributing in AI discussions like this regardless of the non-ST/BT/UE topics 
/** Indicates how Tags from slots and parent object are combined to be evaluated by a TagQuery from a find request. */
UENUM()
enum class ESmartObjectSlotShape : uint8
{
Circle,
Rectangle
};
Cool comment, very helpful
I need to add support to my smart objects to have per-behavior preconditions, which is possible by assigning each behavior to its own slot... but that means I have to duplicate the same set of three slots three times for this particular one I'm working on currently which I don't think I want to do...
At this stage I guess I'll duct-tape another custom feature into a new find smart object node that can do it via some other method, would be nice to have it better integrated but what can you do (other than an engine source build with modifications but I don't know if I'm interested in dealing with this)
I have a little component that grabs the pathing points off of a controller so we can render the nav path:
But if the map changes, the rendered path won't match the character's actual movements:
like the path from "Get Current Path Points" will update to reroute, but the actual character will continue along their original dumb path that only gets as close as possible
The movement is being driven by an AI move to.
I'm actually ok with the character not updating their movement in light of new information but I need the pathing renderer to not show a hypothetical better path that isn't being used...
Interesting that it would go out of sync like that 🤔 I think get current path points should always return the path the controller is currently using
Maybe you can just cache the current path points when the path is initially started so you can just read them from there?
The detour avoidance makes it dynamic over the route, possibly by a lot.
interestingly this behavior only occurs when the original goal seeking becomes possible. If the desired path becomes impossible the AI move to reroutes itself.
well, it's dumb but I guess I cant check if the path is partial initially, and if it is, set the target destination to the partial path endpoint instead
hmm but that doesn't work if the path goes from good to partial and then back to good
ah well
question with smart objects. i know you can make slots linked to each other, but is there a way to link multiple? for example with old school cod zombies, at the barricades it has kind of a slot order. so the slots closest to the barricades are active until claimed and are targeted first, then the next row is active until claimed, then the next row, so on and so forth. im not sure how to really handle this with smart object slots. im not home atm so my terminology might be incorrect with the question
Hello, when it comes to NPC AI, is it okay to skip Behavior Tree and jump right into State Tree, or should I learn both?
And is it realistic to migrate what I've built with Behavior Tree over to a State Tree?
I'm really keen on learning State Tree, but it seems like there aren't many good, all-around tutorials out there right now. That's got me thinking maybe I should just learn Behavior Tree and then try to apply what I pick up to State Tree later on.
Any suggestions would be appreciated! 🙂
I think you could have a link in a linked slot, but I don't know if there's much logic builtin that deals with this so you might need to build your own around this
Has anyone done a custom Smart Object World Condition Schema? I'm having some trouble with it, it doesn't seem to be saving the schema type correctly into the shared definition used by the conditions, which then fail their initialization because they just get the default schema type
As far as I can tell it seems to assume EditableConditions has values in it in before it sets the schema type, and for some reason EditableConditions is always empty even though I have defined preconditions in the smart object definition
...as far as I can tell, the only place where EditableConditions is initialized is getting called from an OnPaste handler and nowhere else
?????
State Tree has everything you need to build behaviors and can scale better in perf than BT, and is overall more "future proof". However you are right that there is a bigger resource of tutorials, docs and general knowledge around BTs still. That is something we are working on improving.
You are right that when you learn to make AI behaviors, you should be able to do them in either BT or ST. The approach is a little different and the UX especially, but also something we want to improve on in the future.
If you are completely new to making AI behaviors, then BTs is probably easier to get started with right now.
did someone mess with entrance/exit defintions on SmartObjects? Im curious if there's a way to get them through BP
Welp this is still broken in 5.5 and possibly 5.6 also based on scanning the sources on github a bit
Really looks like an engine bug, I guess they never tried using a different schema than the default even though the support is supposedly there, unless I'm doing something wrong which I can't identify 🤔
And to make things extra fun it appears there's also some kind of corruption now in the smart object definition which is causing something to trip during startup as it's breaking on a line in world condition query... guess I gotta remake it from scratch...
Wow, it looks like 5.5 literally broke smart object preconditions altogether? Is this real
I literally can't have any preconditions on smart objects now because it will always nag "Failed to initialize query for ... due to missing schema"
Oh okay good that one just randomly went away after a random number of repeats of "resave this, delete the preconditions, resave this, readd the conditions, resave this.."
But the main issue still remains where it doesn't seem to ever correctly initialize the custom schema 🤔
Does state machine provide something to handle state or task cooldowns or is that something I'm meant to implement myself? I was looking for something similar to the "cooldown" decorator provided in behaviortree
whats the preferred way to have the player pathfind around enemies with click to move (and enemies around each other/the player) in something like an ARPG? is it the crowd manager stuff?
Nothing "out of the box" yet, but its on our list 🙂 Currently not too hard to handle on your own with a combination of a condition, parameter and a task.
Generally that whole topic is called avoidance. UE ships with Detour and RVO implementations (and another one in Mass).
i feel like the enemy horde pathing will probably fit well into the detour/crowd manager stuff but i'm less sure about having the player cleanly pathfind around enemies, do you think detour or RVO is the way to go for that?
In click to move games, there is not much difference between a player and an NPC. Your click issues a MoveTo order, and the main difference is how frequently you can interrupt the last order and issue a new one.
is there a quick way to set a state param from inside a task? I can't seem to find a way to bind the output
You can use a FStateTreePropertyRef property on the task (instance data)
Is it possible to get at this from a blueprint base task
Im not 100% sure but Im guessing no, since you have to work with pointers directly.
Here is a quick sample.
Define the param like this:
UPROPERTY(EditAnywhere, Category = Parameter) TStateTreePropertyRef<int32> ParameterRef;
Then in code:
auto MutableParam = InstanceData.ParameterRef.GetMutablePtr(Context); *MutableParam = 1234;
TStateTreePropertyRef is a templated version of FStateTreePropertyRef that is a little easier to work with btw.
How would one modify navmesh generation to markup crouch polys vs walking polys? I think this requires engine changes as I don't see anything within the navmesh generation process thats supports this out of the box?
My guess would be its animation related? Lacking blend spaces and such
hmm im only using 2d blendspace
with 1 axis
@chilly nebula it feels like my units is not affectiong the mav mesh
shouldent it show on the navigation ?
I have no idea what the problem in that is supposed to be
You need to have a nav mesh bounds in the persistent level
iirc otherwise it won't work
Well then I'm out of information I've heard from others that I can quote :D I've not used streaming levels much, but maybe someone else can help
I can see that is working, its the nav in the Lunar surface Base which doesn't seem to be doing its navigation
odd so sorted it by deleted and replacing the Nav mesh thats in the persient level
For normal avoidance they shouldnt. You can make them do that if you really need to, but its slow since the mesh will be constantly updated.
Does unreal have an local llm general planning solution?
or are we still years away from that
Hey all, I have a simple request for State Tree visual improvement =)
Can someone move the task list in column formation? It is really hard to read tasks when they all in one line. And also it would be more cooler if they can be collapsed or hiding if it need to be
I don’t believe so. Also you’re looking for #generative-ai
Okeeeeey, I started to send a lot of bugs of State Tree =)
This is first one =)
Situation (First Screen):
I have (1) State Tree that activate another (2) State Tree.
(2) State Tree has a parameter for transfer data - Selected Unit.
In (1) State Tree I connected this Parameter and data is Valid 100%.
Problem (Second Screen):
When (2) State Tree is Activated Global Task in first launch doesn't see this Parameter (pointer == nullptr).
But State Tasks can see this pointer and can work with this data.
On Next Tick Global Tasks also starts to see this Parameter
Log In Third Screen.
That's not a bug I think. The flow in the state tree evaluator will always tick the global taks and the process the parameters. The very first tick, the global taks will run before the params update (it has a specific name I can't recall now). If you look into the State tree Context tick you will see the flow
I might be wrong since I'm not with code in front of me but maybe @chilly nebula can confirm/deny
QofL Request =))
If I have a lot same tasks - I cannot see edited name of the task in list of task names =)
That said: yeah I agree with you that, ideally, params would be set before anything else
The very first tick, the global taks will run before the params update
It is not what I expect =) In this logic the Actor pointer must be updated also after Global Tasks =(
I mean Context*
I might be wrong but I r3call event consumption and global taks being the very first 2 ticking
Yep, But Global Parameters - it's like Context - something solid and must be updated before any tasks will be run at all =)
I mean It is what I expected =(
Agree
Ohhh finally I got that darn precondition for smart objects with a custom schema working
So it turns out... If you have a custom schema, it does not work at all if you configure Preconditions for the entire smart object
But... it works fine if you configure selection preconditions on a per-slot basis
I wonder where do I file a bug report for this...
so, in 2025 and UE5.5 (soon 5.6), what's hot for NPCs AI (combat and friendly) - BTs or State Trees or something else (I haven't touched AI since 4.27 😓 ) ?
State Trees are the cool new thing but they may still be a lil rough around the edges so you're going to need to be able to figure stuff out yourself
so, should I just stick with BTs ?
We should start pinning answers/questions like this.
- St or bt? St are the new toy, Bt's are industry standard across engines
- my movement/path fails - > use visual logger to get more info
And the likes
That's partially why I've been writing stuff on my site lol
Easy to link those kinds of things from there
I tried to work with BT several times and always dropped it in half way. But State Tree is the best solution for me =)
I don't see whole a lot of training material on State Trees
Oh. I forgot add the fact that connections with that parameters (in 2 State Tree) often crash project in 5.5
I don't think there's any need to throw out BT's for state trees if you already have built up knowledge and infrastructure for your BT's (ie decorators, tasks and services)
unless maybe you're also going to do Mass
if you're starting from the beginning, especially "how do I do AI" beginning then I'd say go with StateTree
though, as noted, there's a lot more out there to help you learn with BT's
We have some, and more docs coming.
Here's a couple to get you started:
https://dev.epicgames.com/community/learning/tutorials/lwnR/unreal-engine-your-first-60-minutes-with-statetree
Show/hide toggles are in 5.6, as well as search!
I believe we fixed this in 5.6 🙂 + lot of other fixes around linked trees and more deterministic processing order for events and transitions.
This works fine in both 5.5 and 5.6 for me, what version are you on? Did you actually rename your tasks in the details view?
https://www.unrealengine.com/en-US/support/report-a-bug
Or Epic Pro Support (UDN) if you have it.
Best is if you can do a PR for a fix that we can review and clean up 😉
I'll consider it if I get around to having a source build at some point :D
Not really. I updated the task name by function GetDescription where I added a tag name to the task name. And I suggest to use this names for task list while trying to link parameters =)
That's really cool, thanks!)
Okay then. Need to wait 5.6 to check all my problems =))
Hmm, seems there's been a behavior change with Group states in 5.5 state trees as opposed to 5.4
I had a group with selection behavior "none" as a container for states which are only entered via events... But this stopped working in 5.5 altogether, the states inside it can't be entered at all now
I had to switch the state type to "state" and then back to "group" for it to work, but it also won't let me change the selection behavior for it
Oh well, I guess it doesn't matter that much
This does make me wonder... what is the purpose of "None" as a selection behavior if this completely prevents selecting the state now, even from an event based transition to a child state 🤔
Im curious about this, interesting pattern! What is firing those events, and what state did you expect the ST to stay in if it couldnt enter a state? My guess is the ST couldnt enter any state, which would go back to root and potentially even stop if there were no valid states to enter.
I didn't think of it that far, my main reasoning was "I never want these states to be selectable, except directly via a transition from another state", so I put them into a Group where the group had its selection behavior as None just to make sure the only way to enter the sub-states was a transition which explicitly did that.
If a None state can't be directly entered, I'd say my expectation would be an error when I try to save the state tree if that was going to happen, or it would be so that I can't even choose an option that would make it do that
It seems like covering all the possible ways a state could be entered might be kinda tricky so I suppose if it shouts loudly enough about it happening at runtime that could also work
As mentioned, not really sure what the intended usage for None is since it seems as of 5.5 it can't be entered and its children also cannot be entered :)
I think originally I was mostly just interested in testing the Group state type and seeing if organizing the states in this way would be helpful
These are good points. We made many fixes in 5.6 regarding transitions and a more deterministic processing order, I'll take a look what the behavior is now wrt None
Hello, I'm currently working on an enemy that's supposed to run towards you while attacking and I'm using this parallel node for that and it correctly works in parallel (enemy moves while attacking) but as soon as the move to node reaches its target (the acceptable radius I set), the attack sequence stops running and it's just the move to node running continuously. How can I make it so even when the target distance is reached the sequence continues to run? (so that the enemy would just stand and attack)
Looks like it's not only with the move to node but with any main task of a parallel
As a follow up question to this: what about tasks?how often do they run and can frame rate affect it?For example this is a simple task that does nothing and finishes execution instantly. But while I would expect it to run every tick of the tree, it doesn't. The service does, but the task seems to run every 3 ticks or so, so it seems it is affected by frame rate. Is that so?
huh.. no TOptional support in STTs 😄
quick question meanwhile: is it possible to create "template" ST assets?
i.e., schema comes with built in global tasks or a tree hierarchy?
I'm working on a combo attack system and global tasks listen for input and send ST events to listening conditions/states to transition to other states
but I'll have to add all of them one by one to each asset
if not, I'll guess I create a template and manually duplicate 😄
The way a parallel node works is that the secondary task runs only while the main does. Your MoveTo is finishing, ending the attack. Then, because you are in a selector, it finishes (selectors run until one child is a success). The tree exist and re-evaluates, enters your selector, move to finishes immediately because the AI is in place. That happens in a loop. It will probably start working again if, while this happens, you move the goal location/actor of your move.
The way to handle this is having a decorator checking the distance to the target. If too far that it need to move while attacking, run the parallel branch. If already at the desired distance, the decorator will fail and the selector will run the next branch, that will be a simple attack sequence (exactly the same you have in the parallel node). Your decorator should abort in the only attack branch. If the goal moves away, abort the branch so the tree re-evaluates and runs the parralel branch
Bt's evaluate every frame, otherwise your service would never run every frame. There isn't a separated logic for services outside the tree logic. When a tree evaluates
Its logic, it goes into all the branches and composite nodes following the execution flow until a leaf can be executed. Then it stays there until the leaf finishes (or a decorator aborts).
If you feel things are running every X frames only it can happen your tree takes time to evaluate due to callbacks, decorator validations that take time to pass etc. For example: you might have a decorator checking for certain thing to happen in your game and that thing might be taking 3 frames to happen. Your decorator will execute every frame but it will not pass until the 3rd, when your gameplay thing happens.
It's imposible for us to know unless we scan your entire logic and that's something you should do
Hi ,I am trying to implement a turn based system. The idea is the ai responds to CanAct member of the blackboard being set to true, performing an action, then ending their turn. However in game the AI is completely ignoring CanAct and just spams its action over and over. .. struggling to understand why the behavior tree is running, even when I set the CanAct key in the blackboard to false before calling Run Behavior Tree in my blueprints. Been stuck on this for days any help is godsend 🙏
See how your decorator is greyed out (blued out really)? That means things. If you hover the mouse you will see a message saying that a decorator in a root node will not run (the root node of a tree is not the one that says root, it's the one under it. Root node is just a visual cue so the user knows where to start adding nodes).
Add a sequence node below your Root node and call it "SQ_ActualRoot" or something like that. Then attach to it your current tree logic. You will see your decorator changes color to it's natural blue and things will work
The exception to this is if your tree was run as a subtree. In that case you can add decorators to it's root, since the root of the tree will actually be just ankther node in a parent tree (it's injected in the parent)
yep haha that works thank you so muchh
i read that and didn't understand and ignored it.. well im glad that only took a few days for adding one node to my tree.
Next time will take 1s to spot. That's the important part
Yes it's possible, and being done by large games. You have to rely on linked subtrees and control the injections (often a few levels deep) at runtime.
Basically you setup base "templates" that have defined injection points (called overrides), than you inject other templates or shared trees at runtime based on the needs of the NPC you are doing. Its common to share things like reactions, pathfollowing etc between different behaviors, and you can even run some of it in parallel (like hit reaction states).
Got it, thanks, I'll keep that in mind
Hi so I am trying to create an AI that would be basically an Enemy archer that would learn how to shoot enemies that are moving continuously in a room
I am using Learning Agents on 5.3.2, also using C++.
My issue is that it will generate the first iteration results, it will run a little bit more, and will give me this error:
Agent with id x has completed episode and will be reset but has not generated any experience. I am having like 7 agents.
This is how my SetupCompletion looks like:
{
TimeCompletion = UTimeElapsedCompletion::AddTimeElapsedCompletion(
this,
FName("TimeCompletion"),
30.0f,
ELearningAgentsCompletion::Truncation
);
}
And this is my SetCompletions implementation:
void ULearningAgentsTrainerR::SetCompletions_Implementation(const TArray<int32>& AgentIds)
{
for (int32 AgentId : AgentIds)
{
float& Timer = EpisodeTimers.FindOrAdd(AgentId);
Timer += GetWorld()->DeltaTimeSeconds;
TimeCompletion->SetTimeElapsedCompletion(AgentId, Timer);
}
}
And basically the error will get spammed, and my ResetAgents method will get called everytime, which basically will teleport my enemies continuously.
I would really appreciate your help, really don't know how to implement this SetupCompletions and SetCompletions, if you have any advice, it would be verry apreaciated.
Is there a way to visually debug AI State Tree ?
There is a debugger in the state tree editor and the visual logger also contains log info for state tree executions
Ok, blackboard keys feel redundant. Why have ai class variables at all if theyre all duplicated as keys.
Can I just store everything in the bb
You don't have to have them as class variables.
I figured class variables would be better to access/update frequently, but managing both is annoying
I have some on BB some on class with specific decorators that can choose based on them
What annoys me about the BB is that it becomes messy easily and it's kinda hard to tell what's what
The c++ syntax for getting/setting is not asthetic. And im lowkey concerned its less peeformant than referencing self-class variables.
Most likely the performance difference is fairly irrelevant unless you're doing it a lot in a hot path or have a gazillion AI's
and C++ is not aesthetic to begin with :D
I've not done BB lookups much there but if it's sufficiently clunky I suppose you could always make your own function or macro for it
It's an abstraction. Ie: you have a bbk target. Target for your melee warrior ai is the player character. Target for your saboteur AI is a building. The BT Attack that does: got to target + attack is now reusable for both, independently of what a target is
Let alone that your different AI's might have different ways to get a target: some use perception, others use some custom logic in a component only them have...
Depends a lot. Get/set things from/to a BB form within a BT node it's cheaper than grabbing actors/components. But the difference is negligible in most cases as very well appointed by zomg
That task literally prints a log on screen. Shouldn't be slower than the service (which also prints on screen) but it runs once every 3 service ticks
Umm strange. I have no idea what could be going on from the top of my head.
Are you printing the frame number in each print? Just to see if anything is printing twice the same frame?
I'm very curious abut what's going on.
Does this happen with a single AI and nothing else happening?
And just to confirm: the task has a Print and a finish task call and that's it right? Nothing else?
A bit more convoluted. I was printing the world delta seconds in both to tell how much time passed in between calls. I also capped fps at 5 so I knew each frame ran every 0,2s. I noticed the service calls were 0,2s from each other as I expected (since it's tick is lower than 0,2s). While the task logs where almost exactly 0,6s from each other
A single AI of that kind yeah, but other things were running in the map so maybe they dirtied the experiment
I would try with just one AI in an empty level and print the frame number without capping the framerate, but your test sounds ok
Anyone know how to do enemy Ai capable of crawling/walking on walls?
How are other people finding state trees in terms of performance? I have a relatively simple tree that works great for 1-2 agents (AI vehicle drivers) but performance takes a nosedive when I go much higher. With 7 AI opponents my frame time increases nearly 20ms confirmed by profiling. Any tips to improve performance?
Can you show the profile? Because that is quite abnormal
For Crawling you can use nav modifier volumes on your nav to mark crawling areas and, while moving following a path, detect if the AI is on one. Then do whatever you need (set movement mode to crawling, scale the capsule, okqy de right anim etc). For walls... That's a completely different topic. Do you need path using walls?
The walls are spawned as a part of a different BP as dynamic terrain. The entire room is one object
Do the walls need to different objects or can the wall meshs be targeted separately from within the BPs?
if you need navigation on the walls, it's complicated.
Unreal doesn't support generating nav mesh on vertical planes, only horizontal.
-> If you need to climb the walls to reach the rooftop of a building, you can have a smart nav link on the walls to connect the bottom floor with whatever is on top of the wall (assuming the top has nav, like the roof of a building) , then play the climbing animation with root motion, then use motion warping to adjust the movement to the wall length (or define very specific wall heights like small/medium/large and have different animations tailored for them)
-> Now, if what you need is to use the walls to navigate within the room, that's a bit more complicated.
One thing you can try is to have entry and exit points defined on the walls. There would be 4 points like in the image.
- find the closes entry point to a wall from the floor where your AI stands
- path to it
- from there, using the mesh topology of the wall as it was the nav mesh, create a path to your exit point of that wall.
- Grab the connecting wall topology and path from the entry point to the last.
This is difficult to do because:
- You need to calculate the exit points, which means you somehow know the direction your AI needs to move and which walls to follow. You can run a very simple A* algoritm to know it where only said points and your goal location are considered. With that, you know which walls you need to take the mesh topology from.
- Although all the code to path any mesh is in the engine, you need to convert your topology data from the walls (their mesh) to something the nav system understands. Or copy the A* algorithm used in the engine or create your own (I recommend the A* JPS which I believe it's what Unreal uses already https://gdcvault.com/play/1022094/JPS-Over-100x-Faster-than)
- you will need to string-pull the path obtained to cover cases like having a window on the walle
or you can use the Kythera plugin, that supports Surface navigation and already gives you wall/ceiling navigation
https://www.youtube.com/watch?v=g9_9E2eDgRM
https://content.kythera.ai/home
Unlock their fears this Halloween with AI-powered Surface Navigation for Horror games and more!
Surface Navigation provides a groundbreaking AI solution that's custom developed to automate NPC and agent navigation across complex, three-dimensional surfaces, like walls and ceilings. Kythera AI’s unique Surface Navigation gives studios a comple...
I see, thank you for your input and assistance. I will see if this can help my situation in any way. Thank you
If not, ask again with a more detailed example. Happy to help
hey, I wanted to follow up on this. Check this CL for an easier way to set overrides at runtime, it will be in 5 .6
https://github.com/EpicGames/UnrealEngine/commit/d5b44e9281bdcebbbb9fc79f58259a7b1af633ab
You are probably doing something expensive in a task or interoping with components or features that cost a lot of perf. Ticks are also a bit heavy, but 7 agents is nothing.. we have an internal project with hundreds of character actors and city sample has thousands (but those are in Mass).
Or Mercuna 🙂
https://mercuna.com/
first time I look into mercuna prices. Bit insane for indies
No idea how that compares to Kythera, but 2.5k the cheapest is a bit much for most solo-devs
gotta be god tier at that price
although to be fair, I'd say rolling your own navigation solution is likely to take more than a few months so this price is quite quickly worth it for business customers
Yeah. As always: how much do you know and how much time do you have?
Why my nav agent only moves if "use acceleration for paths" is on? I tried everything, from recreating the nav bound and deleting the recast actor.
It would be ok but "use acceleration for paths" has its issues.
How are you moving your actor?
Move To in the Behaviour Tree. It was working before by the way, but then suddenly it stopped. Only that setting make it semi work.
personal opinion: kythera isnt worth it and their pricing isnt any lower than mercuna
and least mercuna has a pricing they give to you if you're an indie
kythera wouldnt answer your support requests and if you dont make it obvious that you are rich they dont contact you for sales either
What did you change in between working and not working? What does visual logger say in the case where it doesn't work?
I modified the BT, then I made it back as it was. Everything is the same. No reason to not work.
I evaluated it for our game but didn't offer anything else we needed. But if you need 3d navigation or moving navigation (their boat example is nice) I guess it's worth checking out
What's the visual logger?
Your best friend. A debug tool provided by unreal. Check google for more info
last time I used they had a custom lua thingy and some DSL to handle data, and web API wasnt nice to use
they were reflecting your web elements to editor through asset creation but it was crashing the editor time to time
which is ok, bugs can happen but it wasnt nice they didnt contact us at all even to buy it
i like tech part though ngl, ORCA2 was nice to see in action
What does Kythera use Orca2 for?
to replace RVO and detour i think
works well/better for zombie games
ooh this conversation reminded me of DetourCrowd.cpp
Siggi, if you can see this (i dont want to ping you), not sure if I'm wrong or not but it looks like everything could be paralellized easily(?)
I think each function that starts with step in detour can be ParallelFor or all steps can be combined within a single for loop and a single ParallelFor can be used
iirc thats what ORCA2 does
Aaaaah that Orca! Hahah OK I thought you meant the MS AI/MLL stuff
Often its not that easy, and ParallelFor adds an overhead 🙂 If you want something that performs better, stay tuned.. we have something new on avoidance perhaps coming in the future.. you can take a look at the avoidance in City Sample for a taste but that is Mass based only.
and ParallelFor adds an overhead
sure, but just at first glance code looked like its eligible for parallelization out of the box 🤔 but of course I'm more alien to the API so I'm not sure
anyone have any ides how to add navmesh into a procedural generated level?
Dynamic nav around invokers
thanks ill look into that now 😄
Hi guys, I want to get and set the global parameters in a StateTree task using c++
Do you know the corresponding API for that?
Thank you very much
You bind them to inputs on your tasks. If you need to change values inside of the task, then use property refs. See example I posted here from a couple days ago.
Oky
Thank you Siggi
Define the param like this:
UPROPERTY(EditAnywhere, Category = Parameter)
TStateTreePropertyRef<int32> ParameterRef;
Then in code:
auto MutableParam = InstanceData.ParameterRef.GetMutablePtr(Context);
*MutableParam = 1234;
this one?
yes, that is an example of an int parameter and how to change the value of it inside a task
is there a way to make ai move whitout a "navmeshboundsvolume"? 😛
I think floating pawn? You can also add input to the character using the character movement component. And you can probably do a move request like the path following component dies within Follow Path
As an FYI - you don't need the CMC to do an Add Input call. That method itself is on the Pawn and it just ferries that info to the movement component.
So it isn't Character/CMC specific
But if you're not using a navmesh - then that is the only solution as far as I know. Because all of the various move tos do require a nav mesh
A new avoidance thing? And it isn't tied to Mass? 🤩
I am lovin' this attention the AI side of UE is actually getting.
Don't tease us man.... That's cruel XD
This is a blessing indeed
This is fantastic! Are any of the other planned improvements (like cooldowns) happening to land in 5.6 as well?
5.6 is filled with goodies 🙂 but direct support for cooldowns no, we need a bit more time to cook what we're thinking there.
A current way to do this (implement a cooldown) is a "3 piece" solution yeah?
-in64 Timestamp - Store unix timestamp of last entry as a task level param
-FStateTreeConditionBase -- Check Timestamp vs Now
-FStateTreeTaskBase -- Set a timestamp as a task level param
Yep that would do it 🙂 just keep the parameter in a place where it wont leave scope and be cleared.. might have to be a global parameter for that reason.
You probably want to add a cooldown duration somewhere, probably on the condition itself.
If I stuff the value in a "Task Parameter" here it shouldn't get GC'd should it? This is an InstancedPropertyBag?
as soon as the state that contains the task is out of scope (ie the state no longer active) it will get cleared
oh wow I did not know that okay
I'll just establish the timestamp in a data store I keep myself outside this tree
This is one of the key differences between BB and the property binding solution in ST, each state has a scope.. almost like its own mini BB.. Only items in that state or child states can read from it, and if no longer in scope its cleared from memory
you can, but probably faster if you just declare it as a global tree level parameter.. or even on the root state
If I want to make a bunch of cooldowns I use a map keyed on name? This is starting to feel messytown
yes, that is indeed where it gets messy 🙂 if you need 10 different cooldowns, you need 10 parameters. This is why we want something better 🙂
We have an idea, but I cant get into details since things often change when implemented 🙂
I'm starting to wonder if having a state tree manage higher level "agent state" and then using a BT to implement combat behavior might not be the correct soltuon for what I"m doing now
thats a viable solution that many use 🙂 even internally many teams do a hybrid solution. But we also have large AAA teams that are doing very complex behaviors with lots of nested subtrees, without any BTs.
Basically go with what works for you now and you are comfortable with.
We really want to get to a future where ST is the tool everyone wants to use 🙂 but we have some work to do to get there still
Yeah I already see the upside I just don't feel like solving some of these foundational issues myself when I know better solutions will probably be incoming soon. Thanks so much for the help you're an amazing resource here!
and you all are a resource for me 🙂 helps us prioritize and see how you all are using the features we work on.
hmmmm... Is there a good unique identifier on a state I could get from it's instance data? I can probably hack together something in my data storage solution to hold onto the timestamps and then I can keep all my logic in here and be part of the future
not atm.. but something is coming with 5.6 😉 Do you mean the unique path? ie "Root -> Idle -> Combat" or a unique ID for the current instance running of a state?
If its the former you need, its called a StatePath and is a string. Im 90% sure thats new in 5.6, cant remember if we shipped it or not with 5.5.
The latter. Looks like I check back on with 5.6 and see all the new stuff. Thanks!
ok just keep in mind that ID will change every time you re-enter that state since it will be a new instance. If you want anything to persist between then the state path is probably a better choice.
Once I'm convinced - then you know you've succeeded in this goal. I'm stubborn. I'm old. And I like the straightforwardness of the BT.
I don't think BT is intuitive for most folks it's just a tool that a lot of us are trained on. The BT pattern has a lot of implicit function that I think this avoids
The possibility of having a g.tag as an ID for a state would be incredibly useful. And if we could do StateTreeComponent->getRunningStateID's returning a g.tag container, that alone will unlock a universe of possibilities
I think it is more intuitive than STs due to how STs work. Many devs have tripped up on the asynchronous nature of task processing and how state transitions work. Let alone how to pass data around.
I'm not talking about deciding how a task should be authored mind you. With BT, it is pretty much - all data flows to the BB and then the BT executes left to right. With decorators to "gate" branches.
With ST - there is the async task processing, keeping track of how the various tasks potentially complete (due to how the state transitions work), deciding where the variables should live (should it be global or should it be on the root or should it be on a parent state, etc...), figuring out the process of getting data from one state to another, etc...
Many more things to wrap your head around because it isn't just a basic hiearchical state machine.
Yeah - the BB being pretty much a global variable bag has its issues, but it is pretty straightforward
In the near future we want pretty much all tasks to complete 😉 unless they are marked to never complete, and with 5.6 you now have controls over what tasks can trigger the transition and if you want ANY (as before) or ALL that contribute to trigger it or not. There is some more work to do here, but 5.6 is already so much better in this regard and just makes more sense.
I 100% agree that issues like this have made STs non-intuitive to pick up, but that is why I want to discover and fix all of this.
Regarding the scoped variables instead of one fat BB, I feel this is also one of the things that will allow ST to scale better than BBs since they are more lightweight. But I do agree that BBs are overall easier to use, and I want to find ways to improve how the data flow happens in STs.
Regarding the above - in 5.6 you as a ST task author can choose if your task will ever or never complete, and if by default it should contribute to triggering the transition or not on completion.
Then as the author you can also toggle this on/off per task on the states.
I'm really excited to check out ST in 5.6, but that is still a month away. I don't have the infrastructure to have my team on a source build.
Ok it's the same
Hi Sigi,How to set global variables outside the state tree.Like Blackboard’s parameters’ settings
Thank you very much
so based on this, why does my first branch of my behavior tree go back and forth between flee-patrol really really fast & my chicken never make any moves?
how about only connect ai Moveto OnSuccess to finish execute node
Of course, you were right. I switched my evaluators to run every 0.1s instead of on tick and managed to save a bunch, but all the calls to the function in green are still costing me a lot...
This is very strange. Just to be sure:
- you have one AI
- that AI is only doing one thing: run a very simple tree
- the tree is just a sequence with 1 child. The sequence has a service running in tick with one print node. The child is a task with just one print node
- you are not setting tick rates or doing anything else anywhere else
You are finishing the task as soon as you call move to. You should only connect it to success and finish task as success = true , and to fail and finish task as success = falss
Good morning.
So does that mean BTs will be deprecated and only available until UE7 in favor of the newer STs?
I have been working with BTs for some years and preferred them, though I am very open to learn STs too.
yeah, it means we won't be maintaining BTs once UE6 goes out, and we'll probably cut the whole thing for UE7 (whenever that is). Having said that, I'll suggest to the team that we extract BTs into a separate plugin, so it's easier to share and maintain by the community, in the far future.
What is the function in green on your graph? I would look into that
Sadly there is no good way to do that atm, but its something we are planning on doing. Currently you have to make your tasks (or property binding functions) pull data in, or you could use events with payload to push data in.
thank you very much
Btw you can use a blackboard for this, it just won't have the nice gui as you get in BT's :)
state trees are great. Shooter AI go brrrr
I just used member variables on the character BP to track data needed, its a bit messy but it works well enough
Hello ! I took the opportunity to ask this :
Any plan to improve or replace the AI Perception System that seems pretty outdated compared to other AI systems?
Outdated how? 🤔
I'm not sure how that's the case, plus I think it's actually not that long ago when there were some updates to IAISightTargetInterface
The stimulus has very few info and event tag is a FName while we could benefit of a gameplay tag container for instance which is easier to use
We have to modify the engine to make it more interesting
Ah, yeah I suppose there are some small aspects like that which could be improved
I wonder how much could you improve by using a custom sense though 🤔 since I think you could have custom info in the sense's stimulus data
No any new custom sense can't add much since all stimulus store the same data in the end (See FAIStimulus)
You can add some inputs to your event but it will be limited to what you store in the stimulus
Oh I see, I've not looked at it in a while, I thought you could have custom data as well :)
gameplay tags are sweet, Ive been using them lately and they are such a boon
state and status effects are so much easier to track with gt than a stack of bools lol
That's why i asked if there is any plan to improve this API
In any case, i'm personally modifying the engine for my need
Let's hope that Fortnite needs it, otherwise it might not lol
Would love to see some StateTree from Fortnite as template project
yeah thatd be wild
Wild life, Npc and so on
this is the current state tree for my shooter ai
I'm personally really interested in modular AI StateTree architecture (such building AI Archetype at runtime by adding/removing states)
