/// <summary> /// In a second pass, we update the referenced data. This is so states dependent on other components /// is correctly applied. /// </summary> /// <param name="prefabLookup">A dictionary with lower-case names as key, and created prefabs as values.</param> private Dictionary <string, IMainComponent> UpdateGameItems(Dictionary <string, IVpxPrefab> prefabLookup) { var componentLookup = prefabLookup.ToDictionary(x => x.Key, x => x.Value.MainComponent); try { // pause asset database refreshing AssetDatabase.StartAssetEditing(); // thanks unity for not letting me pass the options to ModelExporter.ExportObject(). var modelExporter = typeof(ModelExporter); var optionsProp = modelExporter.GetProperty("DefaultOptions", BindingFlags.Static | BindingFlags.NonPublic); var optionsValue = optionsProp !.GetValue(null, null); var optionsType = optionsValue.GetType(); var exportFormatField = optionsType.BaseType !.GetField("exportFormat", BindingFlags.Instance | BindingFlags.NonPublic); exportFormatField !.SetValue(optionsValue, 1); // set to binary var exportObject = modelExporter.GetMethod("ExportObjects", BindingFlags.NonPublic | BindingFlags.Static); // first loop: write fbx files foreach (var prefab in prefabLookup.Values) { prefab.SetReferencedData(_sourceTable, this, this, componentLookup); prefab.FreeBinaryData(); if (prefab.ExtractMesh) { var meshFilename = $"{prefab.GameObject.name.ToFilename()}.fbx"; var meshPath = Path.Combine(_assetsMeshes, meshFilename); if (_options.SkipExistingMeshes && File.Exists(meshPath)) { continue; } if (File.Exists(meshPath)) { AssetDatabase.DeleteAsset(meshPath); } // export via reflection, because we need binary. exportObject !.Invoke(null, new[] { meshPath, new UnityEngine.Object[] { prefab.GameObject }, optionsValue, null }); } } } finally { // resume asset database refreshing AssetDatabase.StopAssetEditing(); AssetDatabase.Refresh(); } // second loop: assign them to the game object. foreach (var prefab in prefabLookup.Values) { if (prefab.ExtractMesh) { var meshFilename = $"{prefab.GameObject.name.ToFilename()}.fbx"; var meshPath = Path.Combine(_assetsMeshes, meshFilename); var mf = prefab.GameObject.GetComponent <MeshFilter>(); mf.sharedMesh = AssetDatabase.LoadAssetAtPath <Mesh>(meshPath); } // patch if (_applyPatch) { _patcher?.ApplyPatches(prefab.GameObject, _tableGo); if (prefab.GameObject) // only if not destroyed.. { prefab.UpdateTransforms(); } } // persist changes if (prefab.GameObject) // only if not destroyed.. { prefab.PersistData(); } } return(componentLookup); }