- Home /
Game optimisation using SetActive partially ineffective.
I am building a cave exploration game (Which is supposed to be infinite on all 3 axis.) that uses a modified version of perlin-noise. I thought I had the optimisation sussed as it runs like butter for the beginning part of the game. If you were to explore further, however, (like Y: -200) then it starts to slow down. I start with a steady 60-100 FPS but it slowly drops down to 20-50 FPS. I'm using a chunk based system and it disables the chunk whenever the player is out of reach. I'm using .SetActive(false/true) on the chunks. I think the main problem is that I have too many GameObjects and the script is having to refer to Lists which are (sometimes) 400+ GameObjects/Vector3's long.
I am trying to think of different ways to go about the problem such as .Destroy() but that would be an even bigger issue for .Destory() is fairly costly, performance wise, as I am sometimes having to destroy 5-7 GameObjects (which contain other GameObjects which contain other GameObjects and so on...) every few seconds. This is also effected by how fast the player is travelling....
I'm going to give the code but it incorporates other parts which have nothing to do with this so feel free to ask questions. I will also put a screen shot.
(P.S. Chunks of gameobjects are called "Parts" and a GameObject inside of the "Part" is called a "Chunk" and inside of "Chunks" are "Rocks". Just to make things confusing. :-p (It was something that happened at the beginning of my code ages ago that I haven't been bothered to change.)) (P.P.S The "Rocks" positions are also perlin-noised. This is probably also a big factor.)
Code:
using UnityEngine;
using System.Collections;
using SimplexNoise;
using System.Collections.Generic;
public class World : MonoBehaviour {
public GameObject rock;
public GameObject chunkTemplate;
public GameObject rawmatter;
public float maxPartDistance = 30f;
public static float maxChunkDistFromPlayer = 0f;
public float seed;
public Transform Player;
public int PartSize;
public List <GameObject> Parts = new List<GameObject>();
public List <Vector3> PartPositions = new List<Vector3>();
List<Vector3> ChunkPositions = new List<Vector3>();
bool startPosOneTime = true;
Camera cam;
// Use this for initialization
void Start () {
Player = GameObject.FindGameObjectWithTag("Player").transform;
maxChunkDistFromPlayer = maxPartDistance;
if(!Application.isEditor)
{
Cursor.visible = false;
Cursor.lockState = CursorLockMode.Locked;
}
cam = GameObject.FindGameObjectWithTag("Player").GetComponentInChildren<Camera>();
}
Vector3 playerToPartPosHasChangedCheck = Vector3.zero;
bool PTPPhasChanged = true;
void Update()
{
Vector3 playerPos = Player.position;
foreach(GameObject go in Parts)
{
if(Vector3.Distance(go.transform.position, playerPos) > maxPartDistance)
{
go.SetActive(false);
}
else
{
go.SetActive(true);
}
}
Vector3 playerToPartPos = new Vector3(Mathf.Round(playerPos.x / PartSize) * PartSize,
Mathf.Round(playerPos.y / PartSize) * PartSize,
Mathf.Round(playerPos.z / PartSize) * PartSize);
if(playerToPartPosHasChangedCheck != playerToPartPos)
{
PTPPhasChanged = true;
}
if(PTPPhasChanged)
{
//Centre
if(!PartPositions.Contains(new Vector3(playerToPartPos.x,
playerToPartPos.y,
playerToPartPos.z))){
CreatePart(PartSize, new Vector3(playerToPartPos.x,
playerToPartPos.y,
playerToPartPos.z));
PartPositions.Add(new Vector3(playerToPartPos.x,
playerToPartPos.y,
playerToPartPos.z));
}
//Forward
if(!PartPositions.Contains(new Vector3(playerToPartPos.x,
playerToPartPos.y,
playerToPartPos.z + PartSize)))
{
CreatePart(PartSize, new Vector3(playerToPartPos.x,
playerToPartPos.y,
playerToPartPos.z + PartSize));
PartPositions.Add(new Vector3(playerToPartPos.x,
playerToPartPos.y,
playerToPartPos.z + PartSize));
}
//Backwards
if(!PartPositions.Contains(new Vector3(playerToPartPos.x,
playerToPartPos.y,
playerToPartPos.z - PartSize)))
{
CreatePart(PartSize, new Vector3(playerToPartPos.x,
playerToPartPos.y,
playerToPartPos.z - PartSize));
PartPositions.Add(new Vector3(playerToPartPos.x,
playerToPartPos.y,
playerToPartPos.z - PartSize));
}
//Forward x 2
if(!PartPositions.Contains(new Vector3(playerToPartPos.x,
playerToPartPos.y,
playerToPartPos.z + (PartSize * 2))))
{
CreatePart(PartSize, new Vector3(playerToPartPos.x,
playerToPartPos.y,
playerToPartPos.z + (PartSize * 2)));
PartPositions.Add(new Vector3(playerToPartPos.x,
playerToPartPos.y,
playerToPartPos.z + (PartSize * 2)));
}
//Backwards x 2
if(!PartPositions.Contains(new Vector3(playerToPartPos.x,
playerToPartPos.y,
playerToPartPos.z - (PartSize * 2))))
{
CreatePart(PartSize, new Vector3(playerToPartPos.x,
playerToPartPos.y,
playerToPartPos.z - (PartSize * 2)));
PartPositions.Add(new Vector3(playerToPartPos.x,
playerToPartPos.y,
playerToPartPos.z - (PartSize * 2)));
}
//Left
if(!PartPositions.Contains(new Vector3(playerToPartPos.x - PartSize,
playerToPartPos.y,
playerToPartPos.z)))
{
CreatePart(PartSize, new Vector3(playerToPartPos.x - PartSize,
playerToPartPos.y,
playerToPartPos.z));
PartPositions.Add(new Vector3(playerToPartPos.x - PartSize,
playerToPartPos.y,
playerToPartPos.z));
}
//Right
if(!PartPositions.Contains(new Vector3(playerToPartPos.x + PartSize,
playerToPartPos.y,
playerToPartPos.z)))
{
CreatePart(PartSize, new Vector3(playerToPartPos.x + PartSize,
playerToPartPos.y,
playerToPartPos.z));
PartPositions.Add(new Vector3(playerToPartPos.x + PartSize,
playerToPartPos.y,
playerToPartPos.z));
}
//Left x 2
if(!PartPositions.Contains(new Vector3(playerToPartPos.x - (PartSize * 2),
playerToPartPos.y,
playerToPartPos.z)))
{
CreatePart(PartSize, new Vector3(playerToPartPos.x - (PartSize * 2),
playerToPartPos.y,
playerToPartPos.z));
PartPositions.Add(new Vector3(playerToPartPos.x - (PartSize * 2),
playerToPartPos.y,
playerToPartPos.z));
}
//Right x 2
if(!PartPositions.Contains(new Vector3(playerToPartPos.x + (PartSize * 2),
playerToPartPos.y,
playerToPartPos.z)))
{
CreatePart(PartSize, new Vector3(playerToPartPos.x + (PartSize * 2),
playerToPartPos.y,
playerToPartPos.z));
PartPositions.Add(new Vector3(playerToPartPos.x + (PartSize * 2),
playerToPartPos.y,
playerToPartPos.z));
}
//Forward, Left
if(!PartPositions.Contains(new Vector3(playerToPartPos.x - PartSize,
playerToPartPos.y,
playerToPartPos.z + PartSize)))
{
CreatePart(PartSize, new Vector3(playerToPartPos.x - PartSize,
playerToPartPos.y,
playerToPartPos.z + PartSize));
PartPositions.Add(new Vector3(playerToPartPos.x - PartSize,
playerToPartPos.y,
playerToPartPos.z + PartSize));
}
//Forward, Right
if(!PartPositions.Contains(new Vector3(playerToPartPos.x + PartSize,
playerToPartPos.y,
playerToPartPos.z + PartSize)))
{
CreatePart(PartSize, new Vector3(playerToPartPos.x + PartSize,
playerToPartPos.y,
playerToPartPos.z + PartSize));
PartPositions.Add(new Vector3(playerToPartPos.x + PartSize,
playerToPartPos.y,
playerToPartPos.z + PartSize));
}
// //Forwardx2, Left
// if(!PartPositions.Contains(new Vector3(playerToPartPos.x - PartSize,
// playerToPartPos.y,
// playerToPartPos.z + (PartSize * 2))))
// {
// CreatePart(PartSize, new Vector3(playerToPartPos.x - PartSize,
// playerToPartPos.y,
// playerToPartPos.z + (PartSize * 2)));
// PartPositions.Add(new Vector3(playerToPartPos.x - PartSize,
// playerToPartPos.y,
// playerToPartPos.z + (PartSize * 2)));
// }
//
// //Forwardx2, Right
// if(!PartPositions.Contains(new Vector3(playerToPartPos.x + PartSize,
// playerToPartPos.y,
// playerToPartPos.z + (PartSize * 2))))
// {
// CreatePart(PartSize, new Vector3(playerToPartPos.x + PartSize,
// playerToPartPos.y,
// playerToPartPos.z + (PartSize * 2)));
// PartPositions.Add(new Vector3(playerToPartPos.x + PartSize,
// playerToPartPos.y,
// playerToPartPos.z + (PartSize * 2)));
// }
//Forward, Left x2
if(!PartPositions.Contains(new Vector3(playerToPartPos.x - (PartSize * 2),
playerToPartPos.y,
playerToPartPos.z + PartSize)))
{
CreatePart(PartSize, new Vector3(playerToPartPos.x - (PartSize * 2),
playerToPartPos.y,
playerToPartPos.z + PartSize));
PartPositions.Add(new Vector3(playerToPartPos.x - (PartSize * 2),
playerToPartPos.y,
playerToPartPos.z + PartSize));
}
//Forward, Right x2
if(!PartPositions.Contains(new Vector3(playerToPartPos.x + (PartSize * 2),
playerToPartPos.y,
playerToPartPos.z + PartSize)))
{
CreatePart(PartSize, new Vector3(playerToPartPos.x + (PartSize * 2),
playerToPartPos.y,
playerToPartPos.z + PartSize));
PartPositions.Add(new Vector3(playerToPartPos.x + (PartSize * 2),
playerToPartPos.y,
playerToPartPos.z + PartSize));
}
//Backwards, Left
if(!PartPositions.Contains(new Vector3(playerToPartPos.x - PartSize,
playerToPartPos.y,
playerToPartPos.z - PartSize)))
{
CreatePart(PartSize, new Vector3(playerToPartPos.x - PartSize,
playerToPartPos.y,
playerToPartPos.z - PartSize));
PartPositions.Add(new Vector3(playerToPartPos.x - PartSize,
playerToPartPos.y,
playerToPartPos.z - PartSize));
}
//Backwards, Right
if(!PartPositions.Contains(new Vector3(playerToPartPos.x + PartSize,
playerToPartPos.y,
playerToPartPos.z - PartSize)))
{
CreatePart(PartSize, new Vector3(playerToPartPos.x + PartSize,
playerToPartPos.y,
playerToPartPos.z - PartSize));
PartPositions.Add(new Vector3(playerToPartPos.x + PartSize,
playerToPartPos.y,
playerToPartPos.z - PartSize));
}
// //Backwards x2, Left
// if(!PartPositions.Contains(new Vector3(playerToPartPos.x - PartSize,
// playerToPartPos.y,
// playerToPartPos.z - (PartSize * 2))))
// {
// CreatePart(PartSize, new Vector3(playerToPartPos.x - PartSize,
// playerToPartPos.y,
// playerToPartPos.z - (PartSize * 2)));
// PartPositions.Add(new Vector3(playerToPartPos.x - PartSize,
// playerToPartPos.y,
// playerToPartPos.z - (PartSize * 2)));
// }
//
// //Backwards x2, Right
// if(!PartPositions.Contains(new Vector3(playerToPartPos.x + PartSize,
// playerToPartPos.y,
// playerToPartPos.z - (PartSize * 2))))
// {
// CreatePart(PartSize, new Vector3(playerToPartPos.x + PartSize,
// playerToPartPos.y,
// playerToPartPos.z - (PartSize * 2)));
// PartPositions.Add(new Vector3(playerToPartPos.x + PartSize,
// playerToPartPos.y,
// playerToPartPos.z - (PartSize * 2)));
// }
//Backwards, Left x2
if(!PartPositions.Contains(new Vector3(playerToPartPos.x - (PartSize * 2),
playerToPartPos.y,
playerToPartPos.z - PartSize)))
{
CreatePart(PartSize, new Vector3(playerToPartPos.x - (PartSize * 2),
playerToPartPos.y,
playerToPartPos.z - PartSize));
PartPositions.Add(new Vector3(playerToPartPos.x - (PartSize * 2),
playerToPartPos.y,
playerToPartPos.z - PartSize));
}
//Backwards, Right x2
if(!PartPositions.Contains(new Vector3(playerToPartPos.x + (PartSize * 2),
playerToPartPos.y,
playerToPartPos.z - PartSize)))
{
CreatePart(PartSize, new Vector3(playerToPartPos.x + (PartSize * 2),
playerToPartPos.y,
playerToPartPos.z - PartSize));
PartPositions.Add(new Vector3(playerToPartPos.x + (PartSize * 2),
playerToPartPos.y,
playerToPartPos.z - PartSize));
}
//Up
if(!PartPositions.Contains(new Vector3(playerToPartPos.x,
playerToPartPos.y + PartSize,
playerToPartPos.z)))
{
CreatePart(PartSize, new Vector3(playerToPartPos.x,
playerToPartPos.y + PartSize,
playerToPartPos.z));
PartPositions.Add(new Vector3(playerToPartPos.x,
playerToPartPos.y + PartSize,
playerToPartPos.z));
}
//Down
if(!PartPositions.Contains(new Vector3(playerToPartPos.x,
playerToPartPos.y - PartSize,
playerToPartPos.z)))
{
CreatePart(PartSize, new Vector3(playerToPartPos.x,
playerToPartPos.y - PartSize,
playerToPartPos.z));
PartPositions.Add(new Vector3(playerToPartPos.x,
playerToPartPos.y - PartSize,
playerToPartPos.z));
}
//Down, Left
if(!PartPositions.Contains(new Vector3(playerToPartPos.x - PartSize,
playerToPartPos.y - PartSize,
playerToPartPos.z)))
{
CreatePart(PartSize, new Vector3(playerToPartPos.x - PartSize,
playerToPartPos.y - PartSize,
playerToPartPos.z));
PartPositions.Add(new Vector3(playerToPartPos.x - PartSize,
playerToPartPos.y - PartSize,
playerToPartPos.z));
}
//Down, Right
if(!PartPositions.Contains(new Vector3(playerToPartPos.x + PartSize,
playerToPartPos.y - PartSize,
playerToPartPos.z)))
{
CreatePart(PartSize, new Vector3(playerToPartPos.x + PartSize,
playerToPartPos.y - PartSize,
playerToPartPos.z));
PartPositions.Add(new Vector3(playerToPartPos.x + PartSize,
playerToPartPos.y - PartSize,
playerToPartPos.z));
}
//Down, Forward
if(!PartPositions.Contains(new Vector3(playerToPartPos.x,
playerToPartPos.y - PartSize,
playerToPartPos.z + PartSize)))
{
CreatePart(PartSize, new Vector3(playerToPartPos.x,
playerToPartPos.y - PartSize,
playerToPartPos.z + PartSize));
PartPositions.Add(new Vector3(playerToPartPos.x,
playerToPartPos.y - PartSize,
playerToPartPos.z + PartSize));
}
//Down, Backwards
if(!PartPositions.Contains(new Vector3(playerToPartPos.x,
playerToPartPos.y - PartSize,
playerToPartPos.z - PartSize)))
{
CreatePart(PartSize, new Vector3(playerToPartPos.x,
playerToPartPos.y - PartSize,
playerToPartPos.z - PartSize));
PartPositions.Add(new Vector3(playerToPartPos.x,
playerToPartPos.y - PartSize,
playerToPartPos.z - PartSize));
}
//Down, Forward, Left
if(!PartPositions.Contains(new Vector3(playerToPartPos.x - PartSize,
playerToPartPos.y - PartSize,
playerToPartPos.z + PartSize)))
{
CreatePart(PartSize, new Vector3(playerToPartPos.x - PartSize,
playerToPartPos.y - PartSize,
playerToPartPos.z + PartSize));
PartPositions.Add(new Vector3(playerToPartPos.x - PartSize,
playerToPartPos.y - PartSize,
playerToPartPos.z + PartSize));
}
//Down, Forward, Right
if(!PartPositions.Contains(new Vector3(playerToPartPos.x + PartSize,
playerToPartPos.y - PartSize,
playerToPartPos.z + PartSize)))
{
CreatePart(PartSize, new Vector3(playerToPartPos.x + PartSize,
playerToPartPos.y - PartSize,
playerToPartPos.z + PartSize));
PartPositions.Add(new Vector3(playerToPartPos.x + PartSize,
playerToPartPos.y - PartSize,
playerToPartPos.z + PartSize));
}
//Down, Backwards, Left
if(!PartPositions.Contains(new Vector3(playerToPartPos.x - PartSize,
playerToPartPos.y - PartSize,
playerToPartPos.z - PartSize)))
{
CreatePart(PartSize, new Vector3(playerToPartPos.x - PartSize,
playerToPartPos.y - PartSize,
playerToPartPos.z - PartSize));
PartPositions.Add(new Vector3(playerToPartPos.x - PartSize,
playerToPartPos.y - PartSize,
playerToPartPos.z - PartSize));
}
//Down Backwards, Right
if(!PartPositions.Contains(new Vector3(playerToPartPos.x + PartSize,
playerToPartPos.y - PartSize,
playerToPartPos.z - PartSize)))
{
CreatePart(PartSize, new Vector3(playerToPartPos.x + PartSize,
playerToPartPos.y - PartSize,
playerToPartPos.z - PartSize));
PartPositions.Add(new Vector3(playerToPartPos.x + PartSize,
playerToPartPos.y - PartSize,
playerToPartPos.z - PartSize));
}
//Down x2
if(!PartPositions.Contains(new Vector3(playerToPartPos.x,
playerToPartPos.y - (PartSize * 2),
playerToPartPos.z)))
{
CreatePart(PartSize, new Vector3(playerToPartPos.x,
playerToPartPos.y - (PartSize * 2),
playerToPartPos.z));
PartPositions.Add(new Vector3(playerToPartPos.x,
playerToPartPos.y - (PartSize * 2),
playerToPartPos.z));
}
//PTPPhasChanged = false;
}
playerToPartPosHasChangedCheck = playerToPartPos;
}
void CreatePart(int partSize, Vector3 pos)
{
GameObject part = new GameObject();
part.transform.position = pos;
part.name = "Part";
part.transform.parent = transform;
for(int y = 0; y < partSize; y++)
{
NoiseMethod method = PerlinWorms.valueMethods[2];
Vector3 point00 = transform.TransformPoint(new Vector3(seed - 0.5f, seed - 0.5f, y)) + pos;
Vector3 point10 = transform.TransformPoint(new Vector3(seed + 0.5f, seed - 0.5f, y)) + pos;
Vector3 point01 = transform.TransformPoint(new Vector3(seed - 0.5f, seed + 0.5f, y)) + pos;
Vector3 point11 = transform.TransformPoint( new Vector3(seed + 0.5f, seed + 0.5f, y)) + pos;
float stepSize = 1f / partSize;
for(int z = 0; z < partSize; z++)
{
Vector3 point0 = Vector3.Lerp(point00, point01, (z + 0.5f) * stepSize);
Vector3 point1 = Vector3.Lerp(point10, point11, (z + 0.5f) * stepSize);
for(int x = 0;x< partSize;x++)
{
Vector3 point = Vector3.Lerp(point0, point1, (x+0.5f) * stepSize);
float sample = PerlinWorms.Sum(method, point, 0.5f, 1, 2, 0.5f);
sample = sample * 0.5f + 0.5f;
if(sample > 0.4f && sample < 0.5f)
{
if(Mathf.Round(x) % 2 == 0 && Mathf.Round(y) % 2 == 0 && Mathf.Round(z) % 2 == 0)
if(!ChunkPositions.Contains(new Vector3(Mathf.Round(x), Mathf.Round(y), Mathf.Round(z)) + pos))
{
CreateChunk(new Vector3(Mathf.Round(x), Mathf.Round(y), Mathf.Round(z)) + pos, part.transform);
ChunkPositions.Add(new Vector3(Mathf.Round(x), Mathf.Round(y), Mathf.Round(z)) + pos);
}
}
// else
// {
// if(startPosOneTime == true && x > partSize / 2 && y > partSize / 2 && z > partSize / 2)
// {
// Player.localPosition = new Vector3(x, y, z) + pos;
// startPosOneTime = false;
// }
// }
}
}
}
Parts.Add(part);
}
void CreateChunk(Vector3 position, Transform Parent)
{
GameObject Chunk = (GameObject)Instantiate(chunkTemplate);
Chunk.transform.position = position;
Chunk.name = "Chunk";
Chunk.transform.parent = Parent;
for(int x = 0; x < 2; x++)
{
for(int y = 0; y < 2; y++)
{
for(int z = 0; z < 2; z++)
{
if(z == 0 | z == 1 | x == 0 | x == 1 | y == 0 | y == 1)
{
GameObject currentRock;
currentRock = (GameObject)Instantiate(rock, Vector3.zero, Quaternion.identity);
currentRock.transform.localPosition = new Vector3(x + Mathf.PerlinNoise(seed + position.x + z + 0.1f, seed + position.y + y + 0.1f) + position.x,
y + Mathf.PerlinNoise(seed + position.x + x + 0.1f, seed + position.y + z + 0.1f) + position.y,
z + Mathf.PerlinNoise(seed + position.x + x + 0.1f, seed + position.y + y + 0.1f) + position.z);
currentRock.transform.parent = Chunk.transform;
GameObject currentRawMatter;
//Front and Back
if(Random.Range(0, 18) == 0)
{
float newZ = new float();
currentRawMatter = (GameObject)Instantiate(rawmatter, Vector3.zero, Quaternion.Euler(0, z * 180, 0));
if(z == 0) newZ = -0.5f;
if(z == 1) newZ = 0.5f;
currentRawMatter.transform.position = new Vector3(currentRock.transform.position.x, currentRock.transform.position.y, currentRock.transform.position.z + newZ);
currentRawMatter.transform.parent = currentRock.transform;
Chunk.GetComponent<ChunkController>().AddMatter(currentRawMatter.transform.position);
}
//Left and Right
if(Random.Range(0, 18) == 0)
{
currentRawMatter = (GameObject)Instantiate(rawmatter, Vector3.zero, Quaternion.Euler(0, 90f + (x * 180), 0));
float lrnewX = new float();
if(x == 0) lrnewX = -0.5f;
if(x == 1) lrnewX = 0.5f;
currentRawMatter.transform.position = new Vector3(currentRock.transform.position.x + lrnewX, currentRock.transform.position.y, currentRock.transform.position.z);
currentRawMatter.transform.parent = currentRock.transform;
Chunk.GetComponent<ChunkController>().AddMatter(currentRawMatter.transform.position);
}
//Top and Bottom
if(Random.Range(0, 18) == 0)
{
currentRawMatter = (GameObject)Instantiate(rawmatter, Vector3.zero, Quaternion.Euler(-90f + (y * 180), 0, 0));
float tbnewY = new float();
if(y == 0) tbnewY = -0.5f;
if(y == 1) tbnewY = 0.5f;
currentRawMatter.transform.position = new Vector3(currentRock.transform.position.x, currentRock.transform.position.y + tbnewY, currentRock.transform.position.z );
currentRawMatter.transform.parent = currentRock.transform;
Chunk.GetComponent<ChunkController>().AddMatter(currentRawMatter.transform.position);
}
}
}
}
}
//chunk.transform.localScale /= 2;
}
}
Screenshots:
Part
Chunk
These screenshots were taken as soon as the game started. I simply paused it in the editor at the beginning and took the screenshots.
Have you considered only setting active to false or true based on if it's already active as well?
if(Vector3.Distance(go.transform.position, playerPos) > maxPartDistance && go.activeSelf)
{
go.SetActive(false);
}
else if (!go.activeSelf)
{
go.SetActive(true);
}
This is only a partial answer as I don't have time to go through most of the code yet. This could have performance benefits or not I'm not certain.
Few things:
You loop through each part in your scene every update. That's probably not necessary - you may only need to keep a references to the parts that are adjacent to the one the player is currently in, and activate/deactivate those if he gets close.
Also, ins$$anonymous$$d of
if(Vector3.Distance(go.transform.position, playerPos) > maxPartDistance && go.activeSelf)
you could do
if((go.transform.position - playerPos).sqr$$anonymous$$agnitude > maxPartDistance * maxPartDistance && go.activeSelf)
that's a bit faster as you remove the sqrt operation from the distance comparison (sqrt is slow. avoid it whenever possible). (and of course your should precompute maxPartDistance * maxPartDistance isn$$anonymous$$d of doing that multiplication in the if each time)
The 'don't loop through everything in the scene' would be a lot more significant though.
It may also be a good idea to look at the profiler, see where your chokepoints are.
When I was working on this problem, the only way I found to do it quickly was to store the tiles as pure data, not as components, so they don't incur GameObject overhead. Then I only instantiated GameObjects for the ones that were visible or otherwise active. Since the data was not tied to the GameObjects, I could do the vast majority of my processing on another thread.
Probably not feasible to you to rewrite your code like that, but maybe it will give you an idea.
Answer by Alban-Gueret · May 19, 2015 at 09:02 AM
Hi Mr_Rockers !
How many Chunks have you in your scene when it starts to slow down ?
I have not read the code in details because this is really too long, but I suppose you should use Dictionary instead of List.
This way, you can easily enable/disable gameobjects by acessing them directly, by computing their index from the player position, instead of checking each of your list through a loop.
I have up-voted your answer. I will accept it as correct when I try it out... Thanks!
I'm not indexing them directly yet, but I got rid of every list in place for a dictionary. The performance is unbelievable. I suppose the dictionary uses a different algorithm which are down to byte level and Im guessing comparing Vector3's are quicker than comparing 2-3 lists using GameObject.Transform.Position. Thanks dude! (I will index later, but for now, using foreach works fine!)
Glad it helped ! I'm quite surprised that without indexing, it works better but it's the more important.
I'm just thinking of something, if you want to index later : maybe you will have problems to access some elements due to Vector3 optimisation. Sometimes you create an object at [0,0,0], but Unity create it at [0,0,0.0001] (for example). If later you try to acces it through the Dictionary at index [0,0,0], of course you will not find it because it is register at index [0,0,0.0001].
You have 2 solutions : casting as integer when registering and accessing or use a custom structure Vector3i composed of 3 integers ins$$anonymous$$d of 3 floats.
Your answer
Follow this Question
Related Questions
Multiple Cars not working 1 Answer
Distribute terrain in zones 3 Answers
[C#] Wondering what is amiss with my 1D Perlin Noise Terrain Generator? 2 Answers
Are nested lists bad? 1 Answer
Use perlin noise for perlin worms? 1 Answer