Inheritance: UnityEngine.ScriptableObject
		void OnEnable () {
			SpineEditorUtilities.ConfirmInitialization();

			atlasAssets = serializedObject.FindProperty("atlasAssets");
			skeletonJSON = serializedObject.FindProperty("skeletonJSON");
			scale = serializedObject.FindProperty("scale");
			fromAnimation = serializedObject.FindProperty("fromAnimation");
			toAnimation = serializedObject.FindProperty("toAnimation");
			duration = serializedObject.FindProperty("duration");
			defaultMix = serializedObject.FindProperty("defaultMix");

			#if SPINE_SKELETON_ANIMATOR
			controller = serializedObject.FindProperty("controller");
			#endif

			#if SPINE_TK2D
			atlasAssets.isExpanded = false;
			spriteCollection = serializedObject.FindProperty("spriteCollection");
			#else
			atlasAssets.isExpanded = true;
			#endif

			#if SPINE_BAKING
			isBakingExpanded = EditorPrefs.GetBool(ShowBakingPrefsKey, false);
			#endif

			m_skeletonDataAsset = (SkeletonDataAsset)target;
			m_skeletonDataAssetGUID = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(m_skeletonDataAsset));
			EditorApplication.update += EditorUpdate;
			m_skeletonData = m_skeletonDataAsset.GetSkeletonData(false);
			RepopulateWarnings();
		}
	void OnEnable () {

		SpineEditorUtilities.ConfirmInitialization();

		try {
			atlasAssets = serializedObject.FindProperty("atlasAssets");
			skeletonJSON = serializedObject.FindProperty("skeletonJSON");
			scale = serializedObject.FindProperty("scale");
			fromAnimation = serializedObject.FindProperty("fromAnimation");
			toAnimation = serializedObject.FindProperty("toAnimation");
			duration = serializedObject.FindProperty("duration");
			defaultMix = serializedObject.FindProperty("defaultMix");
			controller = serializedObject.FindProperty("controller");
#if SPINE_TK2D
			spriteCollection = serializedObject.FindProperty("spriteCollection");
#endif

			m_skeletonDataAsset = (SkeletonDataAsset)target;
			m_skeletonDataAssetGUID = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(m_skeletonDataAsset));

			EditorApplication.update += Update;
		} catch {


		}

		m_skeletonData = m_skeletonDataAsset.GetSkeletonData(true);

		showUnity = EditorPrefs.GetBool("SkeletonDataAssetInspector_showUnity", true);

		RepopulateWarnings();
	}
		void OnEnable () {

			SpineEditorUtilities.ConfirmInitialization();

			try {
				atlasAssets = serializedObject.FindProperty("atlasAssets");
				atlasAssets.isExpanded = true;
				skeletonJSON = serializedObject.FindProperty("skeletonJSON");
				scale = serializedObject.FindProperty("scale");
				fromAnimation = serializedObject.FindProperty("fromAnimation");
				toAnimation = serializedObject.FindProperty("toAnimation");
				duration = serializedObject.FindProperty("duration");
				defaultMix = serializedObject.FindProperty("defaultMix");
				#if SPINE_SKELETON_ANIMATOR
				controller = serializedObject.FindProperty("controller");
				#endif
				#if SPINE_TK2D
				spriteCollection = serializedObject.FindProperty("spriteCollection");
				#endif

				m_skeletonDataAsset = (SkeletonDataAsset)target;
				m_skeletonDataAssetGUID = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(m_skeletonDataAsset));

				EditorApplication.update += Update;
			} catch {
				// TODO: WARNING: empty catch block supresses errors.

			}

			m_skeletonData = m_skeletonDataAsset.GetSkeletonData(true);

			showBaking = EditorPrefs.GetBool("SkeletonDataAssetInspector_showUnity", false);

			RepopulateWarnings();
		}
        protected void LoadSpine()
        {
            SkeletonDataAsset asset = (SkeletonDataAsset)_contentItem.skeletonAsset;

            if (asset == null)
            {
                return;
            }

            SetSpine(asset, _contentItem.width, _contentItem.height, _contentItem.skeletonAnchor);
        }
 protected static BlendModeMaterialsAsset FindBlendModeMaterialsModifierAsset(SkeletonDataAsset skeletonDataAsset)
 {
     foreach (var modifierAsset in skeletonDataAsset.skeletonDataModifiers)
     {
         if (modifierAsset is BlendModeMaterialsAsset)
         {
             return((BlendModeMaterialsAsset)modifierAsset);
         }
     }
     return(null);
 }
    override public void OnInspectorGUI()
    {
        serializedObject.Update();
        SkeletonDataAsset asset = (SkeletonDataAsset)target;

        EditorGUI.BeginChangeCheck();
        EditorGUILayout.PropertyField(atlasAssets, true);
        EditorGUILayout.PropertyField(skeletonJSON);
        EditorGUILayout.PropertyField(scale);
        if (EditorGUI.EndChangeCheck())
        {
            if (serializedObject.ApplyModifiedProperties())
            {
                if (m_previewUtility != null)
                {
                    m_previewUtility.Cleanup();
                    m_previewUtility = null;
                }

                RepopulateWarnings();
                OnEnable();
                return;
            }
        }


        if (m_skeletonData != null)
        {
            DrawAnimationStateInfo();
            DrawAnimationList();
            DrawSlotList();
            DrawBaking();
        }
        else
        {
            DrawReimportButton();
            //Show Warnings
            foreach (var str in warnings)
            {
                EditorGUILayout.LabelField(new GUIContent(str, SpineEditorUtilities.Icons.warning));
            }
        }

        if (!Application.isPlaying)
        {
            if (serializedObject.ApplyModifiedProperties() ||
                (UnityEngine.Event.current.type == EventType.ValidateCommand && UnityEngine.Event.current.commandName == "UndoRedoPerformed")
                )
            {
                asset.Reset();
            }
        }
    }
Example #7
0
    protected void LoadSpineDataAsset(string path, Action <SkeletonDataAsset> callback)
    {
        var loader = CStaticAssetLoader.Load(path, (_isOk, _obj) =>
        {
            SkeletonDataAsset dataAsset = _obj as SkeletonDataAsset;
            Logger.Assert(dataAsset);
            dataAsset.name = path;
            callback(dataAsset);
        });

        ResourceLoaders.Add(loader);
    }
Example #8
0
    /// <summary>Add and prepare a Spine component that derives from SkeletonRenderer to a GameObject at runtime.</summary>
    /// <typeparam name="T">T should be SkeletonRenderer or any of its derived classes.</typeparam>
    public static T AddSpineComponent <T> (GameObject gameObject, SkeletonDataAsset skeletonDataAsset) where T : SkeletonRenderer
    {
        var c = gameObject.AddComponent <T>();

        if (skeletonDataAsset != null)
        {
            c.skeletonDataAsset = skeletonDataAsset;
            c.Initialize(false);
        }

        return(c);
    }
    private void SetAspect(SkeletonDataAsset bodyData, SkeletonDataAsset hairData, bool flipX)
    {
        body.skeletonDataAsset = bodyData;
        if (hair != null)
        {
            hair.skeletonDataAsset = hairData;
        }

        float xScale = flipX == true ? -bodyScale.x : bodyScale.x;

        body.gameObject.transform.localScale = new Vector2(xScale, bodyScale.y);
    }
Example #10
0
    public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    {
        if (property.propertyType != SerializedPropertyType.String)
        {
            EditorGUI.LabelField(position, "ERROR:", "May only apply to type string");
            return;
        }

        var dataProperty = property.serializedObject.FindProperty(TargetAttribute.dataField);

        if (dataProperty != null)
        {
            if (dataProperty.objectReferenceValue is SkeletonDataAsset)
            {
                skeletonDataAsset = (SkeletonDataAsset)dataProperty.objectReferenceValue;
            }
            else if (dataProperty.objectReferenceValue is SkeletonRenderer)
            {
                var renderer = (SkeletonRenderer)dataProperty.objectReferenceValue;
                if (renderer != null)
                {
                    skeletonDataAsset = renderer.skeletonDataAsset;
                }
            }
            else
            {
                EditorGUI.LabelField(position, "ERROR:", "Invalid reference type");
                return;
            }
        }
        else if (property.serializedObject.targetObject is Component)
        {
            var component = (Component)property.serializedObject.targetObject;
            if (component.GetComponentInChildren <SkeletonRenderer>() != null)
            {
                var skeletonRenderer = component.GetComponentInChildren <SkeletonRenderer>();
                skeletonDataAsset = skeletonRenderer.skeletonDataAsset;
            }
        }

        if (skeletonDataAsset == null)
        {
            EditorGUI.LabelField(position, "ERROR:", "Must have reference to a SkeletonDataAsset");
            return;
        }

        position = EditorGUI.PrefixLabel(position, label);

        if (GUI.Button(position, property.stringValue, EditorStyles.popup))
        {
            Selector(property);
        }
    }
Example #11
0
    /// <summary>Add and prepare a Spine component that derives from SkeletonRenderer to a GameObject at runtime.</summary>
    /// <typeparam name="T">T should be SkeletonRenderer or any of its derived classes.</typeparam>
    public static T AddSpineComponent <T> (GameObject gameObject, SkeletonDataAsset skeletonDataAsset) where T : SkeletonRenderer
    {
        var c = gameObject.AddComponent <T>();

        if (skeletonDataAsset != null)
        {
            c.skeletonDataAsset = skeletonDataAsset;
            c.Reset();             // TODO: Method name will change.
        }

        return(c);
    }
Example #12
0
    public void SetEffect(SkeletonDataAsset asset, SkeletonDataAsset role)
    {
        effect.gameObject.SetActive(true);
        effect.skeletonDataAsset = asset;
        effect.ResetNew();

        roleasset.gameObject.SetActive(true);
        roleasset.skeletonDataAsset = role;
        roleasset.loop = true;
        roleasset.ResetNew();
        roleasset.state.SetAnimation(0, Def.RoleStanby, true);
    }
