Merge pull request #2774 from GeneTailor/asset-editing-blocks

Editor Importer Optimization: AssetDatabase StartAssetEditing & StopAssetEditing blocks
This commit is contained in:
ousttrue 2026-02-19 16:35:07 +09:00 committed by GitHub
commit c005fe0264
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 77 additions and 13 deletions

View File

@ -1,9 +1,10 @@
using System;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using UnityEditor;
using System.Linq;
using Unity.Profiling;
using UnityEditor;
using UnityEngine;
namespace UniGLTF
{
@ -20,6 +21,9 @@ namespace UniGLTF
private readonly IReadOnlyDictionary<SubAssetKey, Texture> m_subAssets;
UnityPath m_textureDirectory;
private static ProfilerMarker s_MarkerStartExtractTextures = new ProfilerMarker("Start Extract Textures");
private static ProfilerMarker s_MarkerDelayedExtractTextures = new ProfilerMarker("Delayed Extract Textures");
public TextureExtractor(GltfData data, UnityPath textureDirectory, IReadOnlyDictionary<SubAssetKey, Texture> subAssets)
{
m_data = data;
@ -77,14 +81,33 @@ namespace UniGLTF
Action<SubAssetKey, Texture2D> addRemap,
Action<IEnumerable<UnityPath>> onCompleted = null)
{
s_MarkerStartExtractTextures.Begin();
var extractor = new TextureExtractor(data, textureDirectory, subAssets);
foreach (var param in textureDescriptorGenerator.Get().GetEnumerable())
try
{
extractor.Extract(param.SubAssetKey, param);
AssetDatabase.StartAssetEditing();
foreach (var param in textureDescriptorGenerator.Get().GetEnumerable())
{
extractor.Extract(param.SubAssetKey, param);
}
}
catch (Exception e)
{
Debug.LogException(e);
}
finally
{
AssetDatabase.StopAssetEditing();
}
s_MarkerStartExtractTextures.End();
EditorApplication.delayCall += () =>
{
s_MarkerDelayedExtractTextures.Begin();
// Wait for the texture assets to be imported
foreach (var (key, targetPath) in extractor.Textures)
@ -97,6 +120,8 @@ namespace UniGLTF
}
}
s_MarkerDelayedExtractTextures.End();
if (onCompleted != null)
{
onCompleted(extractor.Textures.Values);

View File

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using UniGLTF;
using Unity.Profiling;
using UnityEditor;
using UnityEngine;
@ -12,6 +13,8 @@ namespace VRM
UnityPath m_prefabPath;
List<UnityPath> m_paths = new List<UnityPath>();
private static ProfilerMarker s_MarkerConvertAndExtractImages = new ProfilerMarker("Convert and Extract Images");
public ITextureDescriptorGenerator TextureDescriptorGenerator => m_context.TextureDescriptorGenerator;
public VRMEditorImporterContext(VRMImporterContext context, UnityPath prefabPath)
@ -76,22 +79,27 @@ namespace VRM
/// </summary>
public void ConvertAndExtractImages(Action<IEnumerable<UnityPath>> onTextureReloaded)
{
s_MarkerConvertAndExtractImages.Begin();
//
// convert images(metallic roughness, occlusion map)
//
var task = m_context.LoadMaterialsAsync(new ImmediateCaller());
if (!task.IsCompleted)
{
s_MarkerConvertAndExtractImages.End();
throw new Exception();
}
if (task.IsFaulted)
{
if (task.Exception is AggregateException ae && ae.InnerExceptions.Count == 1)
{
s_MarkerConvertAndExtractImages.End();
throw ae.InnerException;
}
else
{
s_MarkerConvertAndExtractImages.End();
throw task.Exception;
}
}
@ -100,6 +108,7 @@ namespace VRM
var task2 = m_context.ReadMetaAsync(new ImmediateCaller());
if (!task2.IsCompleted || task2.IsCanceled || task2.IsFaulted)
{
s_MarkerConvertAndExtractImages.End();
throw new Exception();
}
@ -110,6 +119,8 @@ namespace VRM
var vrmTextures = new BuiltInVrmMaterialDescriptorGenerator(m_context.VRM);
var dirName = $"{m_prefabPath.FileNameWithoutExtension}.Textures";
TextureExtractor.ExtractTextures(m_context.Data, m_prefabPath.Parent.Child(dirName), m_context.TextureDescriptorGenerator, subAssets, (_x, _y) => { }, onTextureReloaded);
s_MarkerConvertAndExtractImages.End();
}
void SaveAsAsset(SubAssetKey _, UnityEngine.Object o)

View File

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using UniGLTF;
using Unity.Profiling;
using UnityEditor;
using UnityEngine;
@ -10,6 +11,8 @@ namespace VRM
{
public class vrmAssetPostprocessor : AssetPostprocessor
{
private static ProfilerMarker s_MarkerCreatePrefab = new ProfilerMarker("Create Prefab");
#if !VRM_STOP_ASSETPOSTPROCESSOR
static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths)
{
@ -63,6 +66,9 @@ namespace VRM
return;
}
System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
sw.Start();
/// <summary>
/// これは EditorApplication.delayCall により呼び出される。
///
@ -73,24 +79,46 @@ namespace VRM
/// <value></value>
Action<IEnumerable<UnityPath>> onCompleted = texturePaths =>
{
s_MarkerCreatePrefab.Begin();
var map = texturePaths
.Select(x => x.LoadAsset<Texture>())
.ToDictionary(x => new SubAssetKey(x), x => x as UnityEngine.Object);
var settings = new ImporterContextSettings();
// 確実に Dispose するために敢えて再パースしている
using (var data = new GlbFileParser(vrmPath).Parse())
using (var context = new VRMImporterContext(new VRMData(data), externalObjectMap: map, settings: settings))
try
{
var editor = new VRMEditorImporterContext(context, prefabPath);
foreach (var textureInfo in context.TextureDescriptorGenerator.Get().GetEnumerable())
AssetDatabase.StartAssetEditing();
var settings = new ImporterContextSettings();
// 確実に Dispose するために敢えて再パースしている
using (var data = new GlbFileParser(vrmPath).Parse())
using (var context = new VRMImporterContext(new VRMData(data), externalObjectMap: map, settings: settings))
{
TextureImporterConfigurator.Configure(textureInfo, context.TextureFactory.ExternalTextures);
var editor = new VRMEditorImporterContext(context, prefabPath);
foreach (var textureInfo in context.TextureDescriptorGenerator.Get().GetEnumerable())
{
TextureImporterConfigurator.Configure(textureInfo, context.TextureFactory.ExternalTextures);
}
var loaded = context.Load();
editor.SaveAsAsset(loaded);
}
var loaded = context.Load();
editor.SaveAsAsset(loaded);
}
catch (Exception e)
{
Debug.LogException(e);
}
finally
{
AssetDatabase.StopAssetEditing();
}
s_MarkerCreatePrefab.End();
sw.Stop();
Debug.Log($"Import complete [importMs={sw.ElapsedMilliseconds}]");
};
using (var data = new GlbFileParser(vrmPath).Parse())