- Home /
AssetBundle to prefab => meshes/textures missing
Sinds Unity Pro 4.2 our AssetBundles no longer work when trying to load them in our Unity web project. The error message says something about rebuilding the AssetBundles. So that's what I'm trying to do.
The problem is that the project started 3 years ago and we can't find the original assets that were used to build the AssetBundles.
I've created an editor script that reads the AssetBundle (in Unity 4.1.5) and creates a prefab from this. Like so:
void ExtractBundle(AssetBundle bundle)
{
var loadNames = new[] { "nav_a", "pick", "nav_z", "nav_y", "opslag" };
var parentName = Path.GetFileNameWithoutExtension(_pathBundle);
var go = new GameObject(parentName);
foreach (var loadName in loadNames.Where(bundle.Contains))
{
var child = (GameObject)bundle.Load(loadName, typeof(GameObject));
child.name = loadName;
child.transform.parent = go.transform;
}
CreatePrefab(go);
//bundle.Unload(true);
}
private static void CreatePrefab(GameObject go)
{
PrefabUtility.CreatePrefab("Assets/Prefabs/" + go.name + ".prefab", go);
}
The problem I'm facing is that the prefabs are missing the meshes and textures/materials.
What am I doing wrong here?
As soon as I close Unity and reopen it again all meshes and textures are gone and Unity says mesh missing. The meshes I see before I restart Unity are clearly in memory (I can see it when instantiating the generated prefab). I've tested this further and discovered that when I write: bundle.Unload(true); in the code after the CreatePrefab(go); line. I never see the meshes so they have to be stored only in memory.
Can someone please help because, although the AssetBundles are not complex, there are almost 200 of them!
Answer by whydoidoit · Aug 01, 2013 at 06:31 AM
Ouch :S
You are going to need to save all of the textures and materials on all of the prefabs as new assets and then update the link on the newly saved prefab to save the ones that you've got there.
It is possible to do this in a couple of ways - firstly there is the method of finding all of the renderers and using them, secondly you could use reflection to work across them. You would use the first way if there is no chance there is a material or texture that is referenced that is not already on a renderer. The second method is more difficult, but you could use it to find references to materials and textures on scripts as well as renderers.
I'll detail the first way and add the second method if it's necessary - let me know...
Now the second Gotcha - might be that the textures are not readable, in that case you "might" be able just to CreateAsset on the resulting texture from the original material - but that might complain that the texture is already an asset - so you "might" be able to use AssetDatabase.DestroyAsset on it first - I can't really check whether any of that works...
public void ResetAllMaterials(GameObject go)
{
var renderers = go.GetComponentsInChildren<Renderer>(true);
var textNum = 1;
var matNum = 1;
foreach(var r in renderers)
{
var newMaterials = new List<Material>();
foreach(var m in r.sharedMaterials)
{
var shader = m.shader;
var newMaterial = Instantiate(m) as Material;
newMaterials.Add(newMaterial);
var count = ShaderUtil.GetPropertyCount(shader);
for(var p = 0; p < count; p++)
{
var name = ShaderUtil.GetPropertyName(shader, p);
switch(ShaderUtil.GetPropertyType(shader, p))
{
case ShaderUtil.ShaderPropertyType.TexEnv:
var original = m.GetTexture(name);
if(original)
{
var texture = Instantiate(original) as Texture;
AssetDatabase.CreateAsset(texture, "Assets/Recovered_Texture_" + (textNum++).ToString() + name + ".asset"); //Or your extension
newMaterial.SetTexture(name, texture);
}
break;
}
}
AssetDatabase.CreateAsset(newMaterial, "Assets/Recovered_Material_" + (matNum++).ToString() + ".mat");
}
r.sharedMaterials = newMaterials.ToArray();
}
}
Thanks for the quick answer! I will try this today and let you know how it went.
BTW the people who neglected to keep the originals are not working for us anymore :-)
Your answer
Follow this Question
Related Questions
Missing textures & materials in asset bundle 1 Answer
Custom Inspector Element on Texture Importer? 2 Answers
Editor class "Texture Importer" question (applying settings to multiple texture assets). 2 Answers
EditorWindow texture effected by Playmode Color Tint 1 Answer
Change texture import settings by script 0 Answers