I am trying to implement AI Perception - Sight into my game. The game is a type of tower defense, with enemy characters that walk on the ground towards a specified goal. I would like to make them see the towers then decide if it should fight or avoid.
However, I can’t seem to get consistent responses from the perception component. I have ‘AI Perception’ component on my Enemy AI Controller, set it to Sight and have set the config to include all 3 “team” members, Neutral, Enemy, Friend (as mentioned by @mieszko). I have added the AI Perception Stimuli Source to the Super parent of my towers and set it to Sight.
I ensure the Stimuli Source is registered, both by Register Node as well as the default ‘Auto Register’ (and I have also attempted altering these to see if something would work.)
As far as I can tell, everything is setup like it should be. When I play and test everything out, some times it will see the tower(s) and sometimes it won’t, which leads me to believe I have everything setup as it should be, because it will on occasion see the placement. I’ll even set 3 of the same placement side by side and sometimes it sees some of them but ignores the others right next to it.
In the first 2 pictures you will notice that it sees different objects under the exact same conditions (nothing changed except a new game instance.) Worth noting that sometimes it won’t see any of them.
And in this final image, you will notice that while it saw 3/4 of the objects, it broke sight after getting a little closer (denoted by the broken green lines that go from the object to behind the enemy.)
If it makes a difference, these assets aren’t loaded into the game on start. They are placed in the world by the player.
Please let me know if I’m doing something wrong or if this is a possible bug? I’m not sure how/why it would be a bug unless it came in 4.10.1 because I’ve tried to do exactly like was done in the Training Twitch by Ian, Alexander and Mieszko where they added perception using I believe only 4.10.0. So I’m not sure if something possibly went wrong with the update. This project was created fresh in 4.10.1 and not migrated up from a previous version.
I have a few questions that could help identify the cause of the issue you are experiencing:
If you try placing the actors in the level manually before you start the game instead of placing them with your player, does the Perception register correctly?
I’ve seen cases where landscape collision blocks line-of-sight. Is it possible that this is occurring in your case?
Thanks for the reply! Initially the landscape does block the direct line of sight as the NPC begins the level but as he draws nearer, line of sight is clear and should be able to pick it up/see it. If the collision is the issue that would mean that perception will only notice new things that entered the line of sight initially rather than at any point it has a clear view of it.
For your other suggestion I will get back to you later when I’m able to test that. I only tried placing persistent objects to test EQS, not perception.
Hey Sean, so I tested this dropping in persistent obects into the world rather than placing them during the game. While it seems slightly more consistent in seeing the objects, it’s still hit-or-miss. If I put 4 towers in side by side, like I did similar to the images above, it will notice some of them when they enter the sight radius and will occasionally see all of them but only when it is right next to them. I’ve tried varying the locations of both the objects as well as where I start the NPC but had similar results as mentioned above regardless of positioning. I then placed only 2 objects in the NPC’s path (persistently not dynamically) and it noticed 1 of the objects and didn’t notice the other till it was literally right next to the object, just before it passed it and out of its field of view.
My results during this round of testing were more consistent in the fact that I could predict which object it would see first and so forth; however, it is still inconsistent with regards to actually seeing the objects when they enter the line of sight.
Thanks for performing the additional tests and providing more information on your issue. I’ve attempted to reproduce the issue that you’re having on our end, but I haven’t been able to see the same behavior.
Have you been able to reproduce your issue in a clean project? If you are unable to do so, would you mind zipping up your project and providing a link to a Dropbox where I can download it?
Thanks Sean. This, for the most part, is a relatively clean project and to reproduce this behavior in another project would still require most of the code I have in the game as of current.
I wouldn’t mind sending you a zipped copy of the project via Dropbox but do you have an email I can send the link to so I don’t have to make the download public?
I’ve spent some time looking into your project, and I’m not sure I’m understanding exactly what is supposed to be happening.
Your perception seems to be set up so the character can see the turrets, but I don’t see you calling any OnPerceptionUpdated events anywhere, other than the unhooked ones in the Controller that you are using for testing purposes. Are you calling OnPerceptionUpdated somewhere else that I am missing?
Basically, I’d just like clarification on exactly which behavior you are expecting to see so that I can better understand what is going on. I see the turrets firing on the enemy without a problem, but I’m having trouble understanding exactly what the enemies are supposed to do when they see the turrets.
Hey Sean. I’m not doing anything with it right now because it’s not seeing anything (or only part of everything.) I had the updated event hooked up to test but it spams the screen with the player pawn (which has always baffled me because it’s not a registered stimuli source) which meant I had to dig through the output log feed.
To make my life easier I was just using the in editor debug feature to view the perception. Using that, and looking at the images above, you can easily tell what it sees and what it doesn’t. The logic for what I want to do hasn’t been implemented yet because it’s not seeing everything. Ultimately I will want it to take everything in its sight radius, evaluate them (they won’t always be the same tower) and decide which tower/target is its best chance for success. But again, I can’t implement this until it actually sees everything in its sight radius.
It’s possible that this could be something related to the debugger not displaying the proper information, which is why I was wondering if it would actually function as expected when you implemented it.
When you had it hooked up for debugging purposes, were you seeing results print out to the log that were consistent with what the debugger was showing you?
Ya everything was consistent. The update perception only occurs when something changes in perception so if it would see the object, it would print it’s name once and ignore what it couldn’t see or failed to see. With the update perception hooked up, if I move an object that is attached to the cursor, before I place it, the update triggered consistently and constantly.
I also had the perception hooked up to tick to get all objects it sees and aside from continually spamming the player pawn, it would only print the name of the object it would see, consistent with the debugger in the editor.
Looking at your pictures again, have you tried increasing the Peripheral Vision Angle on your EnemyController_Ground’s Perception component? It could be that the turrets that are not being detected are outside of that 90 degree arc that is set by default. Try making it something like 180 or even higher depending on what suits you.
I did try this and result is the same. The PVA is actually calculated from both sides of the forward vector of the actor so a 90 degree PVA is 90 degrees to both sides, giving the actor a 180 degree field of view while a 180 PVA would give the actor a full 360 degrees of sight. The debug editor displays this with a green line (which should be different by default for clarity) that you can see in the images running perpendicular and through the actor in the sphere of its sight radius.
I’ve spent some more time looking into your project, and it’s still a bit difficult to determine exactly what the issue is.
Do you notice that the debug “ball” (the one that should rest on a perceived actor), for lack of a better word, moves as you move the camera? It doesn’t actually seem to attach to the perceived actor. Is this the same behavior you are experiencing?
Also, I upgraded the project to 4.11 Preview 3, and the perception seemed to be functioning properly. Although there were other errors that appeared as a result of the conversion, the perception was registering much more clearly. Give that a shot and see if you can get the same results.
Ya I think it’s quite odd that the perception registers the player pawn/camera since it has no stimuli source to it but I noticed this behavior when Ian Shadden does his perception in the AI live streams.
That concerns me that you received a bunch of errors when you updated to 4.11.P3 hopefully it’s because P3 is only a preview. I would hate not being able to update the project to an expectedly feature rich update. I could make a backup copy of the project and attempt the perception in that. I will let you know how it goes.
The sight sense uses as a default GetActorLocation as the target point for tracing to check if an actor is visible. So one thing you should check is the pivot point of your mesh. If it’s at the base of the mesh, then it may be coincident with or slightly below the landscape. Even on a perfectly flat landscape, floating point precision errors could mean that sometimes the trace will hit the landscape before hitting the mesh, which will result in a failed sight sense.
An easy way to see if this is the issue would be to replace your tower meshes with the default sphere mesh, and see if that fixes things.
That is a very sensible answer! I’m going to give that a shot and let you know. If this is the case how would you suggest I handle placing the towers? Move the pivot up some then offset the mesh up that amount when placed?
Yeah I guess just adjust it in your 3D modelling program, or add an extra scene component into the blueprint to offset it.
Ideally the right approach is to override the method the perception system uses to determine if an object is visible. This way you can account for the object’s size and other variables if you need to. There’s an interface set up for this in the code, but as far as I’m aware it’s not currently exposed to blueprints.
This was absolutely the correct answer! I put each tower/object only 10cm up from the landscape and ** every ** object was seen when it should have been seen! I figured GetActorLocation used the pivot point but I didn’t figure Perception used it. I assumed it would look for the bounds or collisions of the object using a trace.
I was able to get similar results, bypassing Perception using EQS, before you gave me the answer. Worked decently but if I’m not mistaken Perception is better to use than EQS for this? Although, now I’m going to combine Perception with EQS to get the desired behaviors I need but at least now my behavior tree doesn’t need the extra EQS procedure to return it’s “seen” actors and can run independently of each other.