If you are using Unity 5, then you must be using baked Global illumination feature as well. Though this gives highly realistic results, there is a issue http://issuetracker.unity3d.com/issues/prefabs-dont-store-ligthtmap-information-correctly . What this means is that Unity 5 assume you calculate GI on a model, then you make it into a prefab. When you duplicate this prefab you wont be getting the baked lightmaps carrying on to the duplicated prefabs.

This is a huge problem, because you will have to instatiate all the prefabs and then do GI calculations on a large geometry which is going to take time as well as your lightmap textures increase in size, as you now have the same lightmap for each of the prefab and each of those textures are being loaded at run time.

So, if we think of a simple solution, then the best way to solve this is somehow get access to the lightmap that was created for a single prefab and then just assign the same lightmap to the other prefabs during run-time. This helps us have quick GI calculation, since we are doing this for only one prefb and we are storing only a single lightmap for that prefab.

Below is a simple script that will do the job, all you have to do is , assign the prefab for which you want lightmaps to be automatically assigned to the instatiated prefabs. In the below script we are just instantiating a bunch of them along a axis. But the core idea is just taking the lightmap of the prefab and assign it to all the other instatiated ones. And it works !

using UnityEngine;
using System.Collections;

public class lightMapAssign : MonoBehaviour {
	public int tunnelPieces = 5 ;
	public GameObject prefab;
	public Vector3 offset;
	// Use this for initialization
	void Start () {
		// Get the render component of our prefab 
		Renderer r = prefab.GetComponent<Renderer>();
		// Store the lighmap index of our prefab 
		int lightmapIndex = r.lightmapIndex; 
		Vector4 lightmapScaleOffset = r.lightmapScaleOffset; 

		GameObject piece;
		for (int i = 1; i < tunnelPieces; i++) {
			// Instatiate our prefab at runtime 
			piece = (GameObject)Instantiate(prefab, new Vector3(i * offset.x, i * offset.y, i * offset.z), Quaternion.identity);
			// Assign our prefabs lightmap index to the instatiated ones 
			Renderer piecer = piece.GetComponent<Renderer>();
			piecer.lightmapIndex = lightmapIndex;
			piecer.lightmapScaleOffset = lightmapScaleOffset ; 
		}

	}
	
	// Update is called once per frame
	void Update () {
	
	}
}

 

Below is a screenshot which shows a single prefab with GI baked into it

lightmap_prefab_1

Now assume we instatiate this prefab, as you see below the lightmap is working only on the prefab but not the instatiated ones.

lightmap_prefab_2

And when you use the above script , it just copies the lightmaps on to all the prefabs at runtime.

lightmap_prefab_3

One Comment

  • Sabz says:

    I can’t make it to work, Here what I did
    1. In my scene, there were
    a. 3 separate light as mixed light.
    b. An empty object (Named – MyFrefab)contains one box and one plane.
    c. a Camera
    2. I drag the empty object in my asset panel
    3. Press generate lighting in the lighting panel
    4. After the Generating I assign your script to my “MyFrefab”
    5. Assign “MyFrefab” in your script prefab as an input object
    5. Press apply for prefab
    6. Then I drag the prefab from asset panel to the scene
    But it won’t work
    Can you please tell me what did I do wrong?

Leave a Reply