Example #13
0
    // 包含json!,不包含圖集
    static CDepCollectInfo GetBuildSpineData(SkeletonDataAsset data)
    {
        string path = AssetDatabase.GetAssetPath(data);

        // DataAsset
        bool needBuildDataAsset = KBuildTools.CheckNeedBuild(path);
        if (needBuildDataAsset)
            KBuildTools.MarkBuildVersion(path);

        // Spine的JSON
        string textAssetPath = AssetDatabase.GetAssetPath(data.skeletonJSON);
        bool needBuildJsonTextAsset = KBuildTools.CheckNeedBuild(textAssetPath);
        if (needBuildJsonTextAsset)
            KBuildTools.MarkBuildVersion(textAssetPath);

        //string originPath = path;
        //string tmpPath = "Assets/~TempSkeletonDataAsset.asset";
        //bool copyResult = AssetDatabase.CopyAsset(path, tmpPath);
        //Logger.Assert(copyResult);
        //SkeletonDataAsset copyData = AssetDatabase.LoadAssetAtPath(tmpPath, typeof(SkeletonDataAsset)) as SkeletonDataAsset;
        if (data.spriteCollection == null || data.skeletonJSON == null)
        {
            Logger.LogError("Err Spine Data: {0}, Lack of SpriteCollection or Json", data.name);
            //return "";
        }

        string spriteColPath = BuildSpriteCollection(data.spriteCollection);
        string spriteColAssetPath = AssetDatabase.GetAssetPath(data.spriteCollection.gameObject);
        bool needBuildSpriteCol = KBuildTools.CheckNeedBuild(spriteColAssetPath);
        if (needBuildSpriteCol)
            KBuildTools.MarkBuildVersion(spriteColAssetPath);

        SkeletonDataAsset copyData = GameObject.Instantiate(data) as SkeletonDataAsset;
        copyData.spriteCollection = null; // 挖空图集, 保留Json!


        // SpineData包括了这个SkeletonData!
        var skeletonDataBuildResult = __DoBuildScriptableObject(DepBuildToFolder + "/SkeletonData_" + data.name, copyData, needBuildDataAsset || needBuildJsonTextAsset);  // json文件直接放在SkeletonDataAsset打包! 分离图集

        CSpineData spineData = ScriptableObject.CreateInstance<CSpineData>();
        spineData.SpriteCollectionPath = spriteColPath;
        spineData.DataAssetPath = skeletonDataBuildResult.Path; // 保留json文件,不挖空 copyData.skeletonJSON

        path = __GetPrefabBuildPath(path);
        // DataAsset或圖集或Json任一重打包了,都要重新打包CSpineData(記錄圖集保存地方和Jsondataasset保存地方)
        var spineDataBuildResult = __DoBuildScriptableObject(DepBuildToFolder + "/SpineData_" + path, spineData, needBuildDataAsset || needBuildSpriteCol || needBuildJsonTextAsset);
        spineDataBuildResult.Child = skeletonDataBuildResult;

        GameObject.DestroyImmediate(copyData);

        return spineDataBuildResult;
    }
 public void GetConfig()
 {
     if (_config == null)
     {
         _config = AssetDatabase.LoadAssetAtPath(configPath, typeof(SpineXiimoonConfig)) as SpineXiimoonConfig;
         if (_config == null)
         {
             _config = SkeletonDataAsset.CreateInstance <SpineXiimoonConfig>();
             AssetDatabase.CreateAsset(_config, configPath);
             AssetDatabase.SaveAssets();
         }
     }
 }
Example #15
0
    public void SetEffect(SkeletonDataAsset asset, SkeletonDataAsset role, Spine.AnimationState.StartEndDelegate action)
    {
        effect.gameObject.SetActive(true);
        effect.skeletonDataAsset = asset;
        effect.ResetNew();

        roleasset.gameObject.SetActive(true);
        roleasset.skeletonDataAsset = role;
        roleasset.loop = true;
        roleasset.ResetNew();
        roleasset.state.SetAnimation(0, Def.RoleStanby, true);
        effect.state.End += action;
    }
Example #16
0
    public static SkeletonAnimation SpawnAnimatedSkeleton(SkeletonDataAsset skeletonDataAsset, Skin skin = null)
    {
        GameObject        go   = new GameObject(skeletonDataAsset.name.Replace("_SkeletonData", ""), typeof(MeshFilter), typeof(MeshRenderer), typeof(SkeletonAnimation));
        SkeletonAnimation anim = go.GetComponent <SkeletonAnimation>();

        anim.skeletonDataAsset = skeletonDataAsset;

        bool requiresNormals = false;

        foreach (Material m in anim.skeletonDataAsset.atlasAsset.materials)
        {
            if (m.shader.name.Contains("Lit"))
            {
                requiresNormals = true;
                break;
            }
        }

        anim.calculateNormals = requiresNormals;

        SkeletonData data = skeletonDataAsset.GetSkeletonData(true);

        if (data == null)
        {
            string reloadAtlasPath = AssetDatabase.GetAssetPath(skeletonDataAsset.atlasAsset);
            skeletonDataAsset.atlasAsset = (AtlasAsset)AssetDatabase.LoadAssetAtPath(reloadAtlasPath, typeof(AtlasAsset));
            data = skeletonDataAsset.GetSkeletonData(true);
        }

        if (skin == null)
        {
            skin = data.DefaultSkin;
        }

        if (skin == null)
        {
            skin = data.Skins[0];
        }

        anim.Reset();

        anim.skeleton.SetSkin(skin);
        anim.initialSkinName = skin.Name;

        anim.skeleton.Update(1);
        anim.state.Update(1);
        anim.state.Apply(anim.skeleton);
        anim.skeleton.UpdateWorldTransform();

        return(anim);
    }
Example #17
0
    static void OnPostprocessAllAssets(string[] imported, string[] deleted, string[] moved, string[] movedFromAssetPaths)
    {
        //debug
//		return;

        AtlasAsset sharedAtlas = null;

        System.Array.Sort <string>(imported);

        foreach (string str in imported)
        {
            if (Path.GetExtension(str).ToLower() == ".json")
            {
                TextAsset spineJson = (TextAsset)AssetDatabase.LoadAssetAtPath(str, typeof(TextAsset));
                if (IsSpineJSON(spineJson))
                {
                    if (sharedAtlas != null)
                    {
                        string spinePath = Path.GetDirectoryName(AssetDatabase.GetAssetPath(spineJson));
                        string atlasPath = Path.GetDirectoryName(AssetDatabase.GetAssetPath(sharedAtlas));
                        if (spinePath != atlasPath)
                        {
                            sharedAtlas = null;
                        }
                    }

                    SkeletonDataAsset data = AutoIngestSpineProject(spineJson, sharedAtlas);
                    if (data == null)
                    {
                        continue;
                    }

                    sharedAtlas = data.atlasAsset;

                    SkeletonAnimation anim       = SpawnAnimatedSkeleton(data);
                    string            dir        = Path.GetDirectoryName(Path.GetDirectoryName(AssetDatabase.GetAssetPath(data)));
                    string            prefabPath = Path.Combine(dir, data.skeletonJSON.name + ".prefab").Replace("\\", "/");
                    PrefabUtility.CreatePrefab(prefabPath, anim.gameObject, ReplacePrefabOptions.ReplaceNameBased);

                    if (EditorApplication.isPlaying)
                    {
                        GameObject.Destroy(anim.gameObject);
                    }
                    else
                    {
                        GameObject.DestroyImmediate(anim.gameObject);
                    }
                }
            }
        }
    }
Example #18
0
    public void CreateSpineObject()
    {
        // 1.Spine/Skeletonのmaterialを生成
        Material material = new Material(Shader.Find("Spine/Skeleton"));

        material.mainTexture = texture;

        // 2.AtlasAssetを生成して、1のmaterialを紐づける
        AtlasAsset atlasAsset = AtlasAsset.CreateInstance <AtlasAsset> ();

        atlasAsset.atlasFile     = atlasText;
        atlasAsset.materials     = new Material[1];
        atlasAsset.materials [0] = material;

        // 3.SkeletonDataAssetを生成して、初期データを投入する
        SkeletonDataAsset dataAsset = SkeletonDataAsset.CreateInstance <SkeletonDataAsset> ();

        dataAsset.atlasAssets     = new AtlasAsset[1];
        dataAsset.atlasAssets [0] = atlasAsset;
        dataAsset.skeletonJSON    = jsonText;
        dataAsset.fromAnimation   = new string[0];
        dataAsset.toAnimation     = new string[0];
        dataAsset.duration        = new float[0];
        dataAsset.defaultMix      = 0.2f;
        dataAsset.scale           = 1.0f;

        // 4.実際にUnityに配置するGameObjectを生成して、SkeletonAnimationをadd
        GameObject        obj          = new GameObject("SpineObject");
        SkeletonAnimation anim         = obj.AddComponent <SkeletonAnimation> ();
        MeshRenderer      meshRenderer = obj.GetComponent <MeshRenderer>();

        meshRenderer.sortingLayerName = "spine";
        meshRenderer.sortingOrder     = 0;
        // 5.SkeletonAnimationにSkeletonDataAssetを紐付け、skinName、reset(),animationNameを設定する。
        anim.skeletonDataAsset = dataAsset;

        // Reset()前に呼び出す必要あり。後に呼ぶとskinデータが反映されない
        anim.initialSkinName = "goblin";

        // Reset()時にDataAssetからAnimationデータを読みだして格納している
        anim.Reset();

        // ループの設定はAnimation指定前じゃないと反映されない
        anim.loop          = true;
        anim.AnimationName = "walk";

        // アニメ終了イベントをセット
        anim.state.Complete += OnCompleteSpineAnim;

        obj.transform.SetParent(this.gameObject.transform);
    }
