How the heck can I include Lightmapping data in unity 5 asset bundles???

I cannot find any way to export a prefab into an asset bundle and include the lightmap data. With unity4 I could read Lightmap assets and later at load time assign them back to LightmapSettings. Using the new Enlighten it is stubbornly hiding the Textures, for no reason, they can’t be read and are no assets either.

WebGL is great, performance of my migrated project is great, all is great, except that unity 5 threw out Beast for no apparent reason, forcing me to rebake all scenes and not allowing me to edit lightmaps in Photoshop.

This way the whole of Unity5 is worthless.

This is the component I use to store the lightmap settings (they must be setup correctly in the editor, but need to be preserved in order to be exported to a bundle). See StoreAll static method (which I call from an editor action in a separate script). It references the lightmaps directly so you won’t have trouble later setting the right import settings for the textures.

At runtime when I load the bundle I have this script in the main project as well (since scripts don’t get exported due to Apple’s policies of having code in the main executable).
At runtime I call RestoreAll and pass the desired Lightmap mode. I only tested this for static single nondirectional lightmaps though (I migrated unity4 Beast with that).

In order to migrate Beast lightmaps, I made an utility to export the lightmap parameters to a textfile and load them again up in unity5, since unity5 would simply clear every setting from Beast (same as what happens at bundle export time). The lightmaps contain bugs and aren’t perfect, but a little adjustment is better than rebaking, at least in my indoor scenes. Of course when you restore the lightmap data, the lightmaps must also be present in the scene.

Regarding the lightmaps I had an intensity issue when simply importing the EXR assets from Beast in unity5, but I found it can be solved rather easily by changing something on the textures and pressing the apply button (and then changing that something back, it’s only about the re-encoding step done by unity5, since lightmapping in unity5 is not using the 2x factor any more).

So, I hope this helps anybody running into the same problems.

using UnityEngine;
using System.Collections.Generic;

/// <summary>
/// Use the provided editor action to put this component on all objects that use static light maps, in order to have their lightmap parameters exported to an asset bundle and later restored properly. 
/// The corresponding lightmaps will automatically be referenced and included in the bundle. At loading time you need to have this script in your hosting project and call the static method RestoreAll. 
/// </summary>
public class LightmapParams : MonoBehaviour 
{
	public Texture2D lightmapNear, lightmapFar; 
	public int lightmapIndex; 
	public Vector4 lightmapScaleOffset; 

	/// <summary>This function is called from an editor action and creates or updates this component on all objects with renderers and static lightmap in the current scene. </summary>
	public static void StoreAll()
	{
		foreach (Renderer r in FindObjectsOfType<Renderer>())
			if (r.lightmapIndex != -1)
			{
				LightmapParams lmp = r.gameObject.GetComponent<LightmapParams>(); 
				if (!lmp)
					lmp = r.gameObject.AddComponent<LightmapParams>(); 
				lmp.lightmapIndex = r.lightmapIndex; 
				lmp.lightmapScaleOffset = r.lightmapScaleOffset; 
				lmp.lightmapNear = LightmapSettings.lightmaps[lmp.lightmapIndex].lightmapNear; 
				lmp.lightmapFar = LightmapSettings.lightmaps[lmp.lightmapIndex].lightmapFar; 
			}
	}

	/// <summary>This function needs to be called after importing an assetbundle with exported lightmap data (see <see cref="StoreAll"/>), in order to restore it to the object. The collection it lightmaps will be set from the set of all lightmaps of all <see cref="LightmapParams"/> instances.</summary>
	public static void RestoreAll(LightmapsMode mode, bool removeComponentsAfterwards = false, bool setStatic = false)
	{
		List<LightmapData> newLightmaps = new List<LightmapData>(); 

		foreach (LightmapParams p in FindObjectsOfType<LightmapParams>())
		{
			Renderer r = p.gameObject.GetComponent<Renderer>(); 
			if (!r)
				continue; 

			r.lightmapIndex = p.lightmapIndex; 
			r.lightmapScaleOffset = p.lightmapScaleOffset; 

			// collect lightmaps from references: 
			while (newLightmaps.Count <= p.lightmapIndex)
				newLightmaps.Add(new LightmapData()); 
			newLightmaps[p.lightmapIndex].lightmapNear = p.lightmapNear; 
			newLightmaps[p.lightmapIndex].lightmapFar = p.lightmapFar; 

			if (setStatic)
				r.gameObject.isStatic = true; 

			if (removeComponentsAfterwards)
				Destroy(p); 
		}

		// activate: 
		LightmapSettings.lightmaps = newLightmaps.ToArray(); 
		LightmapSettings.lightmapsMode = mode; 
	}

	/// <summary>This function is called from an editor action to remove all <see cref="LightmapParams"/> components in the scene.</summary>
	public static void RemoveAll()
	{
		foreach (LightmapParams p in FindObjectsOfType<LightmapParams>())
			DestroyImmediate(p); 
	}
}

Best,
Matt

I won’t be able to try the new version since I’m heading out to vacation for a week and NOT taking my laptop :slight_smile:
But I did get it to work with the following scripts:

First I made a new class that save the index and coordinates of the lightmap.

public class LightmapParam : MonoBehaviour {
	public int lightmapIndex;
	public Vector4 lightmapScaleOffset;
}

