- Home /
How to reduce time of instantiating a prefab that contains many objects/components in it.
Well basically I have level management system which loads the level prefab whenever needed. We develop hyper-casual games so most of the times destroying and loading next level prefab does not really bother user because of the amount of objects and the components that level prefab has but this time it's a bit different, we use same level management system for an idle game(project did not start as idle at first) which has lots of object and component count so the destroy/instantiate time is now pretty bothering us, at this time it is a bit late and hard to change the current system we have so I just wonder if there is any trick or something that could help us reduce this destroy/instantiate time without really going deep in the project or not wasting too much time. We already use object pooling in the project but cannot really apply it to all components we have in the level prefabs, everything happens in one scene.
Did my answer help at all? You must find the file containing the prefab and swap "/sharedassets1.assets.resS" with that file.
Are you on a PC or Phone device? It doesn't help with destroy, but it is "a trick, without really going deep in the project" as you wanted.
Hello, well thank you so much friend, your answer seems pretty cool actually. Project is for mobile devices, does it make too much difference? Again I really appreciate your time and answer and sorry for late reply..
Thanks, I don't think mobile devices has a disk-cache in the same way as a PC, but maybe... For me the file was 1GB, and running the game directly after a restart of the system (nothing in cache) it reduced the loading time from about 7 sec down to 1 sec, on a fairly fast computer with 16GB RAM. If I exit the app and run it again nothing is gained since the file is already in cache. It can be worth testing on mobile, and if it works - try to access all data files through this thread before they are needed/loaded by Unity.
Answer by rh_galaxy · Nov 04, 2021 at 03:38 AM
This is going to sound a bit insane, and I don't use it any more because I have since reduced the texture data size from 1 GB to 0.1 GB, so it is not a problem now. But I used this in the Menu scene before the user started a level (which load the Game scene and access the "sharedassets1.assets.resS" data file).
I preloaded the resource file into the system cache by reading the file in a thread like this code here, and it worked, it reduced the loading time by several seconds.
using System.IO;
using System.Threading;
//to avoid a 6 second freeze when the file is not in cache
// this is loaded here once hopefully while the user spend some seconds in the menu
// before this will be accessed by LoadSceneAsync.
byte[] preLoadBytes = new byte[1024 * 1024]; //1MB buffer
string preLoadDataPath;
Thread preLoadThread;
void PreLoadAssetsToCache()
{
bool allRead = false;
int iChunkSize = preLoadBytes.Length;
int iChunkNr = 0;
FileStream fs = null;
try
{
fs = File.OpenRead(preLoadDataPath + "/sharedassets1.assets.resS");
} catch { }
while (fs != null && !allRead)
{
int fr = fs.Read(preLoadBytes, 0 + iChunkNr * iChunkSize, iChunkSize);
if (fr != iChunkSize) allRead = true;
iChunkNr++;
Thread.Sleep(5);
}
}
//done at the first state in the Update() state machine
//to avoid stalls of 6+ sec the first time a level is started after app start
preLoadDataPath = UnityEngine.Application.dataPath;
ThreadStart ts = new ThreadStart(PreLoadAssetsToCache);
preLoadThread = new Thread(ts);
preLoadThread.Priority = System.Threading.ThreadPriority.Lowest;
preLoadThread.Start();
You can try it, hope it will work. But there must be some idle time before you want to load the data in Unity for it to not instead increase the workload. This is most useful on a PC, don't think it will work well on Android or similar.