Ejemplo n.º 1
0
    public override void OnInspectorGUI()
    {
        AnimationExporter obj = (AnimationExporter)target;

        Undo.RecordObject(obj, "AnimationExporter");

        if (obj.GetComponent <Animation>() != null)
        {
            if (GUILayout.Button("Edit Animation"))
            {
                EditorApplication.ExecuteMenuItem("Window/Animation");
            }
        }
        else
        {
            if (GUILayout.Button("Create Animation"))
            {
                Undo.AddComponent <Animation>(obj.gameObject);
            }
        }

        // 保存するキーを表示する
        GUILayout.BeginVertical(GUI.skin.box);
        GUILayout.Label("Export Keys");
        var clip     = obj.ExportedAnimationClip;
        var bindings = AnimationUtility.GetCurveBindings(clip);

        for (int i = 0; i < bindings.Length; ++i)
        {
            AnimationCurve curve = AnimationUtility.GetEditorCurve(clip, bindings[i]);
            string         key   = bindings[i].path + "/" + bindings[i].propertyName;
            EditorGUILayout.TextField(key);
        }
        GUILayout.EndVertical();

        DrawDefaultInspector();

        if (GUILayout.Button("Add Save File"))
        {
            string file = EditorUtility.SaveFilePanel("Curve File", "", "curve.json", "json");

            if (file != null && file.Length > 1)
            {
                var fileURI  = new System.Uri(file);
                var refURI   = new Uri(Application.streamingAssetsPath);
                var relative = refURI.MakeRelativeUri(fileURI).ToString();

                if (obj.PathsForRelativeAssets == null)
                {
                    obj.PathsForRelativeAssets = new List <string>();
                }

                obj.PathsForRelativeAssets.Add(relative);
            }
        }
        if (GUILayout.Button("Save !"))
        {
            obj.Write();
        }
    }
Ejemplo n.º 2
0
        public static IEnumerable <Validation> Validate(GameObject root)
        {
            if (root == null)
            {
                yield break;
            }

            var animationClips = new List <AnimationClip>();
            var animator       = root.GetComponent <Animator>();
            var animation      = root.GetComponent <UnityEngine.Animation>();

            if (animator != null)
            {
                animationClips = AnimationExporter.GetAnimationClips(animator);
            }
            else if (animation != null)
            {
                animationClips = AnimationExporter.GetAnimationClips(animation);
            }

            if (!animationClips.Any())
            {
                yield break;
            }

            foreach (var animationClip in animationClips)
            {
                foreach (var editorCurveBinding in AnimationUtility.GetCurveBindings(animationClip))
                {
                    // is root included in animation?
                    if (string.IsNullOrEmpty(editorCurveBinding.path))
                    {
                        yield return(Validation.Error(ExporterValidatorMessages.ROOT_ANIMATED.Msg()));

                        yield break;
                    }
                }
            }
        }
Ejemplo n.º 3
0
        private static void ValidateAnimation(GameObject gameObject)
        {
            // NOTE: Editorコードを含んでいるため、ランタイムでValidateすることができない
            // TODO: Runtime 時にどうするかを考える
#if UNITY_EDITOR
            // Check 1: root の Animator/Animation で自身を animate していない
            // NOTE: root についてる animation の export は UniGLTF 側で行われる
            //       その時、Animator か Animation どちらか片方が一つのみアタッチされていること前提で export される
            var animationClips = new List<AnimationClip>();
            var animator = gameObject.GetComponent<Animator>();
            var animation = gameObject.GetComponent<Animation>();
            if (animator != null)
            {
                animationClips.AddRange(AnimationExporter.GetAnimationClips(animator));
            }
            else if (animation != null)
            {
                animationClips.AddRange(AnimationExporter.GetAnimationClips(animation));
            }

            if (!animationClips.Any())
            {
                return;
            }

            foreach (var animationClip in animationClips)
            {
                foreach (var animationCurveBindings in AnimationUtility.GetCurveBindings(animationClip))
                {
                    if (string.IsNullOrEmpty(animationCurveBindings.path))
                    {
                        var errorText = VCIConfig.GetText($"error{(int) ValidationErrorType.RootIsAnimated}");
                        throw new VCIValidatorException(ValidationErrorType.RootIsAnimated, errorText);
                    }
                }
            }
#endif
        }
