I moved every possible thing into 3 separate threads, but the main thread is still very slow and looking at the profiler, the main cause is Thread.Start(), but it always shows two sets of Thread.Start(), and both take the same exact amount of time, so it’s like a duplicate thread runs whenever thread.start is called.
So I disabled all but one thread.start that I know for a fact NEVER gets called twice in one frame, and it still shows two separate instances of Thread.Start() happening in a single frame. (I am only at maximum launching three threads at once, but it would be rare, most of the time there should only be one thread.start in any given frame)
It is so frustrating to put everything on another thread and it is still slow. My game is fairly simple and doesn’t even have proper physics so maybe I’ll just learn OpenGL or Vulcan or something.
This is where all the threads are started (below). I’m not an expert but could it be that I am using lambda functions and passing a bunch of parameters to the thread? I hope that is not the issue because I have no other choice but to pass data to the thread because Unity classes aren’t thread-safe. Ideally, this whole thing would be in another thread but I’ve got to break it apart and leave flags for when threads are done because Unity.
private void Update()
{
if (generateNewChunks)
{
if (sortChunksToGenerate)
{
Vector3Int playerPos = Vector3Int.CeilToInt(player.transform.position);
sortingThread = new Thread(() => SortChunksToGenerate(chunksToGenerateCounter, playerPos));
sortingThread.Start();
//SortChunksToGenerate(chunksToGenerateCounter, playerPos);
sortChunksToGenerate = false;
chunksToFillKeys = new Vector3Int[chunksToGenerateCounter];
chunksToFillScripts = new Chunk[chunksToGenerateCounter];
chunksToFillKeysCounter = 0;
}
if (sortingComplete)
{
GenerateChunkFromQueue(chunksToGenerate[sortedChunksToGenerate[chunkQueueCounter].a]); // if only this could be multithreaded too
chunkQueueCounter++;
if (chunkQueueCounter >= chunksToGenerateCounter) // using chunksToGenerateCounter because it might be less than the batch size but is always set to the batch size if not
{
startingThreadsThread = new Thread(() => FillChunksThread(chunksToFillKeys, chunksToFillScripts, chunksToFillKeysCounter));
startingThreadsThread.Start();
//FillChunksThread(chunksToFillKeys, chunksToFillScripts, chunksToFillKeysCounter);
chunkQueueCounter = 0;
generateNewChunks = false;
sortingComplete = false;
}
}
}
else
{
manageChunksCounter += Time.deltaTime;
if (manageChunksCounter >= manageChunksFreq)
{
if (!checkingForNewChunks)
{
Vector3 playerCameraPos = playerCamera.transform.position;
Vector3 playerCameraForward = playerCamera.transform.forward;
checkingForNewChunks = true;
checkDictionaryThread = new Thread(() => CheckForNewChunksAroundMultiplePoints(playerCameraPos, playerCameraForward, startRenDist, renIncrement));
checkDictionaryThread.Start();
}
if (checkForNewChunksDone)
{
checkingForNewChunks = false;
checkForNewChunksDone = false;
ActivateAndDeactivateObjectsOnMainThread(); // turns generate and sort chunks on
manageChunksCounter = 0;
Debug.Log(currentlyRenderedChunks.Count);
}
}
}
}