Before anything I’m well aware that Physics.CapsuleCastAll is another optimization issue, but at least that’s one I understand. What I DON’T understand is what this “GC.Collect” thing is, why it’s slowing down the game so much, and how I can go about fixing it.
To be fair, I have a FAIRLY good idea of what GC is. It’s the garbage collector that frees up the variable space occupied by temporary variables at the end of each update (roughly speaking). What I DON’T understand is why it’s eating so much ms especially after I tried to reallocate what variables I could outside of loops that would constantly use declarations as an excuse to eat up more space.
Vector3 FindPath(float angle, float magnitude)
{
//Set up essential variables
int direction = 0; //Left = 0, Right = 1
Vector3[] directions = new Vector3[2];
Vector3[] nodes = new Vector3[2];
int loopLock = 0;
//Assign nodes
nodes[0] = transform.position;
nodes[1] = transform.position;
//Set up master loop variables
float radius;
RaycastHit[] hits;
bool obstacleCheck;
//Master loop. Only runs for a maximum of 1000 cycles
do
{
//Left first
{
//Set direction
direction = 0; // Left = 0
//Set up other variables
float leftAngle = AngleBetween(nodes[direction], destination);
radius = cc.radius * transform.localScale.x + (cc.skinWidth + MARKER) * 2;
hits = Physics.CapsuleCastAll(nodes[direction], Top(nodes[direction]), radius, AngleToVector(leftAngle), magnitude);
obstacleCheck = true;
//Comprehensive obstacle check
if (!ObstacleCheck(hits, gameObject, leftAngle, magnitude))
{
//Greater radius unit check
foreach (RaycastHit hit in hits)
{
if (obstacleCheck && hit.collider.GetComponent<TestScript>() != null && hit.collider.GetComponent<TestScript>() != this)
{
obstacleCheck = hit.collider.GetComponent<TestScript>().IsShovable(gameObject, leftAngle, magnitude);
}
}
//Lesser radius absolute check
if (obstacleCheck)
{
radius = cc.radius * transform.localScale.x + MARKER;
hits = Physics.CapsuleCastAll(nodes[direction], Top(nodes[direction]), radius, AngleToVector(leftAngle), magnitude);
obstacleCheck = ObstacleCheck(hits, gameObject, leftAngle, magnitude);
}
}
//Process obstacle check
if (!obstacleCheck)
{
//Create bisection variables
float offsetLow = 0;
float offsetHigh = 180;
//Bisect until the difference between offsetLow and offsetHigh is 1 or less
do
{
//Create working offset
float offset = (offsetHigh + offsetLow) / 2;
//Obstacle check at leftAngle - offset
radius = cc.radius * transform.localScale.x + (cc.skinWidth + MARKER) * 2;
hits = Physics.CapsuleCastAll(nodes[direction], Top(nodes[direction]), radius, AngleToVector(leftAngle - offset), magnitude);
obstacleCheck = true;
if (!ObstacleCheck(hits, gameObject, leftAngle - offset, magnitude))
{
//Greater radius unit check
foreach (RaycastHit hit in hits)
{
if (obstacleCheck && hit.collider.GetComponent<TestScript>() != null && hit.collider.GetComponent<TestScript>() != this)
{
obstacleCheck = hit.collider.GetComponent<TestScript>().IsShovable(gameObject, leftAngle - offset, magnitude);
}
}
//Lesser radius absolute check
if (obstacleCheck)
{
radius = cc.radius * transform.localScale.x + MARKER;
hits = Physics.CapsuleCastAll(nodes[direction], Top(nodes[direction]), radius, AngleToVector(leftAngle - offset), magnitude);
obstacleCheck = ObstacleCheck(hits, gameObject, leftAngle - offset, magnitude);
}
}
//Reassign offsetLow or offsetHigh based on obstacle check
if (obstacleCheck)
{
offsetHigh = offset;
}
else
{
offsetLow = offset;
}
} while (offsetHigh - offsetLow > 1);
//Assign direction vector if it's empty
if (directions[direction] == Vector3.zero)
{
directions[direction] = AngleToVector(leftAngle - offsetHigh) * magnitude;
}
//Reassign node
nodes[direction] += AngleToVector(leftAngle - offsetHigh) * magnitude;
}
else
{
//Return the vector at the left direction
return directions[direction];
}
}
//Then right
{
//Set direction
direction = 1; // Right = 1
//Set up other variables
float rightAngle = AngleBetween(nodes[direction], destination);
radius = cc.radius * transform.localScale.x + (cc.skinWidth + MARKER) * 2;
hits = Physics.CapsuleCastAll(nodes[direction], Top(nodes[direction]), radius, AngleToVector(rightAngle), magnitude);
obstacleCheck = true;
//Comprehensive obstacle check
if (!ObstacleCheck(hits, gameObject, rightAngle, magnitude))
{
//Greater radius unit check
foreach (RaycastHit hit in hits)
{
if (obstacleCheck && hit.collider.GetComponent<TestScript>() != null && hit.collider.GetComponent<TestScript>() != this)
{
obstacleCheck = hit.collider.GetComponent<TestScript>().IsShovable(gameObject, rightAngle, magnitude);
}
}
//Lesser radius absolute check
if (obstacleCheck)
{
radius = cc.radius * transform.localScale.x + MARKER;
hits = Physics.CapsuleCastAll(nodes[direction], Top(nodes[direction]), radius, AngleToVector(rightAngle), magnitude);
obstacleCheck = ObstacleCheck(hits, gameObject, rightAngle, magnitude);
}
}
//Process obstacle check
if (!obstacleCheck)
{
//Create bisection variables
float offsetLow = 0;
float offsetHigh = 180;
//Bisect until the difference between offsetLow and offsetHigh is 1 or less
do
{
//Create working offset
float offset = (offsetHigh + offsetLow) / 2;
//Obstacle check at leftAngle - offset
radius = cc.radius * transform.localScale.x + (cc.skinWidth + MARKER) * 2;
hits = Physics.CapsuleCastAll(nodes[direction], Top(nodes[direction]), radius, AngleToVector(rightAngle + offset), magnitude);
obstacleCheck = true;
if (!ObstacleCheck(hits, gameObject, rightAngle + offset, magnitude))
{
//Greater radius unit check
foreach (RaycastHit hit in hits)
{
if (obstacleCheck && hit.collider.GetComponent<TestScript>() != null && hit.collider.GetComponent<TestScript>() != this)
{
obstacleCheck = hit.collider.GetComponent<TestScript>().IsShovable(gameObject, rightAngle + offset, magnitude);
}
}
//Lesser radius absolute check
if (obstacleCheck)
{
radius = cc.radius * transform.localScale.x + MARKER;
hits = Physics.CapsuleCastAll(nodes[direction], Top(nodes[direction]), radius, AngleToVector(rightAngle + offset), magnitude);
obstacleCheck = ObstacleCheck(hits, gameObject, rightAngle + offset, magnitude);
}
}
//Reassign offsetLow or offsetHigh based on obstacle check
if (obstacleCheck)
{
offsetHigh = offset;
}
else
{
offsetLow = offset;
}
} while (offsetHigh - offsetLow > 1);
//Assign direction vector if it's empty
if (directions[direction] == Vector3.zero)
{
directions[direction] = AngleToVector(rightAngle + offsetHigh) * magnitude;
}
//Reassign node
nodes[direction] += AngleToVector(rightAngle + offsetHigh) * magnitude;
}
else
{
//Return the vector at the left direction
return directions[direction];
}
}
//Increment
loopLock++;
} while (loopLock < 1000);
//Report a theoretical infinite loop
if (loopLock >= 1000)
{
print("Theoretical infinite loop detected");
}
//Return nothing if something goes wrong
return Vector3.zero;
}
So what are some things I could do to optimize this so that the garbage collector isn’t such a problem?
