mirror of
https://github.com/vrm-c/UniVRM.git
synced 2026-05-16 07:34:05 -05:00
Merge pull request #2534 from ousttrue/fix/vrma_scripted_importer
[vrma][editor] VRMA の EditorImport
This commit is contained in:
commit
4e6cab5400
63
Assets/VRM10/Editor/ScriptedImporter/VrmaScriptedImporter.cs
Normal file
63
Assets/VRM10/Editor/ScriptedImporter/VrmaScriptedImporter.cs
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
using UniGLTF;
|
||||
using UnityEngine;
|
||||
using System.Linq;
|
||||
using UnityEditor.AssetImporters;
|
||||
|
||||
|
||||
namespace UniVRM10
|
||||
{
|
||||
[ScriptedImporter(1, "vrma")]
|
||||
public class VrmaScriptedImporter : ScriptedImporter
|
||||
{
|
||||
/// <summary>
|
||||
/// Vrm-1.0 の Asset にアイコンを付与する
|
||||
/// </summary>
|
||||
static Texture2D _AssetIcon = null;
|
||||
static Texture2D AssetIcon
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_AssetIcon == null)
|
||||
{
|
||||
// try package
|
||||
_AssetIcon = UnityEditor.AssetDatabase.LoadAssetAtPath<Texture2D>("Packages/com.vrmc.vrm/Icons/vrm-48x48.png");
|
||||
}
|
||||
if (_AssetIcon == null)
|
||||
{
|
||||
// try assets
|
||||
_AssetIcon = UnityEditor.AssetDatabase.LoadAssetAtPath<Texture2D>("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<Vrm10AnimationInstance>();
|
||||
// context.AddObjectToAsset("__boxman_mesh__", vrma.BoxMan.sharedMesh);
|
||||
// context.AddObjectToAsset("__boxman_mesh__material__", vrma.BoxMan.sharedMaterial);
|
||||
|
||||
context.AddObjectToAsset(root.name, root, AssetIcon);
|
||||
context.SetMainObject(root);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 19427481f19aca9429da3548d28da6f5
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -5,7 +5,7 @@ MonoImporter:
|
|||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
icon: {fileID: 2800000, guid: ad4861e134018c948ac79793d290f48b, type: 3}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
|
|||
|
|
@ -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<SubAssetKey, UnityEngine.Object> 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<string, IDisposable> 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<Animator>();
|
||||
var animator = Root.AddComponent<Animator>();
|
||||
animator.avatar = avatar;
|
||||
}
|
||||
|
||||
if (expressions.Length > 0)
|
||||
if (m_expressions.Length > 0)
|
||||
{
|
||||
var animation = instance.GetComponentOrThrow<Animation>();
|
||||
var animation = Root.GetComponentOrThrow<Animation>();
|
||||
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<Vrm10AnimationInstance>();
|
||||
animationInstance.Initialize(expressions.Select(x => x.Key), defaultMaterial);
|
||||
var animationInstance = Root.AddComponent<Vrm10AnimationInstance>();
|
||||
|
||||
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<Vrm10AnimationInstance>();
|
||||
take(SubAssetKey.Create(animationInstance.BoxMan.sharedMesh), animationInstance.BoxMan.sharedMesh);
|
||||
|
||||
var animator = Root.GetComponent<Animator>();
|
||||
take(SubAssetKey.Create(animator.avatar), animator.avatar);
|
||||
|
||||
base.TransferOwnership(take);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user