Search Unity

How can I make this faster?

Discussion in 'Scripting' started by Senladar, Jan 31, 2015.

  1. Senladar

    Senladar

    Joined:
    Jan 1, 2015
    Posts:
    45
    I'm working on a isometric game and I want to have a lot of AI that follow and attack the player (Think zerging). I'm currently getting a decent (about 5-10FPS) drop if I have 10+ AI chasing me at the same time.

    I'm using the unity navMesh stuff to control the AI. The reduction seems to start when they actually start moving towards the player, which is this code:

    Code (CSharp):
    1. if (playerFound == true && selectedPlayer != 100 && aiRanged.hitDetected == false) {
    2.             navMesh.destination = targetTransform.position;
    3.         } else {
    4.             //Stops the AI
    5.             navMesh.Stop ();
    6.         }
    I just recently set the targetTransform so it only has to calculate that once and that helped, but wondering if there's anything else I can do.

    Note that I'm still pretty new to coding in general.
     
  2. Senladar

    Senladar

    Joined:
    Jan 1, 2015
    Posts:
    45
    Looks like the issue was related to how I was calculating the selecterPlayer, all fixed :)
     
  3. Crayz

    Crayz

    Joined:
    Mar 17, 2014
    Posts:
    193
    I'm not sure if you're executing this in an Update or FixedUpdate, but you could place it in a coroutine or set up a a sort of timer that runs every ~0.1 seconds rather then every frame/tick. It doesn't make any visible difference but cuts back pretty decently on execution.
     
  4. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    Kind of a fan of queues myself. AI generally runs each frame if close enough, but expensive stuff is queued, and executes max one per frame.
     
  5. Senladar

    Senladar

    Joined:
    Jan 1, 2015
    Posts:
    45
    Sorry, can you explain a bit more? I moved out the "find player" stuff so it only calculate if it needs too rather then every frame, but if there's a better way I'm interested! (Again, I'm really just doing stuff to learn)

    To give a bit more context, I have four "players" that I can switch between. I use a function with a OverlapSphere to find the closet "player" and set that as the target, then move to it.

    Here's the code:

    In Update
    Code (CSharp):
    1.     void Update () {
    2.  
    3.         //If a player isn't found, look for one
    4.         if (!playerFound) {
    5.            
    6.             FindNewPlayer ();
    7.            
    8.         }
    9.        
    10.         //Moves the AI if a player was found in range
    11.         if (playerFound == true && selectedPlayer != 100 && aiRanged.hitDetected == false) {
    12.             navMesh.destination = targetTransform.position;
    13.         } else {
    14.             //Stops the AI
    15.             navMesh.Stop ();
    16.         }
    17.  
    18.         //Sphere ray
    19.         minPlayerRange = Physics.OverlapSphere (myTransform.position, minRange, layerMask);
    20.  
    21.         //Checks minPlayerRange
    22.         if (minPlayerRange.Length > 0) {
    23.  
    24.             FindNewPlayerMin();
    25.  
    26.         }
    27.        
    28.     }
    FindNewPlayerMin is used to switch targets if a new one gets really close:

    Code (CSharp):
    1.     void FindNewPlayerMin(){
    2.  
    3.        
    4.         int i = 0;
    5.         float distance = 0;
    6.        
    7.         //Loops through each of the colliders
    8.         foreach (Collider other in minPlayerRange) {
    9.             //Adds the distance between the AI and the player to an array
    10.             playerPOS.Add (Vector3.Distance (myTransform.position, other.transform.position));
    11.             //subtracts the distance from the distance int to determine the closest target
    12.             if ((distance - playerPOS [0 + i]) < 0) {
    13.                 //Sets the closet target
    14.                 distance = playerPOS [0 + i];
    15.                 selectedPlayer = other.GetComponent<Player_Selector> ().playerID;
    16.                 targetTransform = target [selectedPlayer].transform;
    17.             }
    18.             i++;
    19.            
    20.         }
    21.  
    22.     }
    FindNewPlayer is used to find a player to begin with

    Code (CSharp):
    1. void FindNewPlayer(){
    2.         //Sphere ray
    3.         targetPlayerRange = Physics.OverlapSphere(myTransform.position,targetRange,layerMask);
    4.  
    5.         //Checks minPlayerRange
    6.         if (targetPlayerRange.Length > 0 && selectedPlayer == 100) {
    7.            
    8.             int i = 0;
    9.             float distance = 0;
    10.             //Loops through each of the colliders
    11.             foreach (Collider other in targetPlayerRange) {
    12.                 //Adds the distance between the AI and the player to an array
    13.                 playerPOS.Add (Vector3.Distance (myTransform.position, other.transform.position));
    14.                 //subtracts the distance from the distance int to determine the closest target
    15.                 if((distance - playerPOS[0 + i]) < 0){
    16.                     //Sets the closet target
    17.                     distance = playerPOS[0 + i];
    18.                     selectedPlayer = other.GetComponent<Player_Selector>().playerID;
    19.                    
    20.                 }
    21.                 i++;
    22.                
    23.             }
    24.            
    25.         }
    26.  
    27.         //If player is found, updates Playerfound.
    28.         if (selectedPlayer != 100) {
    29.            
    30.             playerFound = true;
    31.             targetTransform = target [selectedPlayer].transform;
    32.         } else {
    33.             playerFound = false;
    34.            
    35.         }
    36.        
    37.     }