- Home /
Is Random.Range in this script causing performance issues?
Hi, I'm definitely new to this and feel like I must be causing a dramatic frame rate drop with the following script:
using UnityEngine;
using System.Collections;
public class Enemy1Controller : MonoBehaviour
{
GameObject player;
public static float speed = 0.07f;
Vector3 playerPosition;
bool waitForCrowd;
float waitTimer;
float waitForCrowdCoolDown;
public CircleCollider2D enemyProximityTrigger;
void Start()
{
waitForCrowd = false;
waitForCrowdCoolDown = 3;
waitTimer = 0.5f;
player = GameObject.Find("Player");
}
void Update()
{
CrowdCoolDown();
Movement();
}
public void Movement()
{
if (waitForCrowd)
{
FightCrowd();
}
else
{
//Follows player
playerPosition = player.transform.position;
transform.position = Vector3.MoveTowards(transform.position, playerPosition, speed);
}
}
public void FightCrowd()
{
//Pauses after trigger and cool down then bounces in a random direction
waitTimer -= Time.deltaTime;
if (waitTimer < 0)
{
int setRandDir = (int)Random.Range(0, 3);
switch (setRandDir)
{
case 0:
transform.Translate(0.2f, 0.0f, 0.0f);
Debug.Log("Left");
break;
case 1:
transform.Translate(0.0f, 0.2f, 0.0f);
Debug.Log("Up");
break;
case 2:
transform.Translate(-0.2f, 0.0f, 0.0f);
Debug.Log("Right");
break;
case 3:
transform.Translate(0.0f, -0.2f, 0.0f);
Debug.Log("Down");
break;
}
waitTimer = 0.5f;
waitForCrowdCoolDown = 3;
waitForCrowd = false;
}
}
public void CrowdCoolDown()
{
waitForCrowdCoolDown -= Time.deltaTime;
Debug.Log(waitForCrowdCoolDown);
}
void OnTriggerStay2D(Collider2D other)
{
Debug.Log("Triggered");
if (waitForCrowdCoolDown <= 0)
{
//Reduces frequency of crowd interaction and not all react at the same time
if (Random.Range(1f, 10f) < 2) //Are too many of these at once to much to process?
waitForCrowd = true;
}
Debug.Log(waitForCrowd);
}
}
What happens here is many these "Enemy1" prefabs are Instatiated by a timer in another script. When they collide with each other while chasing the player, they have a chance of pausing for a moment and getting bumped around. When too many collisions are happening at once, the frame rate can plummet to single digits.
It is just a bunch of circle sprites chasing a square. It seems like when 4 to 6 of the circles are touching each other, that's when the frame rate drops to unbearable levels.
I was thinking the culprit might be the RNG being called so often but if anyone can point me in a better direct to get these results I would really appreciate it.
The short answer is "No." When I remove the random numbers and set those variables, it still runs just as slow.
The only thing that prevents the frame rate drop is disabling the triggers. What seems to help somewhat is changing OnTriggerStay2D to OnTriggerEnter2D. The trigger doesn't go off as often and I get similar results but performance still drops dramatically.
Please do not post a follow-up as an Answer. I converted this one for you.
Cache transforms in Start to avoid implicit 'Search' per frame. Line 49 will never select 3 (Random.Range Int is exclusive). 88 is using float syntax with the 'f'. 13 is declared but not used. Turn on the Profiler and see.
Caching the transform component is a micro optimisation that's not worth mentioning unless you use it like 10000 times per frame. Anyways good catch at line 49. Line 88 is ok that way, however it's probability is frame-rate dependent.
If anything is called to much except for methods, floats and bools i usually get a huge framerate drop
Answer by Bunny83 · Dec 06, 2016 at 02:35 AM
No. Random.Range is extremely fast as Unity uses Xorshift128. What is most likely the biggest performance hit is all those Debug.Log statements. Those are like 100000 times slower than Random.Range. You effectively are printing three Debug.Logs "per frame" when you currently collide with something, otherwise just one per frame. You should remove them all when you're done debugging.
Debug.Log() / print() are extremely slow, especially inside the editor. You should use them only for debugging and avoid to call them every frame.
Pretty much this. Debug.Log is a killer on performance. To add onto Bunny83's comment, I highly recommend you use Unity's built in FPS script and print your FPS to screen at all times. That way, you can see the change in performance throughout the life of the program.
Wow. I've read comments and threads about removing Debug.Log before building but I did not realize the impact it really had. I just removed them and let the game spawn more than 2 dozen enemies and never saw the frame rate drop below 60 FPS.
Answer by joebopie · May 09 at 04:10 PM
Random.Range is Very slow in unity, i had to switch them all out for UnityEngine.Random.Range.
I don't quite get what you want to tell us here. The OP used UnityEngine.Random.Range
since he imported the UnityEngine namespace and not the System namespace.
Your answer
Follow this Question
Related Questions
Collider other doesnt recognize other gameobjects 1 Answer
What is the difference between these two scripts? 1 Answer
Collision Detection - Strange issues! Working when it shouldnt, not working when it should! 2 Answers
Attaching multiple animation events to player 1 Answer
I can't get 2DCollider to work. 1 Answer