Download

Training Stream - Making Game Ready AI, part 10 - March 1st, 2016

WHAT
In this multi-part series, Ian Shadden and Alexander Paschall show you how to use all of the relevant systems and features (Behavior Trees, EQS, Navigation Meshes, AnimBlueprints, AnimMontages, and more) to design, create, and optimize AI for use in a game environment with all of the requirements and restrictions that go along with that.

In Part 10 Mieszko will take us through the converting some of our functionality to C++ so we can create a custom C++ Environment Query Test.

Part 9

WHEN
Tuesday, Mar 1st @ 2:00PM-3:00PM ET - Countdown

WHERE

WHO
Ian Shadden - Sr Training Content Creator @Shaddenfreude](https://twitter.com/Shaddenfreude)
Alexander Paschall - Community Manager @UnrealAlexander](https://twitter.com/UnrealAlexander)
Mieszko Zielinski - Sr AI Programmer @MieszkoZ](https://twitter.com/MieszkoZ)

Feel free to ask any questions on the topic in the thread below, and remember, while we try to give attention to all inquiries, it’s not always possible to answer everyone’s questions as they come up. This is especially true for off-topic requests, as it’s rather likely that we don’t have the appropriate person around to answer. Thanks for understanding!

How to set up your VS2015 free edition!

I’m exited, I will for sure be present for this. I am a new developer in the making trying to learn this program.

Awesome! Sorry for the slightly off topic question, I’m just wondering if there’ll be some more detailed documentation on the amazing AI Perpection node that has been in the editor for a while now, along with some solid examples linked in with behavior trees and EQS! I understand you guys are super busy, especially working on titles while developing these features, so it’s totally understandable, but I would love to see Mieszko’s blog return, there was some really valuable info on there! Also is there a reason that EQS is still in experimental in the editor? (I always shy away from using features in experimental for some reason, even though EQS works like a charm). Keep up the awesome work and thank you for the great tools!

In line with TYGABYTE’s question, should AI Perception be used in place of Pawn Sensing? In conjunction? Any reason we should use one and not the other? Sorry for the broad questions, but any/all information on this topic would be incredibly helpful!

I’m very excited for this. Would like to know more about Epic’s plan on making Dynamic QueryParameters in EQS. Right now parameters have to be manually set , this isn’t ideal.

For this I have to hardhack the dynamic parameters into custom test when all it takes is a dynamic queryparameter.

Hey All,

Just talked with Miezsko and to get the most out of what we’re going to show, we’ll be updating to 4.11 Preview 6. We’ve tested everything we’ll be doing and it all seems solid.

So yea, setup VS 2015 Community if you don’t have it yet (remember it doesn’t install C++ by default!) and pull 4.11 Preview 6 if you want to follow along.

Sweet, its always double the party when Mieszko joins =)

I’m using an github build of the Engine. Can can follow along with VS13 as well? Did Not install VS15 so far.

regards

Some questions for Mieszko if there’s time:

  • Is it possible to procedurally alter path cost, so that pathing choice can be affected based on dynamic agent/world state?

  • How is path length for nav link proxies calculated, does it use the linear distance between the endpoints? A path using a nav link proxy (with NavAreaDefault) is showing a significantly lower cost than a very similar path directly over the nav mesh.

  • Is the navigation system set up such that it’s possible to add a custom implementation of ANavigationData (to handle a different kind of movement, for example, hanging/climbing along structures), combine these in a level with a regular navmesh, and the pathfinding will automatically integrate both?

Thanks!

I just found this series last week and have followed it to today’s broadcast. I’ve been able to create everything you’ve done as you’ve done it. That is, until episode 9 when you performed a lot of refactoring offline. You even said you did a little debugging during that refactoring, which may have changed some functionality, even if unintended.

Could we got a catchup? Posting of your blueprints as they are? This video was perfect in that you showed everything that was done (mostly, you did fix that one bug offline). Point being, I can’t maintain parity with the project.

An even better concept, generally speaking from a training perspective, would be to have a GitHub project that we could clone and have the commit history over the life of the project. Then we’ve got commit history per episode and any offline work. It’d probably really help those following the live stream as they could just git the advanced project notes (should be a small download at that point).

And thanks for this, BTW. One of the best training feeds I’ve seen in a while.

I second this request. The editor crashed on me during the last video and subsequently corrupted a number of blueprints at random. Really weird. So I’ve kind of lost interest in following along now without being able to keep my project in sync with what is going on.

Been following eagerly since the start. Great work guys!
I got lost last episode with the changes done offline:

can we get an upload of the project or some blueprints that were affected?
I tried to follow what changes were done by pausing the video and attempting to recreate everything that you went past but i got a bit lost.
So for a newbie its a bit beyond me to stray from the path and figure this out.
Thanks for all your efforts - this has been a really interesting stream for AI
Keep up the great work - appreciate it

Awesome series guys! Keep it going.

A small clipping of the AI Dude I’ve made based of this series. Cheers!

Also, I dunno if this is a thing, but I might have noticed a possible bug; say you have more than one object variable type in your blackboard, say DesiredObject and Shrine. When you put in a “MoveTo” node in the tree, the node only lists the first added object variable. Is this intentional? If so, any particular reason for this?

