#gameplay-ai
1 messages Β· Page 64 of 1
Thanks. This worked! π
How reliable is your measurement here? Have you stepped through code in visual studio or rider to see if it really is only processing one node per tick?
iirc the behavior tree is designed to kind of tick as needed, it will tick a single active node and related nodes, then schedule the next node's tick, which may be the current frame, honestly best to look through the code to see whats really going on.
what does visual logger say for a frame?
The truth of the matter too, is that ai decisions dont really need to tick super often, so does this even matter? most games i've shipped have had a 15 to 30 frame tick rate on the ai's decision logic..
Heya! The measurements is fairly consistent every time. I have stepped through the code and from what I could tell it goes one node per tick (after every node in the sequence, the end of Tick method of the BT hits for me), but that seemed strange so I didn't trust myself haha.
In my case this matters a lot, as I was creating sort of Goal-Oriented / BT AI hybrid, and the entirety of the sequence is meant to go in a single tick. This became noticeable lot more now as I've made a combo system where the extra nodes cause a (visually) very noticeable delay between the moves that is nearly gone when I remove the other nodes.
For me the decision is made by a single node in the tree and instead I rather wanted to leverage the tree to have a well debuggable/rearrangable way of giving it ways to accomplish the various goals. Perhaps this by design isn't viable then and I have to write my own.
Vislog is a new thing for me actually, super handy, thanks for the new wisdom! π I was wondering why the time gaps there are lower for a moment until I realized the game slows down a lot when I record it haha! Based on that, it indeed executes 1 node per tick, as a GAS Attribute regen that happens every tick that happens to be logged by default there matches the nodes being executed. (The missing gap is the MoveTo node, as I logged inside of my derived node class)
Sounds a lot like youβre trying to make the BT handle what should happen almost entirely in GAS
The BT doesn't do anything with the attr regen, it's just a thing that happened to be logged by default that showed me nicely the nodes indeed run one per frame
Iβm talking about the βnoticeable with combo systemβ part
Ah, You mean the GAs deciding whether to follow up on the combo? That'd turn into a horrible mess really quickly having the definitions spread out like that along with conditions and chances for which follow ups to choose and such haha, hence why I wanted the "AI" part to be in charge of that
BT should be telling the thing to run the GAS, the latter which should handle combos and stuff, afaik anyways. But ik very little, maybe Luthage will descend with her pointy spear of knowledge
Well the BT only has 1 node that tells gas "do ability"
Which does the whole GAS thing
I could have potentially made the "set focus, move to, etc" be part of the ability itself, which I don't particularly like the thought of, however the frame delay between nodes is still an issue for me at that point, as the game is fast and will in 95% of the cases only run 1-2 AIs at once. Custom AI it is I guess
Yeah, no, I didnβt mean make the set focus and move to as part of GAS.
(The reason I don't want those to be part of the GA is I have ways to drop the goal halfway if the AI hasn't committed to finishing it, e.g., if the player kites the AI as it tries to melee him, it will timeout and go to different goal)
so im not super sure what your goal oriented stuff is specifically for in this case, but im not sure a goal based system to drive combo execution is a good fit? My gut feel is that the goals should be higher tier than that, (like "be aggressive" "take a defensive posture" etc) and the tree should internally determine how to traverse combo branches (makes sense, combos fee like they would map pretty well to a tree structure.)
In fact that's how we did it on a couple of games i worked on (a smash bros clone, and a game influenced by psp/ps3 era god of war combo systems ).. the body/pawn's combo systems really did the bulk of the work, while the AI made choices at junction points in the combo tree, basically using the moment between move execution to roll on building a combo or not, and which combo branch to go down.
in all these cases tho the AI still didnt really update that frequently (certainly not every frame, the decision tick rates were around every 10-15 frames, divided among all the active ai, so only a few update a frame)
I have a different structure that determines what can combo into what, what the specific combo windows are, and lot of other modifiers, which I feel wound make for an unsightly BT haha. However the combos are only a subset of the mechanics, as there is more abilities with cooldowns and costs than the comboable basic ones, and the AI can drop combo in favor of casting something that has a long CD, which I feel like gets more complex for BT. Hence why I had a node to determine what it is aiming to do, a service that checked for potential to abandon the goal or a temporary goal it can accomplish along the way (e.g. trying to hit player 1, they move away, but player 2 is in the way, so might as well smack him while approaching p1), and then was defining the goal w/ a structure of nodes.
For me the combo isn't just "finished ability A, now cast B", but it can involve various logic within the combo window, like maintaining range/line of sight. This is possibly dependent on the step in the combo and such, thus I had it split into Nodes for the BT. It is entirely possible I just have a very specific vision of how to make the AI work for my case haha, I'm remaking a project I previously worked on for ~7y engine-less, so I want to keep the responsive snappy behavior that reacts to thing "instantly" that I had previously π
sounds reasonable yeah like i said i dont really know what you're doing haha
i havent noticed any weird frame delay per node personally.. makes me wonder if you've got some settings set on accident or for a nother purpose that might be interfering
Ye, that's what I've been trying to find out, if there's some way to set the BT to behave in various ways. Haven't found anything on that tho, only that it "used to run top to bottom every frame in older versions of UE"
i've yet to run into cases where ai need higher responsiveness than like 0.15 seconds in my 17 years of game ai haha players are so slow
most of that time is not UE so when it comes to UE-isms im a bit fresh ahha
Haha fair, the game I'm making is fairly quick and skill demanding (in the old version I still have to carry people in coop through the "tutorial" fight π )
what does the ai debugger look like when they process?do you see the nodes executed?
In the old version w/o engine I had basically AI in tick, where it ran parallel movement logic and ability logic, I'm changing that around now since I will be using root motion for some abilities and such. So it had logic on how to move and then it literally tried to spam every ability in given priority order every frame, and whichever was off CD and meeting range conditions would go through haha
By AI debugger you mean breakpoint in the BT?
Oh, the Gameplay Debugger probably. In the AI section it only shows "None" in the ActiveTask if that's what You mean, but below the Gameplay Tasks is 0, so I assume those aren't the BT ones. In the Behavior Tree section it flashes wherever the tree is at
i mean the ' debugger thing there's a section for AI and the behavior tree which shows you what nodes were executed
Ye, I think we're talking about the same thing
i do get the feeling ue spreads the node execution out
in the tick function of the behavior tree component it will execute cursory nodes and the active node, then schedule the next tick update.. this can be for the current frame, but it might not be
at least thats what i get out of reading the code haha
oh apparently 0 means next frame π so i guess that it spreads out executing active nodes
Ye that's more or less what I got from poking the BT tick in debug too... Meaning farewell BT, here we go once again to write something of my own π As if already bending half of GAS wasn't enough ahaha
and more than 0 just means more frames away
will say UE's definitely got opinions on behavior trees π
the issue with rolling your own is you cant leverage all that tasty editor features and debug tools without writing your own stuff
Ye, that's really the only reason I was trying to use BT in the first place, ease of debugging and rearrangement. (the ' debugger was new thing for me just now too tho haha)
granted you can send stuff to the visual logger, i think there's a macro: UE_VLOG
Ye, that's what I used before when You asked for it, was also a new thing for me haha, that one seems handy since it can capture locations and shapes n stuff too
there's a bit in the code that makes me think that other nodes will process with your active node, but it maybe is only the nodes that your active node may depend on? decorators that need to update to determine aborts, services and such?
yeah visual logger is neat hehe
Ye that's how I understand it
Because those nodes don't do any logic themselves but guide where the BT itself flows
yeah .. flow control nodes def get hit pretty reliably
def a departure from other BT systems i've written to stop at a leaf node.. but in the context of UE that sort of makes sense? like its aiming to be very event driven and the only leaf nodes you have are action nodes which one could maybe safely assume would take some amount of time to execute, so executing a single active node a tick makes sense perhaps in that context? maybe it means that the work you are doing maybe shouldnt be in an leaf node?
Perhaps, but if it wasn't in the BT, then I don't need the BT at all at that point haha. It'd be nice to have a way to tell it how to run. Also the MoveTo is like an optional node in my case, but it still eats up a frame of reaction time of the AI even when the target is already within the distance and it just passes right away.
I think it's made this way to run fine with a TON of AIs, because lots of games nowadays have a lot of mediocre AI enemies at once, so the flaws of their AI somewhat fade away since You don't pin Your attention to a particular one all the time. Since I have very few AIs active, often only 1 at a time, it's just a lot more noticeable in my case I think.
perhaps.. im still of the belief decision logic doesnt really need a fast update rate
anything that does is almost always handled by something else.. like deciding to move, the decision to move is done in the bt, but if you look at the behavior task's code, all it does after starting a move to task is wait for a few events and some house keeping.. so i think its the right call to aim at low cost ai decision logic, but it means you probably need explicit systems that the BT calls into or gets events from to do the actual leg work where you may need higher tickrate to execute on the result of the decision the ai makes
But even then the BT introduced delay between these systems if they happen in different tasks, You have MoveTo task, and then perhaps CastAbility task, if You wanted to avoid this delay You would have to wrap the entire goal logic into the task, at which point You have no BT left as it turns into more of a switch haha. This is more so magnificed since I have the goal determined in the beginning of the tree already, I suppose You could use the tree itself to determine the goal, that just didn't seem optimal for my case
When it comes to child states of state trees. If I define transition rules in the parent but not in the children. Is it the default behavior to follow the transition rules set in the parent?
--Ohp Nevermind. I'm tired...I see that is very well the case. As the child states...have no transitions.
a single frame between the two isnt really the end of the world tho right, like... for most players its not percievable
If You have bunch of dummy AIs then definitely not, as You don't focus on one in particular, but as I mostly have only 1 You glue Your focus on, and every Node in its way only multiplies this "delay", for me this is a dealbreaker sadly
yeah thats what im talking about i dont see how it could be, a single frame delay between actions .. most players cant react fast enough to matter
most players need more time than a single frame
at least in a tree that's been built understanding that not all actions in the branch may get executed that frame
Well in my case this already ramped up to ~60ms, since it was more than 1 node away. But yes, my game isn't designed to be very beginner friendly haha, my main target audience is myself π Through struggle for difficult games I've ~9y ago set out on a journey to provide myself with one ahaha
fair hehe
So, thanks to Timo asking about State Trees I found out STs are a thing, did a mini setup and it seems ST does NOT have this limitations and can go brrr through X tasks in a single frame!
Maybe it goes too brrr now ahaha, as when I make 3 tasks that go into one another and immediatelly return success, it executes 5 per frame, so they each can run more than once a frame... so I wonder if it just now has a hard cap of 5 and does 5 even if that means repeating things π Also it seems a new instance of the task is created every time it is entered, which seems a little rough
Yep. The 5 is a limit. Dang it, fine, I'll make my own one π I just can't have nice things π
yeah i mean tbh its all a perf concern
Funny you mention this. I just saw this problem while profiling today and I'm looking into it. It's like if a state was repeating in loop or something like that
Any clues on what's going on? My educated guess is that the short tasks (the ones that immediately finish) will run until the last one (the one that takes longer) finishes
As many times as possible
I haven't honestly explored it any further, once I noticed the strange limit of 5 I just begun coding my own BT/ST replacement, almost finished with what's needed to replicate my former BT logic (minus the BT issues) haha π
I would expect it to run from top to either a possibly latent task that doesn't finish right away, or all the way to the bottom every frame. The "5 tasks a frame" is really odd
reads to me as the BT reasoning, entirely perf related
Well if it were limit of 5 perhaps, but if Your State Tree has 3 tasks but still executes 5 per frame, repeating two of the 3 twice, then something is fishy
(would also not surprise me if ther eare issues, state trees are still pretty under developed from what i know?
but one of the use cases is driving AI in Mass, so i can imagine that the intent here is high performance too
is there a way to control an AI controlled pawn with movement input? OR a player controlled pawn with path finding? Basically, I need something that can do path finding and movement input at the same time. Solution should work on multiplayer as the top down template is not working on a dedicated server setup.
I am doing something like this and I have an AI Player Character with an AI Controller as it's controller, I also have the player controller that has a reference to both. When I move with WASD I just get the character and add movement input and when I right click on a space I just start a behavior tree that has a Move To Location
interesting, I've thought about it too but I was thinking the transition from player controller to AI controller might not be smooth for multiplayer especially there might be a chance that it will change multiple times just after a few frames on our end. I can give it a try too, thanks!
Ah yeah I have not dealt with any multiplayer stuff so that could be a problem
I think 5 is a good limit to make sure most transitions complete in one frame, but it would be good to have it as a configurables setting in the future, as well as tree depth limit of 8.
Why would you want your system to be looping the same nodes in a single frame?
Is there a way to jump to a specific state in a state tree?
Hey all looking for advice about this because I feel like I'm going about this wrong.
I'm working with state trees. I made a task to execute an eqs query. The idea would be I have to wait for it to end before going on to the next state. But with the way states and tasks work I would not be able to go to a sibling state and still have the information of my eqs result since the state that executed that is dropped at that point. Any advice?
You can make an output parameter on your task instance data. Then, tasks in sibling and child states can access that parameter
You simply bind to the parameter in your state tree editor
Siblings can't access output parameters
Oh they can't? Store the data outside the state tree then
Pretty much
Good Afternoon, I was wondering if anyone could explain evaluators with a use case?
I don't, that's what I'm saying haha, State Tree behaves that way, which I don't like
Ohhh gotchya
I wrote a custom system that just adds 1 frame delay if it detects itβs trying to start a node it already previously activated that frame
Though Iβm curious what other solutions people have~~
I like how mass is doing it and I modified it a little for my use case. The state tree only ticks on demand. Works wonders for performance and the behaviour is a lot more predictable for me. Ticking on demand simply means I progress the state tree to select a new state only if the previous state != Running
So there's very few tasks that would cause the state tree to tick every frame. Any behaviour that needs to tick is done outside the state tree, like path finding and following, delays
I agree I feel like that's the best design if you systems support it~~
I did something similar but it ends up ticking every frame to check a set of conditions that could cause the task to finish-fast or fail
What I like about my setup is that if it needs to tick every frame, then it absolutely would. But I try to design my tasks in a way that it wouldn't
For example, this is how I handle delays:
/* Enter State */
auto Delay = [](const flecs::entity Entity, const double Duration) -> UE5Coro::TCoroutine<>
{
co_await UE5Coro::Latent::Seconds(Duration);
// Tick state tree after delay has elapsed to continue
Entity.add(EKCStateTreeTick::Enabled);
};
Delay(entity, InstanceData.Duration);
/* TickState */
if (InstanceData.Duration <= 0.0f) { return EStateTreeRunStatus::Running; }
InstanceData.TimeElapsed += DeltaTime;
return InstanceData.TimeElapsed <= InstanceData.Duration ? EStateTreeRunStatus::Running : EStateTreeRunStatus::Succeeded;
/* Function to tick state tree */
if (entity.has(EKCStateTreeTick::Enabled))
{
TickStateTree()
}
// When last tick status is "Running", the state tree doesn't need to be ticked
if (context.GetLastTickStatus() == EStateTreeRunStatus::Running)
{
entity.add(EKCStateTreeTick::Disabled);
}
With this kind of task, the tick function on the Delay task is only run once, by which time the duration has elapsed. So, I don't have to check every frame to see if the delay has ended.
Are your delays not state itself?
Now I just need to figure out how to jump to an arbitrary state.
The delay is a task.
It can be on any state
But its best used as the only task on a state
My setup is a bit hard to explain cause I'm running it on an ECS. But I'm making an RTS and ticking the state tree (every frame) for thousands of units didn't sound too appealing to me
Aren't StateTrees HSMs?
what is HSM?
hierarchal state machine
Oh yeah they are
IE you can specify transitions to other states?
can a subtask not transition to like a parent task or something~~
Yep. Now that I think about it, jumping to a specific state may not be the best approach. I'd probably just split into multiple state tree assets.
I don't think that's necessarily bad?
The design I have in mind is a bit weird and I'm still working it out. I want to use the state tree as a kind of "orders" system. So, I issue an order from outside the state tree and the tree jumps to the specific state that represents the order
So, its not natural transitions from within the state tree, but hard jumps from external influence
Sounds kinda like a utility-AI approach
Yeah pretty much. I probably shouldn't force it into the state tree, but I'm to lazy to write a custom system from scratch
GenericGraphPlugin
Plus, the UI is already done for me
I've seen that plugin. Isn't it kinda the same thing. I can't jump to an arbitrary node, I have to follow the transitions
has a couple other fancy things with how it handles transitions
nahnahnah that's just for the GUI editor
it doesn't have any functionality in regards to AI own its own.
This is my custom AI-editor built on top of it
Oh really? I'll give it a look then
Its basically just a bunch of Slate code + some C++ classes for Node/Edge/Graph types~~
Oh its mainly a UI plugin. Not sure it would fit my use case too well. But I'll see what I can do with it
im just saying if you wanted to roll your own AI system
Yeah, I get you. Handles the UI for me. I might actually consider it since I had a custom system before switching to state trees
You can always do that mixed thing where the StateTree dispatches the UtilityAI
(though tbh I never looked back once I had a custom system)
Probably the other way around for me.
Now I'm trying to think of any reason I'd want to continue using state trees
bahahaha
StateTree is getting utility scoring in 5.5 I think
I made my own because I wanted to be able to write Trees + StateMachines in the same graph
too many times I wanted to specify a transition
i have a custom BT Decorator which triggers an infinite loop warning (even tho i'm sure that there isn't an infinite loop...) anyone had that issue before?
Can you share the logic you're running in PerformConditionCheckAI?
it's quite the read... π
it triggers on the Moves towards Animal node
and FleeFrom is populated in the AnimalBP
oh wait, i made some "progress"
when i set the decorator to not abort the node tree it seems to work
maybe it's just way too involved to be run each tick π
guess i'll move the condition logic out of the BTD and add it to the animal bp
or maybe just make it an C++ decorator, since i want the check actually each tick -_-
uhm
wtf
why would it call it recursive?
does the blackboard update force a reevaluation of the BT?
or the current node maybe π€
Or the abortion triggers it? Though, it would be a strange behavior
tho this seems to fix it
or rather work around the issue
maybe i should do the whole check in an parallel task or smth
instead of the decorator
as that workaround (in my current setup) would never unset the value
Wait, I see you try to do some MovesTowardsAnimal, so it's some passive action that should be performed, why are you doing it in decorator instead of Service?
that's a check
if the other actor is moving towards the NPC
not a task/action
i think i'm just not supposed to update blackboard values in a decorator
should probably go in a parallel task or a service maybe π€·
while the decorator just pulls data
Node reevaluation is called every time if condition is On Value Change.
This is the reason of your recursion, you set blackboard key, Value Changed, reevaluation happens and so on.
yea, just checked the source, it notifies the observer
ok, since i'm an AI noob... this should be fine?!
it works, just not sure if Service is the right choice
Hi everybody!
I have a PC possesing my pawn and i want to be able to "Move to location" with a callback in case of fail/finish/canceled.
Any advice?
honestly wit behavior nodes, its best to be as atomic as possible
minimize side effects
I canβt remember what SimpleMoveToLocation has for pins
I think location and actor, but no callback
I already implemented something, but needed to use a AIController : (
Why is the PC possession required ?
later i'll see if i can replicate the MoveToLocationOrActor method from AIController, into PC
Already have all the setup for PC, dont want to change everything
also, less pieces
What setup, what do you need from the possession
Your PC logic will still run even if youβre using AICon to control the movement if thatβs what youβre worried about
Just not things like Possessed obviously
have you used the isometric example/template before?
it does click to move
its probably a simple example, but its a good spot to start potentially?
Some GetControlledPawn nodes, i'm already changing it with a cache ref and a interface
that shoudl be enough
Already checked, wasn't what i was looking for sadly
I think it also used simpleMoveTo and it swaped the PC for AIPC on the fly
honestly the base components for moving a pawn down a path are: something that generates paths, and assigns them to a path following component
i have to double check if that requires an ai controller or not, but iirc it just requires a CMC
ultimately the ai move to stuff calls into this
Shouldn't require CMC - should only require a nav movement comp
Which, all the movement comps inherit from
But I know some people have been having issues with this recently
Been awhile since I've went down this rabbit hole
ah fair i was going off memory so good catch
at the least that's where i'd start, generating paths for the path following component to consume and direct the movement component
I have a CMC but i can't find a way to call movement with a callback
i need to be notified when it's finished/canceled/interrumped
and so far i can only see those in the AIController
the path follow component does this iirc
is that a subcomp of CMC?
Yeah
hmm i'm going to check it out
ideally i would like to replicate the functionality into the PC and don't use a AIPC, so that may do it
its what does the actual path following work so i would think so, it gives callbacks and all that too
Should i be saving the task and in case of the event called again while the task is ongoing, remove it before calling it again or that is already taken care of?
Solved: Yeah, they are all active at the same time otherwise
Is there a way to force an NPC to use specific nav agent type in runtime? Like for example I want to have 2 nav agent types "calm" and "pursuing" where they will have the same parameters for everything except for nav agent step height. I'm thinking about adding some kind of monitor for MoveTo task where it will run shape sweeps to make NPC jump and climb over obstacles when it chases the player, but at the same time I want NPCs to use "normal" paths in the town without jumping over everything
Is there a way to make navmeshes only generate at runtime and not every time you move a rock in editor?
I still want a dynamic navmesh but only for it to be built at runtime
There is. There is a setting somewhere in project settings. Automatically update navmesh or something like that.
I have it turned off as well. Very annoying.
If you can't find it, Google "disable automatic navmesh rebuilding UE5". Should be one of the first links.
Thanks! I had tried setting the "Update Navigation Automatically" bool to false in editor prefs which works but then it doesn't build at all at runtime. I'll try looking around more on the forums or else try and enable that bool at runtime only
I want to avoid calling RebuildNavigation at runtime as it's blocking
Ah in combination with project setting ForceRebuildOnLoad it seems to work as expected after deleting the nav mesh actor in the world
Thank you
I just wanted to thank you. I ran into the same problem with updating vector locations in the behavior tree and knew there was some simple answer I was missing. Sure enough, not only was it just a checkbox to resolve but someone else had the same problem just a few days ago!
New to all this so forgive me if Ive gone about this wrong. Im using a simple EQS query to make my character move to the nearest point that has line-of-sight to the target actor (in this case player) I'm moving them with a MoveTo in my behaviour tree. It works great when it's dodging the thin doorway mesh in the middle but it's really struggling to find the more obscure angles like in the second half of the video. I've noticed it fail to find any valid point and return (invalid) as the updated move location.
Im using a box collision, set with high width only so it doesnt clip the floor as my trace filter, idea being that by making it fairly wide it'll only choose points that expose a decent amount of character to the player.
Is there a way around this that doesn't involve adding more nodes through reducing "space between"? Or a better way of establishing a finer location that has LOS? Would need to be doable with EQS, Behaviour Tree, or Blueprint
(EDIT: Got a substantially better result doing a second smaller EQS around the chosen EQS node to refine the result, is this the best practice?)
\o/
Hey folks. Has anyone tried 3D AI Studio? I'm not a graphics guy and their vids looked promising but I think they're fairly new..
Wrong channel bud #generative-ai
Hi all!
Looking for best practice methods for my horde shooter on alerting nearby enemy AI that they are "under attack".
- My first thought was to leverage the perception system (adding additional senses other than sight) but I don't have a ton of experience with sound and such.
- Another thought I had was some sort of "communication" system where if a target actor got set on one monster, it would trigger a sphere collider and set the target actors of surrounding monsters (if they didn't already have a target actor set) and so on and so forth. Worried about freaking the engine out (didn't want it to detect and infinite loop)
If anyone has any feedback or ideas on this it would be greatly appreciated
Just finished coding my custom solution, which is sort of a goal-oriented BT with focus on executing the entirety of goal (all it's tasks) in a single frame if they allow it, and capability to abort goals if they no longer feel valid (maybe the goal is to melee hit the player but the player kites the AI for few seconds, so the AI "gives up" on completing the goal and gets a new one) or do temporary goals in meanwhile (maybe the AI is trying to reach player 1 cuz they have aggro but player 2 happens to walk into melee range, so the AI can melee him on his way to player 1).
Now my combo animations finally align smoothly! (since the goals drive my combo system too)
It's hard to judge what approach would fit best here as they would alter the resulting gameplay! You could only trigger the area in which the other AIs get alerted once from the source AI and not further from the ones that got alerted via this area, for example. But perhaps this isn't desirable for Your game. You can absolutely play a SFX and have some sort of collision or proximity check determine who gets alerted instead of relying on a perception system.
If You want alerted AIs to further alert other AIs, You could simply have a bool flag on them to know which ones are already alerted and thus not retrigger the area from those. But this might be strange, as the AIs could, based on their positioning, alert enemies from way too far away instantly.
Another, more natural, approach might be mix of the bool flag, but also having the AI be engaged with player for few seconds before they do the alerting. This would prevent the recursion, and spread "slowly". Also as the AIs would approach the player, they would likely move out of range of more and more AIs that way. This would also allow some "stealthy picking out enemies without alerting more", but perhaps that isn't desirable either π
These are really cool ideas to experiment with. Thank you!
Where can i seleect ai controller class? 5.3? its missing...
Huh? It has never been in game mode settings
If you're spawning or placing pawns for AI's, the default controller is specified in the pawn's settings
i didn't get it
ye, i've created a mob and behavior tree with task, where should i put "run behavior tree"?
Target is Ai controller
In your AI controller blueprint
Depending on what the problem is you may need to put it into the on possessed event instead of begin play
oh nvm, found the couple issues, i had to select ai controller class inside bp mob, and this:
now it works
Ah, yeah those settings aren't super obvious at first :)
state tre
Can anyone give me tips on how I would get an NPC to detect a gun is being pointed at it?
Simple. Have a line trace on the gun, cast to the NPC, if successful, call whatever event on that npc
granted doing a line trace constantly from the gun might not be ideal perfwise
you can also use vector delta checks on player aiming direction and clamp the distance
Yeah I was thinking that but thought there was a better way
i've done that in past games
basically if the npc is within a certain fov from the player and within the squared distance check, you can send an event to the npc that they're in view
Sure, thereβs perception with EQS, dot products, you name it.
Entirely depends on your use case, and whatβs needed but line traces themselves are not expensive, perf should not really be a consideration here until profiling determines otherwise
alone sure, but casts add up, and its pretty simple to not use one here
ime, dont use casts if you dont need to
Then send an interface message and call it a day π
hi, is there a way to know in BP that if the EQS succeded or not?
I have a system which uses two movement system one with EQS and one withone eqs (nav mesh volume) and I want to only use EQS when close to the player and fail (which it automatically does) when not close to it. is there anyway to check if it failed or not? and then do some stuff from there.
Anyone know if there a way to Get/Set state tree parameters from within and outside state tree tasks? I'm not seeing any function that helps with that
All the AI behavior business feels like a real knowledge test on how good one is at creating good logging standards π
Is there some way to directly move an AI controller ACharacter class, adding acceleration to it explicitly how I want? Something like AddInputMovement would be good, but I'm not sure how suitable that is for AI characters, and whether there might not be issues with path following overriding it etc.
I guess something like AddForce could be a very hacky solution to this...
It does seem that AddInputMovement actually works for locally controlled ai, which is ok for me, but it still feels a bit hacky.
what are you trying to do
Add some zig-zag dodging for an AI bot. Following a path finding result directly might just be "go forward" but I want it to zig zag to some extent.
Hi everybody!
I'm having some troubles with tiles having a navigable static mesh.
The mesh is set for navigation, but it doesn't generates it when the pawn is on top (pawn has a navigation invoker atm)
Just a reminder that checkbox basically says βthis geometry should be treated as an obstacleβ (make hole in the navmesh all around it) - afaik
The mesh used also seems to have navigation data
Oh, thatβs def something else, guessing itβs used by the nav system but idk exactly what it does
Guys how does EQS calculate the score when there's multiple tests? Does it just add them together?
Is this the right room to talk about LLM application in UE?
No go to generative ai
Hi!
I still couldn't solve this one, any idea on why this may not be working for navigation? it does have a static mesh that is set for navigation, but it just doesn't constructs the navigation cells
The navmesh bounds are okey and it works on other plane that i have
Hard to see the green navmesh in that sea of orange π
Is there a navmesh volume placed at all? Or are you using invokers, how are you generating the navmesh again
I swapped it for nav mesh bounds without invokers, it works okey in another place close by that, let me remove the orange
is the line trace the only method to make an ai jump if it reaches an obstacle that it must jump over it if the destination target is on top of the obstacle?
I don't really want to use nav links as those are too tedious to work with
I need a more dynamic ai adaption
Check out this video for a taste of whatβs in the new Unreal Engine Game Animation Sample Project.
Interested in creating high-quality character locomotion and other gameplay animation systems? Look no furtherβyou can now download the Game Animation Sample Project for free!
Supercharge your development with this animation database of over 500 ...
how does that help?
may help, there's functionality to trigger jump over boxes animations
You could use overlap detection
So the navmesh volume needs a mesh to generate nav on, or at least a plane in your case. Iβm not sure what the grey part youβre showing is, is that another plane? Where did the tiles go
Solved, the bounds Z was outside of the plane
weird, because in the viewport it looked inside, but changed Z and works now
Unsolved: Actually, it's still not working, it was using the navmesh of the plane below it :/
Guys what happens after a conditional abort in a behavior tree? Does the whole tree restart from the root? Or does execution go "back" to the decorator?
anyone know of a project that has smart ai's I can look at and pick apart the logic?
Im trying to learn how to make advanced enemy npcs that take cover shoot, do stuff in groups, learn from the players mistakes, etc
Hi, I have the issue that the smart nav links are not working. The AI stands and does nothing. When I use simple link it is working correctly. Anyone have an idea what could cause this issue?
I just gotta scream it somewhere, but I just got a GOAP system working by myself, all my own code, where the enemy uses GAS for abilities, hit reactions, etc.
still work to do but the performance is great and it feels excellent. So damn happy when it finally all comes together.
That is all, thank you
Not sure where to put this but I have an issue where my enemies seem to step into each other, any way to fix this?
Pretty sure it goes back to the beginning
Well assuming that the failure doesnβt drive it forward like in a selector
Congrats dude! That's awesome!
hi guys I was adding AI bots to my game, I have a navmesh and everything is green as you can see, however when I PIE the recast navmesh disappears or unloads from the level and thus my bots don't move from spawn. When I simulate the level, however, all seems to work fine, the recast navmesh works well and the bots are moving around, Does Anyone know what could be wrong?
Gas for Hit reactions? How does that work??
so on taking damage, it triggers the hit react ability, which is tied to a cooldown so it can't be spammed
Thank you!!!
Ah I see,nice! What are the benefits of using gas for enemies?
And how did you go about learning it?
using any sort of ability system for enemies is key to building an AI that doesnt actually have to implement abilities in the behavior tree
hit reactions, attacking, etc should not be hanlded by the tree directly at all.. it also lets you embed metadata in the abilities and have ai pick abilities based on the available abilities that meet the criteria its looking for and then they simply can just use it, and wait for that to finish
How did you go about measuring performance? Just keeping a timer on the major operations?
I appreciate the reply!
so , two questions, what are different approaches two having enemy soldier groups that work together to find and take down the player? like what we see in the mgs series
also,
is there a defualt way to configure ai sense on runtime? to either lower the distance, or turn it off, for example the enemy is blind , or there is minimum light, etc
in c++ yes, you just set the values
alright thanks!
and for the ai learning about the player, if I use a datatable with statistics like where the player took cover, where he hid etc, and based on how many times he does something adapt the ai to do that, would this be an effecient way to make the enemy seem more aware like in mgs v?
You canβt store info in DTs at runtime, I thought?
Do you have a persistent level + sub-levels in your game?
Either you use RVO or Detour Crowd Control or you use something like what Sunset Overdrive did: each AI moves towards an actor that's invisible and which location is calculated (and updated) from the player location + offset.
Something like this (X is AI, C is the target actor, P player)
X1...C1...P....C2....X2
You can then play around with thing like curves that control how close C will be to P based on the distance X - P, how close to C's can be etc
You can
Just not recommended
Ah
honestly dont know why a struct or something isnt preferred
It generally is
in this case i mean
Iβve had some success with a mixed approach, IE damage is still activated by the ability system but the AIGraph itself still has nodes for βWaitForDamageToFinishβ
Attacking also has βAttackSelectorβ for contextual attacks but the AIGraph can still request specific attacks as well
(Soulslike combat/AI fwiw)
I personally have been watching for memory leaks via framerate and leaving them running and fighting each other for hours then reading the logs.
@vivid fern hit the nail on the head.
I learned GAS via a class I took a year ago, but that was primarily for the player. I implemented a ton of stuff I had to learn more on my own with through testing, trial and error over the last year. But once you get a good grasp on GAS, it simplifies so many systems, you start to question "What shouldn't I use GAS for?"
(I am biased but while GAS at a surface level is literally not as flashy as something like Niagara or PCG, it honestly should be a core learning material for devs)
((also also, do not use tools like GAS Companion from the marketplace if you decide to go learn GAS. Learn it the manual way or I can almost guarantee you will not learn GAS properly. GAS Companion can be used later after you have a firm grasp on the concepts, though I do not use it myself))
I see, what is the manual way? Im trying to get my game demo out in 3-6 months so idk if I should wait or not
The thing is I'll rebuild the demo probably to make the game more scalable
Several or one Blackbroad is better for performance?
use one for all BT or several ...?
It is just a UObject that holds data. Not much more.
Performance isn't even a concern really.
I mainly use one
In all the games ive shipped, ive only used one black board type for every ai
nod, you're playing a game of micro optimization at that point ... better to spend that time profiling and going after actual problems
ok thanks
Yes I do.
Hello!
got a "basic" question for AI?
My character is not moving, what am I might be doing wrong?
Tree~
Custom Ai Controller~
pawn (Parent: Character) has the Ai Controller~
EQS test seems to be ok~
Yes, there's a NavMEsh and Pawn itself doesnt affect it~
Use visual logger to find out the cause
Is not being set? π€
What do I do now?
I mean, I've selected all that is supposed to be selected and is not clear to me why the PAWN is Null~
Is that vislog? It looks diff. Are you in UE4 like some savage? π
UE4.27 yes~
Ok well for starters
Youβre using a selector instead of what should probably be a sequence
With a selector if the left branch succeeds thereβs no reason for it to move to the right branch
So start there
Done~
Still no movement~
can't debugg cause "Its imposible to find campatible actors"
You can still debug
Sorry, My gui is in spanish for some reason
You can use breakpoints in the tree or even watch it live at runtime by hitting alt+P
I founf the issue~
I was Adding a Component here, I had to Execute a Behaviour Tree~
It now moves
All Good~
what is a good way of having ai's teamwork in order to defeat the enemy? should I use a certian blueprint like a radiotower to manage the different ai?
Hi!
Not sure if this is the best place, but does anyone know if there's a way to know when this navigation mesh finished updating?
-Solved: Is navigation being built does the job
Mentioned this yesterday but I posted in Blueprint channel and did not provide pictures so I got them this time. I'm having an issue where the default value of tasknum integer from the blackboard being set to 0 breaks this code (same for any int out of the scope), where for some reason the random select does not even play. However, changing the default value to an integer inside the scope does let the code work, however it will always perform the sction corresponding to the default value of tasknum first, then it functions like normal, randomly selecting either integer 1 or integer 2 (I have it this way so I can later expand this code with more integer choices)
When the default value of tasknum is set outside of the randomselection scope, the selector from root only seems to go to the second sequence, completely ignoring the lefthand side
I have absolutely no idea why this problem is happening, I hope it's a stupid mistake but at least in theory this code looks good to me
Alt+P, then pause and step through the code (you can also step backwards in BTs)
yeah its doing exactly as I expected, where its never reaching the random selection when the default value is outside of scope
weirdly the first frame of it being active instantly triggers the random selection when default is applicable
then behavior is normal
You keep saying out of scope, but can you clarify what you mean by that here
the scope is integer between 1 and 2
when the default value set in blackboard is 0, it never goes to the random input method
So why are you setting it to 0 then
I want to have it set to 0 initially so then it can be set to whatever it is randomized to after it reaches the method
using alt+p it shows that it is correctly picking random options its just that first frame that is causing the problems when the default is an acceptable integer
Show a screenshot of what is happening in the first iteration, while paused
this is the first iteration
it went straight out of the selection after the default value is set to 1 and played the corresponding logic
it being on the right side initially is right as the ai currently does not see the player, but it triggers the logic like it did instantly regardless on any condition just because of that default value
earlier i posted what the inside of random selection looks like
I put a print statement in the random selector and when the default value is not 1 or 2 it never reaches the random selection, when it is one of those numbers it will show what that screenshot displays
Im baffled as to why the tick wont even be recieved if its not 1 or 2, theres no input to the service so it should be just outputting the tasknum's new value
one thing i did notice is its not instantly going off frame 1, the problem is jsut that the default value outside of 1 and 2 are not being considered/if the default is 1 or 2 then when that behavior is triggered there is no randomization for the first instance
Maybe it doesn't tick initialially? plug the logic into activation?
what about plugging it into task search? it may be that it doesnt get activated all?
the only bandaid fix i have working is to have a case for when task num is 0 and do nothing
wdym
its being activated but only if the default value is 1 or 2
then it always activates those results without randomization before functioning normally
tick "Call Tick on Search Start" in the default properties of your service or plug them into search start as well π€·ββοΈ ?
I have no idea what you mean lol
oooo tht
i get what you mean
thats switched on
i switched it off and it disappeared
no nothing changed
dont remove it, activate it
o
it was activate the whole time before i removed it
now for some reason it's not showing up anymore
It's not enabled by default
the confusing thing is there was no difference when it was switched on or off
is there an easier way to implement random selection in behavior trees? i thought this would have been the simpliest way but this issue is proving otherwise
ideally I want this to work so I can implement other logic like being able to lock choices depending on situations
the bandaid fix of having nothing happen on a tasknum 0 works but I can already envision that making future code messy
any one work with State Tree?
Did you try just plugging it into Task Search?
if you mean that toggle its gone
idk what you mean by plugging into task search
I mean, the event inside the service
thank you so much
It should be the same thing as toggling on "Call Tick on Search Start" though :P
but you made it disappear by toggling it off, the toggling it off and hiding the entire option is weird
there is no way to toggle it back on lol
I guess, not sure what the person that made that had in mind though
gonna see if i can duplicate the service and get that toggle back
The property that hides it is transient though so it shouldnt be saved π€·ββοΈ
damn they really handing out curses by removing that toggle
that's so strange, is it a bug they just never fixed?
regardless it is a little concerning that the toggle even when flipped on did nothing
Ill try to figure that out later but again thank you for the help
Actually looking at how bCallTickOnSearchStart is implemented it might not do as advertised lol
wdym
is it firing before anything else is triggered?
also I noticed that it has two checkboxes, one for a bool to activate/decativate and the other that removes the option, i think I may have gotten confused and assumed the remove option meant bool was set to true, but idk how the actual code for that is implemented
yea I figured you did that wrong, thats why I wanted to confirm if just manually plugging it into search start helped for you :P
It doesn't help that the property disppears and you cant test it again
was manually changing search start trigger the equivalent? asking after you mentioned it not doing as advertised when you checked its code or if thats jsut generally it being a strange method
It should fire tick as well, so if your logic was in tick it should be equivalent to plugging it into both. As for my previous comment, just ignore it, I was confused with where it was being called, thinking it might not do as advertised.
O lol
thats because the values are not 1 or 2 so the branches fail and the tree goes to the fallback
imo index task randomization like this is not the way to go
I assume the best way would be to just make a custom selector node in c++? but I dont think there would be a BP equilevant?
its honestly pretty simple to write one
between selector and sequencer you already have examples too
Then try this: make sure that you have at least one nav mesh volume in your persistent level. Doesn't matter where or how big. If you didn't have one, place one at 0,0,0 and delete the recast object. The build the nav again and save all levels. There's a "bug" in unreal (it's really the way it works) where, if you don't have a nav volume in the persistent level, it will grab the first one it finds in a sub level (random) and place the recast object there. This causes that, unless you stream in that specific level, you don't get any nav due to your recast object nor being present
This helped so much bless up.
Additional question since im new to this, should the AI bots work regardless of the net modes like Play and Client or Listen Server, or they only work on Play as Standalone
Does anybody know how to set a Param value in a State Tree from code? I feel that I'm close to figuring it our, but I can't find any information on how PropertyBags are used.
In my case, I have a global param in the State Tree that is a TSoftObjPtr<UBehaviorTree>.
I want to do two things:
- been able to get it to load the soft reference when I need it
- been able to set a different BT in my param
So far this is how I'm doing it within the State Tree Component extension I use.
FInstancedPropertyBag& mainTreePropertyBag = StateTreeRef.GetMutableParameters();
if (const UPropertyBag* bag = mainTreePropertyBag.GetPropertyBagStruct())
{
const FPropertyBagPropertyDesc* desc = bag->FindPropertyDescByName(TEXT("ReactionTree")); // this indeed resturns the Param I'm looking for
const TSoftObjectPtr<UBehaviorTree> bt = Cast<UBehaviorTree>(desc->ValueTypeObject); // the valuetypeobject is valid, but no idea how to get is as what it is, a TSoftObjectPtr<UBehaviorTree>
}
Any help is much appreciated. Documentation is lacking to say the least
UPDATE
ok, figured it out. Turns out there are getters for different types
FInstancedPropertyBag& mainTreePropertyBag = StateTreeRef.GetMutableParameters();
TValueOrError<FSoftObjectPath, EPropertyBagResult> propertyAsSoftPath = mainTreePropertyBag.GetValueSoftPath(TEXT("ReactionTree"));
FSoftObjectPath& sofPath = propertyAsSoftPath.GetValue();
AI in unreal is server side and then replicated to the clients. Should work in every version
hey. does state tree task gets destroyed when state finishes? or is it getting reused and not destroyed? looks like i have to unbind all dispatchers on state end or else they leave binded when that task gets run again. or am i misunderstanding something
As far as I can tell, the tasks are instanced and then re-used (hence the concept of context and instanced data of the tree)
following up on this: if I set the param value of a tree from c++, and then I bind that param to a StTask property... how do I get the value of the bound param in the Task itself?
Is there a way to detect if a UPROPERTY in a Task has been bound to a tree param?
should i be using binding to events inside a task?
I don't see why not. I use them for GAS related stuff. But as always with event-driven-logic: make sure you clear out your bindings at some point, whether it's EndTask, EndPlay or as soon as you get the callback
thanks for the help!
even though I got the code to work I'll try this just for the c++ practice
Hi everybody!
Any idea on why i am having a different behavior with Navigation between this 2 planes?
A) I can keep the click to move pressed and each new "MoveToLocationOrActor" Task will be retrigggered succesfully and override the previous one.
B) Only when i lift up the mouse it succesfully creates a new task
A) https://gyazo.com/52960bffdd827c1cdcafb780ee210fce
B) https://gyazo.com/2031f21ab26df70b7414eb9b47c62d76
Same thing for both, one plane with same collision type and navigation enable
You can see on the second video, in the left upper corner, that the NewAiTasks are still being fired, but it doesn't move until i lift the mouse
Solved: Forgot to call parent constructor of the second actor
I'm facing a bit of an issue with my AI, when other AI die they still seen for the cooldown time of the AI perception. So if they were seen, it won't be until the age expires that they stop thinking they are still there. So the NPCs try to walk around them.
Is there a way for me to have a dead AI to be cleared immediately from visibility of others?
I imagine if you destroy it
Yes, destroying fixes it no problem. But I want the corpses to remain.
Iβm not sure if changing the stimuli sourceβs age dynamically will update the current timer but you can try
Otherwise what people usually do is destroy the actual AI and replace it with a regular mesh (dead actor)
This way itβs also less expensive to keep loaded
Ooooh, that's a good suggestion. Swapping it on death.
Yeah, and less expensive. Ok, I'll do that, just need to create a system for it. Thanks!
Destorying controller or Unregister death body from perception system can also do the trick. You can have a look how to unregister it in UAIPerceptionComponent::CleanUp(). This is called when you destory controller or its pawn
Anyone here knows how to properly use FStateTreePropertyRef so, from within a State Tree Task, I can write data into Param (don't care if global or in the Evaluator) to later read said data from a different State Tree Task?
Have you tried binding it via InstanceData?
I'm not a 100% sure if you can even write into params tbh
Do you mean in the tree editor by binding it? If there's other way, I'm not familiar with it
Yes, that's usually how you would do it
Although I'm not entirely sure whether it would get reflected in the original value as I don't recall if I've used it for modifying them in this fashion
In theory the property ref is there to write/read params in between tasks, but there's 0 info on how (aside epic making the statement).
Will ask epic in UDN and see if I get an answer.
Please share it if you do, I recall this has been discussed here once or twice in the past and it was equally confusing :)
Meant to look into it myself at some point but haven't gotten around to it
You can mark the UPROPERTY as Category Input or Output, is that what you want? that is basically what makes it bindable automagically.
Honestly I'm not super sure because there's something I don't know. Let's say your evaluator has a param set as Input.
Then you bind that param in your task so tome uproperty member in the task.
Does that mean that, whatever value the tasks sets to its memeber UPROPERTY will be the one hold by the Param in the Evaluator?
If that's the case: can you simply read that value in a different task?
What I mean: is this true?
- Output -> you can change it from within the evaluator logic (enter/tick/exit) and it's read only from Conditions and Tasks
- Input -> you can change from everywhere (evaluator, conditions and tasks). I'm trying to check this but this makes little sense to me, because if you want to have a default value, you need 2 properties: one you bind to the param and one with your default value. Then in code, assign the default value to the bound param, so it's present in the Evaluator.
- Parameter -> same as output but the value comes from another bound parameter (which, as far as I can tell, has to be a Global Parameter)
Side question: are we expected to assume Global Params in the tree are unmutable (at runtime) read only values? Asking because that seems to be the case, but then you can set values through the Properties Bag (returns success) but, when you read the value you just set, you get whatever was set in the editor tree (your runtime value is nowhere to be found) <-- this I asked to Epic too
will do
Parameter is the same as Input afaik, only difference being that Input must be bound and Parameter can be entered on the spot or bound. Not sure about the Global params, but I think they are supposed to be read only.
(If they were supposed to be editable then I think the naming would have been global variables, and not parameter.)
so... in theory... if I set an Evaluator property as Parameter, I should be able to write into it if I bind it to a property in a Task? (trying as we speak)
Input is what comes into the Evaluator, its what you evaluate, Output is what your result is... you never modify the input. (Of course I assume if you input some pointer to an object you can modify the object but that probably wouldn't be ideal for an evaluator.)
yeah... I think I'm back to square one: indirection.
- Task writes value into a Uproperty somewhere.
- Evaluator caches it in Tick into an output param so it's available for everyone in an easy manner
I think the problem is... me. I keep thinking there's some sort of BlackBoard hidden somewhere in the State Trees ecosystem.
I've only used the state tree with Mass, and there the Fragments are basically where you store things..
I'm not actually sure how it works without Mass, what replaces the fragments. π€ there must be something.
maybe I should look into how they implemented it and see if that's something I would like to have
I might as well have one evaluator that acts as a BB/Fragment. You can access them through the InstancedData and the Context. Just put there my "BBK's" and make the evaluator "expose" them as params on tick. Hate to do things in tick but... it's what it is
You use the GameplayStateTree plugin?
Yeah, that's the only one I use (no mass whatsoever)
You have a reference to the actor there, so wouldnt you just store whatever you want in the actor?
Yeaaaah, but trying to avoid that to spread things thin. I would like some form of cetralization for variables that are calculated "here" and used "there". In the end I have several trees feeding info to a main one (can't give more details unfortunately).
Wait.... That said... I think I know why my stuff doesn't work....
Oh my... I'm writing to the evamuator of treeA and trying to read from the evaluator of treeB....
Thanks a lot for the input, you just made me realize about the hole in my logic.
Hey all, is there a way to rebuild my navmesh at runtime myself? I know about the editor options to do it automatically, but I only need to do it infrequently in a controlled manner. I tried NavSystem->Build() but as much didn't seem to do anything
For what reason
Level generation via tiles
So the level starts out empty, and then on load a bunch of geometry is generated by selecting tiles. Pretty standard I reckon, and this is only done once when the level is loaded. I know the rough bounds of the resulting map so its easy enough to cover with the nav volume, but then I need to actually build it
For perf reasons I don't want to do it 'every x seconds' as the setting provides...
Is your navmesh set to dynamic?
Er. I don't want it to be fully dynamic? I want to control when it regenerates
As mentioned, I only want the rebuild to happen once
is your world constantly changing? if not doesn't dynamic work just fine if you only place the volume after its done?
That said I'm not that sure placing volumes works that well, but alternatively you can fill in the entire volume beforehand but only add an invoker that cover the whole map. π€·ββοΈ I guess you main issue is that you load in the map in pieces and it starts generating chunks over and over because its changing as it loads in more?
No, its not constantly changing, the level is generated once on load, and then persists until the player leaves it again, but it seems like its impossible to generate the nav data at runtime if its not set to dynamic. Since little is moving/chaning in the normal lifecycle I suppose its 'okay' to just have it be dynamic, but I'd prefer to just know for sure that its not going to be regenerating it during actual play down the line.
@still crypt I looked into the code some more and there is an AddNavigationBuildLock that may be the proper way to disable it from rebuilding when you dont want it to. (That said I'm not entirely sure and you'd have to play around with it. I see several other things related to locking that seem to be Editor only, but this one seems to always work.)
My ai seems a lot more responsive having moved some logic out of a BT task and into the ai controller
is there anything obvious that would drive that? Do they delay execution or something as it moves through nodes?
Afaik there may be like a tick between nodes in some cases, but this is generally not something you would notice
since that's like 1/60th of a second or less unless your game is running fairly poorly
Behavior trees only tick one leaf node at a time
It will tick decorators and services and composites like sequencers
Until it hits a leaf node
But honestly most leaf nodes are durative tasks anyway so you generally wont be processing nodes after their tick
It does imply some design considerations with your tree however: you shouldnt have nodes that return success or fail immediately if you can help it.
But really ai dont need to make decisions very quickly so there's no real reason to "get more responsiveness" from it
How would I go about letting an IA "remember" where it previously was? Specifically I've got a tree running an environment query to get a new location but the AI keeps going back and forth between the same two locations because the node weights don't account for being previously traversed, I'd like this AI to randomly explore areas it hasn't been to recently
π€ maybe assign a higher weight to that area so it only takes it if it canβt find another way around?
I canβt rmbr the exact terminology rn but talking about nav cost iirc
nav cost, I could look into that, haven't been sure what exactly it was but that sounds the right track
Thereβs a GDC on death strandingβs navigation where they mention it. Ofc they made their own system but afaik thatβs something Unreal has too
I'd just probably have to find out how to modify the navmesh cost by code or something
Iβd be surprised if Allora or others here havenβt dealt with this
quick forum search it seems an approach to changing nav cost realtime is by spawning navmesh volumes, that's not opportune as it's spawning in a bunch of additional actors instead of what I'm thinking would just be modifying "q-states" or state weights essentially in the navmesh or something
Well thereβs always nav modifiers you can use
I think thatβs how itβs usually done, you can for sure just turn those areas into straight up obstacles but iirc they also have other options for nav cost
And this way you can set your nav generation to dynamic - modifiers only
ofc the official docs are barebone but the unrealcommunity wiki mentions a custom nav area class, that looks like probably the best option, have a mesh defined per team that changes its weights per mesh as teammates traverse it
or a simpler approach, change the env query to weigh higher locations in front of the player, it might kind of work
personally i just keep a running list of prior destinations and then use those to reduce scoring when using an EQS haha
probably cap the last destinations to like 5 or something or less probably
honestly as long as its not the same destination, or area around a destination, its probably good enough
personally i wouldnt really mess with the navmesh if i could help it
like ill do that for like, doors, or hazards or something, but if its just not to repeat the same traversal, i j ust make sure not to pick destinations near some previous list of destinations
Messing the nav (specially if it involves nav modifiers or re-gen in dynamic) is not the cheapest way (cpu). I suggest you follow Allora's advice, which is also what I have been doing in released games. Have a tracking component (you could use your extension of the movement component) and save the last X locations. Then, as mentioned, consider them in an eqs test. You can create overlap spheres at each point with a radius of X meters. If your new point overlaps any of them, it means you are getting back to an area (defined by the radius) you already were.
If for some reason you need to save dozens or hundreds of locations, I would then use an Octree and check the test against it (I did this to save cover locations in a shooter game to drive the AI). Fairly cheap to run, not straight forward to implement since there's barely any info about how to use Octree
ultimately its just a radius check that you would use to decrease eqs scoring
still, you probably never need to remember more than a few previous locations
heck you can do destination picking that does this without extending any eqs tests in c++ for many things
yeah, a sq distance with inverse distance score. No need for the sphere stuff I mentioned (I was thinking in overlaps)
Okay how would you guys introduce personal traits to npcβs along with relationship system
I would start scanning gdc vault, youtube and the tree volumes of Game AI Pro books looking for answers in other games based on what my game needs
Cause Iβm doing two separate actor components but idk if itβs the ways to go because of having to reference them in each other and I feel like there has to be another way
It feels tidous
honestly you really need to define the experience first, whats the end result. That will inform where you should go
what is difference between 'Receive Execute ' and 'Receive Execute AI ' ?
Nothing except the other one gets the AI controller as a parameter
Hard to say why they even make a distinction between them
thanks ...
honestly they look the same in code, probably a legacy thing
My best guess is they were thinking of exposing gameplay tasks
Or yeah I suppose maybe the other one was intended if you use a BT outside of an AIC
one does seem 'for generic stuff' and the other 'is ai specific'
{
ReceiveExecuteAI(AIOwner, AIOwner->GetPawn());
}
else if (ReceiveExecuteImplementations & FBTNodeBPImplementationHelper::Generic)
{
ReceiveExecute(ActorOwner);
}```
ends up executingthis
so /shrug
yes exactly
makes me wonder if they were making bt's more generic instead of ai things
From the comments:
entry point, task will stay active until FinishExecute is called. @Note that if both generic and AI event versions are implemented only the more suitable one will be called, meaning the AI version if called for AI, generic one otherwise
seems like there was some intent to make bts work on other things outside of ai controllers
and another question you work with Damage type ...?
?
Yeah that actually looks like the non-ai variant is for if it wasn't in an ai controller, but I vaguely recall they don't really even work outside of one
but then again I never tried it so might be my memory playing tricks on me
might need some c++ finagling to work
I have BT working on plain Actor. It is Squad Actor that run custom Squad BT. It hold references to Squad Members controllers and can release a command to them or store data in their knowledge representation. IN c++ OwnerComp.GetAIOwner() isreturning nullref, so you need to use OwnerComp.GetOwner() to get owner actor. Other then that it worked same as Controller one. I am not sure about BP Nodes, as I do not use them
Ah interesting
I guess the non AI variants for the BP event are for usecases like that, just never tried it so wasn't sure if that actually worked :)
Just to confirm - yes, legacy.
I mean is it really? If you look at what Vavro.Srobar just said
the ReceiveExecuteAI function would not get called in his usecase
Yes. It is legacy.
The damage system is also legacy - but it still works for some people.
Working or not does not constitute legacy or not
So if it's legacy what is the non-legacy way of using it outside of an AIC?
Yeah so if that's the intended way to use it, I don't really see how it's legacy :P
The damage system is (one could argue) superceded by GAS
But this one isn't as far as I can tell
Considering she has been using UE for like 10 years, for indie -> AAA, - I'm willing to wager she has some historical knowledge.
There's no question that the AI version could be newer, but there's clearly a separate use case here for the non-AI version, and if it was deprecated that usecase would no longer be possible
Much in the same way as you can use state trees outside of AIC's
For cases where you do use it in an AIC, then you could certainly consider the other one as obsolete as it serves no practical purpose - but only for the usecase within AICs
Hi everyone, How can I reset blackboard when stopping logic via BrainComponent? It seems StopLogic doesn't reset Blackboard values!?
I want to reset all keys, Since Keys could be different isn't there any way to reset Values for keys?
You just set the values to some default value
I know, But I want to do it via C++, I need to acccess Keys via C++, Is there anyway that I can access keys via C++?
Of course
Would you please tell me?
Look at how the Move To task does it
But we are passing key to MoveToTask
So?
Isn't it what you are saying?
I am telling you to look at the C++ code for the move to task
Go look at it and then see how they access the BB value
Then you look at how you can change the value
I have access to the Blackboard, I need dynamically get all Keys and reset them.
Then you will end up using reflection most likely
That is what I mean I know How to access the value of BlackboardKeySelector and even Clear the value.
My problem is need to get access all keys without BlackboardKeySelector.
Or I need to create a task to clear all keys and call that task once each time BehaviorTree Starts.
Use reflection to iterate over the uprops in the BB. Then set the value to a default value. You'll have to check the type.
So go out and look up how to use reflection to look at uprops of a certain class
Any thoughts on https://www.unrealengine.com/marketplace/en-US/product/nody-entity-perception
I wonder if it is actually better
I know how to iterate over Uprops I only was looking for some functions to do this, But it seems there isn't any.
Yes. Which is why I've been telling you that you have to do it manually.
No thoughts. But if they're comparing to PawnSensing and not AI Perception, then there baseline is already wrong. PawnSensing has long been superceeded by AI Perception.
So it uses AI Perception under the hood?
Could be a typo, it's pretty recent so I would think they are going for perception.
And why even mention PawnSensing?

I have my doubts. Plenty of people still used PawnSensing in 2024. Heck, one of the bigger tutorial makers was pushing it.
If it works for you - great. But personally, I wouldn't even bother.
I can't see the price either. But if it is cheap as well and solves your problems faster than what it would take for you to write it yourself, then go for it.
It's free that's why I even thought about it.
Then go for it I'd say
Yeah after checking the code it's a very simple sight only sensor, idk why the reviews are what they are.
Might be friends of the dev
Or other complete beginners who only ever use sight.
Β―_(γ)_/Β―
Why is the value still "false" after I set it to true?
Is updating a blackboard value inside a task deferred to the end of the task execution or something?
What is the value of Intro Complete?
Initial value is false
I mean what is the value of that specific variable
As in the blackboard key selector in your task
@misty wharf
I'm using the BT to drive my tutorial scenario. The behavior tree is run from the GameMode, I'm not sure if this has anything to do with it.
You might have to dig into the C++ code for this because there shouldn't be anything that defers setting the value or anything like that
There might be something where it isn't getting the blackboard correctly or something, and breakpointing the C++ code would probably let you see if that was the case
I assume you have added a blackboard component to your gamemode in addition to the BT comp?
Good idea!
I was trying to use the AI debugger, but that requires my BT to be on a Pawn with an AI controller, so that was not an option.
Yes, exactly!
wait, you need a blackboard component?
Yes
Doesn't the BT recognizes its BB when I assign it the BT?
It does get auto-created under some circumstances, but I'm not sure if those circumstances are AI Controller -specific
So just to be safe I would try creating it manually and seeing if it has any effect
Thanks for the insight! I will try it.
It gets auto created when you do the "Run Behavior Tree" function in the AIController if I recall.
Yeah that could be it
It was it. I added a Blackboard Component and it worked like a charm. Thank you very much! π
π
Sure
@harsh storm No, it doesn't log anything. It just fails silently.
Cool
@harsh storm
I did it like this, No needed for iteration or even type casting, I am sharing it in here if anyone need it can learn how to do it
if (UBlackboardData* BlackboardData = BlackboardComponent->GetBlackboardAsset()) { for (int32 i = 0; i < BlackboardData->Keys.Num(); ++i) { BlackboardComponent->ClearValue(BlackboardData->Keys[i].EntryName); } }
Side note: perfect example for state trees
Heya guys, any reason my AI vibrates wildly when it gets to it's destination?
I keep increasing the acceptance radius MoveToLocation(location, 80);
And it just vibrates for about 5 seconds every time it reaches the destination
I've just increased the acceptance radius to 1000 and it does nothing. does it even work?
just a guess but at 1000 its within the acceptance range in this video, so i would not expect the ai to move
what are you moving to
the target actor? a position next to the target actor?
have you debugged your behavior tree? have you checked visual logger?
Any one able to help on this one, so background, I'm using the Train Sim World 5 Public editor so content that isn't mine is cooked
I am trying to have a character I've made traverse the nav mesh however it seems to not be able to. Is there a way to force it's AI Controller or something that it is on a valid nav mesh as at the moment I don't think it sees it is. Also, it doesn't seem to take into account collision bits that are on the nav mesh anyone have any ideas for that one ?
anyone know how in the viewport I can see the result of the EQS query ??
I know I can make a child quier thing and pass in player character instead but that'll only work on runtime so difficult for me to see if my EQS query will work right
Tools -> Visual Logger
have I done this right aswell to get the result of the EQS query ?
when I run the code it seems to not give out any results
EQS is asynchronous. There's an event like query finished or something like this, you have to bind to that and get the results from that event
The event is available in the value you get from the Run EQSQUery node
arr right, makes sense
MoveToLocation(location, 80); this code on the AI Controller to move it to a specific location (not involving behavior tree), seems to completely ignore the acceptance radius -- can manually positions also be done through blackboard? with the ability to stop random movement and stuff?
What's the difference between evaluators and global tasks in state trees
They seem to fulfull similar roles
I'm working on an endless map where I need to refresh the NavMesh volume so it can follow the actor as it move through the level and spawn AI enemies.
Currently, I'm updating the NavMesh volume every X seconds with "RebuildNavigation", but this approach is putting a significant strain on performance because the volume is quite large.
Is there a more efficient way to refresh the NavMesh or optimize this process to improve performance?
Don't manually rebuild the navigation, use navmesh invokers
Wont I need to have the NavMesh volume itself rebuilt/moved for the invokers to work? Tried adding invokers to my character BP, and it stopped generating once the character got out from the navmesh volume.
Just make the navmesh volume massive, only build navmesh around invokers (in project settings)
None. Evaluators are gonna be replaced by global tasks. From the epic tutorial about state trees
Global Task - Tasks that run for the lifetime of the StateTree. These can be useful in exposing external data to the tree, configuring event listeners, and cleaning up the tree when stopping.
Evaluator - These have largely been phased out in favor of using Global Tasks. Global Tasks handle the same uses as Evaluators
I hope they also make the effort of actually telling you how to use those
And the random features that will cause endless headaches unless you Just Knowβ’οΈ - like the fact that finishing a global task will stop the entire tree with no indication of why it happened :P
Problem will still be "what if" someone manage to play the game long enough to get outside the box. π
Every game has limits...
Hello,
My ProvideSingleLocation context returns a Stimulus Location vector.
But my EQS Query still fails.
It is working when setting an actor context in "center actor" parameter of the generator.
Is it ok to set a vector context in the "center actor" parameter of a generator ?
Thanks π
Exactly, I figured something like this would happen
It's weird cause I may have to make multiple versions of the same task. One that finishes early and the other that runs forever.
You could probably make it a UPROPERTY on it to toggle the option :)
Maybe simpler than making many versions
Ah this tooo π
yeah... or all this
https://jeanpaulsoftware.com/2024/08/13/state-tree-hell/
Yeah
is there a way to read the navigation situation of an ai when its set to move to a target using the navmesh?
like, if its gonna reach a path that is blocked by something and the only way to pass it is by jumping over it
right now I only know how to make it jump when needed only if its following a target that is right in front of it
the answer would probably be Nav Links, but I want a more dynamic method
If the obstacles aren't changing the navmesh you would probably need to have some kind of system that can detect it either via linetracing or collision
yeah, but it also needs to know if it has to go through the blocking object
so the line trace doesn't stay enabled all the time when the ai has to use the navmesh to navigate
Well yes and no, if your obstacles aren't dynamically affecting the navmesh, they are in essence invisible to navigation so there's no way for the nav system to know when one is in the way
So one way to work around it is to set up a system that would constantly scan in some way like a trace or through collisions whether you're bumping into something, and you would need some kind of logic then to determine what to do about it
actually, now that I think about it, the path trace will start moving to the side of an object by a few meters right? meaning that I would need to make the line trace short enough so it won't hit the object that does not block the path
I think I might be getting to something
iirc there's an event on the path finding comp that will trigger if it's unable to continue moving as a result of being blocked which might be useful also
if only I could work with c++.... cause with blueprint there's more calculations to be done because the huge amount of c++ lines blueprint nodes have
yeah, there's the AI Move To node that has a enum output
but I think the enum fires only once?
Could be, can't recall the specifics. It might be you can read it on the move failed pin
but yeah there's a few more things in C++ for this, like the path finding comp bits, I don't think they're BP exposed
a shame epic hasn't made more useful blueprint nodes....
just export the nodes yourself?
Rather than lone trace checks etc, isn't it easier to have a nav modifer in the obstacles with some custom nav area? If the obstacles nav mod volume is wide enough to encompass the obstacle + some more you should be able to detect when the character enters that area (checking the nav area flags on the nav where the AI stands). If it's over an obstacle area, then decide what to do. With path filters you can ask the movement component to calculate paths that can go through obstacle areas or not. That way you have AI's that go through and others that go around.
There will be some problems with how aligned the character is towards the obstacle (ai might walk next to an obstacle, entering its nav area, but not toward it, just passing by. Those you want to ignore)
If you could use c++ you would be able to check the next segment in the path (within path following component), and detect if it trayectory passes through an obstacle (line trace form the hip for example in the direction of the path segment). If it does, then you can trigger some other logic that gives you the contact point to trigger the jump over animation or whatever
Still would be a good idea to make obstacles use a nav modifier in case you want enemies that go around (using nav filters when pathing)
similarly if these are static obstacles, navlinks are a good way to get ai to jump them
my only point against nav links is that, if you have an obtacle that is a cube, you need to add at least 2 navlinks: one to cross it North-South and another to cross it Weast-East. More over, each shape will need its own config. If an artists changes the asset, they will need to re-visit how nav links are setup. If you also want other directions to cross over, you need to add more nav links.
With nav areas and knowing where the center of the obstacle is, it's realitevly easy to make it general to any shape and approach direction
Anybody here has tried to construct a State Tree from code in runtime?
I'm playing with the idea of having a state in a tree that has other children states. Each of the children would be a subtree. The thing is, not all AI's would have the same subtrees to run.
Something like this:
Root
EvaluateSubtrees
Subtree
Subtree
Subtree
DoOtherStuff
SomeOtherThing
I would like to dynamically set the children of EvaluateSubtrees, but no idea if this is possible or not.
If not at runtime, at least have some editor tool that will read data and create the asset. Does anybody know if that's possible?
I would imagine that I should be somehow use this type of functionality
I should add "AI Perception Stimuli Source" just on AI or I can add on Player ?
If it has to be a stimuli source, then yes -- add it to the player
Note that by default (IIRC) everything is treated as stimuli source, so you would need to disable that setting to have a manual control over that
All Pawns are stimuli sources by default (such as Characters), it can be disabled via editing config files https://zomgmoz.tv/unreal/AI-Perception/AISense-Sight#turning-off-pawn-autoregistration
Does anyone know whether there's a delegate to notify that a dynamic navmesh was regenerated? I'm trying to recompute AI path when I update my environment, but doing that the same frame it happens on doesn't work as it uses the old navmesh data. Using a delay works, but I would like to be extra sure that it uses the new version
There is an OnNavigationGenerationFinished delegate on the NavigationSystem, it may be what you want.
I'm having a navmesh inconsistency on runtime.
If you look at the navmesh before playing, the path is is separated at all, however, when I run the game, and visualize the navmesh using show navigation, it's sliced right there. There's no other path like that in the entire area I have, even in paths that are way more narrow than that. The landscape is flat enough to not cause any issue either.
Does anyone know what might be wrong?
Nevermind, moving the collision (orange boxes) and CtrlZ did make it work somehow π
Hi, Does anyone know how I can rotate a sense's detection area ?
let's say I have an AIPawn that I want to be stationary but look around(search an area) using an animation. I want the sight's area of detection move left and right based on where the pawn is looking when playing the searching animation. but I dunno how, is that doable ?
Override GetActorViewpoint or something like that and return the vector of a socket that is attached to the mesh. So put a socket on the eyes and return that.
thanks! I will have a look
Anyone knows a solution to NavWalking mode in CMC gets stuck because its out of nav bounds? (not horizontally, sometimes characters fail to spawn in navmesh and half of their body is below of the landscape)
I tried to call FindFloor and FindNavFloor to snap them to navmesh but doesnt seem to work
and since its difficult to reproduce I cant debug it
what is the best way for set players in multiplayer game as target for enemies ?
There is no "best"
what is better?
Than what?
for example in perception sight
I have no idea what game you're doing.
I have no idea what you want
I can't help you if you are just asking for some arbitrary "best" or "better" thing with no other information
No one can
Use perception
There
Use perception and then slowly build from there
if player run select nearest player again as target
Then do that?
i had this same issue
do they fall through floor whilst moving
or just when your spawning them?
i think both
once they switch to navwalking we find at least a few characters fell down
well the first most common issue is not enabling the nav projection
in the cmc
this will 100% result in your chars falling through the terrain
bProjectNavMeshWalking should be true
and we do it on both channels but if your certain everything is world static then you dont need too
bProjectNavMeshOnBothWorldChannels
saw that just after sending the msg here, in case if it doesnt work whats the CMC-way to snapping chars back to ground? I want to reproduce the effect when you drag drop a character to floor it snaps capsule's lower tip to ground
I thought calling FindFloor and setting actor loc to found floor loc would work
but didnt yield any results
so we do projectlocation to navmesh
then we call World->FindTeleportLocation
we also have this function
FindTeleportLocation is custom?
bool USolsticeUtilityLibrary::AdjustActorSpawnLocation(const UObject* WorldContextObject, TSubclassOf<AActor> ActorType, UPARAM(ref) FVector& InOutLocation, bool bProject, FVector VerticalAdjustment, UPARAM(ref) TSubclassOf<UNavigationQueryFilter> NavFilterClass /*= UNavFilter_IgnoreNonFloor::StaticClass()*/)
{
QUICK_SCOPE_CYCLE_COUNTER(STAT_USolsticeUtilityLibrary_AdjustActorSpawnLocation);
FNavLocation NavLoc;
bool bSuccess = true;
if (bProject)
{
const UNavigationSystemV1* NavSys = USolsticeObjectLibrary::GetNavigationSystem(WorldContextObject);
if (!NavSys)
{
return false;
}
const ANavigationData* NavData = USolsticeObjectLibrary::GetNavigationData(WorldContextObject);
if (!NavData)
{
return false;
}
if (NavFilterClass == nullptr)
{
NavFilterClass = UNavFilter_IgnoreNonFloor::StaticClass();
}
const FSharedConstNavQueryFilter NavFilter = UNavigationQueryFilter::GetQueryFilter(*NavData, WorldContextObject, NavFilterClass);
bSuccess = NavSys->ProjectPointToNavigation(InOutLocation, NavLoc, NavData->GetDefaultQueryExtent(), NavData, NavFilter);
}
else
{
NavLoc.Location = InOutLocation;
}
if (ActorType && ActorType->GetDefaultObject<AActor>()->GetRootComponent())
{
if (const UCapsuleComponent* Capsule = Cast<UCapsuleComponent>(ActorType->GetDefaultObject<AActor>()->GetRootComponent()))
{
VerticalAdjustment *= Capsule->GetScaledCapsuleHalfHeight();
}
else
{
VerticalAdjustment *= ActorType->GetDefaultObject<AActor>()->GetPlacementExtent().Z;
}
}
InOutLocation = (bSuccess ? NavLoc.Location : InOutLocation) + VerticalAdjustment;
return bSuccess;
}```
// Adjusts the InOutLocation vector Z component to be half capsule height above the navigation mesh
UFUNCTION(BlueprintCallable, Meta = (WorldContext = "WorldContextObject", Category = "Spawn", AutoCreateRefTerm = "NavFilterClass"))
static bool AdjustActorSpawnLocation(const UObject* WorldContextObject, TSubclassOf<AActor> ActorType, UPARAM(ref) FVector& InOutLocation, bool bProject = true, FVector VerticalAdjustment = FVector::UpVector, TSubclassOf<UNavigationQueryFilter> NavFilterClass = nullptr);
also engine has FindTeleportLocation
we use
* Try to find an acceptable non-colliding location to place TestActor as close to possible to PlaceLocation. Expects PlaceLocation to be a valid location inside the level.
* Returns true if a location without blocking collision is found, in which case PlaceLocation is overwritten with the new clear location.
* Returns false if no suitable location could be found, in which case PlaceLocation is unmodified.
*/
bool FindTeleportSpot( const AActor* TestActor, FVector& PlaceLocation, FRotator PlaceRotation );
its in world, so GetWorld()->FindTeleportSpot
@celest python
FVector USolsticeUtilityLibrary::FindTeleportLocation(AActor* Actor, const FVector& InLocation, const FRotator InRotation, bool& bSuccess)
{
if (!Actor)
{
bSuccess = false;
return InLocation;
}
if (UWorld* World = GEngine->GetWorldFromContextObject(Actor, EGetWorldErrorMode::LogAndReturnNull))
{
FVector Loc = InLocation;
bSuccess = World->FindTeleportSpot(Actor, Loc, InRotation);
return Loc;
}
bSuccess=false;
return InLocation;
}```
this is the static we made for it
UFUNCTION(BlueprintCallable, Meta = (WorldContext = "WorldContextObject"), Category = "Solstice")
static FVector FindTeleportLocation(AActor* Actor, const FVector& InLocation, const FRotator InRotation, bool& bSuccess);
```
you're awesome, thank you very much π
21 CMC costs 8ms on ryzen 2600 
had to go through navwalking pain
Even on my Ryzen 1600, I was able to get more than 21
anim bp affects CMC overhead directly
our animbp costs are quite low
though we use worker thread for all calcs
and our animgraph is all fast pathed
with 0 BP calls
appearently there is even a way to skip evaluation and set the pose directly so you avoid tree traversal cost in anim instance
in case if its interesting with red solstice 2
not really needed, 100 monsters on screen costs us next to nothing
with budgeted skeletalmesh
how about pathfind requests
they should be costing a bit
even on async
yeah but we dont send 100 path finds every tick
also path find cost is related to your navmsh resoloution
the more precise the mesh, the more it costs
our navmesh is very broad
which does have some minor quirks, but its super fast to build and path find on
probably those minor quirks are UE implementation of recast induced π
hi! I've parent blueprint base mob and child bp wolf, and i wonder is there approach to create like base animation blueprint, i want to use a lof of mobs, but only 4 animations, and each mob has diffrent skeleton. So i need to create each time anim bp for each mob and copy paste the same logic like from idle to walk velocity and etc...
This isn't an #gameplay-ai question, but an #animation one. But yes, you can. I think they're called animation templates. When creating the ABP, there is another tab you can use that is skeleton agnostic.
Then, you'd just create child ABPs from this template.
I have added in a nav mesh modifier volume set to obstacle in hopes of ai avoiding it. But if the ai does go inside, they just stay there. How can I go about telling the AI to get out as soon as possible? Cause in my case at least they take damage in that area.
Any why do they stay there? Is it their path goal? You could always detect when they get into a they specific nav area y path outisde it or detect the damage and check for how long it have been receiving damage or the total damage accumulated of that type and path your way out
Hello everyone, I made custom Navlink to launch my AI enemies between platforms. There are 25 AI enemies which are following me. Usually chokeholds occurs in navlinks' start or end location and enemies get stuck. Do you have any suggestions?
I'm trying to set collision ignore for the pawn channel (so they ignore each other) for a duration when they touch the navlink. it helps but I'm still having problems.
Are you processing the AIs on a separate worker thread?
(apologies for the double ping) do you just mean your BPs dont tick?
any one have a reference, tutorial, document, guide ... for DetourCrowdAIController?
If you haven't seen this yet you really should. Apparently UE 5.5 is going to have automated navlink generation. This is so freaking cool! I've spent so much time fine tuning jump links and can't wait to use it on future levels.
https://x.com/HoussineMehnik/status/1838420710735134739
Some wild ideas:
- you implement a queue system so they patiently wait in line until they can use the navlink
- when starting the game, each navkink calculates 10 pairs of points. A pair has 2 points, one on each side of the nav link. You calculate them in the vecinity areas of the nav link real stsrt/end. When an AI picks the navlink, you address them (aka replace points in the path the follow) to the points of the choosed pair. Make sure your pairs are parallel to avoid AI's crossing each other mid air
our ai claims navlinks
once a navlink is claimed, another ai cant useit till the first ai unclaims it
claimed navlinks are then not allowed to be pathed
thats because the nav link is the only route across, so of course it causes a bottleneck.. you can add more links or build a different system from scratch to deal with disconnected navmeshes, or extend navlinks as bruno suggested
ultimately tho the reason the bottlneck happens is because navlinks only provide a singular route through between navmeshes, so if there's only one link, EVERY path that crosses those platforms will have to go through it
Getting an issue where when trying to use the ai move to node with a boilerplate character pawn with no code and the ai controller set to mine and a boilerplate ai controller with only an event tick that calls ai move to with the dest set as 0 0 0. It crashes immediately when the node tries to run. I am on 5.4.4 if this makes any difference
Not sure why it's crashing but calling move to on tick is rarely a good idea
Are you null checking the controller and character too
Although that doesn't typically crash in BP it's possible that move to node is missing a check
Hey ! I would love to know about that as well
I have parked the idea for now, but there's a file called StateTreeTest.cpp where Epic constructs one from code. They add transitions, linked state trees and what not
Has anybody tried to have 2 State tree components running different trees on one single character?
It seems it should work but, when you do it, the second tree will not initialize due to this (image)
It seems the first entry (of two) is not valid.
I have no idea what is this refering to
It should work yes
I think what that code is doing is checking whether the state tree context or something like that is valid
Or something along those lines
you nailed it. I had set something wrong in the Schema.
Thanks for the answer!
Hey! I have a quick question! Actually I'm using a floating pawn movement component for a lighter AI, but I need to implement the RVO avoidance interface, have some people implemented it already or do you have any advice on how to implement it? I'm trying to see some implementation examples on the CMC but if I do the same thing I just need to go back to a CMC. I may have misunderstood how to integrate the interface but basically I shift the interface definitions I register to the avoidance manager and I did an update of the RVO but it doesn't change anything
Any ideas/recommendations for big numbers of enemies using Behavior Trees and EQS queries?
I have implemented a system using those for AI enemies as well as a custom perception component, however I am not sure if it will be optimized enough for 50-100 enemies.
I will test it myself, however I want to know if you guys happened to have any recommendations.
Just looked up and saw this message. Is this still plausible? π
tbh ai wont be the perf bottleneck you hit with 100 enemies
it'll be the pawn animation, physics, etc that will cost
So I am trying to replace the base class of my AIController BP with my own C++ AIController class so that I can add functionality to all of my AIController BPs at there base class. That's all fine and good except that when I reparent the AIC BP MoveTo no longer seems to work anymore... I've since tried overriding the MoveTo just print to the log and then call the AAIController::MoveTo, but it's not even printing anything to the log, but I see the Behavior Tree leaving that Sequence immediately after the MoveTo call making me thing it's the MoveTo itself that's failing. Any ideas?
Just for sanityβs sake. Did you change the AI controller to the new one in game mode settings?
If so, use visual logger to see what exactly is causing the move to fail
As far as the pawns are concerned itβs the same ai controller, I just changed itβs parent class to my C++ class instead of the base one. How would I use the visual logger to see what is causing it?
hmm... when I changed it back to the base class it does in fact fix it
so it's something with my C++ AIController for sure... think I'll make another one as simple as can be and if that works, slowly add funcationality until it break again...
Don't worry, the Character movement component will kill your framerate before that becomes a problem.
You should still be able to get a good number
But worst comes to worst, you can just make your own basic movement component.
Depending on your needs - it isn't all that difficult.
Ok, it seems to be something to do with my override of the OnPossession... weird... I'm just doing the super and the then creating a timer...
In my experience, it's incredibly hard. Handling detecting floors and ledges, different movement modes, network support, collision detection.... It's not a small task.
My advice would be: before doing your own, you might want to try some optimizations in the existing one or try the new experimental movement component (Can't recall what was it called, there was a talk in unreal fest Prague this summer about it)
That's why I prefaced with "depending on your needs". Because it is quite easy if you just need something like the floating pawn comp but with gravity.
And using Mover 2.0, perf isn't supposed to change much from what users have said
It isn't going to be the silver bullet
for what I saw in the talk and couple questions I asked, performance is way better. But all I know is from what Epic told me, never tried myself.
I read some time ago that Square Enix modified the current CMC heavily and they made it super light for the FFVII remake.
Would be nice to see what and how they changed it
I don't care what Epic says. I care what 3rd party says.
I would like to see some side-by-side insights captures of a test project using one or the other
Btw, there's this playlist with a very in-depth explanation about how the cmc works. It's quite nice
https://www.youtube.com/watch?v=urkLwpnAjO0&list=PLXJlkahwiwPmeABEhjwIALvxRSZkzoQpk
https://discord.gg/uQjhcJSsRG
In this video I am introducing a series I will be making which explores the character movement component and how you can extend it in depth.
0:00 Intro
1:00 What is the CMC?
2:00 Do you need a custom CMC?
5:35 What does the CMC provide?
7:10 Outro
I got my thing... was a stupid mistake, thanks anyways^^
what was the problem then?
I see, so BT and EQS are generally performant, it's the character movement component that I should keep in mind
well... not an straight answer but, when dealing with big numbers, CMC will be the first bottleneck. Once you improve that as much as possible, you will see other things.
EQS are tricky, the are async but they run in the game thread. They are optimized by checking the budget per frame.
They execute doing something like this:
- run a test
- check how much of the budgets is left
- budget left? run another test.
You probably noticed you can assign a category to each test defining how expensive it is. That's the only check they do towards the next test.
The problem with that is that, if the budget is 10ms (not sure how much it's in reality, but bear with me), the first test might have taken 5ms. The engine would say "great, 5ms left, run the next one", but the next one might be doing some crazy stuff and take another 10ms, going out of budget.
Those are the ones you want to control. There's a log warning when you go overbudget with EQS's
BT's are... depends.
Dynamic injection to run trees is expensive. Single run trees too because they get instanced constantly.
Aside that, they are more or less performant. It will be whatever you do in your decorators, tasks and services what will increase its consumption
Unfortunately, there's no magic rule.
There are some talks here and there about general optimizations in AI's that are more or less applyable to every game but, in the end, you will have to inspect your game with Insights and tackle down each problem at a time.
Chapter 20 in this book talks about Level Of Detail in AI Systems, which will help your case. If you can't afford the book, there are things here and there over the internet
https://www.routledge.com/Game-AI-Uncovered-Volume-One/Roberts/p/book/9781032343235?srsltid=AfmBOooqmjAOb4mtS5--EzOXC8vAW6CDwjCBDs1mNCS2lGbGhgRHwivg
Game AI Uncovered: Volume One kicks off a brand-new series of books that focus on the development of artificial intelligence in video games. This volume brings together the collected wisdom, ideas, tricks, and cutting-edge techniques from 20 of the top game AI professionals and researchers from around the world.
The techniques discussed in thes...
Thank you a lot for the info. Will do as you suggested! Also will check out the book.
That series is good. As good as Game AI Pro. They are releasing new volumes now and then
Also if you use bt make sure you put common actions first to avoid tree searches. Use selectors and sequences properly to avoid tree searches. Avoid BT based decorators as they can be expensive
Yeah I use BT and EQS for picking targets and other tests.
There is the option of State Trees too which are simpler but I am personally new to them and prefer BTs. Not sure if state trees bring a significant advantage over BTs performance-wise.
I mean it all depends I have BT running super fast 600 ai at about .4ms
By optimising if the tree is ticking or not based on enemy state
with EQS queries as well?
If the trees are constantly searching then you will hit performance issues
It's all about only making the trees do work if they need to
Same with eqs you only want to do eqs when needed
And we try to avoid going path finding tests in eqs but just use projection as that's cheaper
But like I said. Performance comes down to how well you manage the stuff. People commonly just have the BT constantly searching through this is bad for performance
Even a small random delay can help improve your fps on certain things
I see. So make common actions higher priority so the trees don't get evaluated entirely.
Is using Subtrees alright? It's mainly for structuring purposes and makes things cleaner instead of having one big BT, but not sure if they add too much extra work.
in reality ai ticks can be very infrequent, think about it as only really needing to tick the behavior tree when you need to make decisions
most resulting work the bt decides to do take time to execute anyway, and you dont really need to execute a ton of ai logic during those actions.
impressive. Is this a released game I can check out?
Hi I want to create my first mob for a project but I havent idea and IDK what should I do...where do I start
I mean that IDK a good basic mob what should it have?
Impossible to say
Depends entirely on your game
And only you know what you're making.
thanks
yes this link can be good start for good idea thanks
I'm currently spawning a lot of AI in the world. That is of course expensive. What is a good way to have the AI be off / not computing while not visible or too far away? Or is there an even better option?
βA lotβ and βOf course expensiveβ are not technical terms
Whatβs a lot? Did you actually profile to see if AI is the issue? Usually itβs the movement components, animations, pawns themselves, etc.. There are some optimizations you can make but do the legwork to find out where the problem is first - if you havenβt yet
Over a hunded. I didn't think it mattered how many, I've identified that's the problem. I'm just not sure on the best way to implement the solution. π
You may have missed my second point. When you profiled, what, precisely was showing as high ms?
I didn't profile. I had fine performance. I 5x the enemies, performance dropped. Didn't really need to profile that.
Ok, yeah I'm not sure what you're trying to explain. Sorry. I understood you want me to profile to see where the performance cost is. I just want to know a good way of disabling / reducing AI performance when far away from player.
My point was the AI portion of the code is likely not the performance hog at a few hundred AI controlled units
Itβs usually something on the char/pawn itself like animations, movement component bloat, etc
Yeah, I understood that. Hence I'm looking for a way to have the character not be a character basically at far away. It eliminats all of that.
You have to profile so that you know what is slow
with 100+ enemies the bottleneck is likely the cmc, animation, etc
but profiling will tell you where to aim optimizations
Yeah, but if I replace the character with a box, then it doesn't matter if it's animation, or ai or whatnot, cause it eliminates all of that.
profile it, and you will know.
you have to profile it to know what to optimize
there's no magic here, you have to analyze your game with quantitative data to understand what to focus on
I get that, and lets say I find out it's the characters. What I'm trying to figure out how to do doesn't change.
Even if I figure out the characters are pefect and cost nothing, I still want to figure out a way to hide them at a distance.
well thats a bit more general than ai, but the general idea is not that different from LODs
distance/fov based, adjusting tick rate, etc
Ok cool. Good to know. I wasn't sure if there was a trick I might have missed. Thanks!
honestly profiling data will tell you where to work
it may not be something you need to do, maybe some bottleneck exists somewhere else
It's also a visual thing, not just performance for me. Hence the performance is a nice bonus.
i mean for the visuals let the LOD system deal with that
Take a look into the significance manager. It's a way to control what should be active based on rules in Unreal. One good rule is "distance to the closest player". But as people told you, you should profile a development build with insights to get a general idea of what is expensive before doing a LOD approach. You might have some BP doing crazy stuff and that needs to be addressed regardless the LOD.
Chapter 20 here explains things in detail agnostic to the engine
https://www.routledge.com/Game-AI-Uncovered-Volume-One/Roberts/p/book/9781032343235
Game AI Uncovered: Volume One kicks off a brand-new series of books that focus on the development of artificial intelligence in video games. This volume brings together the collected wisdom, ideas, tricks, and cutting-edge techniques from 20 of the top game AI professionals and researchers from around the world.
The techniques discussed in thes...
Thanks I'll check it out!
Updated the answer a bit
How do I handle situations, when 1 NPC is stuck in MoveTo when surrounded by other static NPCs? Crowd following doesn't seem to help in this case or I might have misused it somehow. In this case I have a patrolling squad when 1 NPC is a leader and some NPCs are following it. I'm going to add some logic for subordinates to disperse around when staying at patrol point which's going to solve this exact case, but it won't solve the fundamental problem of NPC not being able to bypass such circle of NPCs nearby π€
Anyone already tried to log through the StateTree Debugger thanks to macro TRACE_STATETREE_XXX ?
I don't get which module i should add to my plugin to make it work π€
StateTreeModule is not the right one
Can i use Async Tasks in Blueprint BTTasks?
what are you trying to do?
the dumb solution is let npcs pass through eachother x_x but maybe that isnt ideal ahha .. some games will push ai out of the way, maybe that's an option? Maybe look at the RVO avoidance stuff?
Where are the macros? The class I mean. Either it's within the StateTreeModule or StateTreeEditorModule (if it's within the time line code). Not at the pc now, but I could swear it's within the state trees module because it's used from within the Execution context class
If you manage to use it effectively and you see things in the debugger, can I ask you the favour of sharing your results and code example here? I'm curious about it (currently dealing with debugging systems in state trees)
You (or... they) can look at my plugin here: https://github.com/Vaei/PushPawn
It gives: Net predicted collisions which means AI won't desync you when walking through you (on the server), organic soft-collisions that feel a lot more natural vs the brick wall that Unreal gives you, and the ability to push other pawns out of the way including the ability to respond to it (play push animation, make them get annoyed, etc.)
I use it in SP games as well as MP
It would resolve the situation they're encountering as well
@keen crow
Its production ready/tested/used, not like most of the amateur stuff you find on MP
Its also completely free/MIT
I should probs update the (old) readme for that
not sure what the ping was for, generally im good tho, i've built many systems like these, esp with player replacement ai
Not sure why you're not sure what the ping was for, I provided a working solution that doesn't require your suggested solution
Just not having collisions isn't a great option for a lot of games
And it lets you do what you suggested, pushing AI out of the way
i dont need anything?
and the first thing i said was that not colliding was not a good solution π
If you don't want pings you can turn them off
that isnt what im saying.
Umm ok
Anyway good luck
like i was saying, you probably meant to ping Reddification, i have no need for this or interest in looking it over.. as i am not the one with the issue
So don't? Why are you getting upset about me replying to you without disabling the ping feature
It's completely relevant to the conversation
I don't maintain a list of people who get precious about that stuff and I'm not going to π
This is too bizarre for me so I'm done here
i dont care about pings, but i expect pings to have relevant information to me, and it didnt heh so it was weird to get a ping for something that didnt apply to me
@vivid fern hi π