Example #19
0
        public static void DrawSelectBone(SkeletonDataAsset skeletonDataAsset, string current, Action <string> selectFunc)
        {
            SkeletonData data = skeletonDataAsset.GetSkeletonData(true);

            if (data == null)
            {
                return;
            }

            var menu = new GenericMenu();

            DrawBonePopulateMenu(menu, skeletonDataAsset, current, selectFunc);
            menu.ShowAsContext();
        }
Example #20
0
    public SkeletonDataAsset GetSkeletonAssetByPath(string p)
    {
        SkeletonDataAsset a = null;

        if (animTable.ContainsKey(p))
        {
            a = animTable[p];
        }
        else
        {
            animTable.Add(p, Resources.Load <SkeletonDataAsset>(p));
        }
        return(animTable[p]);
    }
		void OnEnable () {
			SpineEditorUtilities.ConfirmInitialization();
			m_skeletonDataAsset = (SkeletonDataAsset)target;

			// Clear empty atlas array items.
			{
				bool hasNulls = false;
				foreach (var a in m_skeletonDataAsset.atlasAssets) {
					if (a == null) {
						hasNulls = true;
						break;
					}
				}
				if (hasNulls) {
					var trimmedAtlasAssets = new List<AtlasAsset>();
					foreach (var a in m_skeletonDataAsset.atlasAssets) {
						if (a != null) trimmedAtlasAssets.Add(a);
					}
					m_skeletonDataAsset.atlasAssets = trimmedAtlasAssets.ToArray();
				}
			}

			atlasAssets = serializedObject.FindProperty("atlasAssets");
			skeletonJSON = serializedObject.FindProperty("skeletonJSON");
			scale = serializedObject.FindProperty("scale");
			fromAnimation = serializedObject.FindProperty("fromAnimation");
			toAnimation = serializedObject.FindProperty("toAnimation");
			duration = serializedObject.FindProperty("duration");
			defaultMix = serializedObject.FindProperty("defaultMix");

			#if SPINE_SKELETON_ANIMATOR
			controller = serializedObject.FindProperty("controller");
			#endif

			#if SPINE_TK2D
			atlasAssets.isExpanded = false;
			spriteCollection = serializedObject.FindProperty("spriteCollection");
			#else
			atlasAssets.isExpanded = true;
			#endif

			#if SPINE_BAKING
			isBakingExpanded = EditorPrefs.GetBool(ShowBakingPrefsKey, false);
			#endif

			m_skeletonDataAssetGUID = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(m_skeletonDataAsset));
			EditorApplication.update += EditorUpdate;
			m_skeletonData = m_skeletonDataAsset.GetSkeletonData(false);
			RepopulateWarnings();
		}
	void OnEnable () {
		atlasAsset = serializedObject.FindProperty("atlasAsset");
		skeletonJSON = serializedObject.FindProperty("skeletonJSON");
		scale = serializedObject.FindProperty("scale");
		fromAnimation = serializedObject.FindProperty("fromAnimation");
		toAnimation = serializedObject.FindProperty("toAnimation");
		duration = serializedObject.FindProperty("duration");
		defaultMix = serializedObject.FindProperty("defaultMix");
		
		m_skeletonDataAsset = (SkeletonDataAsset)target;
		m_skeletonDataAssetGUID = AssetDatabase.AssetPathToGUID( AssetDatabase.GetAssetPath(m_skeletonDataAsset) );
		
		EditorApplication.update += Update;
	}
        void OnEnable()
        {
            SpineEditorUtilities.ConfirmInitialization();
            m_skeletonDataAsset = (SkeletonDataAsset)target;

            bool newAtlasAssets = atlasAssets == null;

            if (newAtlasAssets)
            {
                atlasAssets = serializedObject.FindProperty("atlasAssets");
            }
            skeletonJSON  = serializedObject.FindProperty("skeletonJSON");
            scale         = serializedObject.FindProperty("scale");
            fromAnimation = serializedObject.FindProperty("fromAnimation");
            toAnimation   = serializedObject.FindProperty("toAnimation");
            duration      = serializedObject.FindProperty("duration");
            defaultMix    = serializedObject.FindProperty("defaultMix");

                        #if SPINE_SKELETON_ANIMATOR
            controller = serializedObject.FindProperty("controller");
                        #endif

                        #if SPINE_TK2D
            if (newAtlasAssets)
            {
                atlasAssets.isExpanded = false;
            }
            spriteCollection = serializedObject.FindProperty("spriteCollection");
                        #else
            if (newAtlasAssets)
            {
                atlasAssets.isExpanded = true;
            }
                        #endif

            m_skeletonDataAssetGUID = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(m_skeletonDataAsset));

            EditorApplication.update -= EditorUpdate;
            EditorApplication.update += EditorUpdate;

            RepopulateWarnings();
            if (m_skeletonDataAsset.skeletonJSON == null)
            {
                m_skeletonData = null;
                return;
            }

            m_skeletonData = warnings.Count == 0 ? m_skeletonDataAsset.GetSkeletonData(false) : null;
        }
Example #24
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="asset"></param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        public void SetSpine(SkeletonDataAsset asset, int width, int height, Vector2 anchor)
        {
            if (_spineAnimation != null)
            {
                FreeSpine();
            }

            _spineAnimation = SkeletonRenderer.NewSpineGameObject <SkeletonAnimation>(asset);
            Spine.SkeletonData dat = asset.GetSkeletonData(false);
            _spineAnimation.gameObject.transform.localScale    = new Vector3(100, 100, 1);
            _spineAnimation.gameObject.transform.localPosition = new Vector3(anchor.x, -anchor.y, 0);
            SetWrapTarget(_spineAnimation.gameObject, false, width, height);

            OnChangeSpine(null);
        }
Example #25
0
    public override Playable CreatePlayable(PlayableGraph graph, GameObject owner)
    {
        var playable = ScriptPlayable <SpinePlayable> .Create(graph);

        var spine = spineObject.Resolve(graph.GetResolver());

//        var abc = owner.GetComponent<PlayableDirector> ();
        if (spine != null)
        {
            _spine             = spine.GetComponent <SkeletonAnimation> ();
            _skeletonDataAsset = _spine.SkeletonDataAsset;
        }
        playable.GetBehaviour().Initialize(spine, actionName, actionKeep);
        return(playable);
    }
 private void AssignAnimationData(string animName, SkeletonDataAsset data)
 {
     if (body.skeletonDataAsset != data)
     {
         body.ClearState();
         body.skeletonDataAsset = data;
         body.Initialize(true);
     }
     if (body.AnimationName != animName)
     {
         Debug.Log(data);
         Debug.Log(animName);
         body.AnimationState.SetAnimation(0, animName, true);
     }
 }
Example #27
0
 public static void ReloadSkeletonDataAsset(SkeletonDataAsset skeletonDataAsset)
 {
     if (skeletonDataAsset != null)
     {
         foreach (AtlasAssetBase aa in skeletonDataAsset.atlasAssets)
         {
             if (aa != null)
             {
                 aa.Clear();
             }
         }
         skeletonDataAsset.Clear();
     }
     skeletonDataAsset.GetSkeletonData(true);
 }
    public static SkeletonDataAsset GetSkeletonDataAsset(string _name)
    {
        try
        {
            SkeletonDataAsset asset = (SkeletonDataAsset)LoadObject(@"SpineResource\Skeleton\" + _name);

            return(asset);
        }
        catch (ArgumentException e)
        {
            Debug.LogError(_name + "은 존재하지 않는 SkeletonDataAsset");
        }

        return(null);
    }
Example #29
0
    void OnEnable()
    {
        atlasAsset    = serializedObject.FindProperty("atlasAsset");
        skeletonJSON  = serializedObject.FindProperty("skeletonJSON");
        scale         = serializedObject.FindProperty("scale");
        fromAnimation = serializedObject.FindProperty("fromAnimation");
        toAnimation   = serializedObject.FindProperty("toAnimation");
        duration      = serializedObject.FindProperty("duration");
        defaultMix    = serializedObject.FindProperty("defaultMix");

        m_skeletonDataAsset     = (SkeletonDataAsset)target;
        m_skeletonDataAssetGUID = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(m_skeletonDataAsset));

        EditorApplication.update += Update;
    }
Example #30
0
    // "Head", "Front", "Rear"
    // "Zebra", "Rhino", "Jiraffe", "Goose", "Red", "Elephant"
    public void SetBodyPart(string slot, SkeletonDataAsset skelData)
    {
        if (!inited)
        {
            Init();
        }

        if (slot == null)
        {
            SetBodyPart("Head", skelData);
            SetBodyPart("Front", skelData);
            SetBodyPart("Rear", skelData);
            return;
        }

        SkeletonPartController controller = null, childController = null;
        SkeletonAnimation      animationComponent = null;

        if (slot == "Head")
        {
            controller = headSkelController;
        }
        else if (slot == "Front")
        {
            controller         = frontSkelController;
            childController    = headSkelController;
            animationComponent = front.GetComponent <SkeletonAnimation>();
        }
        else if (slot == "Rear")
        {
            controller         = rearSkelController;
            childController    = frontSkelController;
            animationComponent = rear.GetComponent <SkeletonAnimation>();
        }
        else
        {
            Debug.Log("Unknown body part slot: " + slot);
        }

        if (controller != null)
        {
            controller.SetSkeleton(skelData);
        }
        if (childController != null && animationComponent != null)
        {
            childController.OnParentSkeletonChanged(animationComponent);
        }
    }
