Search Unity

Question OverlapCircleAll Optimization

Discussion in 'Physics' started by maxreee, Jun 7, 2023.

  1. maxreee

    maxreee

    Joined:
    Mar 21, 2020
    Posts:
    39
    I'm working on a game where you control minions to go and fight enemies and this targeting system, I made was supposed to allow the targeting of multiple enemies (at least I hope so anyway)
    it has some issues 2 big ones, but the one I wanted to discuss is OverlapCircleAll as I've heard that it makes new arrays and discards them later.
    leading to garbage collecting and lower performance overtime especially if you are trying to have multiple targets.

    is there any way I can improve this?
    I've heard of NonAlloc but I don't really know how to apply it to my code without breaking it (more than it already is)
    Code (CSharp):
    1. private void FOV()
    2.     {
    3.        
    4.          rangeCheck = Physics2D.OverlapCircleAll(transform.position, radius, targetLayer);
    5.         if (rangeCheck.Length > 0)
    6.         {
    7.             Transform target = rangeCheck[0].transform;
    8.             Vector2 directionToTarget = (target.position - transform.position).normalized;
    9.  
    10.             float distanceToTarget = Vector2.Distance(transform.position, target.position);
    11.             //used in another script to determine movement
    12.             targetT = rangeCheck[0].transform;
    13.  
    14.             if (!Physics2D.Raycast(transform.position, directionToTarget, distanceToTarget, obstructionLayer))
    15.             {
    16.                 CanSeeTarget = true;
    17.             }
    18.             else
    19.                 CanSeeTarget = false;
    20.         }
    21.         else if (CanSeeTarget)
    22.             CanSeeTarget = false;
    23.     }
     
  2. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    7,935
    This is performance speculation. Do you presently have a performance issue? Did you profile to confirm that you have a performance issue? Y/N?

    If N, don't worry about it and move on with your project.

    And the only difference in usable with the NonAlloc versions of methods is you provide an already allocated collection for it to fill (passed in via reference), rather than getting a new collection as a return value.
     
    Yuchen_Chang likes this.
  3. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,500
    Don't use any of the "NonAlloc" physics calls they are tentatively deprecated. All physics queries (without exception) have overloads without that suffix so look at OverlapCircle; you can pass a fixed-array or more preferably pass and reuse a List<T> for your results. The lists capacity will automatically be increased if necessary and its size will always be
    how many results you get. This means you'll get little to no GC if you reuse.

    Well it's not really different other than you providing an array or list to return the results to so just look at the Scripting API for what to use.

    What I don't understand is why you're asking for everything in the circle then only look at the first one, that in itself is very wasteful.

    Note that there's a Physics2D.LineCast that enables you to check between two positions in world-space so you don't need to calculate direction and distance.
     
  4. maxreee

    maxreee

    Joined:
    Mar 21, 2020
    Posts:
    39
    pardon me for the wait

    if im not mistaken i just have to provide a list or an array to overlapcircle as a result instead of using NonAlloc

    the reason for that is to allow some enemies/minions to be able to attack multiple individuals at once
    which kinda makes setting the target as the first one in the [Field of View] script kind of pointless but that is just for testing purposes

    I also have a question regarding what i should do if the target is lost/leaves the FOV of the pursuer as everytime the target does leave the radius it throws out an error and breaks the script
     
  5. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,500
    It's the same as NonAlloc where you provide where the results should go expect it's going to be supported moving forward and doesn't have a silly suffix. ;)

    I don't understand unless you mean you've not written it to deal with no results returned.
     
  6. maxreee

    maxreee

    Joined:
    Mar 21, 2020
    Posts:
    39
    cool cool ill try and use it now

    yeah thats the gist if it

    Edit: my rangecheck variable is a collider2D[] and adding a result makes it an integer right
    so i wouldn't be able to check the length of it
    unless there is something I'm not getting
    Code (CSharp):
    1. public Collider2D[] rangeCheck;
    2.     private Collider2D[] result;
    3.  
    4.  
    5. rangeCheck = Physics2D.OverlapCircle(transform.position, radius, result, targetLayer);
    6.         if (rangeCheck.Length > 0)
    7.         {
    8.             Transform target = rangeCheck[0].transform;
    9.             Vector2 directionToTarget = (target.position - transform.position).normalized;
     
    Last edited: Jun 10, 2023
  7. maxreee

    maxreee

    Joined:
    Mar 21, 2020
    Posts:
    39
    just curious does this only work on one target or multiple
     
  8. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,500
    Just look at the docs, it returns an integer saying how many results were returned. You'll need this to know how many elements of the array were filled so you can only look at those. (Re)use a List<T> instead of an array, that way the size of the list is always the same as the number of results.

    All physics queries return multiple results. Again, no need to ask me, just look at the scripting docs! :)
     
  9. maxreee

    maxreee

    Joined:
    Mar 21, 2020
    Posts:
    39
    alright will do