- Home /
Loading prefabs to prevent a lag during play
Hey! I'm just hoping for some advice with loading prefabs at the start of a level.
My issue first appeared when I started my game. I have multiple cubes, when one collides it is destroyed and another gameobject is put in its place for a few seconds which shows the points score of the cube and a particle system etc for a few seconds. The problem was that the very first cube to be destroyed would cause the game to freeze for around 1/4 second, I'm guessing whilst the new gameobject loaded initially, because every cube after it would not cause any lag at all.
To fix this I created a loading script, with an array of various prefabs I want to load at the start of the scene. In the script, each prefab is instantiated in the scene, and then destroyed. When this has been done with all prefabs the game can begin.
As long as this loading script runs before I start playing, I encounter no lag during the game for the first cube, or any others after it.
So... this solved my problem. But my question, why I'm posting on here, is to ask whether this is a good approach? Is this what everyone else would do to load a list of prefabs into memory to prevent lag, or is there another method I should look at that would be better? I could just get on with it now everything is working but as this was just me thinking up a method, and I'm very new to Unity I thought I would check in case there is a much easier, or better method.
Thanks!
Hey,
Can you maybe post your code, that you used to aviod the lags in here? I have the same problem at the $$anonymous$$oment!
Thank You!
Answer by karljj1 · Nov 29, 2013 at 05:44 PM
Asset bundles are also a very good way to stream in data as and when you need it.
http://docs.unity3d.com/Documentation/ScriptReference/AssetBundle.html
Answer by GameVortex · Nov 29, 2013 at 06:43 PM
You are stating that you have to instantiate the prefab to have it load into memory? That is not a necessary approach. The prefab should already have been loaded into memory if you have the possibility to instantiate it.
A prefab gets loaded into memory at the start of the game if the prefab is referenced by a public variable of some sort. Nothing more is needed then to load it. For example like this:
public class Test : MonoBehaviour
{
public GameObject prefab; //The prefab is already loaded here
public void CreateObject()
{
Instantiate(prefab); //This should not cause a lag except for big big prefabs
}
}
If you are not storing the references before the start of the game, then maybe you are using Resources.Load to load the prefabs? The prefabs will be loaded into memory before you instantiate them then as well:
public class Test : MonoBehaviour
{
public string prefabLocation; //path to prefab
private GameObject loadedPrefab;
private void Start()
{
loadedPrefab = Resources.Load(prefabLocation) as GameObject; //The prefab gets loaded here, so any lag should happen here as well
}
public void CreateObject()
{
Instantiate(loadedPrefab ); //This should not cause a lag except for big big prefabs
}
}
In conclusion: as long as you use Resources.Load and load your prefabs at the start of the game, you should not have to instantiate them as well to have them loaded.
Thanks GameVortex, thats interesting, as there is definitely a lag if I dont Instantiate. When you say setting the prefab as a public variable automatically loads it, does that include further prefabs within that? As that seems to be where my problem is.
I have:
Level Controller contains a public prefab for 'Cube' Cube contains a public prefab for 'Score'
Loading the cubes cause no lag, it's only Score that causes lag, so maybe when loading a scene it only loads one level of prefabs and doesn't actually go into each to load further prefabs?
Either that or I've got something very wrong with my score script, this is the code within CubeController which causes the lag: it instantiates the scoreText prefab, and then run's UpdateScore within it's script.
GameObject scoreObj = Instantiate(scoreText, transform.position, transform.rotation) as GameObject;
CubeScoreController scoreScript = scoreObj.GetComponent<CubeScoreController>();
scoreScript.UpdateScore( score, scoreColor );
Sorry for my late reply, I was not on this weekend.
As far as I know the loading should include prefabs that are referenced through public variables on other prefabs as well.
$$anonymous$$aybe it is the scoreScript.UpdateScore that causes the lag? Could you copy paste the code for it here? Have you tried testing without calling UpdateScore?
If you have pro you could also try doing a Deep Profile and see exactly what piece of code is causing the lag as well.
Thanks for your reply! It could be UpdateScore, although I wasn't sure as the lag is only present the first time the script runs, are scripts loaded into memory as well on the first time they run so they're smoother later?
Unfortunately I don't have Pro yet so cant deep profile :(
Here is the contents of CubeScoreController, it's very basic and doesn't really do a lot.
using UnityEngine;
using System.Collections;
public class CubeScoreController : $$anonymous$$onoBehaviour {
public float fadeSpeed = 1.0f;
public float riseAmount = 1.0f;
private Text$$anonymous$$esh text$$anonymous$$esh;
private Vector3 targetPos;
void Awake()
{
text$$anonymous$$esh = gameObject.GetComponent<Text$$anonymous$$esh>();
targetPos = new Vector3(transform.position.x, transform.position.y + riseAmount, transform.position.z);
}
void Update()
{
transform.position = Vector3.Lerp( transform.position, targetPos, Time.deltaTime );
text$$anonymous$$esh.color = Color.Lerp( text$$anonymous$$esh.color, Color.clear, fadeSpeed * Time.deltaTime );
if ( text$$anonymous$$esh.color.a <= 0.5f )
{
text$$anonymous$$esh.color = Color.clear;
Destroy(gameObject);
}
}
public void UpdateScore( int score, Color color )
{
text$$anonymous$$esh.text = score.ToString();
text$$anonymous$$esh.color = color;
}
}
Scripts does not behave like that when loaded no, so I don't think that would be the cause of the lag.
I don't see anything in your code that would lag except text$$anonymous$$esh could possibly do some sort of initialization the first time it is used, not sure because I have not used Text$$anonymous$$esh before. Did you try instantiating without calling UpdateScore and see if that had any effect? If not it may be time to start removing things from the prefab, and check piece by piece if it causes lag or not.
Also if you want, you could send the project to me and I could do a Deep Profile for you and do some checks. Just let me know. =)
Answer by Subhajit-Nath · Nov 29, 2013 at 05:23 PM
Yes, people generally do it this way. Make a public variable of GameObject or Transform. Make a reference of the prefab that you want to Instantiate. But of course scenario changes with each and every game. If you wish to load a whole bunch of data at a time, you might consider saving it as a new level and loading it with Application.LoadLevelAsync() at a proper time.
Your answer
Follow this Question
Related Questions
Unity stuck on loading at "Apply active color space" 1 Answer
Loading Screen - FLASH export 2 Answers
how to preload assets with progress bar 1 Answer
Reloading the same screen taking minutes. But loading from another scene is instant. 1 Answer
When I load the Loading-Screen level, how do I tell it to then load the next level that I want? 1 Answer