Search Unity

Physics2D casts for object detection questions, colliders vs casts, NonAlloc size, multiple casts...

Discussion in 'Physics' started by KOKOStern, Dec 21, 2018.

  1. KOKOStern

    KOKOStern

    Joined:
    Dec 22, 2013
    Posts:
    13
    I have a bunch of AI agents in my strategy / simulation game. As they are autonomous I want each to constantly check its surrounding and react to objects and other Npcs. I have identifiers on each 'thing' in my game to know what it is and how to behave towards it. My question is about physics performance and best practices.

    My area checks happens roughly 10 times a second for each AI (but spaced for performance). Consider up to 100 agents in the scene (big skirmishes). I'm using Physics2D.OverlapCircleNonAlloc for up to 10 targets as I don't want constant allocations.
    Q1: Can I up that to 20? 50? 100? I don't want allocs for sure but how much can I allow myself to just hold for those times where I actually need the whole hit array?

    Q2:
    Is there any 'method' to the hits I get? Am I guaranteed the first hit is the closest and the last the furthest? If not I might have to check what's closest which is not fun when dealing with so many units. If they are all tight together and I lose some (I check for 10 but there are 20 in a skirmish) I could pick a target that's not optimal.

    Aside from my identifiers, I also have some things on different layers. Items (static) and agents (move around) for example.
    Q3: Is it better to cast multiple times - one for each layer, or make one cast for all the layers and then sort them out? Single casts allows me to already know what I'm dealing with, but I would assume as little casts as possible is the smartest choice here. I'm gonna be doing lots of casts anyways so minimize as much as possible. Right?
    Example: I hit 10 targets, 0-8 are items, but 9 is an enemy. I have to check what each thing is until I reach the enemy because I'll address it before any items. If I cast for enemies and hit that, I don't even cast for items in that check since I'm dealing with an enemy.
    Separate casts also allow me to have different radius for each 'thing' category, which might be useful in the future.
    Bottom line - what's the performance difference between these?

    Q4: Since I don't need frame by frame checks I went with casts instead of colliders. Doing some digging colliders have a ton of fancy optimizations and you should totally use them for continuous jobs over casts. Casts should only be used for very specific checks!
    Is this true and should I switch to constant collider checks or stick to my spaced out casts (which to me make sense are way more performant but I don't know that).

    Any advice would be greatly appreciated. Shedding some light on these big physics questions can really make me make more educated decisions about my systems.

    Please let me know if you require any additional info.
     
    adar_unity likes this.
  2. alior

    alior

    Joined:
    Sep 6, 2014
    Posts:
    25
    Hi!

    A1 you can use large array to get all overlaps (lets say 1000 entries) and reuse it every time you need. The function returns how much actual overlaps you got.

    A2 There is no particular order so you should not rely on that. You can for instance sort them by distance or other characteristic you want (sorting of small list/array will be pretty much for-free)

    A3 The less you do, the less you pay. But in that case you better to overlap with max radius (I mean if max item reach is 10 and max attack reach is 1000, you just overlap for 1000) once and then manually decide is it okay for your category to be that far. If you don't want, you can take advantage of layers with multiple overlap approach but I believe it will be a bit slower. (but you have to test it to know for sure)

    A4 for sure colliders has some optimizations (I believe), but, it's hard to manage them and sometimes it gets messy. I would say that you have to test overlap approach.

    Don't hesitate to contact me.