Example #31
0
 static void AfterLoad(SkeletonGraphic skeletonGraphic, SkeletonDataAsset skeletonDataAsset, string[] actions = null)
 {
     skeletonGraphic.skeletonDataAsset = skeletonDataAsset;
     if (actions == null && actions.Length >= 1)
     {
         skeletonGraphic.startingAnimation = actions[0];
     }
     skeletonGraphic.Initialize(true);
     if (skeletonGraphic.AnimationState != null && actions != null)
     {
         for (int i = 0; i < actions.Length; i++)
         {
             skeletonGraphic.AnimationState.SetAnimation(i, actions[i], (i == (actions.Length - 1)));
         }
     }
 }
    public void SetSkeleton(SkeletonDataAsset newSkeleton)
    {
        SkeletonAnimation skeletonAnimation = gameObject.GetComponent <SkeletonAnimation>();

        if (skeletonAnimation != null)
        {
            string anim = skeletonAnimation.AnimationName;
            skeletonAnimation.ClearState();

            skeletonAnimation.skeletonDataAsset = newSkeleton;
            skeletonAnimation.Initialize(true);

            skeleton = newSkeleton;
            skeletonAnimation.AnimationName = anim;
        }
    }
Example #33
0
        public static SkeletonAnimation ForceChangeMode(GameObject obj, SkeletonDataAsset skeletonDataAsset, string action = "idle")
        {
            SkeletonAnimation animation = obj.GetComponent <SkeletonAnimation>();

            if (animation != null)
            {
                DestroyImmediate(animation);
            }

            animation = obj.AddComponent <SkeletonAnimation>();
            animation.skeletonDataAsset = skeletonDataAsset;
            animation.Initialize(true);
            animation.state.SetAnimation(0, action, true);

            return(animation);
        }
Example #34
0
 public static void ReloadAnimationReferenceAssets(SkeletonDataAsset skeletonDataAsset)
 {
     string[] guids = UnityEditor.AssetDatabase.FindAssets("t:AnimationReferenceAsset");
     foreach (string guid in guids)
     {
         string path = UnityEditor.AssetDatabase.GUIDToAssetPath(guid);
         if (!string.IsNullOrEmpty(path))
         {
             var referenceAsset = UnityEditor.AssetDatabase.LoadAssetAtPath <AnimationReferenceAsset>(path);
             if (referenceAsset.SkeletonDataAsset == skeletonDataAsset)
             {
                 referenceAsset.Initialize();
             }
         }
     }
 }
        public static void UpdateBlendModeMaterials(SkeletonDataAsset skeletonDataAsset, ref SkeletonData skeletonData,
                                                    bool upgradeFromModifierAssets = ShallUpgradeBlendModeMaterials)
        {
            TemplateMaterials templateMaterials = new TemplateMaterials();
            bool anyMaterialsChanged            = ClearUndesiredMaterialEntries(skeletonDataAsset);

            var blendModesModifierAsset = FindBlendModeMaterialsModifierAsset(skeletonDataAsset);

            if (blendModesModifierAsset)
            {
                if (upgradeFromModifierAssets)
                {
                    TransferSettingsFromModifierAsset(blendModesModifierAsset,
                                                      skeletonDataAsset, templateMaterials);
                    UpdateBlendmodeMaterialsRequiredState(skeletonDataAsset, skeletonData);
                }
                else
                {
                    return;
                }
            }
            else
            {
                if (!UpdateBlendmodeMaterialsRequiredState(skeletonDataAsset, skeletonData))
                {
                    return;
                }
                AssignPreferencesTemplateMaterials(templateMaterials);
            }
            bool success = CreateAndAssignMaterials(skeletonDataAsset, templateMaterials, ref anyMaterialsChanged);

            if (success)
            {
                if (blendModesModifierAsset != null)
                {
                    RemoveObsoleteModifierAsset(blendModesModifierAsset, skeletonDataAsset);
                }
            }

            skeletonDataAsset.Clear();
            skeletonData = skeletonDataAsset.GetSkeletonData(true);
            if (anyMaterialsChanged)
            {
                ReloadSceneSkeletons(skeletonDataAsset);
            }
            AssetDatabase.SaveAssets();
        }
Example #36
0
            public static void ShowInstantiateContextMenu(SkeletonDataAsset skeletonDataAsset, Vector3 spawnPoint, Transform parent)
            {
                var menu = new GenericMenu();

                // SkeletonAnimation
                menu.AddItem(new GUIContent("SkeletonAnimation"), false, HandleSkeletonComponentDrop, new SpawnMenuData {
                    skeletonDataAsset   = skeletonDataAsset,
                    spawnPoint          = spawnPoint,
                    parent              = parent,
                    instantiateDelegate = (data) => EditorInstantiation.InstantiateSkeletonAnimation(data),
                    isUI = false
                });

                // SkeletonGraphic
                var skeletonGraphicInspectorType = System.Type.GetType("Spine.Unity.Editor.SkeletonGraphicInspector");

                if (skeletonGraphicInspectorType != null)
                {
                    var graphicInstantiateDelegate = skeletonGraphicInspectorType.GetMethod("SpawnSkeletonGraphicFromDrop", BindingFlags.Static | BindingFlags.Public);
                    if (graphicInstantiateDelegate != null)
                    {
                        menu.AddItem(new GUIContent("SkeletonGraphic (UI)"), false, HandleSkeletonComponentDrop, new SpawnMenuData {
                            skeletonDataAsset   = skeletonDataAsset,
                            spawnPoint          = spawnPoint,
                            parent              = parent,
                            instantiateDelegate = System.Delegate.CreateDelegate(typeof(EditorInstantiation.InstantiateDelegate), graphicInstantiateDelegate) as EditorInstantiation.InstantiateDelegate,
                            isUI = true
                        });
                    }
                }

#if SPINE_SKELETONMECANIM
                menu.AddSeparator("");
                // SkeletonMecanim
                menu.AddItem(new GUIContent("SkeletonMecanim"), false, HandleSkeletonComponentDrop, new SpawnMenuData {
                    skeletonDataAsset   = skeletonDataAsset,
                    spawnPoint          = spawnPoint,
                    parent              = parent,
                    instantiateDelegate = (data) => EditorInstantiation.InstantiateSkeletonMecanim(data),
                    isUI = false
                });
#endif

                menu.ShowAsContext();
            }
Example #37
0
	public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) {
		if (property.propertyType != SerializedPropertyType.String) {
			EditorGUI.LabelField(position, "ERROR:", "May only apply to type string");
			return;
		}

		SpineSlot attrib = (SpineSlot)attribute;

		var dataProperty = property.serializedObject.FindProperty(attrib.dataField);

		if (dataProperty != null) {
			if (dataProperty.objectReferenceValue is SkeletonDataAsset) {
				skeletonDataAsset = (SkeletonDataAsset)dataProperty.objectReferenceValue;
			} else if (dataProperty.objectReferenceValue is SkeletonRenderer) {
				var renderer = (SkeletonRenderer)dataProperty.objectReferenceValue;
				if (renderer != null)
					skeletonDataAsset = renderer.skeletonDataAsset;
			} else {
				EditorGUI.LabelField(position, "ERROR:", "Invalid reference type");
				return;
			}

		} else if (property.serializedObject.targetObject is Component) {
			var component = (Component)property.serializedObject.targetObject;
			if (component.GetComponentInChildren<SkeletonRenderer>() != null) {
				var skeletonRenderer = component.GetComponentInChildren<SkeletonRenderer>();
				skeletonDataAsset = skeletonRenderer.skeletonDataAsset;
			}
		}

		if (skeletonDataAsset == null) {
			EditorGUI.LabelField(position, "ERROR:", "Must have reference to a SkeletonDataAsset");
			return;
		}

		position = EditorGUI.PrefixLabel(position, label);

		if (GUI.Button(position, property.stringValue, EditorStyles.popup)) {
			Selector(property);
		}

	}
Example #38
0
	static void UpdateMecanimClips (SkeletonDataAsset skeletonDataAsset) {
		if (skeletonDataAsset.controller == null)
			return;

		SkeletonBaker.GenerateMecanimAnimationClips(skeletonDataAsset);
	}
Example #39
0
	public static SkeletonAnimator InstantiateSkeletonAnimator (SkeletonDataAsset skeletonDataAsset, string skinName) {
		return InstantiateSkeletonAnimator(skeletonDataAsset, skeletonDataAsset.GetSkeletonData(true).FindSkin(skinName));
	}
Example #40
0
	/// <summary>Instantiates a new UnityEngine.GameObject and adds a prepared SkeletonAnimation component to it.</summary>
	/// <returns>The newly instantiated SkeletonAnimation component.</returns>
	public static SkeletonAnimation NewSkeletonAnimationGameObject (SkeletonDataAsset skeletonDataAsset) {
		return SkeletonRenderer.NewSpineGameObject<SkeletonAnimation>(skeletonDataAsset);
	}
    void OnEnable()
    {
        SpineEditorUtilities.ConfirmInitialization();

        try {
            atlasAssets = serializedObject.FindProperty("atlasAssets");
            skeletonJSON = serializedObject.FindProperty("skeletonJSON");
            scale = serializedObject.FindProperty("scale");
            fromAnimation = serializedObject.FindProperty("fromAnimation");
            toAnimation = serializedObject.FindProperty("toAnimation");
            duration = serializedObject.FindProperty("duration");
            defaultMix = serializedObject.FindProperty("defaultMix");

            m_skeletonDataAsset = (SkeletonDataAsset)target;
            m_skeletonDataAssetGUID = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(m_skeletonDataAsset));

            EditorApplication.update += Update;
        } catch {

        }

        m_skeletonData = m_skeletonDataAsset.GetSkeletonData(true);

        RepopulateWarnings();
    }
