Cannot modify Prefab

Through an editor script I am loading in a shape file, then trying to modify the position, rotation, and material of a lot of shapes it contains. Using the unity debugger synchronized with monodevelop, I verified that the prefab transforms are modified correctly by the editor script. Up to that point, I have not instantiated any of those prefabs into my scene. In the same script, I save an asset bundle with these objects. When I load the asset bundle back into my scene, the changes to the prefabs are not present. So the objects come in the wrong location, wrong color. After the script has stopped, I look in the project tab and all of the prefab transforms are not modified.

First Question: why are the changes not being saved in the project prefabs?

Other question: When I build the UnityEngine.Object array for the BuildPipeline.BuildAssetBundle function, how recursive do I need to be? Let’s say for example that I have some GameObject “myobj”. Do I need to include the object’s transform, collider, renderer, in the array for buildAssetBundle? Or will the function recursively find all dependencies and include them in the asset bundle? I have the impression that if I don’t include the child components in the array, then the asset bundle does not include them, and when it’s loaded it just creates default components. I want it to include the modified components.

So far the only workaround I can think of is to instantiate my shapes from the shape file, make my modifications to the scene instances, and then build a prefab from the scene instances. This seems tedious though, and I’m sure will consume tons of RAM while the editor script runs, meaning my script might crash sooner rather than later. It also seems silly to me that I start with a prefab, need a prefab for the asset bundle, but cannot use/modify the initial prefab.

The changes are likely not being saved because you aren’t calling EditorUtility.SetDirty on the asset you want to save.

If you want everything saved in the AssetBundle, use the CollectDependencies and CompleteAssets BuildAssetBundleOptions. There is an example here.

So I added lines to mark my game objects, and their components, dirty using the EditorUtility.SetDirty function. I also added the “BuildAssetBundleOptions.CompleteAssets” to my arguments that build the asset bundle. Unfortunately what I’m saving into the asset bundle does not match what comes out when I load it into my scene.

assets Before save:

Index, Name, type

0, C4 Terrain, GameObject

1, Building on C4, GameObject

2, Group_1_1, GameObject

3, Mesh1, GameObject

4, Group_2_1, GameObject

5, Mesh2, GameObject

6, Mesh3, GameObject

7, Mesh4, GameObject

  • I verified through the debugger that the terrain object transform indeed has the correct position.

assets After loading (order does not matter, changes each time):

Index, Name, type

0, C4, GameObject

1, C4, Transform

2, Mesh1, Mesh

3, Mesh2, Mesh

4, Mesh3, Mesh

5, Mesh4, Mesh

6, C4, TerrainData

7, SplatAlpha 0, Texture2D

  • All objects are brought in at the world origin, my changes to the position were lost again.

And yet again, if I look into my project tab, and view the transform attached to my building prefab (not scene instance), the position is at the world origin. My changes to the prefab are not being persisted.

I think that maybe “SetDirty” needs some kind of follow up step? I looked through the EditorUtility but could not find anything. Any ideas?

Ok so here is an extremely simplified version of my pseudo-code that does not work:

String dirPath = "Assets\\Shapes\\"+cellName;
String destFilePath = dirPath+"\\"+cellName+".fbx";
AssetDatabase.GenerateUniqueAssetPath(destFilePath.Replace("\\","/"));
DirectoryInfo destDir = new DirectoryInfo(Directory.GetCurrentDirectory()
                   + "\\"+dirPath);
if (! destDir.Exists)
    destDir.Create();
FileUtil.CopyFileOrDirectory(fileInfo.ToString(),destFilePath.Replace("\\","/"));
AssetDatabase.Refresh();
String s = dirPath.Replace("\\","/")+"/"+cellName+".fbx";
UnityEngine.Object[] assets = AssetDatabase.LoadAllAssetsAtPath(s);
AssetDatabase.StartAssetEditing();
foreach (UnityEngine.Object asset in assets) {
    if (! (asset is GameObject))
        continue;
    GameObject gameObjectAsset = (GameObject)asset;

    // there is code here to modify the position and rotation of the game object asset...

    // from the debugger I have confirmed that the changes were made to the object correctly.

    EditorUtility.SetDirty(gameObjectAsset);
    EditorUtility.SetDirty(gameObjectAsset.transform);
    EditorUtility.SetDirty(gameObjectAsset.transform.position);
}
AssetDatabase.StopAssetEditing();
AssetDatabase.SaveAssets();

// I select the asset in my project view, under the shapes folder.
// I look in the inspector at the objects I build, 
// and the changes I made to the transform are not there.