Ejemplo n.º 4
0
        public override void Export()
        {
            base.Export();

            var gltf     = GLTF;
            var exporter = this;
            var go       = Copy;

            //exporter.Prepare(go);
            //exporter.Export();

            gltf.extensions.VCAST_vci_material_unity = new glTF_VCAST_vci_material_unity
            {
                materials = exporter.Materials
                            .Select(m => glTF_VCI_Material.CreateFromMaterial(m, exporter.TextureManager.Textures))
                            .ToList()
            };

            if (Copy == null)
            {
                return;
            }

            // vci interaction
            var vciObject = Copy.GetComponent <VCIObject>();

            if (vciObject != null)
            {
                // script
                if (vciObject.Scripts.Any())
                {
                    gltf.extensions.VCAST_vci_embedded_script = new glTF_VCAST_vci_embedded_script
                    {
                        scripts = vciObject.Scripts.Select(x =>
                        {
                            int viewIndex = -1;
#if UNITY_EDITOR
                            if (!string.IsNullOrEmpty(x.filePath))
                            {
                                if (File.Exists(x.filePath))
                                {
                                    using (var resader = new StreamReader(x.filePath))
                                    {
                                        string scriptStr = resader.ReadToEnd();
                                        viewIndex        = gltf.ExtendBufferAndGetViewIndex <byte>(0, Utf8String.Encoding.GetBytes(scriptStr));
                                    }
                                }
                                else
                                {
                                    Debug.LogError("script file not found. スクリプトファイルが見つかりませんでした: " + x.filePath);
                                    throw new FileNotFoundException(x.filePath);
                                }
                            }
                            else
#endif
                            {
                                viewIndex = gltf.ExtendBufferAndGetViewIndex <byte>(0, Utf8String.Encoding.GetBytes(x.source));
                            }

                            return(new glTF_VCAST_vci_embedded_script_source
                            {
                                name = x.name,
                                mimeType = x.mimeType,
                                targetEngine = x.targetEngine,
                                source = viewIndex,
                            });
                        })
                                  .ToList()
                    }
                }
                ;

                var springBones = Copy.GetComponents <VCISpringBone>();
                if (springBones.Length > 0)
                {
                    var sbg = new glTF_VCAST_vci_spring_bone();
                    sbg.springBones = new List <glTF_VCAST_vci_SpringBone>();
                    gltf.extensions.VCAST_vci_spring_bone = sbg;
                    foreach (var sb in springBones)
                    {
                        sbg.springBones.Add(new glTF_VCAST_vci_SpringBone()
                        {
                            center       = Nodes.IndexOf(sb.m_center),
                            dragForce    = sb.m_dragForce,
                            gravityDir   = sb.m_gravityDir,
                            gravityPower = sb.m_gravityPower,
                            stiffiness   = sb.m_stiffnessForce,
                            hitRadius    = sb.m_hitRadius,
                            colliderIds  = sb.m_colliderObjects
                                           .Where(x => x != null)
                                           .Select(x => Nodes.IndexOf(x))
                                           .ToArray(),
                            bones = sb.RootBones.Where(x => x != null).Select(x => Nodes.IndexOf(x.transform)).ToArray()
                        });
                    }
                }

                // meta
                var meta = vciObject.Meta;
                gltf.extensions.VCAST_vci_meta = new glTF_VCAST_vci_meta
                {
                    exporterVCIVersion = VCIVersion.VCI_VERSION,
                    specVersion        = VCISpecVersion.Version,

                    title = meta.title,

                    version            = meta.version,
                    author             = meta.author,
                    contactInformation = meta.contactInformation,
                    reference          = meta.reference,
                    description        = meta.description,

                    modelDataLicenseType     = meta.modelDataLicenseType,
                    modelDataOtherLicenseUrl = meta.modelDataOtherLicenseUrl,
                    scriptLicenseType        = meta.scriptLicenseType,
                    scriptOtherLicenseUrl    = meta.scriptOtherLicenseUrl,

                    scriptWriteProtected  = meta.scriptWriteProtected,
                    scriptEnableDebugging = meta.scriptEnableDebugging,
                    scriptFormat          = meta.scriptFormat
                };
                if (meta.thumbnail != null)
                {
                    gltf.extensions.VCAST_vci_meta.thumbnail = TextureIO.ExportTexture(
                        gltf, gltf.buffers.Count - 1, meta.thumbnail, glTFTextureTypes.Unknown);
                }
            }

            // collider & rigidbody & joint & item
            for (var i = 0; i < exporter.Nodes.Count; i++)
            {
                var node     = exporter.Nodes[i];
                var gltfNode = gltf.nodes[i];

                // 各ノードに複数のコライダーがあり得る
                var colliders = node.GetComponents <Collider>();
                if (colliders.Any())
                {
                    if (gltfNode.extensions == null)
                    {
                        gltfNode.extensions = new glTFNode_extensions();
                    }

                    gltfNode.extensions.VCAST_vci_collider           = new glTF_VCAST_vci_colliders();
                    gltfNode.extensions.VCAST_vci_collider.colliders = new List <glTF_VCAST_vci_Collider>();

                    foreach (var collider in colliders)
                    {
                        var gltfCollider = glTF_VCAST_vci_Collider.GetglTfColliderFromUnityCollider(collider);
                        if (gltfCollider == null)
                        {
                            Debug.LogWarningFormat("collider is not supported: {0}", collider.GetType().Name);
                            continue;
                        }

                        gltfNode.extensions.VCAST_vci_collider.colliders.Add(gltfCollider);
                    }
                }

                var rigidbodies = node.GetComponents <Rigidbody>();
                if (rigidbodies.Any())
                {
                    if (gltfNode.extensions == null)
                    {
                        gltfNode.extensions = new glTFNode_extensions();
                    }

                    gltfNode.extensions.VCAST_vci_rigidbody             = new glTF_VCAST_vci_rigidbody();
                    gltfNode.extensions.VCAST_vci_rigidbody.rigidbodies = new List <glTF_VCAST_vci_Rigidbody>();

                    foreach (var rigidbody in rigidbodies)
                    {
                        gltfNode.extensions.VCAST_vci_rigidbody.rigidbodies.Add(
                            glTF_VCAST_vci_Rigidbody.GetglTfRigidbodyFromUnityRigidbody(rigidbody));
                    }
                }

                var joints = node.GetComponents <Joint>();
                if (joints.Any())
                {
                    if (gltfNode.extensions == null)
                    {
                        gltfNode.extensions = new glTFNode_extensions();
                    }

                    gltfNode.extensions.VCAST_vci_joints        = new glTF_VCAST_vci_joints();
                    gltfNode.extensions.VCAST_vci_joints.joints = new List <glTF_VCAST_vci_joint>();

                    foreach (var joint in joints)
                    {
                        gltfNode.extensions.VCAST_vci_joints.joints.Add(
                            glTF_VCAST_vci_joint.GetglTFJointFromUnityJoint(joint, exporter.Nodes));
                    }
                }

                var item = node.GetComponent <VCISubItem>();
                if (item != null)
                {
                    var warning = item.ExportWarning;
                    if (!string.IsNullOrEmpty(warning))
                    {
                        throw new System.Exception(warning);
                    }

                    if (gltfNode.extensions == null)
                    {
                        gltfNode.extensions = new glTFNode_extensions();
                    }

                    gltfNode.extensions.VCAST_vci_item = new glTF_VCAST_vci_item
                    {
                        grabbable      = item.Grabbable,
                        scalable       = item.Scalable,
                        uniformScaling = item.UniformScaling,
                        groupId        = item.GroupId,
                    };
                }

                // Attachable
                var vciAttachable = node.GetComponent <VCIAttachable>();
                if (vciAttachable != null &&
                    vciAttachable.AttachableHumanBodyBones != null &&
                    vciAttachable.AttachableHumanBodyBones.Any())
                {
                    if (gltfNode.extensions == null)
                    {
                        gltfNode.extensions = new glTFNode_extensions();
                    }

                    gltfNode.extensions.VCAST_vci_attachable = new glTF_VCAST_vci_attachable
                    {
                        attachableHumanBodyBones = vciAttachable.AttachableHumanBodyBones.Select(x => x.ToString()).ToList(),
                        attachableDistance       = vciAttachable.AttachableDistance,
                    };
                }

                // Text
                var tmp = node.GetComponent <TextMeshPro>();
                var rt  = node.GetComponent <RectTransform>();
                if (tmp != null && rt != null)
                {
                    if (gltfNode.extensions == null)
                    {
                        gltfNode.extensions = new glTFNode_extensions();
                    }

                    gltfNode.extensions.VCAST_vci_rectTransform = new glTF_VCAST_vci_rectTransform()
                    {
                        rectTransform = glTF_VCAST_vci_RectTransform.CreateFromRectTransform(rt)
                    };

                    gltfNode.extensions.VCAST_vci_text = new glTF_VCAST_vci_text
                    {
                        text = glTF_VCAST_vci_Text.Create(tmp)
                    };
                }
            }

            // Audio
            var clips = exporter.Copy.GetComponentsInChildren <AudioSource>()
                        .Select(x => x.clip)
                        .Where(x => x != null)
                        .ToArray();
            if (clips.Any())
            {
                var audios = clips.Select(x => FromAudioClip(gltf, x)).Where(x => x != null).ToList();
                gltf.extensions.VCAST_vci_audios = new glTF_VCAST_vci_audios
                {
                    audios = audios
                };
            }

#if UNITY_EDITOR
            // Animation
            // None RootAnimation
            var animators  = exporter.Copy.GetComponentsInChildren <Animator>().Where(x => exporter.Copy != x.gameObject);
            var animations = exporter.Copy.GetComponentsInChildren <Animation>().Where(x => exporter.Copy != x.gameObject);
            // NodeIndex to AnimationClips
            Dictionary <int, AnimationClip[]> animationNodeList = new Dictionary <int, AnimationClip[]>();

            foreach (var animator in animators)
            {
                var animationClips = AnimationExporter.GetAnimationClips(animator);
                var nodeIndex      = exporter.Nodes.FindIndex(0, exporter.Nodes.Count, x => x == animator.transform);
                if (animationClips.Any() && nodeIndex != -1)
                {
                    animationNodeList.Add(nodeIndex, animationClips.ToArray());
                }
            }

            foreach (var animation in animations)
            {
                var animationClips = AnimationExporter.GetAnimationClips(animation);
                var nodeIndex      = exporter.Nodes.FindIndex(0, exporter.Nodes.Count, x => x == animation.transform);
                if (animationClips.Any() && nodeIndex != -1)
                {
                    animationNodeList.Add(nodeIndex, animationClips.ToArray());
                }
            }

            int bufferIndex = 0;
            foreach (var animationNode in animationNodeList)
            {
                List <int> clipIndices = new List <int>();
                // write animationClips
                foreach (var clip in animationNode.Value)
                {
                    var animationWithCurve = AnimationExporter.Export(clip, Nodes[animationNode.Key], Nodes);
                    AnimationExporter.WriteAnimationWithSampleCurves(gltf, animationWithCurve, clip.name, bufferIndex);
                    clipIndices.Add(gltf.animations.IndexOf(animationWithCurve.Animation));
                }

                // write node
                if (clipIndices.Any())
                {
                    var node = gltf.nodes[animationNode.Key];
                    if (node.extensions == null)
                    {
                        node.extensions = new glTFNode_extensions();
                    }

                    node.extensions.VCAST_vci_animation = new glTF_VCAST_vci_animation()
                    {
                        animationReferences = new List <glTF_VCAST_vci_animationReference>()
                    };

                    foreach (var index in clipIndices)
                    {
                        node.extensions.VCAST_vci_animation.animationReferences.Add(new glTF_VCAST_vci_animationReference()
                        {
                            animation = index
                        });
                    }
                }
            }
#endif

            // Effekseer
            var effekseerEmitters = exporter.Copy.GetComponentsInChildren <Effekseer.EffekseerEmitter>()
                                    .Where(x => x.effectAsset != null)
                                    .ToArray();

            if (effekseerEmitters.Any())
            {
                gltf.extensions.Effekseer = new glTF_Effekseer()
                {
                    effects = new List <glTF_Effekseer_effect>()
                };

                foreach (var emitter in effekseerEmitters)
                {
                    var index = exporter.Nodes.FindIndex(x => x == emitter.transform);
                    if (index < 0)
                    {
                        continue;
                    }

                    var effectIndex = AddEffekseerEffect(gltf, emitter);
                    var gltfNode    = gltf.nodes[index];
                    if (gltfNode.extensions == null)
                    {
                        gltfNode.extensions = new glTFNode_extensions();
                    }
                    if (gltfNode.extensions.Effekseer_emitters == null)
                    {
                        gltfNode.extensions.Effekseer_emitters = new glTF_Effekseer_emitters()
                        {
                            emitters = new List <glTF_Effekseer_emitter>()
                        };
                    }

                    gltfNode.extensions.Effekseer_emitters.emitters.Add(new glTF_Effekseer_emitter()
                    {
                        effectIndex   = effectIndex,
                        isLoop        = emitter.isLooping,
                        isPlayOnStart = emitter.playOnStart
                    });
                }
            }
        }