Example #42
0
	public static Spine.BoneData GetBoneData(string boneName, SkeletonDataAsset skeletonDataAsset) {
		var data = skeletonDataAsset.GetSkeletonData(true);

		return data.FindBone(boneName);
	}
		public static SkeletonAnimation InstantiateSkeletonAnimation (SkeletonDataAsset skeletonDataAsset, Skin skin = null, bool destroyInvalid = true) {
			SkeletonData data = skeletonDataAsset.GetSkeletonData(true);

			if (data == null) {
				for (int i = 0; i < skeletonDataAsset.atlasAssets.Length; i++) {
					string reloadAtlasPath = AssetDatabase.GetAssetPath(skeletonDataAsset.atlasAssets[i]);
					skeletonDataAsset.atlasAssets[i] = (AtlasAsset)AssetDatabase.LoadAssetAtPath(reloadAtlasPath, typeof(AtlasAsset));
				}
				data = skeletonDataAsset.GetSkeletonData(false);
			}

			if (data == null) {
				Debug.LogWarning("InstantiateSkeletonAnimation tried to instantiate a skeleton from an invalid SkeletonDataAsset.");
				return null;
			}

			if (skin == null) skin = data.DefaultSkin;
			if (skin == null) skin = data.Skins.Items[0];

			string spineGameObjectName = string.Format("Spine GameObject ({0})", skeletonDataAsset.name.Replace("_SkeletonData", ""));
			GameObject go = new GameObject(spineGameObjectName, typeof(MeshFilter), typeof(MeshRenderer), typeof(SkeletonAnimation));
			SkeletonAnimation newSkeletonAnimation = go.GetComponent<SkeletonAnimation>();
			newSkeletonAnimation.skeletonDataAsset = skeletonDataAsset;

			{
				bool requiresNormals = false;
				foreach (AtlasAsset atlasAsset in skeletonDataAsset.atlasAssets) {
					foreach (Material m in atlasAsset.materials) {
						if (m.shader.name.Contains("Lit")) {
							requiresNormals = true;
							break;
						}
					}
				}
				newSkeletonAnimation.calculateNormals = requiresNormals;
			}

			try {
				newSkeletonAnimation.Initialize(false);
			} catch (System.Exception e) {
				if (destroyInvalid) {
					Debug.LogWarning("Editor-instantiated SkeletonAnimation threw an Exception. Destroying GameObject to prevent orphaned GameObject.");
					GameObject.DestroyImmediate(go);
				}
				throw e;
			}

			newSkeletonAnimation.skeleton.SetSkin(skin);
			newSkeletonAnimation.initialSkinName = skin.Name;

			newSkeletonAnimation.skeleton.Update(1);
			newSkeletonAnimation.state.Update(1);
			newSkeletonAnimation.state.Apply(newSkeletonAnimation.skeleton);
			newSkeletonAnimation.skeleton.UpdateWorldTransform();

			return newSkeletonAnimation;
		}
		public static SkeletonAnimator InstantiateSkeletonAnimator (SkeletonDataAsset skeletonDataAsset, Skin skin = null) {
			string spineGameObjectName = string.Format("Spine Mecanim GameObject ({0})", skeletonDataAsset.name.Replace("_SkeletonData", ""));
			GameObject go = new GameObject(spineGameObjectName, typeof(MeshFilter), typeof(MeshRenderer), typeof(Animator), typeof(SkeletonAnimator));

			if (skeletonDataAsset.controller == null) {
				SkeletonBaker.GenerateMecanimAnimationClips(skeletonDataAsset);
				Debug.Log(string.Format("Mecanim controller was automatically generated and assigned for {0}", skeletonDataAsset.name));
			}

			go.GetComponent<Animator>().runtimeAnimatorController = skeletonDataAsset.controller;

			SkeletonAnimator anim = go.GetComponent<SkeletonAnimator>();
			anim.skeletonDataAsset = skeletonDataAsset;

			// Detect "Lit" shader and automatically enable calculateNormals.
//			bool requiresNormals = false;
//			foreach (AtlasAsset atlasAsset in anim.skeletonDataAsset.atlasAssets) {
//				foreach (Material m in atlasAsset.materials) {
//					if (m.shader.name.Contains("Lit")) {
//						requiresNormals = true;
//						break;
//					}
//				}
//			}
//			anim.calculateNormals = requiresNormals;

			SkeletonData data = skeletonDataAsset.GetSkeletonData(true);
			if (data == null) {
				for (int i = 0; i < skeletonDataAsset.atlasAssets.Length; i++) {
					string reloadAtlasPath = AssetDatabase.GetAssetPath(skeletonDataAsset.atlasAssets[i]);
					skeletonDataAsset.atlasAssets[i] = (AtlasAsset)AssetDatabase.LoadAssetAtPath(reloadAtlasPath, typeof(AtlasAsset));
				}
				data = skeletonDataAsset.GetSkeletonData(true);
			}

			skin = skin ?? data.DefaultSkin ?? data.Skins.Items[0];

			anim.Initialize(false);
			anim.skeleton.SetSkin(skin);
			anim.initialSkinName = skin.Name;

			anim.skeleton.Update(0);
			anim.skeleton.UpdateWorldTransform();
			anim.LateUpdate();

			return anim;
		}
	public static SkeletonAnimation InstantiateSkeletonAnimation (SkeletonDataAsset skeletonDataAsset, Skin skin = null) {
		string spineGameObjectName = string.Format("Spine GameObject ({0})", skeletonDataAsset.name.Replace("_SkeletonData", ""));
		GameObject go = new GameObject(spineGameObjectName, typeof(MeshFilter), typeof(MeshRenderer), typeof(SkeletonAnimation));
		SkeletonAnimation anim = go.GetComponent<SkeletonAnimation>();
		anim.skeletonDataAsset = skeletonDataAsset;

		bool requiresNormals = false;

		foreach (AtlasAsset atlasAsset in anim.skeletonDataAsset.atlasAssets) {
			foreach (Material m in atlasAsset.materials) {
				if (m.shader.name.Contains("Lit")) {
					requiresNormals = true;
					break;
				}
			}
		}



		anim.calculateNormals = requiresNormals;

		SkeletonData data = skeletonDataAsset.GetSkeletonData(true);

		if (data == null) {
			for (int i = 0; i < skeletonDataAsset.atlasAssets.Length; i++) {
				string reloadAtlasPath = AssetDatabase.GetAssetPath(skeletonDataAsset.atlasAssets[i]);
				skeletonDataAsset.atlasAssets[i] = (AtlasAsset)AssetDatabase.LoadAssetAtPath(reloadAtlasPath, typeof(AtlasAsset));
			}

			data = skeletonDataAsset.GetSkeletonData(true);
		}

		if (skin == null)
			skin = data.DefaultSkin;

		if (skin == null)
			skin = data.Skins.Items[0];

		anim.Initialize(false);

		anim.skeleton.SetSkin(skin);
		anim.initialSkinName = skin.Name;

		anim.skeleton.Update(1);
		anim.state.Update(1);
		anim.state.Apply(anim.skeleton);
		anim.skeleton.UpdateWorldTransform();

		return anim;
	}
		public static void ShowInstantiateContextMenu (SkeletonDataAsset skeletonDataAsset, Vector3 spawnPoint) {
			var menu = new GenericMenu();

			// SkeletonAnimation
			menu.AddItem(new GUIContent("SkeletonAnimation"), false, HandleSkeletonComponentDrop, new SpawnMenuData {
				skeletonDataAsset = skeletonDataAsset,
				spawnPoint = spawnPoint,
				instantiateDelegate = (data) => InstantiateSkeletonAnimation(data),
				isUI = false
			});

			// SkeletonGraphic
			var skeletonGraphicInspectorType = System.Type.GetType("Spine.Unity.Editor.SkeletonGraphicInspector");
			if (skeletonGraphicInspectorType != null) {
				var graphicInstantiateDelegate = skeletonGraphicInspectorType.GetMethod("SpawnSkeletonGraphicFromDrop", BindingFlags.Static | BindingFlags.Public);
				if (graphicInstantiateDelegate != null)
					menu.AddItem(new GUIContent("SkeletonGraphic (UI)"), false, HandleSkeletonComponentDrop, new SpawnMenuData {
						skeletonDataAsset = skeletonDataAsset,
						spawnPoint = spawnPoint,
						instantiateDelegate = System.Delegate.CreateDelegate(typeof(InstantiateDelegate), graphicInstantiateDelegate) as InstantiateDelegate,
						isUI = true
					});
			}

			#if SPINE_SKELETONANIMATOR
			menu.AddSeparator("");
			// SkeletonAnimator
			menu.AddItem(new GUIContent("SkeletonAnimator"), false, HandleSkeletonComponentDrop, new SpawnMenuData {
				skeletonDataAsset = skeletonDataAsset,
				spawnPoint = spawnPoint,
				instantiateDelegate = (data) => InstantiateSkeletonAnimator(data)
			});
			#endif

			menu.ShowAsContext();
		}
	public static SkeletonAnimation SpawnAnimatedSkeleton (SkeletonDataAsset skeletonDataAsset, Skin skin = null) {
		GameObject go = new GameObject(skeletonDataAsset.name.Replace("_SkeletonData", ""), typeof(MeshFilter), typeof(MeshRenderer), typeof(SkeletonAnimation));
		SkeletonAnimation anim = go.GetComponent<SkeletonAnimation>();
		anim.skeletonDataAsset = skeletonDataAsset;



		SkeletonData data = skeletonDataAsset.GetSkeletonData(false);

		if (data == null) {
			return null;
		}

		if (skin == null)
			skin = data.DefaultSkin;
			
		if (skin == null)
			skin = data.Skins[0];

		anim.Reset();
		
		anim.skeleton.SetSkin(skin);
		anim.initialSkinName = skin.Name;
		
		anim.skeleton.Update(1);
		anim.state.Update(1);
		anim.state.Apply(anim.skeleton);
		anim.skeleton.UpdateWorldTransform();

		return anim;
	}
		public static SkeletonGraphic InstantiateSkeletonGraphic (SkeletonDataAsset skeletonDataAsset, Skin skin = null) {
			string spineGameObjectName = string.Format("SkeletonGraphic ({0})", skeletonDataAsset.name.Replace("_SkeletonData", ""));
			var go = NewSkeletonGraphicGameObject(spineGameObjectName);
			var graphic = go.GetComponent<SkeletonGraphic>();
			graphic.skeletonDataAsset = skeletonDataAsset;

			SkeletonData data = skeletonDataAsset.GetSkeletonData(true);

			if (data == null) {
				for (int i = 0; i < skeletonDataAsset.atlasAssets.Length; i++) {
					string reloadAtlasPath = AssetDatabase.GetAssetPath(skeletonDataAsset.atlasAssets[i]);
					skeletonDataAsset.atlasAssets[i] = (AtlasAsset)AssetDatabase.LoadAssetAtPath(reloadAtlasPath, typeof(AtlasAsset));
				}

				data = skeletonDataAsset.GetSkeletonData(true);
			}

			if (skin == null)
				skin = data.DefaultSkin;

			if (skin == null)
				skin = data.Skins.Items[0];

			graphic.Initialize(false);
			graphic.Skeleton.SetSkin(skin);
			graphic.initialSkinName = skin.Name;
			graphic.Skeleton.UpdateWorldTransform();
			graphic.UpdateMesh();

			return graphic;
		}
		public static SkeletonGraphic InstantiateSkeletonGraphic (SkeletonDataAsset skeletonDataAsset, string skinName) {
			return InstantiateSkeletonGraphic(skeletonDataAsset, skeletonDataAsset.GetSkeletonData(true).FindSkin(skinName));
		}
