|
18 | 18 | using System.Collections.Generic;
|
19 | 19 | using System.IO;
|
20 | 20 | using System.Linq;
|
| 21 | +using System.Reflection; |
21 | 22 | using UnityEditor;
|
| 23 | +using UnityEditor.Formats.Fbx.Exporter; |
22 | 24 | using UnityEditor.SceneManagement;
|
23 | 25 | using UnityEngine;
|
24 | 26 | using UnityEngine.SceneManagement;
|
@@ -244,27 +246,55 @@ private Dictionary<string, IVpxPrefab> InstantiateGameItems()
|
244 | 246 | private Dictionary<string, IMainComponent> UpdateGameItems(Dictionary<string, IVpxPrefab> prefabLookup)
|
245 | 247 | {
|
246 | 248 | var componentLookup = prefabLookup.ToDictionary(x => x.Key, x => x.Value.MainComponent);
|
247 |
| - foreach (var prefab in prefabLookup.Values) { |
248 |
| - prefab.SetReferencedData(_sourceTable, this, this, componentLookup); |
249 |
| - prefab.FreeBinaryData(); |
| 249 | + try { |
| 250 | + // pause asset database refreshing |
| 251 | + AssetDatabase.StartAssetEditing(); |
250 | 252 |
|
251 |
| - if (prefab.ExtractMesh) { |
252 |
| - var mfs = prefab.MeshFilters; |
253 |
| - foreach (var mf in mfs) { |
254 |
| - var suffix = mfs.Length == 1 ? "" : $" ({mf.gameObject.name})"; |
255 |
| - var meshFilename = $"{prefab.GameObject.name.ToFilename()}{suffix.ToFilename()}.mesh"; |
| 253 | + // thanks unity for not letting me pass the options to ModelExporter.ExportObject(). |
| 254 | + var modelExporter = typeof(ModelExporter); |
| 255 | + var optionsProp = modelExporter.GetProperty("DefaultOptions", BindingFlags.Static | BindingFlags.NonPublic); |
| 256 | + var optionsValue = optionsProp!.GetValue(null, null); |
| 257 | + var optionsType = optionsValue.GetType(); |
| 258 | + var exportFormatField = optionsType.BaseType!.GetField("exportFormat", BindingFlags.Instance | BindingFlags.NonPublic); |
| 259 | + exportFormatField!.SetValue(optionsValue, 1); // set to binary |
| 260 | + var exportObject = modelExporter.GetMethod("ExportObjects", BindingFlags.NonPublic | BindingFlags.Static); |
| 261 | + |
| 262 | + // first loop: write fbx files |
| 263 | + foreach (var prefab in prefabLookup.Values) { |
| 264 | + prefab.SetReferencedData(_sourceTable, this, this, componentLookup); |
| 265 | + prefab.FreeBinaryData(); |
| 266 | + |
| 267 | + if (prefab.ExtractMesh) { |
| 268 | + var meshFilename = $"{prefab.GameObject.name.ToFilename()}.fbx"; |
256 | 269 | var meshPath = Path.Combine(_assetsMeshes, meshFilename);
|
257 | 270 | if (_options.SkipExistingMeshes && File.Exists(meshPath)) {
|
258 |
| - mf.sharedMesh = AssetDatabase.LoadAssetAtPath<Mesh>(meshPath); |
259 | 271 | continue;
|
260 | 272 | }
|
261 | 273 | if (File.Exists(meshPath)) {
|
262 | 274 | AssetDatabase.DeleteAsset(meshPath);
|
263 | 275 | }
|
264 |
| - AssetDatabase.CreateAsset(mf.sharedMesh, meshPath); |
| 276 | + |
| 277 | + // export via reflection, because we need binary. |
| 278 | + exportObject!.Invoke(null, new[] { meshPath, new UnityEngine.Object[] {prefab.GameObject}, optionsValue, null }); |
265 | 279 | }
|
266 | 280 | }
|
267 | 281 |
|
| 282 | + } finally { |
| 283 | + // resume asset database refreshing |
| 284 | + AssetDatabase.StopAssetEditing(); |
| 285 | + AssetDatabase.Refresh(); |
| 286 | + } |
| 287 | + |
| 288 | + // second loop: assign them to the game object. |
| 289 | + foreach (var prefab in prefabLookup.Values) { |
| 290 | + |
| 291 | + if (prefab.ExtractMesh) { |
| 292 | + var meshFilename = $"{prefab.GameObject.name.ToFilename()}.fbx"; |
| 293 | + var meshPath = Path.Combine(_assetsMeshes, meshFilename); |
| 294 | + var mf = prefab.GameObject.GetComponent<MeshFilter>(); |
| 295 | + mf.sharedMesh = AssetDatabase.LoadAssetAtPath<Mesh>(meshPath); |
| 296 | + } |
| 297 | + |
268 | 298 | // patch
|
269 | 299 | if (_applyPatch) {
|
270 | 300 | _patcher?.ApplyPatches(prefab.GameObject, _tableGo);
|
@@ -572,8 +602,8 @@ public GameObject GetGroupParent(string name)
|
572 | 602 | private string GetMeshPath(string parentName, string name)
|
573 | 603 | {
|
574 | 604 | var filename = parentName == name
|
575 |
| - ? $"{parentName.ToFilename()}.mesh" |
576 |
| - : $"{parentName.ToFilename()} ({name.ToFilename()}).mesh"; |
| 605 | + ? $"{parentName.ToFilename()}.fbx" |
| 606 | + : $"{parentName.ToFilename()} ({name.ToFilename()}).fbx"; |
577 | 607 | return Path.Combine(_assetsMeshes, filename);
|
578 | 608 | }
|
579 | 609 |
|
|
0 commit comments