Ejemplo n.º 5
0
        public override void Export(MeshExportSettings configuration)
        {
            base.Export(configuration);

            var gltf     = glTF;
            var exporter = this;



            // VCIのmaterial拡張
            {
                var VCAST_vci_material_unity = new glTF_VCAST_vci_material_unity();
                VCAST_vci_material_unity.materials = new List <glTF_VCI_Material>();
                foreach (var material in exporter.Materials)
                {
                    VCAST_vci_material_unity.materials.Add(VCIMaterialExporter.CreateFromMaterial(material, TextureManager.Textures));
                }

                var f = new UniJSON.JsonFormatter();
                glTF_VCAST_vci_material_unity_Serializer.Serialize(f, VCAST_vci_material_unity);
                glTFExtensionExport.GetOrCreate(ref gltf.extensions).Add(glTF_VCAST_vci_material_unity.ExtensionName, f.GetStore().Bytes);
            }


            if (Copy == null)
            {
                return;
            }

            // vci interaction
            var vciObject = Copy.GetComponent <VCIObject>();

            if (vciObject != null)
            {
                // script
                if (vciObject.Scripts.Any())
                {
                    var VCAST_vci_embedded_script = new glTF_VCAST_vci_embedded_script
                    {
                        scripts = vciObject.Scripts.Select(x =>
                        {
                            int viewIndex = -1;
#if UNITY_EDITOR
                            if (x.textAsset)
                            {
                                viewIndex = gltf.ExtendBufferAndGetViewIndex <byte>(0,
                                                                                    Utf8String.Encoding.GetBytes(x.textAsset.text));
                            }
                            else
#endif
                            {
                                viewIndex = gltf.ExtendBufferAndGetViewIndex <byte>(0,
                                                                                    Utf8String.Encoding.GetBytes(x.source));
                            }

                            return(new glTF_VCAST_vci_embedded_script_source
                            {
                                name = x.name,
                                mimeType = x.mimeType,
                                targetEngine = x.targetEngine,
                                source = viewIndex,
                            });
                        })
                                  .ToList()
                    };

                    var f = new UniJSON.JsonFormatter();
                    glTF_VCAST_vci_embedded_script_Serializer.Serialize(f, VCAST_vci_embedded_script);
                    glTFExtensionExport.GetOrCreate(ref gltf.extensions).Add(glTF_VCAST_vci_embedded_script.ExtensionName, f.GetStore().Bytes);
                }

                var springBones = Copy.GetComponents <VCISpringBone>();
                if (springBones.Length > 0)
                {
                    var VCAST_vci_spring_bone = new glTF_VCAST_vci_spring_bone();
                    VCAST_vci_spring_bone.springBones = new List <glTF_VCAST_vci_SpringBone>();
                    foreach (var sb in springBones)
                    {
                        VCAST_vci_spring_bone.springBones.Add(new glTF_VCAST_vci_SpringBone()
                        {
                            center       = Nodes.IndexOf(sb.m_center),
                            dragForce    = sb.m_dragForce,
                            gravityDir   = sb.m_gravityDir,
                            gravityPower = sb.m_gravityPower,
                            stiffiness   = sb.m_stiffnessForce,
                            hitRadius    = sb.m_hitRadius,
                            colliderIds  = sb.m_colliderObjects
                                           .Where(x => x != null)
                                           .Select(x => Nodes.IndexOf(x))
                                           .ToArray(),
                            bones = sb.RootBones.Where(x => x != null).Select(x => Nodes.IndexOf(x.transform)).ToArray()
                        });
                    }

                    var f = new UniJSON.JsonFormatter();
                    glTF_VCAST_vci_spring_bone_Serializer.Serialize(f, VCAST_vci_spring_bone);
                    glTFExtensionExport.GetOrCreate(ref gltf.extensions).Add(glTF_VCAST_vci_spring_bone.ExtensionName, f.GetStore().Bytes);
                }

                // meta
                {
                    var meta           = vciObject.Meta;
                    var VCAST_vci_meta = new glTF_VCAST_vci_meta
                    {
                        exporterVCIVersion = VCIVersion.VCI_VERSION,
                        specVersion        = VCISpecVersion.Version,

                        title = meta.title,

                        version            = meta.version,
                        author             = meta.author,
                        contactInformation = meta.contactInformation,
                        reference          = meta.reference,
                        description        = meta.description,

                        modelDataLicenseType     = meta.modelDataLicenseType,
                        modelDataOtherLicenseUrl = meta.modelDataOtherLicenseUrl,
                        scriptLicenseType        = meta.scriptLicenseType,
                        scriptOtherLicenseUrl    = meta.scriptOtherLicenseUrl,

                        scriptWriteProtected  = meta.scriptWriteProtected,
                        scriptEnableDebugging = meta.scriptEnableDebugging,
                        scriptFormat          = meta.scriptFormat
                    };
                    if (meta.thumbnail != null)
                    {
                        VCAST_vci_meta.thumbnail = TextureExporter.ExportTexture(
                            gltf, gltf.buffers.Count - 1, meta.thumbnail, glTFTextureTypes.Unknown);
                    }

                    var f = new UniJSON.JsonFormatter();
                    glTF_VCAST_vci_meta_Serializer.Serialize(f, VCAST_vci_meta);
                    glTFExtensionExport.GetOrCreate(ref gltf.extensions).Add(glTF_VCAST_vci_meta.ExtensionName, f.GetStore().Bytes);
                }
            }

            // Audio
            var clips = exporter.Copy.GetComponentsInChildren <AudioSource>()
                        .Select(x => x.clip)
                        .Where(x => x != null)
                        .ToArray();
            glTF_VCAST_vci_audios VCAST_vci_audios = null;

            if (clips.Any())
            {
                var audios = new List <glTF_VCAST_vci_audio>();
                foreach (var clip in clips)
                {
                    if (audios.Exists(x => x.name == clip.name))
                    {
                        continue;
                    }

                    var audio = FromAudioClip(gltf, clip);
                    if (audio != null)
                    {
                        audios.Add(audio);
                    }
                }

                VCAST_vci_audios = new glTF_VCAST_vci_audios
                {
                    audios = audios
                };

                var f = new UniJSON.JsonFormatter();
                glTF_VCAST_vci_audios_Serializer.Serialize(f, VCAST_vci_audios);
                glTFExtensionExport.GetOrCreate(ref gltf.extensions).Add(glTF_VCAST_vci_audios.ExtensionName, f.GetStore().Bytes);
            }

            // collider & rigidbody & joint & item & playerSpawnPoint & audioSource
            for (var i = 0; i < exporter.Nodes.Count; i++)
            {
                var node     = exporter.Nodes[i];
                var gltfNode = gltf.nodes[i];

                // 各ノードに複数のコライダーがあり得る
                var colliders = node.GetComponents <Collider>();
                if (colliders.Any())
                {
                    var VCAST_vci_collider = new glTF_VCAST_vci_colliders();
                    VCAST_vci_collider.colliders = new List <glTF_VCAST_vci_Collider>();

                    foreach (var collider in colliders)
                    {
                        var gltfCollider = glTF_VCAST_vci_Collider.GetglTfColliderFromUnityCollider(collider);
                        if (gltfCollider == null)
                        {
                            Debug.LogWarningFormat("collider is not supported: {0}", collider.GetType().Name);
                            continue;
                        }

                        if (VciColliderSetting.TryGetVciLayerLabel(node.gameObject.layer, out var label))
                        {
                            if (!string.IsNullOrEmpty(label))
                            {
                                gltfCollider.layer = label;
                            }
                        }

                        VCAST_vci_collider.colliders.Add(gltfCollider);
                    }

                    var f = new UniJSON.JsonFormatter();
                    glTF_VCAST_vci_colliders_Serializer.Serialize(f, VCAST_vci_collider);
                    glTFExtensionExport.GetOrCreate(ref gltfNode.extensions).Add(glTF_VCAST_vci_colliders.ExtensionName, f.GetStore().Bytes);
                }

                var rigidbodies = node.GetComponents <Rigidbody>();
                if (rigidbodies.Any())
                {
                    var VCAST_vci_rigidbody = new glTF_VCAST_vci_rigidbody();
                    VCAST_vci_rigidbody.rigidbodies = new List <glTF_VCAST_vci_Rigidbody>();

                    foreach (var rigidbody in rigidbodies)
                    {
                        VCAST_vci_rigidbody.rigidbodies.Add(
                            glTF_VCAST_vci_Rigidbody.GetglTfRigidbodyFromUnityRigidbody(rigidbody));
                    }

                    var f = new UniJSON.JsonFormatter();
                    glTF_VCAST_vci_rigidbody_Serializer.Serialize(f, VCAST_vci_rigidbody);
                    glTFExtensionExport.GetOrCreate(ref gltfNode.extensions).Add(glTF_VCAST_vci_rigidbody.ExtensionName, f.GetStore().Bytes);
                }

                var joints = node.GetComponents <Joint>();
                if (joints.Any())
                {
                    var VCAST_vci_joints = new glTF_VCAST_vci_joints();
                    VCAST_vci_joints.joints = new List <glTF_VCAST_vci_joint>();

                    foreach (var joint in joints)
                    {
                        VCAST_vci_joints.joints.Add(glTF_VCAST_vci_joint.GetglTFJointFromUnityJoint(joint, exporter.Nodes));
                    }

                    var f = new UniJSON.JsonFormatter();
                    glTF_VCAST_vci_joints_Serializer.Serialize(f, VCAST_vci_joints);
                    glTFExtensionExport.GetOrCreate(ref gltfNode.extensions).Add(glTF_VCAST_vci_joints.ExtensionName, f.GetStore().Bytes);
                }

                var item = node.GetComponent <VCISubItem>();
                if (item != null)
                {
                    var warning = item.ExportWarning;
                    if (!string.IsNullOrEmpty(warning))
                    {
                        throw new System.Exception(warning);
                    }

                    var VCAST_vci_item = new glTF_VCAST_vci_item
                    {
                        grabbable      = item.Grabbable,
                        scalable       = item.Scalable,
                        uniformScaling = item.UniformScaling,
                        attractable    = item.Attractable,
                        groupId        = item.GroupId,
                    };

                    var f = new UniJSON.JsonFormatter();
                    glTF_VCAST_vci_item_Serializer.Serialize(f, VCAST_vci_item);
                    glTFExtensionExport.GetOrCreate(ref gltfNode.extensions).Add(glTF_VCAST_vci_item.ExtensionName, f.GetStore().Bytes);
                }

                // Attachable
                var vciAttachable = node.GetComponent <VCIAttachable>();
                if (vciAttachable != null &&
                    vciAttachable.AttachableHumanBodyBones != null &&
                    vciAttachable.AttachableHumanBodyBones.Any())
                {
                    var VCAST_vci_attachable = new glTF_VCAST_vci_attachable
                    {
                        attachableHumanBodyBones =
                            vciAttachable.AttachableHumanBodyBones.Select(x => x.ToString()).ToList(),
                        attachableDistance = vciAttachable.AttachableDistance,
                        scalable           = vciAttachable.Scalable,
                        offset             = vciAttachable.Offset
                    };

                    var f = new UniJSON.JsonFormatter();
                    glTF_VCAST_vci_attachable_Serializer.Serialize(f, VCAST_vci_attachable);
                    glTFExtensionExport.GetOrCreate(ref gltfNode.extensions).Add(glTF_VCAST_vci_attachable.ExtensionName, f.GetStore().Bytes);
                }

                // Text
                var tmp = node.GetComponent <TextMeshPro>();
                var rt  = node.GetComponent <RectTransform>();
                if (tmp != null && rt != null)
                {
                    {
                        var VCAST_vci_rectTransform = new glTF_VCAST_vci_rectTransform()
                        {
                            rectTransform = glTF_VCAST_vci_RectTransform.CreateFromRectTransform(rt)
                        };

                        var f = new UniJSON.JsonFormatter();
                        glTF_VCAST_vci_rectTransform_Serializer.Serialize(f, VCAST_vci_rectTransform);
                        glTFExtensionExport.GetOrCreate(ref gltfNode.extensions).Add(glTF_VCAST_vci_rectTransform.ExtensionName, f.GetStore().Bytes);
                    }

                    {
                        var VCAST_vci_text = new glTF_VCAST_vci_text
                        {
                            text = glTF_VCAST_vci_Text.Create(tmp)
                        };

                        var f = new UniJSON.JsonFormatter();
                        glTF_VCAST_vci_text_Serializer.Serialize(f, VCAST_vci_text);
                        glTFExtensionExport.GetOrCreate(ref gltfNode.extensions).Add(glTF_VCAST_vci_text.ExtensionName, f.GetStore().Bytes);
                    }
                }

                // PlayerSpawnPoint
                var psp = node.GetComponent <VCIPlayerSpawnPoint>();
                if (psp != null)
                {
                    {
                        var VCAST_vci_player_spawn_point = new glTF_VCAST_vci_player_spawn_point
                        {
                            playerSpawnPoint = glTF_VCAST_vci_PlayerSpawnPoint.Create(psp)
                        };

                        var f = new UniJSON.JsonFormatter();
                        glTF_VCAST_vci_player_spawn_point_Serializer.Serialize(f, VCAST_vci_player_spawn_point);
                        glTFExtensionExport.GetOrCreate(ref gltfNode.extensions).Add(glTF_VCAST_vci_player_spawn_point.ExtensionName, f.GetStore().Bytes);
                    }

                    var pspR = node.GetComponent <VCIPlayerSpawnPointRestriction>();
                    if (pspR != null)
                    {
                        var VCAST_vci_player_spawn_point_restriction = new glTF_VCAST_vci_player_spawn_point_restriction
                        {
                            playerSpawnPointRestriction = glTF_VCAST_vci_PlayerSpawnPointRestriction.Create(pspR)
                        };

                        var f = new UniJSON.JsonFormatter();
                        glTF_VCAST_vci_player_spawn_point_restriction_Serializer.Serialize(f, VCAST_vci_player_spawn_point_restriction);
                        glTFExtensionExport.GetOrCreate(ref gltfNode.extensions).Add(glTF_VCAST_vci_player_spawn_point_restriction.ExtensionName, f.GetStore().Bytes);
                    }
                }

                var audioSources = node.GetComponents <AudioSource>()
                                   .Where(audioSource => audioSource.clip != null)
                                   .ToArray();

                if (audioSources.Any())
                {
                    var VCAST_vci_audio_sources = new glTF_VCAST_vci_audio_sources
                    {
                        audioSources = new List <glTF_VCAST_vci_audio_source>()
                    };

                    foreach (var audioSource in audioSources)
                    {
                        VCAST_vci_audio_sources.audioSources.Add(
                            glTF_VCAST_vci_audio_source.CreateFrom(audioSource, VCAST_vci_audios));
                    }

                    var f = new UniJSON.JsonFormatter();
                    glTF_VCAST_vci_audio_sources_Serializer.Serialize(f, VCAST_vci_audio_sources);
                    glTFExtensionExport.GetOrCreate(ref gltfNode.extensions).Add(glTF_VCAST_vci_audio_sources.ExtensionName, f.GetStore().Bytes);
                }
            }

#if UNITY_EDITOR
            // Animation
            // None RootAnimation
            var animators  = exporter.Copy.GetComponentsInChildren <Animator>().Where(x => exporter.Copy != x.gameObject);
            var animations = exporter.Copy.GetComponentsInChildren <Animation>()
                             .Where(x => exporter.Copy != x.gameObject);
            // NodeIndex to AnimationClips
            Dictionary <int, AnimationClip[]> animationNodeList = new Dictionary <int, AnimationClip[]>();

            foreach (var animator in animators)
            {
                var animationClips = AnimationExporter.GetAnimationClips(animator);
                var nodeIndex      = exporter.Nodes.FindIndex(0, exporter.Nodes.Count, x => x == animator.transform);
                if (animationClips.Any() && nodeIndex != -1)
                {
                    animationNodeList.Add(nodeIndex, animationClips.ToArray());
                }
            }

            foreach (var animation in animations)
            {
                var animationClips = AnimationExporter.GetAnimationClips(animation);
                var nodeIndex      = exporter.Nodes.FindIndex(0, exporter.Nodes.Count, x => x == animation.transform);
                if (animationClips.Any() && nodeIndex != -1)
                {
                    animationNodeList.Add(nodeIndex, animationClips.ToArray());
                }
            }

            int bufferIndex = 0;
            foreach (var animationNode in animationNodeList)
            {
                List <int> clipIndices = new List <int>();
                // write animationClips
                foreach (var clip in animationNode.Value)
                {
                    var animationWithCurve = AnimationExporter.Export(clip, Nodes[animationNode.Key], Nodes);
                    VciAnimationExporter.WriteAnimationWithSampleCurves(gltf, animationWithCurve, clip.name, bufferIndex);
                    clipIndices.Add(gltf.animations.IndexOf(animationWithCurve.Animation));
                }

                // write node
                if (clipIndices.Any())
                {
                    var node = gltf.nodes[animationNode.Key];

                    var VCAST_vci_animation = new glTF_VCAST_vci_animation()
                    {
                        animationReferences = new List <glTF_VCAST_vci_animationReference>()
                    };

                    foreach (var index in clipIndices)
                    {
                        VCAST_vci_animation.animationReferences.Add(
                            new glTF_VCAST_vci_animationReference()
                        {
                            animation = index
                        });
                    }

                    var f = new UniJSON.JsonFormatter();
                    glTF_VCAST_vci_animation_Serializer.Serialize(f, VCAST_vci_animation);
                    glTFExtensionExport.GetOrCreate(ref node.extensions).Add(glTF_VCAST_vci_animation.ExtensionName, f.GetStore().Bytes);
                }
            }
#endif

            // Effekseer
            var effekseerExtensions = new glTF_Effekseer()
            {
                effects = new List <glTF_Effekseer_effect>()
            };

            // Effekseer emitter
            for (var i = 0; i < exporter.Nodes.Count; i++)
            {
                var node     = exporter.Nodes[i];
                var gltfNode = gltf.nodes[i];

                var emitters = node.GetComponents <Effekseer.EffekseerEmitter>();

                if (emitters != null && emitters.Length > 0)
                {
                    var Effekseer_emitters = new glTF_Effekseer_emitters()
                    {
                        emitters = new List <glTF_Effekseer_emitter>()
                    };

                    foreach (var emitter in emitters)
                    {
                        var effectIndex = AddEffekseerEffect(gltf, effekseerExtensions, emitter);
                        Effekseer_emitters.emitters.Add(new glTF_Effekseer_emitter()
                        {
                            effectIndex   = effectIndex,
                            isLoop        = emitter.isLooping,
                            isPlayOnStart = emitter.playOnStart
                        });
                    }

                    var f = new UniJSON.JsonFormatter();
                    glTF_Effekseer_emitters_Serializer.Serialize(f, Effekseer_emitters);
                    glTFExtensionExport.GetOrCreate(ref gltfNode.extensions).Add(glTF_Effekseer_emitters.ExtensionName, f.GetStore().Bytes);
                }
            }

            // Effekseer extension
            if (effekseerExtensions.effects != null && effekseerExtensions.effects.Count() > 0)
            {
                var f = new UniJSON.JsonFormatter();
                glTF_Effekseer_Serializer.Serialize(f, effekseerExtensions);
                glTFExtensionExport.GetOrCreate(ref gltf.extensions).Add(glTF_Effekseer.ExtensionName, f.GetStore().Bytes);
            }


            // LocationBounds
            var locationBounds = exporter.Copy.GetComponent <VCILocationBounds>();
            if (locationBounds != null)
            {
                var VCAST_vci_location_bounds = new glTF_VCAST_vci_location_bounds
                {
                    LocationBounds = glTF_VCAST_vci_LocationBounds.Create(locationBounds)
                };

                var f = new UniJSON.JsonFormatter();
                glTF_VCAST_vci_location_bounds_Serializer.Serialize(f, VCAST_vci_location_bounds);
                glTFExtensionExport.GetOrCreate(ref gltf.extensions).Add(glTF_VCAST_vci_location_bounds.ExtensionName, f.GetStore().Bytes);
            }

            // Scene Lighting
#if VCI_DEVELOP
            ExportSceneLighting(exporter, gltf);
#endif
        }