//		[MenuItem("Assets/Spine/Instantiate (UnityUI)", false, 20)]
//		static void InstantiateSkeletonGraphic () {
//			Object[] arr = Selection.objects;
//			foreach (Object o in arr) {
//				string guid = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(o));
//				string skinName = EditorPrefs.GetString(guid + "_lastSkin", "");
//
//				InstantiateSkeletonGraphic((SkeletonDataAsset)o, skinName);
//				SceneView.RepaintAll();
//			}
//		}
//
//		[MenuItem("Assets/Spine/Instantiate (UnityUI)", true, 20)]
//		static bool ValidateInstantiateSkeletonGraphic () {
//			Object[] arr = Selection.objects;
//
//			if (arr.Length == 0)
//				return false;
//
//			foreach (var selected in arr) {
//				if (selected.GetType() != typeof(SkeletonDataAsset))
//					return false;
//			}
//
//			return true;
//		}

		// SpineEditorUtilities.InstantiateDelegate. Used by drag and drop.
		public static Component SpawnSkeletonGraphicFromDrop (SkeletonDataAsset data) {
			return InstantiateSkeletonGraphic(data);
		}
Example #51
0
	public static SkeletonAnimator InstantiateSkeletonAnimator (SkeletonDataAsset skeletonDataAsset, Skin skin = null) {
		GameObject go = new GameObject(skeletonDataAsset.name.Replace("_SkeletonData", ""), typeof(MeshFilter), typeof(MeshRenderer), typeof(Animator), typeof(SkeletonAnimator));

		if (skeletonDataAsset.controller == null) {
			SkeletonBaker.GenerateMecanimAnimationClips(skeletonDataAsset);
		}

		go.GetComponent<Animator>().runtimeAnimatorController = skeletonDataAsset.controller;

		SkeletonAnimator anim = go.GetComponent<SkeletonAnimator>();
		anim.skeletonDataAsset = skeletonDataAsset;

		bool requiresNormals = false;

		foreach (AtlasAsset atlasAsset in anim.skeletonDataAsset.atlasAssets) {
			foreach (Material m in atlasAsset.materials) {
				if (m.shader.name.Contains("Lit")) {
					requiresNormals = true;
					break;
				}
			}
		}

		anim.calculateNormals = requiresNormals;

		SkeletonData data = skeletonDataAsset.GetSkeletonData(true);

		if (data == null) {
			for (int i = 0; i < skeletonDataAsset.atlasAssets.Length; i++) {
				string reloadAtlasPath = AssetDatabase.GetAssetPath(skeletonDataAsset.atlasAssets[i]);
				skeletonDataAsset.atlasAssets[i] = (AtlasAsset)AssetDatabase.LoadAssetAtPath(reloadAtlasPath, typeof(AtlasAsset));
			}

			data = skeletonDataAsset.GetSkeletonData(true);
		}

		if (skin == null)
			skin = data.DefaultSkin;

		if (skin == null)
			skin = data.Skins.Items[0];

		anim.Reset();

		anim.skeleton.SetSkin(skin);
		anim.initialSkinName = skin.Name;

		anim.skeleton.Update(1);
		anim.skeleton.UpdateWorldTransform();
		anim.LateUpdate();

		return anim;
	}
Example #52
0
		public static void GenerateMecanimAnimationClips (SkeletonDataAsset skeletonDataAsset) {
			//skeletonDataAsset.Clear();
			var data = skeletonDataAsset.GetSkeletonData(true);
			if (data == null) {
				Debug.LogError("SkeletonData failed!", skeletonDataAsset);
				return;
			}

			string dataPath = AssetDatabase.GetAssetPath(skeletonDataAsset);
			string controllerPath = dataPath.Replace("_SkeletonData", "_Controller").Replace(".asset", ".controller");

		#if UNITY_5
			UnityEditor.Animations.AnimatorController controller;

			if (skeletonDataAsset.controller != null) {
				controller = (UnityEditor.Animations.AnimatorController)skeletonDataAsset.controller;
				controllerPath = AssetDatabase.GetAssetPath(controller);
			} else {
				if (File.Exists(controllerPath)) {
					if (EditorUtility.DisplayDialog("Controller Overwrite Warning", "Unknown Controller already exists at: " + controllerPath, "Update", "Overwrite")) {
						controller = (UnityEditor.Animations.AnimatorController)AssetDatabase.LoadAssetAtPath(controllerPath, typeof(RuntimeAnimatorController));
					} else {
						controller = (UnityEditor.Animations.AnimatorController)UnityEditor.Animations.AnimatorController.CreateAnimatorControllerAtPath(controllerPath);
					}
				} else {
					controller = (UnityEditor.Animations.AnimatorController)UnityEditor.Animations.AnimatorController.CreateAnimatorControllerAtPath(controllerPath);
				}

			}
		#else
		UnityEditorInternal.AnimatorController controller;

		if (skeletonDataAsset.controller != null) {
			controller = (UnityEditorInternal.AnimatorController)skeletonDataAsset.controller;
			controllerPath = AssetDatabase.GetAssetPath(controller);
		} else {
			if (File.Exists(controllerPath)) {
				if (EditorUtility.DisplayDialog("Controller Overwrite Warning", "Unknown Controller already exists at: " + controllerPath, "Update", "Overwrite")) {
					controller = (UnityEditorInternal.AnimatorController)AssetDatabase.LoadAssetAtPath(controllerPath, typeof(RuntimeAnimatorController));
				} else {
					controller = (UnityEditorInternal.AnimatorController)UnityEditorInternal.AnimatorController.CreateAnimatorControllerAtPath(controllerPath);
				}
			} else {
				controller = (UnityEditorInternal.AnimatorController)UnityEditorInternal.AnimatorController.CreateAnimatorControllerAtPath(controllerPath);
			}
		}
		#endif

			skeletonDataAsset.controller = controller;
			EditorUtility.SetDirty(skeletonDataAsset);

			UnityEngine.Object[] objs = AssetDatabase.LoadAllAssetsAtPath(controllerPath);

			var unityAnimationClipTable = new Dictionary<string, AnimationClip>();
			var spineAnimationTable = new Dictionary<string, Spine.Animation>();

			foreach (var o in objs) {
				//Debug.LogFormat("({0}){1} : {3} + {2} + {4}", o.GetType(), o.name, o.hideFlags, o.GetInstanceID(), o.GetHashCode());
				// There is a bug in Unity 5.3.3 (and likely before) that creates
				// a duplicate AnimationClip when you duplicate a Mecanim Animator State.
				// These duplicates seem to be identifiable by their HideFlags, so we'll exclude them.
				if (o is AnimationClip) {
					var clip = o as AnimationClip;
					if (!clip.HasFlag(HideFlags.HideInHierarchy)) {
						if (unityAnimationClipTable.ContainsKey(clip.name)) {
							Debug.LogWarningFormat("Duplicate AnimationClips were found named {0}", clip.name);
						}
						unityAnimationClipTable.Add(clip.name, clip);
					}				
				}
			}

			foreach (var anim in data.Animations) {
				string name = anim.Name;
				spineAnimationTable.Add(name, anim);

				if (unityAnimationClipTable.ContainsKey(name) == false) {
					//generate new dummy clip
					AnimationClip newClip = new AnimationClip();
					newClip.name = name;
					#if !(UNITY_5)
					AnimationUtility.SetAnimationType(newClip, ModelImporterAnimationType.Generic);
					#endif
					AssetDatabase.AddObjectToAsset(newClip, controller);
					unityAnimationClipTable.Add(name, newClip);
				}

				AnimationClip clip = unityAnimationClipTable[name];

				clip.SetCurve("", typeof(GameObject), "dummy", AnimationCurve.Linear(0, 0, anim.Duration, 0));
				var settings = AnimationUtility.GetAnimationClipSettings(clip);
				settings.stopTime = anim.Duration;

				SetAnimationSettings(clip, settings);

				AnimationUtility.SetAnimationEvents(clip, new AnimationEvent[0]);

				foreach (Timeline t in anim.Timelines) {
					if (t is EventTimeline) {
						ParseEventTimeline((EventTimeline)t, clip, SendMessageOptions.DontRequireReceiver);
					}
				}

				EditorUtility.SetDirty(clip);

				unityAnimationClipTable.Remove(name);
			}

			//clear no longer used animations
			foreach (var clip in unityAnimationClipTable.Values) {
				AnimationClip.DestroyImmediate(clip, true);
			}

			AssetDatabase.Refresh();
			AssetDatabase.SaveAssets();
		}
