#gameplay-ai
1 messages Β· Page 12 of 1
Is there a way to reset navmesh settings to default ?
π I tend to have a blank project to reference the default values
I wish they had those yellow arrows to reset
is there an easy way to disable the obstacle check on the AI sight sense?
Today I thought about a crazy idea like parsing FMath and FVector and converting each util function to ST conditions
So I wont have to write functions like this manually
Once I saw a wacky BP node that just has C++ text in it that changes the file on your system when you change it
I wonder if you could just have a little dinky textbox that raw edits the condition of that statetree?
Probably not worth the effort
MagicNodes?
Aren't all nodes magic?
@celest python Trying to do a task in C++. I keep getting an error on compile for the state tree. "missing instance value". I thought implementing this virtual const UStruct* GetInstanceDataType() const override { return InstanceDataType::StaticStruct(); } would've handled that. What is the minimum needed in order to do this?
USTRUCT()
struct FMoveTaskInstanceData
{
GENERATED_BODY()
};
USTRUCT()
struct FMoveTask : public FStateTreeTaskCommonBase
{
GENERATED_BODY()
typedef FMoveTaskInstanceData InstanceDataType;
FMoveTask() = default;
virtual const UStruct* GetInstanceDataType() const override { return InstanceDataType::StaticStruct(); }
virtual EStateTreeRunStatus Tick(FStateTreeExecutionContext& Context, const float DeltaTime) const override;
};
This is what I have. I copied from DelayTask
Why all the love for StateTree recently? something happen?
Ooohh shiny pretty much
Fair enough π
Jokes aside - I am doing it 'cause Eren is doing it. No real reason otherwise π
I just randomly decided to do it last night. We're both making zombie games. So I was just like, ehhh - screw it. I'll join in on this journey with you
Isn't literally the whole channel making zombie games?
Are there other types of games to be made?
Oh my π
I've got to spend more time with Houdini, more time with NLP, more time with geometry scripts.. more time with ML code.. I guess can't hurt to add StateTree for giggles π
BT's are fine.. I'm not a fan of the UX though π
I guess in order to actually update the task, you have to remove the task from the state and then add it back (after changing some .h stuff in C++ that is)
I swear - I'm like one of the only people here who do like it π€£
It could do with a usability overhaul is all.. the basic concepts of BT's are easy enough
although hardly anyone seems to get them π
And personally, I'd have wanted better parallelism
But the amount of pain people seem to go through with BT's in UE is probably more a UX issue
I think thats true of UE in general though.. wonky naming, weird conventions, inconsistent UI etc.
The fact that different node editors do different things because they were made at different times by different groups of developers..
comrade
I never got this error before, is it coming from compiler or StateTree in editor somehow?
oh yeah its statetree's compiler
it checks !TaskNode.Instance.IsValid() && TaskNode.InstanceObject == nullptr
if returns true, throws that error
i have two tasks with exactly same format - except my instance data struct has properties
in your defense it magically started to work a few times for me too
after doing nothing
One does not simply do nothing.. one must BE nothing for it to work
real question is, zoombapup... π
did you get any ideas about how verse will work as AI scripting language?
from that.. very scientific paper and slides
I'm curious of your opinions
FP as an AI scripting language
No, I ran away from it hard
functional languages hurt my feelings
Besides, I've got other fish to fry.. I doubt I'll be adopting a new language anytime soon
hard enough putting up with the smell of python
Look at their examples though, its going to be a cold day in hell before most UE users adopt it.. unless someone manages to convince Tim S that documentation is a good thing out of the blue π
Which seems unlikely
i mostly wonder functional programming itself can be useful for AI scripting
Well, prolog was one of the initial AI languages, so yes it can
verse inherits some prolog features too
But I don't think it has the right mindset.. games are largely event driven.. functional languages are mostly data driven
I guess we'll see.. I'm sure it will work, but work nicely?
If literally every other game engine adopts it as a language then MAYBE
which scripting language is your favorite for game AI? I also know you dont like lua
but.. given the ML world literally adopted the worst language ever as its defacto standard (python), I'm not hopeful for rationality to win out
you mentioned AngelScript a while ago
yeah pretty much "C# at home", and very C-like
There was one called GameMonkeyScript that was fun π
I think honestly my favourite language is C#
so if someone made an unmanaged C# with pointers.. I'd be on board
I guess everyone with experience in this server favorites C# π
The reason I like C# is mostly to do with the lack of header/cpp and the like
the language itself is near enough to C/C++ but without the shitty syntax
$&^^ crap
you get first class delegates, properties etc..
linq is also hella cool for inventories
and lambda's in C# don't break my brain the same way they do in C++
Don't get me wrong, I still hate it, but I hate it less than all the other choices
python is an abomination
π
Seriously.. its so bad π
scientist like it... 
Scientists aren't programmers obviously π
you have a point 
Btw: Houdini indie is free for the next few months.. if anyone wants to try a node based geometry thingy
as part of GGJ they're giving a license
Do recommend playing with it
Cascadeur is also v1 now, worth a play
that crap is pretty critical to how data is moved and referenced
True, but it isn't "good" its obscure crap because of the language.. making different choices for language design is the point
not sure if obscure is the correct term
You know what I mean though..
it just sounds like you don't know about how it works π
Its more that when you work with students, you feel the pain of someone new to it
so yeah, C# is easier because it manages stuff for you
yea there's a reason why java was the freshman language instead of C when I started in university
Java has its own can of worms too π
I was trying to explain aspect oriented programming to some second years struggling with pointers a few days ago
got me thinking about a bunch of these pain points
given we're teaching OOP, but the game industry is desperately trying to ditch it for perf reasons
well, not OOP per-se, but the idea of large monolithic classes (AActor etc)
Unity just made their DOTS thing a proper thing.. UE introducing Mass etc.
Its yet another concept that people have had to learn and then learn its not good π
"Here's how to write a class"
the game industry is desperately trying to ditch it for perf reasons
finally we see the light.. slowly
"oh by the way, classes are way too slow now, so lets break the class apart" π
You can forgive people being a tad confused
classes are way too slow now
data is slow?
Maybe I should teach Mass and StateTree in my graphics class π
large classes that don't fit in cache π
sloooow
but its about how you evaluate rather than size of the class π¦
even with oop, cpu should try to fit things you access over and over afaik
so rather than class size itself the amount of data you are evaluating should matter
the point is to try and package up one aspect and iterate it in a tight loop all at once in-cache
and ideally in parallel across cpu threads
along with parallel GPU versions of same
its not an OOP problem per-se
but it kind of stems from the way that OOP is taught
i.e. "bind all your functions to your data"
oop makes things difficult to thread
big blobs of oopy goodness
unfortunately big oop blobs mean terrible perf π
I could generate some big oop blobs for a lecture π
turns out that the C guys had it right..
rust
it doesn't really work that way, memory if fetched linearly, so yeah one object can fit into CPU cache, but the next one might not be the one you need, cache need to be evicted, and next chunk of memory fetched.. Which still might not be the one that is needed
that's why usuall OOP design is bane of peformance
i didnt know "object"s fetched to memory completely
i though the "instruction"s matter
rather than object itself
i simplified it
in general
imagine memory as cells
cpu fetches X cells forward
it doesn't care what is inside those cells
if there was nothing usuful for current context, well though luck, evict cache and fetch next cells
is there a way to "breakpoint" CPU reads? would be super useful as a learning resource
you can monitor cache hit rates
and debug them
but never accurately
btw @echo lark since you are here..
as usual I was roaming around yours and vblanco's message history and found you mention something about "vectorVM" -- but you refer it as "VM behind the BP", isnt it specifically created for niagara?
this night spent a few hours with vectorvm's source code
you could be right, I honestly don't remember
ah, alright. I'm just generally curious about BP's VM and other VMs used in the engine
just wanted to ensure I'm not missing anything π
do Epic ever upload those things to P4?
probably will drop in sometime next year
no
it is developed on fortnite stream
sometimes something leaks to github
;d
π so they were not intentional
, yeah well sometimes you need to make change to main engine it is just auto merged
to be honest I'm very hyped about Solaris, it was first mentioned at 2019 without a name
2019 also when epic had a deal with shookumscript
it's for Verse
i hope verse/bp mix VM comes out of it
vblanco said BP might be transpiled to verse
for nativization purposes
the idea of not switching to C++ each time I need to loop an array more than 10 element excites me a lot
@dawn schooner https://github.com/InsomniacGames/ig-cachesim
grat thanks!!
valgrind equivalent works for windows 10
and it.. something like emulates PS4 cpu
so you'll debug your hit rate on lowest common denominator
it also can display where hit rate is low on your code
etc
existence of tools like this proves to ship PS4 successfully you need to take care of your cpu caches and threads, tbh π
because all related tools come out from console developers
How can I get nav link proxies to work over large gaps?
It seems that the range is very low, surely it is possible to account for large launch pads and such that AI can use to traverse a map?
Have you looked at the "Beef" language? Silly name, but it is modeled quite heavily after C#.
I'm waiting to see real-world examples personally. That talk was aimed at language designers and what not.
why do i run into a lot of problems trying to spawn an enemy with AI after a time
and it works fine if placed before run
i solved it
weird stuff
oop is bad now?
oh yeah thats fair I suppose. Can scope alot of behavior out of giganatic classes into components, utility objects, blueprintlibs, gsa abilities, ect nowadays
classes with thousands of lines are so much fun to comprehend
Its more about not having enough cache mem to keep them in cache while iterating.. if you want tens of thousands you really only want the smallest set of data to calculate and you want to do that in a tight loop across every entity for that aspect at once.. basically what Mass is trying to do
So its only a bit of a side effect that the code often seems a bit easier.. I guess its a natural evolution of components
But I read about this kind of thing years ago.. when looking at data oriented programming and then aspect oriented programming
You'd think.. but no π
Its a bit weird.. because we still teach old school OOP, but that's still the "standard" method if you're not about performance
But then, people use python, so who cares about perf π
perf is only a problem if the profiler tells you it's a problem tbh
for the applications python is used for developer time is much more expensive than cpu time
technically true.. but imagine all the crappy python code out there in the real world.. slowly killing all of the CPU's and making Santa cry... all... slowly... like molasses
actually let me remove those conditionals lol
developer time is much more valuable than cpu time
pfft, I'm not a fan of that idea.. so you're ok with everything just getting slower and less responsive as long as some no-code idiot can do it?
that's where that heads
nah. people have a tolerance for performance that doesn't change
eventually it'll be your mother "coding" your life support machine and it'll only be able to pump once a minute
then we're in the realm where html is "coding" again π
the industry simply tries to hit that equilibrium
@verbal shore How much slate you wrote for the "Parameter Groups" thing? π
https://www.unrealengine.com/marketplace/en-US/product/behavior-tree-extension
looks damn cool btw, solves one of the main problems of the BT. I might buy it in the future
processing power goes up -> optimization goes down -> fps/responsiviness stays within the range people can tolerate
Thanks! It's like %70 of the code haha
course AI coding threatens to upend this whole thing
cheap/fast developer time producing highly optimized code
Injecting values, running behavior trees were not that difficult but dealing with slate was a nightmare.
Looks kind of like someone redid some of the UX π
why not? it makes BT more instance-node based and removes the repetitiveness
but that sort of thing shouldn't even be in the behavior tree
no? it exactly how BT should have been at the first place
1/2 of my obsession with ST comes from the flexibility of how you control the data and params
walk speed is a character property and attack on sight is a controller property
its composed to AI tool that way
easier to work with imo
i exactly follow same pattern
that way you only get to care about the AI graph
so BT somehow becomes the "controller" of the AI
thats disturbing but you do you I guess
I was doing the same thing with data assets, then I thought maybe doing it within behavior tree would enable more possibilities and it did
Yeah, I'd rather BT was decision only.. certainly wouldn't try and tie in animation control and such
that feels exactly what you were complaining about earlier zoom lol
But hey, whatever floats your boat
I can create behavior trees for combat, for patrol behaviors etc. and reuse them as many times as I want while being able to tweak the settings for each AI character
Yes, but then you need some object to feed those values
this is what my behavior tree looks like lol
that thing is still there? 
I've always had a seperation from my logic and my execution, so that I can feed the execution from outside the logic
i also have something similar to this, but i use data assets instead. state of the BT affects the character movement properties and state machine on anim graph that way
PaintRoam?
poorly named
PaintRome?
WhileRoamingPaintEnviroment would be too verbose
probably should be a task as well but I dislike using parallels
Yeah, that's how it works in my case but it's just exposed to Run Behavior task node π
I remade my AI systems for like five times since I started working on my project and this is the best outcome I came in terms of comfortably designing them
Are decorator variables also exposed to parameter groups?
Yep, you just need to replace them with the plugins base classes and it does the job
nice
It takes a little bit setup but I tried to explained them as best as I can in tutorial
Native properties are not exposed but it's not too difficult to include them
Native properties = UPROPERTY(EditAnywhere) float Something;?
Yep, it only detects variables created in blueprints
hmm, interesting. I thought it should be easy to query all reflected properties
is it because of the BlueprintBase classes?
No, I was going to go in that route but it would be too limiting for the future. I actually query them but there was a flag I was checking that basically preventing native properties to be exposed.
I recently discovered that blackboard checking decorators are actually effectively free performance wise since they are purely event based so I think I'll be merging my three BTs into one and just toggling BB values using my controller
dont you just need to add || It->HasAnyPropertyFlags(CPF_Edit)? 
If my computer wasn't really this slow... I'm checking it right now.
how can I make my npc go through from the door when its open? Navmesh isnt generating a navigation for it(using navmesh proxy works but its buggy, I dont know why)
Dont let door prevent navmesh from getting created at that point
Sorry, it took too long for me to test it out, everything went wrong while I was simply trying to edit a single line.
I completely forgot that it was actually a choice I made. I didn't want to include native properties so I decided to filter them out, that's why I preferred that. It was just a plugin for my project before I decided to publish it. Without filtering them something like this happens:
I completely forgot that it was actually a choice I made.
π
makes sense though
if you didnt want to filter them
LogicDriver also goes with BlueprintVisible method
to avoid filtering code
Haha, it's late and I didn't sleep well last night π
what I can recommend though, if you ever decide to add filtering, add two arrays to project settings via developer settings and exclude properties from name based on that array, possibly with mapping to specific uclass. I had some serious issues with logicdriver because this feature didnt exist and had to wrote on my own
it happens π
Great advice, I will look into that! That would also enable native class support
Anyway I should go and get some sleep π
Good night 
You too!
Hi. If i create a UNavigationPath, say using FindPathToLocation etc, is there a way to know if a nav link proxy is a part of the path, and get a reference to it perhaps (or call its interface functions)? Or is that solely done through the use of PathFollowingComponent?
Also same question but get the nav area of a segment of the NavigationPath instead
Trying to learn more in depth the code for pathfollowingcomponents, navlinkproxy, etc by reading through the source code and just had this curious thought.
I'd recommend nav modifiers and turn on modifiers only in the nav regen of the project settings. That means that when closed the door blocks nav and when opened it won't.
You might be able to, but I haven't been in that code for awhile. I'd look at the function SetMoveSection in the path following component. That's where it gets the data for the next section and can determine if it's a nav link and check the area class flags.
Yes I was making note of those "MoveSection" functions of PathFollowingComponent but didnt get around to reading that one in particular, good to know that's where it reads the data. I'll check it tonight when I'm home, thanks
whats the difference between dynamic and nav modifiers only?
I guess the better question is why are nav modifiers cheaper then regular navigation regen?
Dynamic modifiers only only cuts the nav mesh instead of fully rebuilding. It's a lot cheaper. You also reduce the amount of geometry that causes a regen, because it's limited by anything with a modifier instead of tracking everything.
ah I see. so you get most of the benefits of static while still being able to have stuff like dynamic doors/abilities
Yeah. There are also a lot of tricks you can do with them to avoid using full regen.
if I turn on dynamic modifiers only should I turn this off?
Probably. I'm not 100% certain it does anything without full regen, but best to just turn it off.
alright. and then how do I set different modes for different levels
just set it in the recastmesh?
I created a post about #statetree channel might be a good idea at #969360633386655744: <#1053174219225190490 message>
If anyone thinks the same, could mention it or put an emoji to the post
@celest python Woohoo - my PR got merged-ish
π₯³
you beat me into it
i was too lazy to clean my ssd and do a pr (and get accepted) earlier than you 
though since ST is stable I dont think I'll ever do any PRs for BT anymore since I wont be using it much π
Oh - this was for the ST π
I'm talkin' a big game - but I just added a setter method π
Any useful AI perceptions functions I can expose to BP? Need to assign my junior dev
all of them?
pretty sure blueprint only gets SetSenseEnabled by default
setters for modifying sense properties during runtime would be a good place to start I guess
Can I get some links/examples to look in the right direction?
I do think, at this current time, BT's are more straight forward than ST's.
never scales well as ST though
but with Emrehan's plugin it might be easier for large scale AIs
scales pretty well if done right π
well cant beat the developer itself in this argument, but at least from my experience in terms of UX and state handling ST helps way more π
or course! Our BTs are almost as old as UE4 itself, and the design is even older. STs are the hot new shit, cutting edge stuff leaning heavily on the UE5's hotness. If it wasn't promising to be a big step forward we wouldn't be investing time in it.
I like how ST itself becomes the "ai controller", meanwhile BT is heavily coupled to the AAIController
yeah, that's one of the lessons we learned from UE3/4 days.
Mass is another expression of that lesson π
Are state trees something like a singleton that processes state changes for a given entity, or you have one ST instance for each entity?
thats why I said I think ai team mostly transforms the engine mostly back then - even though you're right expressing the idea directly like this is unfair to the rest of the Epic team contributed to the hardwork
first one
you have a "context" parameter, which is the actor ST is bound to
sounds like it could be really performant for Mass
sounds like a really good use case for processing the animation states of my entities
since anim graph can run on another thread i think you shouldnt stay away from it? 
it exactly does what ST does, works on top of the data bindings
you know, for example, show walk+attack animation if unit velocity is bigger than x and unit is attacking
only difference is you can also bind ufunctions unlike ST π¦
dont stay away from anim bp for this
well the idea would be to just set a state each frame, and then I have a special processor that actually runs in the game thread and performs the animation changes
also, I am supporting two unit types - skeletal mesh rendered, and Niagara rendered
so the animation handling itself is bound to those
I am just interested in the ST to set a logical state, not to directly change the animation
not sure I am explaining myself very well xD
I think anim graph is still more performant and convenient
in a sense ST is a fancy data structure and a few modules evaluating things each tick
meanwhile anim graph also is a state and runs on another thread
and you cause less instructions on it's NativeTick function to set values
then binding things on anim graph
mmm I will look into the anim graph then, not sure if we are using it already since I have not worked with the sk anim implementations
however I'll need something to process the state and set the Niagara animations on tick
do it in some uobject
handle state in it
and bind to animgraph
and feed niagara from the same uobject
an ai is just a bunch of state trees all tied together lol
animation state, movement state, pathfinding state, behavior state, perception state
better it all be compartmentalized instead of all being in one sphagetti class
For state tree context, is external data == schema params?
Well - sure. So far, I don't really like how the state tree events work. Only being able to process the event in tick is a bit wonky. I imagine it is specifically for cache stuff.
It really is more convoluted to get perception working with ST than BT. At least imo.
I'm not 100% sure on when I should be using the InstanceData or not. The two default tasks show both ways. My assumption was that if you want a value to be unique per-actor (or entity), put it in the InstanceData struct. If you want it to be global, put it in the task.
I find that many of Unreal's system would be super useful it would be possible to call them manually instead of just ticking
I'm not 100% sure what you mean by that. Maybe I just haven't encountered that kind of functionality as often? Or maybe I have and just haven't realized it π
I mean, for example - MassEntity has processors that work per tick. It would be very useful sometimes to execute those "tick" events on demand, in lower frequencies etc
Oh - I'm pretty sure it has to be on tick because of cache stuff
I haven't dealt with #mass specifically. Too early for me.
funny you should mention that - I have something locally that will let you do that (with minor tinkering) π
happy dev noises although now I already designed everything to run on tick but... π
It could be a great thing for replication, I'm doing some replication stuff and if I could run queries on a timer, it might be faster than my current manual approach
@crystal hatch I saw that my PR was merged-ish (and I think Mikko added one or two things to it). I'm not sure how ya'll actually do it, but π₯³. 2 days π
I can now confirm that AI team is receptive to PRs π
I think ya'll merge internally somehow (or just copy paste the code π ) and then just close the PR on github?
98% of the time we touch up the PRs, for a number of reasons.
Keep the PRs coming and we'll keep on pulling them in π
Oh - I'm fine with touching up. Wasn't trying to convey I wasn't if that's how it came across.
No worries, I'm just saying that's pretty much the regular process.
Anyone know why warnings such as LogNavigationDirtyArea: Warning: Skipping dirty area creation because of empty bounds (object: FoliageInstancedStaticMeshComponent are spammed in the logs for certain painted instanced foliage meshes?
In this case many dense ones that do get culled at distance, I haven't seen this warning for other painted foliage
In this case the foliage doesn't have collision but it appears to have a valid bounds when viewing in the static mesh editor. Is it fine to just ignore these warnings? Using 4.27
with State Tree is there a way to get the owner in BP Tasks? FStateTreeExecutionContext is not a blueprint type, do I need to make a cpp task or is there another way to get a handle on the context in BP
In your task, create an Actor variable and put it in the Context category. Then when you use it, you can bind to the Actor context variable that you selected the class of for the state tree
@crystal hatch Actually - real quick if you don't mind. How would you (or Mikko) look to use perception data in the State Tree? I'm currently sending a ST event when the perception is successfully triggered and then switching to the state on reception of said event. The event contains the actor that I sensed. The first task gets that actor and sets it so following tasks can use it.
It feels kind of weird to have a task for that part (receiving the perception data that is). Would an evaluator be a better fit?
π€·ββοΈ I haven't used STs myself yet (other than a very dirty super simple prototype months ago) so... dunno π
How about this: I tag @lyric flint and you keep your fingers crossed he has notifies enabled π
Also since Mikko is tagged - do you guys plan introducing the feature of being able to bind UFUNCTIONs to properties for data binding system? Its a default feature of animation graphs and lack of it in ST forces us to rely on evaluators more to fetch data from an external source
Instance data is used when you need to mutate the data
since every function is const you and mutate a member property
and there might be some data locality / cpu cache trick behind the instance data thingy
So - we can't mutate properties that are not in the InstanceData?
How is that part enforced?
Maybe I'm not being clear
I have bProcessedEvent in my Task. It is not in InstanceData
I can freely change it in the task.
I lie.
Forgive me Eren
I see what you are saying now
It seems to auto-const properties
i was about to ask about your magical power to breach const correctness and mutate that property π
thats weird, probably it cant do something like that
rider might be being ambigious
its about function that you are in is const
not the property itself
Yeah - it's rider shenanigans
Just tried in a non-const function
Didn't know a const function did that to be honest
All of my const functions are pretty much just getters though π
there is an optimization trick that I dont understand yet behind that decision
Wait - I'm silly. Of course I knew that about const functions. Silly brain. Brain fart moment.
I'm just going to go about my merry way
What is the correct way to make use of nav link proxies over large distances? For example if telling an AI that a teleporter can connect navmesh location A to navmesh location B?
Is it possible to lift the nav mesh proxy allowance distance? (As currently it seems to fail (the dark green segment doesn't show) after quite short distances)
hello, how would i make an enemy follow a path, however that path can have a width and they can choose a location inside that width? (sorry if that doesnt make much sense idk how to explain it)
@harsh storm did you create non-instanced BT node before in C++? If I understand correctly, the instance data is just what instance memory is for BT nodes. Same concept. The node is not instantiated, so things you would usually store in class vars and set during runtime, should go in instance data.
Unless you make the node instanced, then you can use class variables as usual
good call on that function!
FNavMeshNodeFlags(PathPt1.Flags).IsNavLink()
and
if (PathPt0.CustomLinkId)
{
UNavigationSystemV1* NavSys = FNavigationSystem::GetCurrent<UNavigationSystemV1>(GetWorld());
INavLinkCustomInterface* CustomNavLink = NavSys->GetCustomLink(PathPt0.CustomLinkId);
StartUsingCustomLink(CustomNavLink, SegmentEnd);
}
(where pathpt0 is an FNavPathPoint getted from the FNavigationPath instance)
pretty much tells me all i need to know
not immediately seeing anything about navarea but i am aware of rama's method of getting the info from the actual nav mesh, from the position of something etc. can probably learn from that too if i end up wanted to know more about getting navarea info.
I believe you can get the nav area flags in the same way. You use the flags to figure out the nav area.
ohh ok cool
Yeah - Eren explained it. Thanks though!
@celest python Have you tried messing with actually processing ST events yet?
not yet
π
I'm trying to figure out if the event is just being dropped because it is definitely not processing it.
it must be similar to GAS's event listener thing
because schema itself has some bounds to event system
are you sending an event and it doesnt reach or not in the events received so far?
Sending it and then transitioning to a new state, which has a task - that on Tick is supposed to process the events through the ForEachEvent function
where do you send it?
it was probably just not relevant anyway - was wondering if something could come up from that additional info
when you step into ForEachEvent, does container has any events stored?
I'm still trying to get a semi-clean way to get perception data into the tree π
I don't like some of the approaches I've done thus far
Completely ignoring the optimal solutions - a ST way of perception would be just an evaluator imo π
Yeah - probably. But I don't want it to be always ticking π
Which is why I want to do it in the Task. Because it is only relevant in a certain state
I thought of enabling/disabling it by events
Yeah - break point isn't even triggered π
Yeah - it just...isn't getting the event π€
gotta debug SendStateTreeEvent() then
Yup
How can you do that?
Didn't even know you could in the context of an evaluator
it still has access to ForEachEvents and instance data struct, i'll just set a boolean by a tag
I'm thinking about creating evaluators for each sense
so they respond to their own tags
so zombies will be able to see but not hear sometimes etc
though -- my zombies has very minimal requirement of this
maybe a large scale perception system needs to be more planned upon
So yeah - putting it in the evaluator definitely receives the event.
There is probably something, somewhere in the process, that is clearing the event prior to my Task getting it perhaps?
Bloody zombies
Okay - so transition order does matter. Seems to evaluate from top to bottom
According to Mikko - evaluators are probably going to be uncommon though.
But it seems like our consensus is that they are a good way to get outside data to the state tree
Would it even be useful to bind to a delegate? I imagine the process to actually do so in this context would be annoying.
I used it two times
to get a callback from a #gameplay-ability-system ability ended
and when move to finished (my moveto system is external - a subsystem)
I wonder what Mikko implies by "lightweight" there by the way.. In terms of evaluators being more lightweight in memory -- which probably not -- or just the intended usecase? 
even with statetree reflection data corruption hunts you at somewhere π
I wonder if its related to BP corruption though.. Why IsScriptStruct doing a CastChecked? 
is property added to schema parameter is essentialy a struct or something?
oh it was StructUtils function
Hmm...I'm in a bit of a pickle. My doorways don't fully connect the navmesh when open, but I can use simple link to allow AI to walk through. when closed, smart link is enabled and they will open the door first. all works fine.
However if they see the door is open and start to head through and I shut the door in their face, they still try to keep walking through along the simple link path, since the smart link is enabled after they entered the link. They think they can still walk through.
Just brainstorming better ways to do this or something I'm maybe missing...any advice/opinions would be helpful
maybe im stupid and just adjusting the nav mesh size settings so that it connects through doorways and deleting the simple link is the best answer ahaha
but i'm more interested in other interesting answers for this here, for learning purposes.
Have the agent store the smartlink object reference and broadcast a message when you close a door that lets and agent using the smartlink know of the change in state? usually I have a resource locking mechanism for things like doors, elevators, ladders etc.
there's probably a resource locking mechanism in gameplay abilities or something you could use
I realize now that you are talking about a delegate with #gameplay-ability-system. I meant with ST. So like having one in a Task or evaluator that another task would bind to π
yeah that's what i'm thinking of doing. i think you can get currently traversing actors of a segment or link as well?
or something like that.
but yeah i think broadcasting change in state to interested parties is the way to go here
can also play a "stumble backwards" animation too for fun like you slammed it in their face
So - it seems like the ST property binding is one way. I wanted to see if I could alter the value in an evaluator, from a task. Did not work.
I added text to image generation into my voice control plugin and didn't quite realize how much fun it would be
it feels.. strange, but in a "how does this not work this way" way
I don't know why, but being able to point to a painting and tell it to change to a random picasso is quite liberating π
Oh crap.. added the default UE text to speech plugin and its so wonky that its almost endearing π
Can highly recommend it for shenanigans
Its like a slightly less depressed Marvyn π
Will have to integrate amazon polly though I think.. just because
It was mentioned before that SM is a superset of what BT can do. It led me to thinking yesterday whether potential BT v2 could be just a different editor for ST and under the hood it would be still ST just with autocreated transitions to mimick BT flow of events. That way it would be basically still just a single system and improvements to ST would improve also BT v2 under the hood. It would look like a BT only because of editor frontend.
I used to write my BT editors in the form that ST uses.. basically its a listcntrl
I always preferred it to be honest..
If you don't need to make use of the events that smart links can provide, should you disable them on any nav mesh proxies to save performance?
Are they causing a perf problem?
I'm just placing dozens of them around, best to just set them all up with minimal cost (not exactly premature optimization since it's just a checkbox, more of a good practice)
As watching a video on them it seems both the smart and simple links are both enabled and overlapping each other by default
No need for smart features in my case so may as well disable
Hello again! More smart link/nav link proxy questions.
https://forums.unrealengine.com/t/how-ai-use-smartlink-equally/403612
Second half of this person's post applies. Wondering how to utilize broadcast enable/disable for nav link proxy
Hello. I am developing AI jump using NavLinkProxy with smartlink. for example, There are lot of bot. may 10 bots. A lots of bots are using only 1 navlink. like this picture. I think AI use a low cost path. I referenced RoboRecall jump proxy. That is amazing way. They are only thinking move to one location. So they only release and lock i...
line 375 of NavLinkCustomComponent is the commented line he's referencing (at least in the code version i have)
i dont care really whether that's commented out or not, but still wondering what event is actually getting called during the broadcast (is it on the AI Pawn?)...supposed to be using SetBroadcastFilter to choose the delegate but i havent found where that's actually called yet (if at all? suppose i could just call it myself)
it seems the delegate should receive the link and a list of all the path following components that are in the radius, in order to call what i assume is something like that commented out line (PFC->OnCustomLinkBroadcast) (which i cant actually find on path following components)...
this seems unfinished/like broadcasting doesn't actually do anything?? lol or im really missing something
I know this is a complex question with no easy answer, so I am more looking for suggestions. I have a building system sorta like Rust or Ark and I want an ai to pathfind through it in order to reach the player. I want them to be able to hit walls, go up steps, break doors, and do this all strategically. I am currently using a modified version of dijkstra's algorithm. This works ok for the tileable builds like foundations, walls, and even ramps to travel to another floor. However I have no way of checking for floor placeables like a storage box and it is staring to feel very limited. Any pointers in the right direction would be great.
A naive input I can give with my limited knowledge is:
path finding just provides an array of FVectors with some other utils, and you can actually change how engine finds path by default instead of using custom pathfinding methods -- there are a few functions engine checks corners, does traces from navigation etc.
so maybe if you can analyze how its done and find a way to purposefully make AI walk towards an obstacle you could handle the rest of the interaction via a component in the character by interpreting what kind of obstacle you are hitting manually (i.e. if you are hitting a door execute break door action or if its a wall play hitting a wall animation etc)
@mental basalt
PathFollowingComponent follows the path from point A to point B blindly in a straight line
so all you have to do is make pathfinding ignore some obstacles create path directly through them
or you can maybe make this contextual -- let obstacles provide path points etc
@celest python Yeah I was definitely considering something along the lines of just modifying the nav system. Definitely a big undertaking tho and I have thought of multiple edge cases that would cause issues. Still something that could provide more insight. Thank you
i have been a bit off the ue5 stuff for a bit, how is state tree going? any updates on EQS and navmesh stuff?
StateTree became stable at 5.1
NavMesh and EQS pretty much same other than small tweaks afaik
There is a new NavCorridor thing related with pathfollowing, probably will form a shape in 5.2
but initial implementation exist in 5.1 too
whats state tree abot? why should i use it instead of cpp state machines or similar
It has a flexible bottom-up state system (nodes determine which state to transit without any limitation) that you cant achieve with other methods without creating a huge sphagetti and there is a data binding system with custom linker & compiler that lets you bind other properties from arbitary sources to properties inside of your ST nodes, just like animation graph
ST also makes you get rid of AIController since its just a struct, so your ST graph becomes the AIController itself with the flexibility of data binding system because you dont rely on tightly coupled systems like BT<->BB<->AIController
Does it actually replace AIController? or act as a component within one?
its a struct, there are wrapper components to make things easier but you can copy paste the boilerplate to init and run it on somewhere uobjects dont even exist
since AIControllers are part of default gameplayframework it doesnt replace it in practice but it theory it makes ai controllers redundant
you just use AIControllers to get pathfollowing comp etc and make AIs possess pawns
and there are "schemas" that let you define what kind of types are allowed in your ST graph, and for example if you have something like a data-only object that acts like blackboard you can just change its type in editor with schema dynamically, it reflects the type change to property so you dont have to cast inside of the nodes
it literally carries everything to graph and you can just work with having generic nodes with input/output parameters instead of specific nodes dedicated to something
Huh - seems like parameters for the ST aren't being passed in the way one would think. Created a parameter, edited the value in the component, checked the value that got passed in and it is the default value.
@short aurora I know you've dabbled with ST's. Have you ran into this issue with them yet? π
nope, never had an issue with that
Okay - sooooo apparently I just had to restart the editor? Interesting (no, not live coding btw)
did you forget to compile a tree?
Nah.
some weird stuff happens if you don't compile after making changes
This isn't the first time I've encountered this with the ST
I've changed a BP task before (different exposed variables) and it didn't update.
Just seems a little buggy for me at the moment. I've had it also flat out not allow me to delete a task until I've restarted the editor as well.
Thankfully there is a PR that makes the compile button work like it does in the other editors (where it can save after a compile automatically). Because of that setting, I always hit compile π . But with ST, have to save manually.
Trying some "Dynamic" nav mesh and some "Dynamic with modifier" navmeshes. But its just not picking up whenever I create a pit.
Tried giving turtwig a modifier and "Can edit" and it works. So It must be something to do with the dissplacement map
I am using a static mesh that gets modified based on the dynamic mesh in order to cast this, so not sure if thats causing issue but cant find anything online.
I all else fails I'm gonna try create an inverse of the pit as a really cheaty way to fix, but gonna keep looking for anything online
Converted this simple BT to ST. Here is how they look side-by-side.
So far, my big gripe with ST is some of the data flow processes. Otherwise, I do think it is much easier to write a native task/condition/evaluator for ST than it is to do a native thing for BT. Not saying it is much more difficult in BT mind you.
The parameter binding is nice - but I would like for it to be two-way instead of one-way. It is probably just my way of approach that needs to be addressed more so than needing two-way binding. But I was trying to clear out a value in a task and it was bound to a value in an evaluator. Clearing it out didn't change anything in the evaluator.
It was mentioned before as well, but having some visualization like how the BT does it, would be nice as well. The VisLog is great though π.
Do NavModifierVolumes support multiple volumes that are disjoint or have holes, properly considering the disjoint area and holes when applying this to the navmesh?
I am trying to construct this case with the geometry brush but so far no luck, I only get odd results from that
I created a tool in UE5 that generates navmesh areas from painted landscape terrain layers (simplified boundaries, triangulated and then extruded) but it doesn't seem to work and i am now trying to construct an minimally viable example based on a NavModifierVolume, but so far it seems it expect a connected and hole-less volume
Ok so the NavModifierVolume when set on Box or Cylinder with "Hollow" on allows to create a hole and it works absolutely flawlessly (altho the Cylinder crashed while changing the parameters at some point)
that's pretty sweet!
My generated volumetric mesh however doesnt work, i suspect it could be the triangle edge directions or something funky like this
So how does the Parameter type work in ST?
Invalid - pretty sure this can be safely ignored in most cases. Used mostly internally I believe.
Context - This is for your context stuff
Input - ST won't compile unless this property is bound
Parameter - ????
Output - Says that the node will always set the value
Parameter is just like void something(float asd);'s float asd
Doesn't look like Parameter is actually used much at all.
π€
Input forces you to put a binding, parameter can take a value that you can hardcode
and output probably copies the value to set to bound property
Simply doing like int Age; with a EditAnywhere UPROP does the same thing though, no?
yep
Seems redundant. I thought it would've meant more π
You dont ever end up needing to pass parameters to tasks? 
I just do EditAnywhere
or the idea of "Category="parameter" sucks
Instead of Category
UPROPERTY(EditAnywhere) vs UPROPERTY(Category=Parameter) - I just do the former
does it let you bind data?
Yeah
nice
Actually, wait. Idk
I'm silly
I'm doing this:
UPROPERTY(EditAnywhere, Category = Parameter)
bool bUseActor;
π€£
I'm literally doing both.
This was when I was first writing stuff and I just guessed that Parameter was a valid Category
Let me take that off and see if I can still bind
I don't think there is any actual enforcement of this - it's more like, "trust me bro, this node will set this value"
So yeah - even without the category, I can still bind
So, like I said, seems kind of redundant at this point in time.
While you're here Eren, do you know if it is possible to actually alter information somewhere else? So, I want a task to clear out a value in an Evaluator for example.
Hey does anyone know where I can find the source code implementation for FindPath()? After going to its definition in VS it just returns (*FindPathImplementation)(AgentProperties, Query). Going to definition of that just takes me to FFindPathPtr FindPathImplementation. This is where I get stuck and confused.
AbstractNavMesh.cpp iirc
its a function ptr declaration, FFindPathPtr is is the type of that func ptr
its being set to a specific function
hey there everyone, i was just going through the AIPerceptionComponent header file and found that there are many functions that are c++ exclusive, so just wanted to ask what are some of the c++ exclusive function that you guys use to make your Ai workflow easier?
Sorry missed this
I think you should use output category?
I don't think that'll actually do what I'm asking. That's there so you can't alter it in the editor, but you can still bind to it because the node is supposed to be altering it.
Hmm, output category doesnt work as I thought then?
i thought it was suppose to act like a reference to property that you bind and it should modify after node executed in ST's update loop
I mean - I can still try to see. Not like it'll take much effort π
Yeah - doesn't work that way @celest python
hmm... well it sucks then, i was expecting it to act more different than an input parameter
Well it kind of does
Input param, you can alter in the editor and bind it and all that
Output is meant ONLY for other stuff to bind to.
Because the node is going to set the value
what "other stuff" covers in that context?
schema parameters etc?
oh wait.. i just understand what you were actually asking btw
you were asking if its possible to alter a different node's property from another node
i dont think it is possible, you need to centralize data into schema parameters and work with in/outs i guess
Look at my TargetLocation output. I don't want anyone to bind this to anything else BUT I do want others to bind TO it.
That is the purpose of output
It should be an output because the task itself is going to alter it. So it should not be edited by outside sources (which is what binding or changing it in the editor would do)
I haven't really found a way to alter the parameters in native code though. I need the StateTreeRef to get access to it I believe, but we don't have access to that to my knowledge.
only in statetreecomponent afaik
Yeah, that's where it exists.
The reference itself is protected. No public way to get it.
So I'd have to inherit and expose it more or less.
But then I need to figure out how to just update like...a single variable.
So to verify I understand:
lets say I have a CurrentTargetLocation in schema parameters
and FindLocation task, that takes an FVector as output to set CurrentTargetLocation and transits to MoveTo task that moves to CurrentTargetLocation - which was FVector::ZeroVector before but now value is set by FindLocation
isnt this what "output" params do?
What you are trying to do feels like a wrong approach to use ST btw
This is how my stuff is set up.
You can't bind an output to anything. Other things bind to the output variable.
Altering the parameters at runtime?
Altering other node's parameters in other nodes directly from code
Oh - yeah, that. Yeah, it felt like that to be honest. But hey, ya' never know π
Only if events provide an FInstancedStruct 
it'd be nice to interact with other nodes
via ST events
this one is confusing - gotta mess with it on my own. Currently doing a project-wide cleanup and organization.. I think I'll be off from actually being productive for a few days since I removed/added around 100 files and it'll take time to fix references and compile after all
It would be nice to be able to at least update the parameters at runtime though.
Which part is confusing?
Find Location task - finds a location and then sets that location to the out variable Target Location. This is something that other tasks would probably want to use.
Move Task - binds to the out variable Target Location to know where it should move the Context actor to
oh i get it now
it becomes something like a local variable scoped to all tasks in a node?
To w/e can bind to it really
so output params becomes something like schema parameters? 
If it wasn't an output param, in the editor, I could bind it to something else - but that would be silly, because the task is going to overwrite it anyway.
Look at it like "output data" more or less. Your task is going to do some work, something else may be reliant on that data. You don't want to let anyone else mess with this data accidently (manually editing it, binding this data to something else, etc...). Mark it as an output param. It lets OTHER things bind to the output param, while not allowing anyone to edit it.
So - Input forces you to bind. Parameter for free editing or binding (or just EditAnywhere). Output for non-editable stuff, but let others bind to it.
Now, my next goal is to see how I can actually update the parameters in the schema through code.
The answer is in PropertyBag.h, FInstancedPropertyBag has a nice comment above it.
I've tried setting the value but it seemed to zero it out π€
It's like the change isn't being saved after leaving the method π€. I've tried going through the various Sync methods as well.
There is also Context property category which binds to your context actor automatically.
nvm, I see you already use it on the screenshot
Yeah, I didn't cover that one 'cause Eren and I were talking about something else really.
@pallid mica 
so tl;dr you create two USTRUCTs
one for the node itself, derives from relevant FStateTree.....CommonBase
either task, condition or evaluator
and one "instance data struct"
I assume this is advanced usage, since BP only people don't have access to C++ Structs?
its the default workflow for any C++ node you want to create rather than advanced, but in BP yeah its just a matter of adding a new variable and settings its category name
linker or compiler goes through property list and does its job behind the scenes
Ah, one sec, then I maybe kow what you mean
Okay so I can only use Struct or Objects
hmm, what do you mean? 
I'm trying to understand how I link up more context
Creating a boolean in a Task and putting it into Context doesn't work
A Struct seems to work but now it's angry about bindings
it should be, ensure you're giving proper names based on available category names
How do I populate more values into this from BPs
"Cound". Lovely. Someone wants a free PR for UE badges?
add a boolean to ST Test Task and set its category to Parameter
if it doesnt appear something is wrong
this struct shouldnt be context
thats why its complaining
it should be either input, output or parameter
Ah
So... Output of something can be Input of the next ?
Difference between Parameter and Input?
yes, it can be input for substates or following states at the same level
And what should all be Context? Without modifying it via the C++ Struct I assume I can't add more to Context?
Not that I need to, just trying to understand the basics here
Context is equal to parameter, its just a helper thing to make it match with your actor type in the schema
it just adds a rule to the ST system that helps people to avoid issues and bind context actor parameter to nodes
schemas are also inheritable, you can override from base schema class and make params promoted to desired type like how Actor param is promoted to another type
Context is like a hardcoded base params of the given type of ST.
In case of AI, you get a Context which is your owner actor.
If you would create own type of ST, called Interaction State Tree Schema, you could define own context vars like Iteractor, InteractedObject.
Alright, but that's C++ only?
creating new schemas are c++ only
But most of the time you just want to run your ST within ST Component of some actor. And for that you can use the default schema.
Yeah totally, again just want to know what I can do
The "Parameter" category, how is that working?
Check this, Duroxxigar recently wrote all the types.
its literally like a function parameter, it copies the data from binding or the value to instance data struct of the node -- if you are on BP its just setting the relevant property without messing with instance data
Right, what I'm missing is where variables in the Parameter category are meant to show up
every non-labeled property in this image is "parameter" - they should show up like that once you created them in BP graph
hey exi wanna check lounge π
Default Category or Parameter Category both seem to not make it show up there
assuming you didnt forget to compile BP and ST also compiles fine, it must be something else wrong. Because it works for both me and Duroxxigar
we tested yesterday -- or one day earlier
Maybe something obvious?
Does it need to be Instanced Editable or so?
Ah yeah it does
ajkfalΓΆsfgjaklΓΆfjkaΓΆs
WELL, okay
So Params are something I can set on the Task, similar to how that worked in BehaviorTreeTasks.
Context is bound to the Context, by default only Actor.
Output is something other same level or children can bind to with Input, so I can forward data from upper tasks.
I assume that goes also for other things than Tasks and is interchangable as in a Task can Output something a Condition can Input?
As well as Evaluator?
Seems straight forward, but the Context, Input, Parameter, Output AND INSTANCED EDITABLE part is something they could have better explained in the examples.
Typical "Just do it." tutorials.
Honestly, no.
Evaluators changed after 5.0
normally every task had its own local evaluators like tasks and enter conditions
but then they removed it
evaluators are only for schema globally now
and it practically has zero difference from a task runs at root node
So I can ignore them?
What were they meant to be used for?
Condition and Task are straight forward
prepare/set/update data for tasks
for example a pathfollowing component or perception component can be replaced with an evaluator
or an EQS that runs every 0.2s
can be an evaluator
it exists and works, its just it was available for every node before, now its just only globally for whole tree
so its activated and ticks until ST is stopped
you dont have control over it much like tasks
siliex created a task that runs an evaluator for this π
just to hack it
Okay, but what does one put in there now? Unless I have something that should tick for the whole tree it seems rather useless?
Is that basically what a Service in Behavior Tree was?
this is what Mikko said - developer of ST
kind of, yeah
though this one was more influence over graph
Okay, so I can put some stuff in there that should push some data (Output?) to Tasks globally, if I ever need it.
That's fair
And that is, on a task level, replaced with the task doing it itself?
yes
Alright
for me, evaluators are used to set external data (schema params etc)
and tasks for working with things in local context
Yeah I'm still at the "try to recreate that AI Behavior Tree in State Tree" level
Cause I HATE BehaviorTrees
I was migrated to FSM completely because I didnt like BTs... i hated that too
then unwillingly came back to BTs
but ST is a blessing for me
literally made me remove 5k lines of code today
because of how it abstracts things away with data binding system
I currently use my evaluator as a way to process state tree events
Putting something in the "Parameter" category seems to be completely optional honestly. Just need to be instance editable or EditAnywhere UPROP.
I'm trying to figure out how to get GraphAStar working for my purposes, I already made a struct based on TGraph and one for TQueryFilter as well as initialise them (I think, unless I'm doing it improperly, is that what's causing the issue? FGraphAStarDefaultNode<TGraph>,false>), but I keep getting this error on line 278 on the sourcebin code:
[
TGraph=FAStarGridGraph,
TQueryFilter=FAStarGridGraphQueryFilter,
TResultPathInfo=TArray<FIntPoint,FDefaultAllocator>
]```
I've been using:
https://github.com/ZioYuri78/GraphAStarExample
https://crussel.net/2020/08/16/builtin-a-pathfinding-in-unreal-engine-4-25/
as examples and although I'm not following them exactly (I'm just trying to make the character move according to square cells, not hex grid, but I think I'm at least getting the principles correct so I'm not sure why it's giving me that error? Thanks if anyone replies, I've tried looking up information but there doesn't seem to be much asides these two.
Unreal Engine 4 generic graph A* implementation for hexagonal grids. - GitHub - ZioYuri78/GraphAStarExample: Unreal Engine 4 generic graph A* implementation for hexagonal grids.
Any good docs/resources about state trees?
Besides the official docs themselves π Doesnβt need to be Unrealβs, can be other implementations/info about the same concepts
None that I've seen. But I've been taking notes during my journey.
There's like 2 more pieces that I am trying to figure out.
Yeah, I imagine it is something quite new. On the other hand, I guess it is based on some concept or system or architecture already existing before
I'm mostly trying to understand what it does and what usecases does it support
Bcs it could be a good solution for our combat system (maybe even replacing our AI controllers), it seems to map well with our current flow diagram
Supposed to be a combo of State machines and behavior Trees.
mmm other 2 concepts I am not very familiar with, will look into it :D
what if I don't trust the nav system to select it for me
Not going to lie. Kind of weird to me that you're familiar with ECS but not state machines, lol
the statetreee docs are actually written
yep
I am making some source changes to make it less painful
I made it actually log missing fragments now
I already had a PR merged for ST π
frankly, it ensuring on a missing fragment is really weird as I mean, the whole idea is to just not run if you don't have the query fragments
Anywho - have you been able to figure out how to actually change a parameter in the FInstancedPropertyBag?
I have changed it but it doesn't seem to actually stick
...which FInstancedPropertyBag?
In StateTreeRef
It has a method, GetMutableParameters(). This is the parameters for your state tree.
I assume it is not syncing
Yeah, that's what I thought too. But even after setting it, I tried each of the Sync* methods, still didn't seem to actually stick
So I'm not sure what I'm missing here.
seems like it needs to be a FStateTreeExecutionContext
FStateTreeExecutionContext::SetParameters is used at least once
:/ I have no clue how this is stored
everything is so complicated
Yeah - it is struct upon struct upon struct upon struct π
Yeah - I don't know if that is actually related to what I'm talkin' about though to be honest π
Pretty sure that is only meant to actually set the params for the execution.
idk though. Just so many structs π
I really dislike making a new struct just for this one thing to have an int that can also be invalid
saving one line of code by making 3 new types for me to have to worry about
For loop go brrr though
I guess if it's to save on every bit I get it though
definitely lots of uint8 etc
I try and look at all this ST complication as just a thing for ECS stuff honestly.
It's completely divorced from the ECS module
GameplayStateTreeModule has one just for regular actors
@shadow furnace @celest python I did it! Changed the parameters at runtime of the state tree
Oh my jeebus is it convoluted though
- Get
StateTreeReffrom the StateTree component (you have to manually expose this with a getter method, just inherit from the component) - In the
StateTreeRef, get the state tree. TheStateTreeRefshould have a reference to the running state tree. The one specifically for this STR. - With the running state tree now, you can get the parameters - which is a
FInstancedPropertyBag.
Now you have the actual params for the state tree. Now you just do the set methods that you can find in the FInstancedPropertyBag struct.
So, it seems like what happens is the asset has its own property bag. Then when the state tree actually gets created at runtime, it copies those params into its own property bag.
I don't know if this is the correct way though. But it does work.
void UStateTreeComponent::StartLogic()
{
STATETREE_LOG(Log, TEXT("%s: Start Logic"), ANSI_TO_TCHAR(__FUNCTION__));
FStateTreeExecutionContext Context(*GetOwner(), *StateTreeRef.GetStateTree(), InstanceData);
if (SetContextRequirements(Context))
{
Context.SetParameters(StateTreeRef.GetParameters());
Context.Start();
bIsRunning = true;
}
}```
once you have a context you can just SetParameters?
StateTreeRef.SetStateTree(MyUStateTree);
I have no clue...
To set the parameters, it has to go through all of them.
So if you're just changing one value...
Also a lot of the parameters are just null for my case
I think the parameters being one giant blob is to pack them in memory?
This is what set params does
FStateTreeIndex8 exists only to make MAX_uint8 the invalid value...
or maybe this is the index of every kind of statetree
One weird thing that happened though.
auto StateTreeRef = PawnStateTree->GetStateTreeRef();
UStateTree* ActualStateTree = StateTreeRef.GetMutableStateTree();
const FInstancedPropertyBag& Params = ActualStateTree->GetDefaultParameters();
float AttackRange = Params.GetValueFloat(FName("AttackRange")).GetValue();
GEngine->AddOnScreenDebugMessage(-1, 3.0f, FColor::Yellow, FString::Printf(TEXT("Value: %f"), AttackRange));
Params.SetValueFloat(FName("AttackRange"), 300.0f);
AttackRange = Params.GetValueFloat(FName("AttackRange")).GetValue();
GEngine->AddOnScreenDebugMessage(-1, 3.0f, FColor::Yellow, FString::Printf(TEXT("New Value: %f"), AttackRange));
This is the code that I'm using. The very first time I ran this code, AttackRange printed 0. Then I set it to 300. The New value was correct at 300.
Then I closed the game and re-ran it. Ever since that first time, the first print prints 300.
ah, this is a compilation thing 
So I'm wondering if there is some behind the scenes thing that I did by doing this approach
I have this in my OnPossess function.
FStateTreeCompiler::Compile touches this
I'm just not sure why it prints 0 the first time, then the correct value every time after.
I assume you are encoding the value into it after it flushes something
also are "DefaultParameters" what we want here?
Might also be PIE shenanigans. When I do it as a standalone, it prints the 0 the first time each time.
It's the only thing we have access to, param wise when we have the StateTree
/** @return List of default parameters of the state tree. Default parameter values can be overridden at runtime by the execution context. */
The comment above the method does seem to imply that it should be overridden by the execution context π
where's your execution context?
What do you mean? StateTree comp and StateTreeRef don't expose that
I am trying to change the parameter value from outside of the StateTree
The context is a local variable in StartLogic()
seems you might want to construct a FStateTreeExecutionContext
Yeah, that is one route. But I'm not sure if that will be the same execution context that is actually being used
I guess to keep it all the same - I'd also need to expose a way to get the StateTree Component's InstanceData.
hahahah fair! I am relatively new to gamedev and programming, I learned about the things I needed but have gaps xD
@shadow furnace So I just did a quick test doing it the way StartLogic() does it (with creating Context and what not). Didn't seem to update.
I have no clue then
my take is that you probably have to set the defaults before you actually start it then
// inherited ST component
FStateTreeInstanceData GetInstanceData() const { return InstanceData; }
// code updating things (this is in a different cpp file)
auto StateTreeRef = PawnStateTree->GetStateTreeRef();
FStateTreeInstanceData Data = PawnStateTree->GetInstanceData();
FStateTreeExecutionContext Context(*InPawn, *StateTreeRef.GetStateTree(), Data);
const FInstancedPropertyBag& Params = StateTreeRef.GetMutableParameters();
float AttackRange = Params.GetValueFloat(FName("AttackRange")).GetValue();
GEngine->AddOnScreenDebugMessage(-1, 3.0f, FColor::Yellow, FString::Printf(TEXT("Value: %f"), AttackRange));
Params.SetValueFloat(FName("AttackRange"), 150.0f);
AttackRange = Params.GetValueFloat(FName("AttackRange")).GetValue();
GEngine->AddOnScreenDebugMessage(-1, 3.0f, FColor::Yellow, FString::Printf(TEXT("New Value: %f"), AttackRange));
Context.SetParameters(StateTreeRef.GetParameters());
hahaha
I'm going to have to wait until Epic gets back from holiday. I have like 2 questions for Mikko π
But as it stands, my first approach does work.
Just don't know if it is the "correct" way
A big part of me wishes that the stuff intended to be used in mass most of the time WAS in Mass
like a lot of the surrounding Mass stuff stores state in a data structure and tracks it for later
when... they could just be mass entities
Maybe it's because they're trying to have access points for the actor system though?
I suppose, but the typed element framework just uses mass
so I don't think it's that unreasonable to have stuff stored in it
code/polymorphism can be regular uobject functions etc
that reminds me, I have to finish this PR
Watch - I probably messed something up here but just don't see it yet π
Oh well - I accomplished what I set out to do tonight.
are you calling sync?
What does that actually do?
ah wait,
Actually don't know if that is even relevant for this to be honest.
FStateTreeReferenceDetails::SyncParameters
ah, this might be asset level
nevermind
I swear something like this is called
Yeah - I was reading that as something for editor stuff
FStateTreeReference::ConditionallySyncParameters ?
Well - at least I did find a way that works though!
Tried to follow what you two discussed, but I wonder what this is even for, or rather what you are trying to accomplish in the end.
(trying to learn here)
Params.SetValueFloat(FName("AttackRange"), 150.0f);
I assume this returns Success?
Regarding what the idea behind this is: Isn't, in this example, AttackRange something you can pull from the Owning Actor from the Context?
Just still wondering what the idea is behind setting those params (and where one even uses those then).
@harsh storm
can I make debug build-only BT nodes? I tried wrapping entire content of logging decorator inside of #if UE_BUILD_DEBUG, but the compiler says that my UPROPERTYies myst not be inside preprocessor blocks
but still how do I do that?
you can only have #if WITH_EDITORONLY_DATA
node itself will stay in BT graph but context wont
yeah so far I'm fine with node staying, I just don't want it to do anything. I think I could also wrap contents of functions in #if UE_BUILD_DEBUG in this case
thhanks anyways
Uhh - yeah, you could 100% just bind to variables that live on the actor and handle it there. This was more a curiosity journey than anything honestly.
What I was messing with was the actual parameters of the state tree. So if you're looking at the state tree asset and look to the left side, there is a section "Parameters". I was trying to work out how to change those values at runtime.
What this does open the door to though is a more generic ST. If I have two unrelated classes, but for w/e reason they both have AttackRange, I now have a way for them to share a state machine. I know I know - I'm kind of stretching here π .
So the context variable might not be one of those two actors. It might just be the generic Actor class.
Wouldn't an Interface do the job then?
Can an interface be the context variable?
Not saying your idea isn't worth exploring
Well what I mean is, your two Actors can have the Interface
You can just use the Interface on the Context I guess?
But bindings then won't work I guess
Yeah - no bindings.
It's strange that there are no "from outside the tree" accessors for this
Did you check if the SetParam thing returned success?
I don't think so. Didn't look honestly.
Would be worth checking I guess
Cause then you can explore why
Ultimately this is just a Set call on the FFloatProperty pointer
So if it does fail, then you can check there
But this whole thing started because I was trying to work out a good way to handle integrating perception data with the ST.
- Use evaluators (which is what I currently do)
- Bind directly to some variable on the actor
- Alter the ST parameters
So - SetParameters inside the ExecutionContext has no return.
Setting things on the Bag though, does return something that we can see if it was successful or not I believe. Returns TValueOrError<Type, EPropertyBagResult>
So, it would be a good idea to check the result and what not if you're operating on the bag directly. This code is just exploratory code anyway, so I'm not really doing that.
The part that was failing was the SetParameters() part. And that returns void.
Is it possible to get the nav mesh to not build for certain static meshes (like rocks) without getting rid of that rocks collision so that AI doesn't get stuck on tricky nav mesh generated areas. Ideally I just want to not generate navigation around rocks so the AI just ignores it and walks around it.
You might be able to override the functionality. The function is something like Find Nav Data For Prop.
You could set Can Affect Navigation to be false, but you'll likely end up with stuck AI because of the collision. The trick is to tweak the agent settings and character movement settings for step height so they can navigate around without looking terrible.
im having an issue where Nav modifier volumes only work if the "mask fill collision underneath for navmesh" flag is checked.. ive already confirmed that i dont have anything above it with 'fill collision underneath', so im not sure why it would be relevant
any ideas about possible causes?
Hello.
The issue I've got is that my enemy with a PawnSensing component ignores the player after the player goes through the wall as shown in the video.
I don't think the issues with the Sight Radius.
ok
@crystal hatch Speaking of which - is it high time we just remove the PawnSensing stuff?
How can I get it to not break the line of sight?
Don't go behind the wall
Thanks - I've got some parts of the wall removed and it works.
Alright, my AI debug overlay says that I have three active smart objects in my map, which is the expected number, but Find Smart Objects returns 0, every time
I'm not doing any filtering, the query box is 200 meters across and all the smart objects are within 20 meters of the character who needs to find them
I'm not getting anything in my log about smart objects
Welp, nevermind, it finds them and claims them, now it just doesn't want to navigate to them
@shadow furnace 
apologies for pinging
since you are familiar with the concept from #mass , do you know how I should return TConstArrayView<> from a function with multiple elements?
TConstArrayView<FStateTreeExternalDataDesc> UZGStateTreeAICharacterSchema::GetContextDataDescs() const
{
// MakeArrayView(&BehaviorDataDataDesc, 1), MakeArrayView(&ContextActorDataDesc, 1)
TConstArrayView<FStateTreeExternalDataDesc> ArrayView(std::initializer_list(&BehaviorDataDataDesc, &ContextActorDataDesc));
return ArrayView;
}
this doesnt work -- compiles fine but crashes and array view is Invalid
Thank you. So if I understand, setting the step up height in the editor to be lower will mean that the nav mesh will see the faces of the rocks as unable to step up on and will then not generate collision on, and if I increase the size of the blocks, it'll get rid of the little islands that appear around and inbetween the rock foliage meshes?
Does this need to directly call MakeArrayView?
I'm honestly clueless if this is doable or even desirable
its calling MakeArrayView in base class
though its not possible to pass multiple elements with it
Can StateTrees be nested similar to BehaviorTrees?
E.g. could I have a generic StateTree that, when reaching a specific State, executes some Dynamic inner one?
I see some "SubTree" and "Linked" Type options for States. Not sure how they work though
Seems like StateTree doesn't come with any tools for navmesh navigation, does it?
Depends on what you need
The Nodes in Behavior Trees weren't the most fleshed out once either. Probably stuff you can just recreated for State Tree
I would like to make a character/actor go from location A to location B
(on top of a 3D landscape)
Maybe I should still go for behavior tree instead?
You can do that with the Tree too though
Yeah? Any tips welcome π
Just write a Task that performs the movement
This doesn't seem any different to Behavior Trees in that regard
I'm moving our BT to StateTrees right now too. Doing the Roaming Task atm
Oh cool. Willing to share your approach? π Cause I'm afraid of having to implement path finding / obstacle avoidance, which sounds complex
those implementations exist in components
BT just calls relevant functions
you can do the same
MoveTo is just AIController->RequestMove + FindPath
Yeah you don't have to code all that stuff
Just the Task the calls MoveToTarget fwiw
if you are willing to go with hardcore way you can rewrite those components as tasks/evaluators but embrace good amount of boilerplate code writing process π
with a custom task i believe
You just have to code the Task that does this for you
Like calls that for you
And ours is a bit more involved
Cause we have a GA that performs the movement
The Tree just sends a GameplayEvent to the Owner with all Info and waits for the Ability to end.
It's a bit more involved so not worth sharing for basics
Hm k
ok ok
The Enter Condition UI is quite sexy I have to say
Editor Property UI that allows Condition Building via some simple clicks is quite nice
That was so much more vague in BTs
Each ST task is just a call to whatever function you want, right?
Yeah, a Task is just there to execute logic for you
What logic that is is up to you
Can be Finding a Location
Moving to one
Dealing Damage
Destroying something
Hell, even just changing the Music that is playing
(StateTree for Music State handling in that case)
It's one of those things where it's surprising no one ever made a proper implementation of State Machines before
I always had to code them myself
(much less complex of course)
Btw a small side question... the current 5.1 docs suggest that in order to get a reference to the Character/Pawn/Actor within the task, I should create an "Actor" variable of the type "Actor (reference)", set it to the "Context" category, and the actual reference will be just somehow magically passed in? or did I miss something?
(https://docs.unrealengine.com/5.1/en-US/statetree-quick-start-guide/ step 5 - Create a New State Tree Task)
Yeah
There are 4 Categories that you can use. I don't know why they don't point this out.
Context: Binds to Variables from the "Context" of your StateTree. Without further C++ changes, that's just a variable named "Actor" with the Type of "Context Actor Class", which you can select in the StateTree asset at the top left.
Parameter: Those show up as parameters when you select the Task/Condition/Evaluator(?). The variable has to be marked as "Instance Editable" though. It's a variable you can define per Task Instance, so if you use the Task in two places, you can pass in a value. E.g. a boolean, and integer, etc. Like a float for how long a Delay should be.
Output: Provides this Value as an "Input" option for other Tasks/etc. that have a variable in the Input Category with the same Type I assume.
Input: Requires you to bind another Variable to this when using it. Example would be a Task that provides a "TargetLocation" as Output and a second Task that requires a "TargetLocation" as Input. When using them both in the same State (not sure about this, but I couldn't bind to anything from a different State on the same level at least), you can then bind the Input of one to the Output of the other, forward variable. Basically like a Function with Outputs and Inputs.
--
So here I can't seem to bind the Input of Roam to Point (or rather Enemy Move To) to Find Point (or rather Output of Enemy Find Roam Location).
Ok, that's valuable information, thank you!
Even though they happen in order
This would work, but that's not what I want
So instead I moved both tasks into one State, after each other. That should theoretically do the trick (: it compiles at least
Gonna try and remake exactly what you've got there xD
At least I think that's correct
Honestly, try to recreate your BehaviorTree first
Mine will look wildly different eventually I assume
Good thing though is that this removes this nasty global Blackboard with TargetLocation in it
Yeah I've got the Tree set up roughly, now I'm trying to implement this MoveTo part (either move to a user-set target point in the level or a random roam point around that target point once the unit arrives)