diff --git a/Assets/VRM10/Editor/ScriptedImporter/VrmaScriptedImporter.cs b/Assets/VRM10/Editor/ScriptedImporter/VrmaScriptedImporter.cs
new file mode 100644
index 000000000..da1791206
--- /dev/null
+++ b/Assets/VRM10/Editor/ScriptedImporter/VrmaScriptedImporter.cs
@@ -0,0 +1,63 @@
+using UniGLTF;
+using UnityEngine;
+using System.Linq;
+using UnityEditor.AssetImporters;
+
+
+namespace UniVRM10
+{
+ [ScriptedImporter(1, "vrma")]
+ public class VrmaScriptedImporter : ScriptedImporter
+ {
+ ///
+ /// Vrm-1.0 の Asset にアイコンを付与する
+ ///
+ static Texture2D _AssetIcon = null;
+ static Texture2D AssetIcon
+ {
+ get
+ {
+ if (_AssetIcon == null)
+ {
+ // try package
+ _AssetIcon = UnityEditor.AssetDatabase.LoadAssetAtPath("Packages/com.vrmc.vrm/Icons/vrm-48x48.png");
+ }
+ if (_AssetIcon == null)
+ {
+ // try assets
+ _AssetIcon = UnityEditor.AssetDatabase.LoadAssetAtPath("Assets/VRM10/Icons/vrm-48x48.png");
+ }
+ return _AssetIcon;
+ }
+ }
+
+ public override void OnImportAsset(AssetImportContext context)
+ {
+ // 2 回目以降の Asset Import において、 Importer の設定で Extract した UnityEngine.Object が入る
+ var extractedObjects = GetExternalObjectMap()
+ .Where(x => x.Value != null)
+ .ToDictionary(kv => new SubAssetKey(kv.Value.GetType(), kv.Key.name), kv => kv.Value);
+
+ using (var data = new AutoGltfFileParser(assetPath).Parse())
+ using (var loader = new VrmAnimationImporter(data, extractedObjects))
+ {
+ var loaded = loader.Load();
+
+ loaded.TransferOwnership((k, o) =>
+ {
+ context.AddObjectToAsset(k.Name, o);
+ });
+
+ var root = loaded.Root;
+ GameObject.DestroyImmediate(loaded);
+
+ // var vrma = root.GetComponent();
+ // context.AddObjectToAsset("__boxman_mesh__", vrma.BoxMan.sharedMesh);
+ // context.AddObjectToAsset("__boxman_mesh__material__", vrma.BoxMan.sharedMaterial);
+
+ context.AddObjectToAsset(root.name, root, AssetIcon);
+ context.SetMainObject(root);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assets/VRM10/Editor/ScriptedImporter/VrmaScriptedImporter.cs.meta b/Assets/VRM10/Editor/ScriptedImporter/VrmaScriptedImporter.cs.meta
new file mode 100644
index 000000000..045128bee
--- /dev/null
+++ b/Assets/VRM10/Editor/ScriptedImporter/VrmaScriptedImporter.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 19427481f19aca9429da3548d28da6f5
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/VRM10/Runtime/Components/VrmAnimationInstance/Vrm10AnimationInstance.cs.meta b/Assets/VRM10/Runtime/Components/VrmAnimationInstance/Vrm10AnimationInstance.cs.meta
index 81ed9bff9..62c6d9dfc 100644
--- a/Assets/VRM10/Runtime/Components/VrmAnimationInstance/Vrm10AnimationInstance.cs.meta
+++ b/Assets/VRM10/Runtime/Components/VrmAnimationInstance/Vrm10AnimationInstance.cs.meta
@@ -5,7 +5,7 @@ MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
- icon: {instanceID: 0}
+ icon: {fileID: 2800000, guid: ad4861e134018c948ac79793d290f48b, type: 3}
userData:
assetBundleName:
assetBundleVariant:
diff --git a/Assets/VRM10/Runtime/IO/VrmAnimationImporter.cs b/Assets/VRM10/Runtime/IO/VrmAnimationImporter.cs
index 41674c19e..3c2d5f9b2 100644
--- a/Assets/VRM10/Runtime/IO/VrmAnimationImporter.cs
+++ b/Assets/VRM10/Runtime/IO/VrmAnimationImporter.cs
@@ -7,12 +7,15 @@ using UniGLTF.Extensions.VRMC_vrm_animation;
using UniHumanoid;
using UniJSON;
using UnityEngine;
+using VrmLib;
namespace UniVRM10
{
public class VrmAnimationImporter : UniGLTF.ImporterContext
{
VRMC_vrm_animation m_vrma;
+ ExpressionInfo[] m_expressions;
+ Material m_defaultMaterial;
public VrmAnimationImporter(GltfData data,
IReadOnlyDictionary externalObjectMap = null,
@@ -230,8 +233,8 @@ namespace UniVRM10
{
// Expression は AnimationClip を分ける。
// glTFData から関連 Animation を取り除いて、取っておく。
- var expressions = IterateExpressions().ToArray();
- foreach (var channelIndex in expressions.Select(x => x.ChannelIndex).OrderByDescending(x => x))
+ m_expressions = IterateExpressions().ToArray();
+ foreach (var channelIndex in m_expressions.Select(x => x.ChannelIndex).OrderByDescending(x => x))
{
var nodeIndex = Data.GLTF.animations[0].channels[channelIndex].target.node;
Data.GLTF.nodes.RemoveAt(nodeIndex);
@@ -243,11 +246,16 @@ namespace UniVRM10
Data.GLTF.scenes[0].nodes = Data.GLTF.scenes[0].nodes.Take(1).ToArray();
// 可視化メッシュ用マテリアル。base.LoadAsync を呼ぶ前に生成する。
- var defaultMaterial = await MaterialFactory.GetDefaultMaterialAsync(awaitCaller);
+ m_defaultMaterial = await MaterialFactory.GetDefaultMaterialAsync(awaitCaller);
// Humanoid Animation が Gltf アニメーションとしてロードされる
var instance = await base.LoadAsync(awaitCaller, measureTime);
+ return instance;
+ }
+
+ protected override Task OnLoadHierarchy(IAwaitCaller awaitCaller, Func MeasureTime)
+ {
// setup humanoid
var humanMap = GetHumanMap();
if (humanMap.Count > 0)
@@ -256,22 +264,23 @@ namespace UniVRM10
//
// avatar
//
- var avatar = description.CreateAvatar(instance.Root.transform);
+ var avatar = description.CreateAvatar(Root.transform);
avatar.name = "Avatar";
// AvatarDescription = description;
- var animator = instance.gameObject.AddComponent();
+ var animator = Root.AddComponent();
animator.avatar = avatar;
}
- if (expressions.Length > 0)
+ if (m_expressions.Length > 0)
{
- var animation = instance.GetComponentOrThrow();
+ var animation = Root.GetComponentOrThrow();
var clip = animation.clip;
+ // m_expressionClip.name = "__expression__";
// Expression の float カーブを追加する
// VrmAnimationInstance の "preset_xx" field に連動する
var gltfAnimation = Data.GLTF.animations[0];
- foreach (var expression in expressions)
+ foreach (var expression in m_expressions)
{
var channel = expression.Channel;
var sampler = gltfAnimation.samplers[channel.sampler];
@@ -284,11 +293,22 @@ namespace UniVRM10
}
}
- // VRMA-animation solver
- var animationInstance = instance.gameObject.AddComponent();
- animationInstance.Initialize(expressions.Select(x => x.Key), defaultMaterial);
+ var animationInstance = Root.AddComponent();
- return instance;
+ animationInstance.Initialize(m_expressions.Select(x => x.Key), m_defaultMaterial);
+
+ return Task.CompletedTask;
+ }
+
+ public override void TransferOwnership(TakeResponsibilityForDestroyObjectFunc take)
+ {
+ var animationInstance = Root.GetComponent();
+ take(SubAssetKey.Create(animationInstance.BoxMan.sharedMesh), animationInstance.BoxMan.sharedMesh);
+
+ var animator = Root.GetComponent();
+ take(SubAssetKey.Create(animator.avatar), animator.avatar);
+
+ base.TransferOwnership(take);
}
}
-}
+}
\ No newline at end of file