Example #53
0
	/// <summary>Adds and prepares a SkeletonAnimation component to a GameObject at runtime.</summary>
	/// <returns>The newly instantiated SkeletonAnimation</returns>
	public static SkeletonAnimation AddToGameObject (GameObject gameObject, SkeletonDataAsset skeletonDataAsset) {
		return SkeletonRenderer.AddSpineComponent<SkeletonAnimation>(gameObject, skeletonDataAsset);
	}
Example #54
0
	public static void GenerateMecanimAnimationClips (SkeletonDataAsset skeletonDataAsset) {
		var data = skeletonDataAsset.GetSkeletonData(true);
		if (data == null) {
			Debug.LogError("SkeletonData failed!", skeletonDataAsset);
			return;
		}

		string dataPath = AssetDatabase.GetAssetPath(skeletonDataAsset);
		string controllerPath = dataPath.Replace("_SkeletonData", "_Controller").Replace(".asset", ".controller");


#if UNITY_5
		UnityEditor.Animations.AnimatorController controller;

		if (skeletonDataAsset.controller != null) {
			controller = (UnityEditor.Animations.AnimatorController)skeletonDataAsset.controller;
			controllerPath = AssetDatabase.GetAssetPath(controller);
		} else {
			if (File.Exists(controllerPath)) {
				if (EditorUtility.DisplayDialog("Controller Overwrite Warning", "Unknown Controller already exists at: " + controllerPath, "Update", "Overwrite")) {
					controller = (UnityEditor.Animations.AnimatorController)AssetDatabase.LoadAssetAtPath(controllerPath, typeof(RuntimeAnimatorController));
				} else {
					controller = (UnityEditor.Animations.AnimatorController)UnityEditor.Animations.AnimatorController.CreateAnimatorControllerAtPath(controllerPath);
				}
			} else {
				controller = (UnityEditor.Animations.AnimatorController)UnityEditor.Animations.AnimatorController.CreateAnimatorControllerAtPath(controllerPath);
			}
			
		}
#else
		UnityEditorInternal.AnimatorController controller;

		if (skeletonDataAsset.controller != null) {
			controller = (UnityEditorInternal.AnimatorController)skeletonDataAsset.controller;
			controllerPath = AssetDatabase.GetAssetPath(controller);
		} else {
			if (File.Exists(controllerPath)) {
				if (EditorUtility.DisplayDialog("Controller Overwrite Warning", "Unknown Controller already exists at: " + controllerPath, "Update", "Overwrite")) {
					controller = (UnityEditorInternal.AnimatorController)AssetDatabase.LoadAssetAtPath(controllerPath, typeof(RuntimeAnimatorController));
				} else {
					controller = (UnityEditorInternal.AnimatorController)UnityEditorInternal.AnimatorController.CreateAnimatorControllerAtPath(controllerPath);
				}
			} else {
				controller = (UnityEditorInternal.AnimatorController)UnityEditorInternal.AnimatorController.CreateAnimatorControllerAtPath(controllerPath);
			}
		}
#endif

		skeletonDataAsset.controller = controller;
		EditorUtility.SetDirty(skeletonDataAsset);

		Object[] objs = AssetDatabase.LoadAllAssetsAtPath(controllerPath);

		Dictionary<string, AnimationClip> clipTable = new Dictionary<string, AnimationClip>();
		Dictionary<string, Spine.Animation> animTable = new Dictionary<string, Spine.Animation>();

		foreach (var o in objs) {
			if (o is AnimationClip) {
				clipTable.Add(o.name, (AnimationClip)o);
			}
		}

		foreach (var anim in data.Animations) {
			string name = anim.Name;
			animTable.Add(name, anim);

			if (clipTable.ContainsKey(name) == false) {
				//generate new dummy clip
				AnimationClip newClip = new AnimationClip();
				newClip.name = name;
#if UNITY_5
#else
				AnimationUtility.SetAnimationType(newClip, ModelImporterAnimationType.Generic);
#endif

				AssetDatabase.AddObjectToAsset(newClip, controller);
				clipTable.Add(name, newClip);
			}

			AnimationClip clip = clipTable[name];

			clip.SetCurve("", typeof(GameObject), "dummy", AnimationCurve.Linear(0, 0, anim.Duration, 0));
			var settings = AnimationUtility.GetAnimationClipSettings(clip);
			settings.stopTime = anim.Duration;

			SetAnimationSettings(clip, settings);

			AnimationUtility.SetAnimationEvents(clip, new AnimationEvent[0]);

			foreach (Timeline t in anim.Timelines) {
				if (t is EventTimeline) {
					ParseEventTimeline((EventTimeline)t, clip, SendMessageOptions.DontRequireReceiver);
				}
			}

			EditorUtility.SetDirty(clip);

			clipTable.Remove(name);
		}

		//clear no longer used animations
		foreach (var clip in clipTable.Values) {
			AnimationClip.DestroyImmediate(clip, true);
		}

		AssetDatabase.Refresh();
		AssetDatabase.SaveAssets();
	}
Example #55
0
	public static Spine.Attachment GetAttachment(string attachmentPath, SkeletonDataAsset skeletonDataAsset) {
		return GetAttachment(attachmentPath, skeletonDataAsset.GetSkeletonData(true));
	}