I build the asset using this script, making sure to add a LIghtmapParam to each object that has a renderer. And manually adding the lightmaps to the assetBundle

	private void BuildAssetBundle(){

		GameObject assetParent = new GameObject();
		assetParent.name = assetName;
		GameObject[] allObjects = UnityEngine.Object.FindObjectsOfType<GameObject>() ;
		foreach(GameObject obj in allObjects){
			if(assetParent != obj){
				obj.transform.SetParent(assetParent.transform, true);
				Renderer r = obj.GetComponent<Renderer>();
				if(r != null){
					LightmapParam lmp = obj.GetComponent<LightmapParam>();
					if(lmp == null)
						lmp = obj.AddComponent<LightmapParam>();
					lmp.lightmapIndex = r.lightmapIndex;
					lmp.lightmapScaleOffset = r.lightmapScaleOffset;
				}
			}
		}

		string path = "Assets/AssetPrefabs/" + assetName + ".prefab";
		PrefabUtility.CreatePrefab(path, assetParent, ReplacePrefabOptions.ReplaceNameBased);
		Debug.Log("prefab " + path);



		//AssetBundleBuild[] abb = new AssetBundleBuild[1];
		//abb[0].assetBundleName = assetName;
		//abb[0].assetNames = new string[]{ path};
		//BuildPipeline.BuildAssetBundles ("Assets/AssetBundles", abb);


		
		string curScene = EditorApplication.currentScene; 
		string[] parts = curScene.Split('/', '\\'); 
		string sceneName = parts[parts.Length - 1].Split('.')[0]; 
		string lightmapPath = Path.GetDirectoryName(curScene) + "/" + sceneName + "/";
		List<string> assetList = new List<string>();
		for(int i = 0; i < LightmapSettings.lightmaps.Length; i++){
			LightmapData lmd = LightmapSettings.lightmaps*;*
  •  	string lmp = lightmapPath + "Lightmap-" + i + "_comp_light.exr";*
    
  •  	assetList.Add(lmp );*
    
  •  	Debug.Log(lmp + " " + File.Exists(lmp));*
    
  •  }*
    
  •  Debug.Log(assetList[0] + " " + assetList.Count);*
    
  •  //string path = "Assets/AssetPrefabs/" + assetName + ".prefab";*
    
  •  assetList.Add(path);*
    

_ AssetBundleBuild abb = new AssetBundleBuild[1]; // *************************************** lightmaps 2_

  •  abb[0].assetNames = assetList.ToArray();// new string[]{ path}; // create asset bundle from this prefab*
    
  •  // build mac*
    
  •  Debug.Log("make osx bundle");*
    
  •  abb[0].assetBundleName =  assetName + "_osx.unity3d";*
    
  •  BuildPipeline.BuildAssetBundles ("Assets/AssetBundles", abb, BuildAssetBundleOptions.None, BuildTarget.StandaloneOSXUniversal);*
    

}
Then when I’m loading the assetBundle I’m looking for the lightmapParam and assigning the values. and assigning the actual maps to the lightmapSettings.

  •  		AssetBundle bundle = www.assetBundle;*
    
  •  		Object[] objects = bundle.LoadAllAssets<Object>();*
    
  •  		List<LightmapData> lmdList = new List<LightmapData>();*
    
  •  		foreach(Object obj in objects){*
    
  •  			if (obj.GetType () == typeof(Texture2D)) {*
    
  •  				if (obj.name.Contains ("Lightmap")) {*
    
  •  					LightmapData lmd = new LightmapData();*
    
  •  					Texture2D tex = obj as Texture2D;*
    
  •  					lmd.lightmapFar = tex;*
    
  •  					lmdList.Add(lmd);*
    
  •  				}*
    
  •  			}*
    
  •  		}*
    
  •  		LightmapSettings.lightmaps = lmdList.ToArray();*
    
  •  		currentScene = Instantiate(bundle.LoadAsset(currentAsset.objectId)) as GameObject;*
    
  •  		Renderer[] rndrs = GameObject.FindObjectsOfType<Renderer>();*
    
  •  		foreach(Renderer rnd in rndrs){*
    
  •  			LightmapParam lmp = rnd.GetComponent<LightmapParam>();*
    
  •  			if(lmp != null){*
    
  •  				//Debug.Log(rnd.name + " " + lmp.lightmapIndex + " " + lmp.lightmapScaleOffset);*
    
  •  				rnd.lightmapIndex = lmp.lightmapIndex;*
    
  •  				rnd.lightmapScaleOffset = lmp.lightmapScaleOffset;*
    
  •  				rnd.gameObject.isStatic = true;*
    
  •  			}*
    
  •  		}*
    

Hope this works for you as well.
The one gatcha that I found is that the lightmaps coming in from the bundle are not tagged Lightmaps, and I couldn’t find a way to change that , so not all shaders work with it. I use legacy>lightmap>diffuse and it works
Cheers

Hi frevd,
Thanks for all your explanation. I am trying to get 4.6.1 beast lightmapping in Unity 5.1.1 WebGL. I followed the process as mentioned below

  1. Built Assetbundles in Unity 4.6.1 with lightparams associated
  2. In Unity 5.1, LoadAssetBundles script at Start, downloading and instantiating assetbundle
  3. Association of ligthmapping information from Lightparams component

but facing similar issue that, in Unity 5 editor I got assetbundles working correctly but somehow not downloading in web Browser. Only difference is that I had copied all the lightmaps manually in the Unity project folder. I am associating lightmaps after instantiation.
It will be great if you can elaborate the necessary steps to get 4.6 lightmapped assetbundles in WebGL Browser.