Hi kamrann,

I am also very interested in this question, I was watching the Training Stream Making Game Ready AI part 10 and @mieszko say that it is possible in C++, he mention something like Path Query Filter (I think that was the name of the class that he mention, my english is not very good :frowning: ) but i can’t find that class, the more similar class that I find is NavigationQueryFilter.h. URecastFilter_UseDefaultArea extend from that class and URecastFilter_UseDefaultArea is one of the filter calss that you can use for example in the Move to BT Task.

FNavigationQueryFilter implement INavigationQueryFilterInterface that has some virtual function like SetAreaCost etc, they seem to be what I’m looking for. But i am not complety sure about that or how exactly use it. Maybe you or @MieszkoZ can point me in the right direction. The think that I need to do is almost exactly the same example that @MieszkoZ say when he answer your question.

PD: Sorry for my english :S

Best regards

Hi @kamrann have you found some way to do this ?

I will appreciate if you or @MieszkoZ can point me in the right direction but with a more clear example :slight_smile:

Thanks so much

Best regards

Hi @nan2cc. Sorry for the really late reply, I have been travelling and not worked on UE4 stuff for the last month or so.

Soon after that stream, I did have a quick look into what Mieszko mentioned. I believe the class he was talking about was dtQueryFilter, in DetourNavMeshQuery.h. I haven’t tried to implement anything yet, but my initial reaction was that this class seems rather low-level, and that it may not be all that easy to implement dynamic pathing on the level I wanted whilst still maintaining compatibility with the higher level parts of UE4’s pathing code.

I didn’t dig in detail, so I could be wrong. But from what I can see, a lot of the nav area/nav filter stuff is implemented such that you are expected to define a new UClass (as opposed to instantiating a new UObject) in order to specify a new type of area/filter, which makes it inherently static. I honestly don’t know why it has been done in this way, it seems unnecessarily limiting.

That said, depending on how dynamic you want it to be, you may well be able to achieve what you need without overriding anything at such a low level (see Rama’s link in your AH post, however I suspect that isn’t quite what you’re after).

I’ll probably have a go at doing this once I’m back from my trip and will report back here if I make some progress, but that likely won’t be for another month or two.

Hi @kamrann

Sorry for the really late reply. I have been busy with another things all this months, but now I am on this again. Let me explain better my problem, because I has been reviewing the QueryFilter (using the Rama’s link) and I think that using query filter I can modify the cost just of specific NavAreas. But this navareas need to be on level

But my problem is that I need to modify the cost without using a pre-placed navarea. See the picture below and the explanation.

http://blog.spissa.com/wp-content/uploads/2016/07/sample.jpg

Option A: Shortest, but exposed to the player. This will be the option selected by the standard Move to, because the A* will select the shortest path. but I dont want this path because is completely exposed to the player, player will kill me immediately.

The best option in this case is the second path (Option B in the picture). Is longer but safe because is not exposed to the player

But the problem is that I only need to modify the path in runtime, because the first path is a bad option ONLY if the player is around that position.

So, the solution that I am trying to get is, check the points involved in each posible path and alter the cost based on some codision, maybe a LOS to Player. By this way I will increase the cost of the path if the points has LOS to the player, because this means that the path is exposed to the player.

Sorry for my english, hopefully now you can get a better picture of what i need.

Thanks for your answer

Yeah I haven’t had a chance to get back to this either. Looks like you would indeed need to look into the dtQueryFilter class (as opposed to the higher level QueryFilter) to properly solve that.

I can think of a couple of higher level workarounds if you want something easier.

You could calculate behaviour at the behaviour tree level - evaluate potential cover spots, then calculate a path to each, analyse the paths to see if they pass too close to the player, and choose which destination to actually path to accordingly.

Or, I imagine you could attach a nav modifier volume (with higher cost area) to your player, and enable dynamic nav mesh. I haven’t tried anything like that before, but I think it should work.

Obviously both these solutions are a fair bit less flexible than true dynamic path cost.

Hi kamrann

Thanks again for your answer,

In this case, suppose that we have only one cover location. Like the example above. I can get the path before call the Move To, and I can get each point and evaluate how many points of that path are exposed to the player. But the problem is that the path that I will get is the shortest, so I need a way to get differents options and then i can run the evaluate function. But I dont know how to get different paths options to one destinatios. Do you know how do it ?

The second solutions that you suggest me, look interesting. I just notice that now we have a NavModifierComponent, I think that if I add that component to the Player, I can get something like the desired behavior because the nav modifier component will increase the cost in the areas around the player. I dont know if this is the best options for solve this problem. Will be great if @MieszkoZ or someone else can point us in the right direction.

The last option is the dtQueryFilter I mean, probably we can solve the problem with that but I think that is a little low level solution, probably the framework provide another higher level way to do it.

Well, I going to test the NavModifierCOmponent options and talk to you soon

As always … sorry for my english :S

Best regards

Nope, can’t think of a reasonable way to do it with the built in functionality. I think NavModifiers is probably the best way to go for your specific requirements.