Example #56
0
	public static void BakeToPrefab (SkeletonDataAsset skeletonDataAsset, List<Skin> skins, string outputPath = "", bool bakeAnimations = true, bool bakeIK = true, SendMessageOptions eventOptions = SendMessageOptions.DontRequireReceiver) {
		if (skeletonDataAsset == null || skeletonDataAsset.GetSkeletonData(true) == null) {
			Debug.LogError("Could not export Spine Skeleton because SkeletonDataAsset is null or invalid!");
			return;
		}

		if (outputPath == "") {
			outputPath = System.IO.Path.GetDirectoryName(AssetDatabase.GetAssetPath(skeletonDataAsset)) + "/Baked";
			System.IO.Directory.CreateDirectory(outputPath);
		}

		var skeletonData = skeletonDataAsset.GetSkeletonData(true);
		bool hasAnimations = bakeAnimations && skeletonData.Animations.Count > 0;
#if UNITY_5
		UnityEditor.Animations.AnimatorController controller = null;
#else
		UnityEditorInternal.AnimatorController controller = null;
#endif
		if (hasAnimations) {
			string controllerPath = outputPath + "/" + skeletonDataAsset.skeletonJSON.name + " Controller.controller";
			bool newAnimContainer = false;

			var runtimeController = AssetDatabase.LoadAssetAtPath(controllerPath, typeof(RuntimeAnimatorController));

#if UNITY_5
			if (runtimeController != null) {
				controller = (UnityEditor.Animations.AnimatorController)runtimeController;
			} else {
				controller = UnityEditor.Animations.AnimatorController.CreateAnimatorControllerAtPath(controllerPath);
				newAnimContainer = true;
			}
#else
			if (runtimeController != null) {
				controller = (UnityEditorInternal.AnimatorController)runtimeController;
			} else {
				controller = UnityEditorInternal.AnimatorController.CreateAnimatorControllerAtPath(controllerPath);
				newAnimContainer = true;
			}
#endif

			Dictionary<string, AnimationClip> existingClipTable = new Dictionary<string, AnimationClip>();
			List<string> unusedClipNames = new List<string>();
			Object[] animObjs = AssetDatabase.LoadAllAssetsAtPath(controllerPath);

			foreach (Object o in animObjs) {
				if (o is AnimationClip) {
					var clip = (AnimationClip)o;
					existingClipTable.Add(clip.name, clip);
					unusedClipNames.Add(clip.name);
				}
			}

			Dictionary<int, List<string>> slotLookup = new Dictionary<int, List<string>>();

			int skinCount = skins.Count;

			for (int s = 0; s < skeletonData.Slots.Count; s++) {
				List<string> attachmentNames = new List<string>();
				for (int i = 0; i < skinCount; i++) {
					var skin = skins[i];
					List<string> temp = new List<string>();
					skin.FindNamesForSlot(s, temp);
					foreach (string str in temp) {
						if (!attachmentNames.Contains(str))
							attachmentNames.Add(str);
					}
				}
				slotLookup.Add(s, attachmentNames);
			}

			foreach (var anim in skeletonData.Animations) {

				AnimationClip clip = null;
				if (existingClipTable.ContainsKey(anim.Name)) {
					clip = existingClipTable[anim.Name];
				}

				clip = ExtractAnimation(anim.Name, skeletonData, slotLookup, bakeIK, eventOptions, clip);

				if (unusedClipNames.Contains(clip.name)) {
					unusedClipNames.Remove(clip.name);
				} else {
					AssetDatabase.AddObjectToAsset(clip, controller);
#if UNITY_5
					controller.AddMotion(clip);
#else
					UnityEditorInternal.AnimatorController.AddAnimationClipToController(controller, clip);
#endif

				}
			}

			if (newAnimContainer) {
				EditorUtility.SetDirty(controller);
				AssetDatabase.SaveAssets();
				AssetDatabase.ImportAsset(controllerPath, ImportAssetOptions.ForceUpdate);
				AssetDatabase.Refresh();
			} else {

				foreach (string str in unusedClipNames) {
					AnimationClip.DestroyImmediate(existingClipTable[str], true);
				}

				EditorUtility.SetDirty(controller);
				AssetDatabase.SaveAssets();
				AssetDatabase.ImportAsset(controllerPath, ImportAssetOptions.ForceUpdate);
				AssetDatabase.Refresh();
			}
		}

		foreach (var skin in skins) {
			bool newPrefab = false;

			string prefabPath = outputPath + "/" + skeletonDataAsset.skeletonJSON.name + " (" + skin.Name + ").prefab";


			Object prefab = AssetDatabase.LoadAssetAtPath(prefabPath, typeof(GameObject));
			if (prefab == null) {
				prefab = PrefabUtility.CreateEmptyPrefab(prefabPath);
				newPrefab = true;
			}

			Dictionary<string, Mesh> meshTable = new Dictionary<string, Mesh>();
			List<string> unusedMeshNames = new List<string>();
			Object[] assets = AssetDatabase.LoadAllAssetsAtPath(prefabPath);
			foreach (var obj in assets) {
				if (obj is Mesh) {
					meshTable.Add(obj.name, (Mesh)obj);
					unusedMeshNames.Add(obj.name);
				}
			}

			GameObject prefabRoot = new GameObject("root");

			Dictionary<string, Transform> slotTable = new Dictionary<string, Transform>();
			Dictionary<string, Transform> boneTable = new Dictionary<string, Transform>();
			List<Transform> boneList = new List<Transform>();

			//create bones
			for (int i = 0; i < skeletonData.Bones.Count; i++) {
				var boneData = skeletonData.Bones[i];
				Transform boneTransform = new GameObject(boneData.Name).transform;
				boneTransform.parent = prefabRoot.transform;
				boneTable.Add(boneTransform.name, boneTransform);
				boneList.Add(boneTransform);
			}

			for (int i = 0; i < skeletonData.Bones.Count; i++) {

				var boneData = skeletonData.Bones[i];
				Transform boneTransform = boneTable[boneData.Name];
				Transform parentTransform = null;
				if (i > 0)
					parentTransform = boneTable[boneData.Parent.Name];
				else
					parentTransform = boneTransform.parent;

				boneTransform.parent = parentTransform;
				boneTransform.localPosition = new Vector3(boneData.X, boneData.Y, 0);
				if (boneData.InheritRotation)
					boneTransform.localRotation = Quaternion.Euler(0, 0, boneData.Rotation);
				else
					boneTransform.rotation = Quaternion.Euler(0, 0, boneData.Rotation);

				if (boneData.InheritScale)
					boneTransform.localScale = new Vector3(boneData.ScaleX, boneData.ScaleY, 1);
			}

			//create slots and attachments
			for (int i = 0; i < skeletonData.Slots.Count; i++) {
				var slotData = skeletonData.Slots[i];
				Transform slotTransform = new GameObject(slotData.Name).transform;
				slotTransform.parent = prefabRoot.transform;
				slotTable.Add(slotData.Name, slotTransform);

				List<Attachment> attachments = new List<Attachment>();
				List<string> attachmentNames = new List<string>();

				skin.FindAttachmentsForSlot(i, attachments);
				skin.FindNamesForSlot(i, attachmentNames);

				if (skin != skeletonData.DefaultSkin) {
					skeletonData.DefaultSkin.FindAttachmentsForSlot(i, attachments);
					skeletonData.DefaultSkin.FindNamesForSlot(i, attachmentNames);
				}

				for (int a = 0; a < attachments.Count; a++) {
					var attachment = attachments[a];
					var attachmentName = attachmentNames[a];
					var attachmentMeshName = "[" + slotData.Name + "] " + attachmentName;
					Vector3 offset = Vector3.zero;
					float rotation = 0;
					Mesh mesh = null;
					Material material = null;

					if (meshTable.ContainsKey(attachmentMeshName))
						mesh = meshTable[attachmentMeshName];
					if (attachment is RegionAttachment) {
						var regionAttachment = (RegionAttachment)attachment;
						offset.x = regionAttachment.X;
						offset.y = regionAttachment.Y;
						rotation = regionAttachment.Rotation;
						mesh = ExtractRegionAttachment(attachmentMeshName, regionAttachment, mesh);
						material = ExtractMaterial((RegionAttachment)attachment);
						unusedMeshNames.Remove(attachmentMeshName);
						if (newPrefab || meshTable.ContainsKey(attachmentMeshName) == false)
							AssetDatabase.AddObjectToAsset(mesh, prefab);
					} else if (attachment is MeshAttachment) {
						var meshAttachment = (MeshAttachment)attachment;
						offset.x = 0;
						offset.y = 0;
						rotation = 0;
						mesh = ExtractMeshAttachment(attachmentMeshName, meshAttachment, mesh);
						material = ExtractMaterial((MeshAttachment)attachment);
						unusedMeshNames.Remove(attachmentMeshName);
						if (newPrefab || meshTable.ContainsKey(attachmentMeshName) == false)
							AssetDatabase.AddObjectToAsset(mesh, prefab);
					} else if (attachment is SkinnedMeshAttachment) {
						var meshAttachment = (SkinnedMeshAttachment)attachment;
						offset.x = 0;
						offset.y = 0;
						rotation = 0;
						mesh = ExtractSkinnedMeshAttachment(attachmentMeshName, meshAttachment, i, skeletonData, boneList, mesh);
						material = ExtractMaterial((SkinnedMeshAttachment)attachment);
						unusedMeshNames.Remove(attachmentMeshName);
						if (newPrefab || meshTable.ContainsKey(attachmentMeshName) == false)
							AssetDatabase.AddObjectToAsset(mesh, prefab);
					} else
						continue;  //disregard unsupported types for now

					Transform attachmentTransform = new GameObject(attachmentName).transform;

					attachmentTransform.parent = slotTransform;
					attachmentTransform.localPosition = offset;
					attachmentTransform.localRotation = Quaternion.Euler(0, 0, rotation);

					if (attachment is SkinnedMeshAttachment) {
						attachmentTransform.position = Vector3.zero;
						attachmentTransform.rotation = Quaternion.identity;
						var skinnedMeshRenderer = attachmentTransform.gameObject.AddComponent<SkinnedMeshRenderer>();
						skinnedMeshRenderer.rootBone = boneList[0];
						skinnedMeshRenderer.bones = boneList.ToArray();
						skinnedMeshRenderer.sharedMesh = mesh;

					} else {
						attachmentTransform.gameObject.AddComponent<MeshFilter>().sharedMesh = mesh;
						attachmentTransform.gameObject.AddComponent<MeshRenderer>();
					}

					attachmentTransform.GetComponent<Renderer>().sharedMaterial = material;
					attachmentTransform.GetComponent<Renderer>().sortingOrder = i;

					if (attachmentName != slotData.AttachmentName)
						attachmentTransform.gameObject.SetActive(false);
				}

			}

			foreach (var slotData in skeletonData.Slots) {
				Transform slotTransform = slotTable[slotData.Name];
				slotTransform.parent = boneTable[slotData.BoneData.Name];
				slotTransform.localPosition = Vector3.zero;
				slotTransform.localRotation = Quaternion.identity;
				slotTransform.localScale = Vector3.one;
			}

			if (hasAnimations) {
				var animator = prefabRoot.AddComponent<Animator>();
				animator.applyRootMotion = false;
				animator.runtimeAnimatorController = (RuntimeAnimatorController)controller;
				EditorGUIUtility.PingObject(controller);
			}


			if (newPrefab) {
				PrefabUtility.ReplacePrefab(prefabRoot, prefab, ReplacePrefabOptions.ConnectToPrefab);
			} else {

				foreach (string str in unusedMeshNames) {
					Mesh.DestroyImmediate(meshTable[str], true);
				}

				PrefabUtility.ReplacePrefab(prefabRoot, prefab, ReplacePrefabOptions.ReplaceNameBased);
			}

			EditorGUIUtility.PingObject(prefab);

			AssetDatabase.Refresh();
			AssetDatabase.SaveAssets();

			GameObject.DestroyImmediate(prefabRoot);
		}

	}
	public static SkeletonAnimation SpawnAnimatedSkeleton(SkeletonDataAsset skeletonDataAsset, string skinName){
		return SpawnAnimatedSkeleton(skeletonDataAsset, skeletonDataAsset.GetSkeletonData(true).FindSkin(skinName));
	}
		public static SkeletonAnimation InstantiateSkeletonAnimation (SkeletonDataAsset skeletonDataAsset, string skinName, bool destroyInvalid = true) {
			var skeletonData = skeletonDataAsset.GetSkeletonData(true);
			var skin = skeletonData != null ? skeletonData.FindSkin(skinName) : null;
			return InstantiateSkeletonAnimation(skeletonDataAsset, skin, destroyInvalid);
		}
	public static SkeletonAnimation SpawnAnimatedSkeleton(SkeletonDataAsset skeletonDataAsset, Skin skin = null){
		
		GameObject go = new GameObject(skeletonDataAsset.name.Replace("_SkeletonData", ""), typeof(MeshFilter), typeof(MeshRenderer), typeof(SkeletonAnimation));
		SkeletonAnimation anim = go.GetComponent<SkeletonAnimation>();
		anim.skeletonDataAsset = skeletonDataAsset;

		bool requiresNormals = false;

		foreach(Material m in anim.skeletonDataAsset.atlasAsset.materials){
			if(m.shader.name.Contains("Lit")){
				requiresNormals = true;
				break;
			}
		}

		anim.calculateNormals = requiresNormals;

		if(skin == null)
			skin = skeletonDataAsset.GetSkeletonData(true).DefaultSkin;
			
		if(skin == null)
			skin = skeletonDataAsset.GetSkeletonData(true).Skins[0];

		anim.Reset();
		
		anim.skeleton.SetSkin(skin);
		anim.initialSkinName = skin.Name;
		
		anim.skeleton.Update(1);
		anim.state.Update(1);
		anim.state.Apply(anim.skeleton);
		anim.skeleton.UpdateWorldTransform();

		return anim;
	}
	public static SkeletonAnimation SpawnAnimatedSkeleton (SkeletonDataAsset skeletonDataAsset, string skinName) {
		SkeletonData skelData = skeletonDataAsset.GetSkeletonData(false);
		if(skelData == null){
			return null;
		}
		return SpawnAnimatedSkeleton(skeletonDataAsset, skelData.FindSkin(skinName));
	}