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): if (playerFound == true && selectedPlayer != 100 && aiRanged.hitDetected == false) { navMesh.destination = targetTransform.position; } else { //Stops the AI navMesh.Stop (); } 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.
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.
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.
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): void Update () { //If a player isn't found, look for one if (!playerFound) { FindNewPlayer (); } //Moves the AI if a player was found in range if (playerFound == true && selectedPlayer != 100 && aiRanged.hitDetected == false) { navMesh.destination = targetTransform.position; } else { //Stops the AI navMesh.Stop (); } //Sphere ray minPlayerRange = Physics.OverlapSphere (myTransform.position, minRange, layerMask); //Checks minPlayerRange if (minPlayerRange.Length > 0) { FindNewPlayerMin(); } } FindNewPlayerMin is used to switch targets if a new one gets really close: Code (CSharp): void FindNewPlayerMin(){ int i = 0; float distance = 0; //Loops through each of the colliders foreach (Collider other in minPlayerRange) { //Adds the distance between the AI and the player to an array playerPOS.Add (Vector3.Distance (myTransform.position, other.transform.position)); //subtracts the distance from the distance int to determine the closest target if ((distance - playerPOS [0 + i]) < 0) { //Sets the closet target distance = playerPOS [0 + i]; selectedPlayer = other.GetComponent<Player_Selector> ().playerID; targetTransform = target [selectedPlayer].transform; } i++; } } FindNewPlayer is used to find a player to begin with Code (CSharp): void FindNewPlayer(){ //Sphere ray targetPlayerRange = Physics.OverlapSphere(myTransform.position,targetRange,layerMask); //Checks minPlayerRange if (targetPlayerRange.Length > 0 && selectedPlayer == 100) { int i = 0; float distance = 0; //Loops through each of the colliders foreach (Collider other in targetPlayerRange) { //Adds the distance between the AI and the player to an array playerPOS.Add (Vector3.Distance (myTransform.position, other.transform.position)); //subtracts the distance from the distance int to determine the closest target if((distance - playerPOS[0 + i]) < 0){ //Sets the closet target distance = playerPOS[0 + i]; selectedPlayer = other.GetComponent<Player_Selector>().playerID; } i++; } } //If player is found, updates Playerfound. if (selectedPlayer != 100) { playerFound = true; targetTransform = target [selectedPlayer].transform; } else { playerFound = false; } }