Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Efficient Handling of AI Proximity

Discussion in 'Scripting' started by jtsmith1287, Feb 18, 2015.

  1. jtsmith1287

    jtsmith1287

    Joined:
    Aug 3, 2014
    Posts:
    787
    My base AI units have colliders for their basic collision stuff. Detecting when hit, running into things, etc. But I'd also like to add larger collider for things that are nearby, and then another even larger collider for things that it should be able to see. The plan is to have only select things interact with the trigger, and allow the AI to process what these things are to determine how to respond. So if there's a slow moving projectile and it determines that it's moving towards it, the AI will attempt to get out of the way. It could also use this to attempt to put nearby obstacles between itself and the attacking player.

    Thoughts on this approach? I'm confident I could make it work, but I'm mostly concerned with the CPU hit for constant collider events, and the iterative method at which I plan to use to process information. Basically adding colliding objects to a list of "adjacent" objects and "nearby" objects and looping over them to apply logic.

    I suppose I could just classify the object upon collision and sort it into varying containers, and process things that way.

    Anyway. Thoughts?

    Oh and this is a static environment. So think arena, I guess. The playing area is the bounds of the viewport and the camera doesn't move.
     
  2. dterbeest

    dterbeest

    Joined:
    Mar 23, 2012
    Posts:
    389
    using colliders to check area might not be the best idea, because colliders are not really intended for moving them around. A simpler approach would be to check the distance to the player using Vector3.Distance(this.transform, playerTransform)

    If you want to go allout and check if the enemy can actually see the player you coudl use a raycast, direct it towards the player for x amount of distance and see if it hits the player
     
  3. jtsmith1287

    jtsmith1287

    Joined:
    Aug 3, 2014
    Posts:
    787
    Oh... wait what? I would be surprised to see a game that did not have a collider that moved around. I would think that using a collider would be more efficient than raycasting to every potential collide-able object in the scene (think projectiles and players and allied AI.
     
  4. Zaladur

    Zaladur

    Joined:
    Oct 20, 2012
    Posts:
    392
    I agree that raycasting could get cumbersome fast - Colliders are fine to move. Smart use of Layers will cut down on the number of Triggers you deal with. As a basis - a ground layer, a unit layer, obstacle layer, projectile layer, and a couple different detection layers.

    Say, the outer detection layer only collides with units and obstacles, and might be used to come up with how best to move about the scene. I would add these objects to a collection when they enter your trigger zone, and remove them when they leave. Occasionally your AI will look into the collection when determining the next course of action, in a broader sense. (My team is fighting some foes over there, I should go and help out! Or.... I need to find cover. What cover zones are nearby that I can take refuge behind?)

    A Middle detection layer might consider units and projectiles, for quick reaction to nearby foes or attacks. These might trigger right when objects enter it. (Whoa! a fireball! And it is headed in my direction! I should attempt to dodge, if possible. Or.... That foe is approaching me. I should swap to a battle stance and commence my attack.)

    And then of course you have your actual collision layer. I was hit by that fireball! Ow!

    Obviously, the more you are trying to do, the harder hit you will take. But separating into, as an example, general information detection, sudden reaction detection, and actual collision detection will allow you to allocate your resources in a smarter manner. And using layers to selectively ignore certain objects (I don't need to know about every projectile in my line of view - only the ones that are nearby and approaching me) will cut back on the number of objects you need to process.

    I'm still refining my system, so I haven't pushed it into the heavy load testing yet, but that is my current approach.
     
  5. jtsmith1287

    jtsmith1287

    Joined:
    Aug 3, 2014
    Posts:
    787
    Glad to hear someone else has the same idea. I hadn't thought of separating the purpose of the 2 outer colliders. I was already planning on using physics layers to cut down on cost, but ya, that's great advice. I also hadn't thought of AI taking care of their buddies. That's something I'll have to look into. Might not work for my game but if I can pull it off it would really add a nice dynamic.
     
  6. Heisenbug

    Heisenbug

    Joined:
    Aug 31, 2012
    Posts:
    40
    I suggest you to profile before making any assumption. You may find out that you have no reason to optimize.
    I can't give you a precise answer, because there are lot of specific details to consider. Of course the more events you are trying to catch, the more computation intensive will be your game.

    Just some hints, from my experience on similar issues.
    I'm working on a 3D stealth game. Each enemy has a 3D view cone through which can detect the player.
    Our basic algorithm work like this:

    1. Use a relatively big sphere trigger for each enemy. When player is outside it, every visibility check is disabled because enemy can't see him.
    2. When enemy sensor are activated by the trigger and the enemy is looking approximately in the player direction a cone-sphere intersection test start to run (not every frame - for our specific relative velocities checking for player visibility every 5/6 frame is enough.. even less). In our case we can approximate player collider with a sphere.
    3. When player is inside the enemy visibility cone we cast a ray over the navmesh to check if player is behind an obstacle (raycasting over navmesh is much faster the a physics raycast)
    4. If an obstacle is in between player and the enemy, depending on the obstacle type (es. stand up behind a low obstacle) some additional more precise tests can performed using raycasts

    General advices:

    • Simplify as much as possible collision matrix
    • Don't try to be super precise in the first attemp, a broad phase which analyze game events can help a lot with performances
    • Don't try to consider everything (does really your AI need to consider every projectile? Maybe it can only try do avoid shot considering its relative position from the player..)
     
  7. jtsmith1287

    jtsmith1287

    Joined:
    Aug 3, 2014
    Posts:
    787
    Super solid advice, thank you! I could probably disable the two inside colliders if there's nothing at all inside the outermost collider. Not sure what that would cut down though but It's something I'll keep an eye out for.

    Question for the masses: Do colliders cost anything when nothing is colliding?

    If this was a single player game I'm sure I'd see some gains by only analyzing some projectiles (I have enemy and player projectiles on separate physics layers already) but there will be multiple players and I am guessing if the projectile is nearby it'll matter. I was initially thinking of analyzing the trajectory of the projectile when it first triggered and discarding it if it didn't pose a threat. However, that's assuming that the AI wouldn't decide to dodge a different projectile and subsequently moving into the path of that discarded projectile. So unfortunately I think I'll have to analyze them all. I could be wrong though. We shall seeeeeee.