Example #1
0
    // 读取Json文件
    public static SkeletonDataAsset IngestSpineProject(string spineJsonPath, AtlasAsset atlasAsset = null)
    {
        string jsonContentStr = File.ReadAllText(spineJsonPath);

        string   primaryName = Path.GetFileNameWithoutExtension(spineJsonPath);
        FileInfo fInfo       = new FileInfo(spineJsonPath + ".json");
        string   assetPath   = Path.GetDirectoryName(fInfo.Directory.FullName);

        if (spineJsonPath != null && atlasAsset != null)
        {
            SkeletonDataAsset skelDataAsset = SkeletonDataAsset.CreateInstance <SkeletonDataAsset>();
            skelDataAsset.atlasAsset = atlasAsset;
            // skelDataAsset.skeletonJSON = spineJsonPath;
            skelDataAsset.jsonFileName    = primaryName;
            skelDataAsset.skeletonJsonStr = jsonContentStr;
            skelDataAsset.fromAnimation   = new string[0];
            skelDataAsset.toAnimation     = new string[0];
            skelDataAsset.duration        = new float[0];
            skelDataAsset.defaultMix      = defaultMix;
            skelDataAsset.scale           = defaultScale;

            return(skelDataAsset);
        }
        else
        {
            Debug.LogError("json 或 atlas 为 null !");
            return(null);
        }
    }
Example #2
0
	void OnEnable () {
		SpineEditorUtilities.ConfirmInitialization();
		atlasFile = serializedObject.FindProperty("atlasFile");
		materials = serializedObject.FindProperty("materials");
		atlasAsset = (AtlasAsset)target;
		UpdateBakedList();
	}
Example #3
0
        //---------------------------------------------------------------------
        public static SkeletonAnimation LoadResourcesPrefab(object atlas, object png, object json, string shaderName)
        {
            SkeletonAnimation playerAnim;
            SkeletonDataAsset playerData;

            AtlasAsset[] atlasdata1 = new AtlasAsset[1];
            AtlasAsset   atlasdata;

            atlasdata  = ScriptableObject.CreateInstance <AtlasAsset>();
            playerData = ScriptableObject.CreateInstance <SkeletonDataAsset>();

            atlasdata.atlasFile = (TextAsset)atlas;

            Material[] materials = new Material[1];
            materials[0]             = new Material(Shader.Find(shaderName));
            materials[0].mainTexture = (Texture)png;
            atlasdata.materials      = materials;

            atlasdata1[0]           = atlasdata;
            playerData.atlasAssets  = atlasdata1;
            playerData.skeletonJSON = (TextAsset)json;

            GameObject go = new GameObject();

            playerAnim = go.AddComponent <SkeletonAnimation>();
            playerAnim.skeletonDataAsset = playerData;
            //var m_Mr = go.GetComponent<MeshRenderer>();
            return(playerAnim);
        }
Example #4
0
    static AtlasAsset GetMatchingAtlas(List <string> requiredPaths, List <AtlasAsset> atlasAssets)
    {
        AtlasAsset atlasAssetMatch = null;

        foreach (AtlasAsset a in atlasAssets)
        {
            Atlas atlas  = a.GetAtlas();
            bool  failed = false;
            foreach (string regionPath in requiredPaths)
            {
                if (atlas.FindRegion(regionPath) == null)
                {
                    failed = true;
                    break;
                }
            }

            if (!failed)
            {
                atlasAssetMatch = a;

                // tsteil - default the GetMatchingAtlas so it tries to returns the 2x atlas
                if (atlasAssetMatch.name.EndsWith("-2x_Atlas"))
                {
                    break;
                }
            }
        }

        return(atlasAssetMatch);
    }
Example #5
0
        //---------------------------------------------------------------------
        SkeletonAnimation _createSpineGameObject(TextAsset atlas, Texture png, TextAsset json, string shader_name)
        {
            Shader shader = Shader.Find(shader_name);

            Material[] materials = new Material[1];
            materials[0]             = new Material(shader);
            materials[0].mainTexture = png;

            AtlasAsset atlasdata = ScriptableObject.CreateInstance <AtlasAsset>();

            atlasdata.atlasFile = atlas;
            atlasdata.materials = materials;

            AtlasAsset[] atlasdata1 = new AtlasAsset[1];
            atlasdata1[0] = atlasdata;

            SkeletonDataAsset skeleton_dataasset = ScriptableObject.CreateInstance <SkeletonDataAsset>();

            skeleton_dataasset.atlasAssets  = atlasdata1;
            skeleton_dataasset.skeletonJSON = json;

            GameObject        go            = new GameObject();
            SkeletonAnimation skeleton_anim = go.AddComponent <SkeletonAnimation>();

            skeleton_anim.skeletonDataAsset = skeleton_dataasset;

            return(skeleton_anim);
        }
    static AtlasAsset GetMatchingAtlas(List <string> requiredPaths, List <AtlasAsset> atlasAssets)
    {
        AtlasAsset atlasAssetMatch = null;

        foreach (AtlasAsset a in atlasAssets)
        {
            Atlas atlas  = a.GetAtlas();
            bool  failed = false;
            foreach (string regionPath in requiredPaths)
            {
                if (atlas.FindRegion(regionPath) == null)
                {
                    failed = true;
                    break;
                }
            }

            if (!failed)
            {
                atlasAssetMatch = a;
                break;
            }
        }

        return(atlasAssetMatch);
    }
Example #7
0
    static SkeletonDataAsset IngestSpineProject(TextAsset spineJson, AtlasAsset atlasAsset = null)
    {
        string primaryName = Path.GetFileNameWithoutExtension(spineJson.name);
        string assetPath   = Path.GetDirectoryName(AssetDatabase.GetAssetPath(spineJson));
        string filePath    = assetPath + "/" + primaryName + "_SkeletonData.asset";

        if (spineJson != null && atlasAsset != null)
        {
            SkeletonDataAsset skelDataAsset = (SkeletonDataAsset)AssetDatabase.LoadAssetAtPath(filePath, typeof(SkeletonDataAsset));
            if (skelDataAsset == null)
            {
                skelDataAsset               = SkeletonDataAsset.CreateInstance <SkeletonDataAsset>();
                skelDataAsset.atlasAsset    = atlasAsset;
                skelDataAsset.skeletonJSON  = spineJson;
                skelDataAsset.fromAnimation = new string[0];
                skelDataAsset.toAnimation   = new string[0];
                skelDataAsset.duration      = new float[0];
                skelDataAsset.defaultMix    = defaultMix;
                skelDataAsset.scale         = defaultScale;

                AssetDatabase.CreateAsset(skelDataAsset, filePath);
                AssetDatabase.SaveAssets();
            }

            return(skelDataAsset);
        }
        else
        {
            EditorUtility.DisplayDialog("Error!", "Must specify both Spine JSON and Atlas TextAsset", "OK");
            return(null);
        }
    }
Example #8
0
    public static SkeletonAnimation CreateSkeAnimFromZip(string fullZipPath)
    {
        FileInfo zipFInfo  = new FileInfo(fullZipPath);
        string   spineName = Path.GetFileNameWithoutExtension(fullZipPath);

        ZipFile  zf         = new ZipFile(fullZipPath);
        ZipEntry jsonEntry  = zf.GetEntry(spineName + ".json");
        ZipEntry atlasEntry = zf.GetEntry(spineName + ".atlas");

        List <ZipEntry> pngEntries = new List <ZipEntry>();
        List <ZipEntry> jpgEntries = new List <ZipEntry>();

        // 将图片加入查找表
        foreach (ZipEntry entry in zf)
        {
            string ext = Path.GetExtension(entry.Name);
            if (ext == ".png")
            {
                pngEntries.Add(entry);
            }
            else if (ext == ".jpg")
            {
                jpgEntries.Add(entry);
            }
        }

        AtlasAsset        atlasAsset        = SpineFileReader.IngestSpineAtlas("man_ok.atlas");
        SkeletonDataAsset skeletonDataAsset = SpineFileReader.IngestSpineProject("man_ok.json", atlasAsset);

        return(SpineFileReader.SpawnAnimatedSkeleton(skeletonDataAsset));
    }
Example #9
0
        void CreateRuntimeAssetsAndGameObject()
        {
            // 1. Create the AtlasAsset (needs atlas text asset and textures, and materials/shader);
            // 2. Create SkeletonDataAsset (needs json or binary asset file, and an AtlasAsset)
            // 3. Create SkeletonAnimation (needs a valid SkeletonDataAsset)

            Texture2D[] textures = new Texture2D[1];

            textures[0] = new Texture2D(0, 0, TextureFormat.RGBA32, false, false);

            textures[0].filterMode = FilterMode.Point;
            byte[] bytes = File.ReadAllBytes(Application.dataPath + "/Resources/Scenes/girl/girl.png");
            textures[0].LoadImage(bytes);
            textures[0].name = "girl";

            Material materialPropertySource = new Material(Shader.Find("Spine/Skeleton"));


            //runtimeAtlasAsset = AtlasAsset.CreateRuntimeInstance(Resources.Load<TextAsset>("Scenes/girl/girl.atlas"), textures, materialPropertySource, true);
            //runtimeSkeletonDataAsset = SkeletonDataAsset.CreateRuntimeInstance(Resources.Load<TextAsset>("Scenes/girl/girl"), runtimeAtlasAsset, true);

            atlasText         = new TextAsset(File.ReadAllText(Application.dataPath + "/Resources/Scenes/girl/girl.atlas.txt"));
            atlasText.name    = "girl.atlas";
            skeletonJson      = new TextAsset(File.ReadAllText(Application.dataPath + "/Resources/Scenes/girl/girl.json"));
            skeletonJson.name = "girl";

            runtimeAtlasAsset        = AtlasAsset.CreateRuntimeInstance(atlasText, textures, materialPropertySource, true);
            runtimeSkeletonDataAsset = SkeletonDataAsset.CreateRuntimeInstance(skeletonJson, runtimeAtlasAsset, true);
        }
Example #10
0
    public static bool SetSoldier(GameObject go, string pathName, int solidify)
    {
        Debug.Log("SetSoldier GameObject go,string pathName,int solidify-----------------");
        if (go.GetComponent <SkeletonAnimation>() == null)
        {
            return(false);
        }
        string name;


        if (solidify < 5)
        {
            name = pathName + (solidify + 1).ToString();
        }
        else
        {
            name = pathName + "JY";
        }

        Debug.Log(name);
        SkeletonDataAsset skeleton  = GameObject.Instantiate(Resources.Load <SkeletonDataAsset>("FightScene/Monster/" + name + "/New SkeletonData")) as SkeletonDataAsset;
        AtlasAsset        assetData = GameObject.Instantiate(Resources.Load <AtlasAsset>("FightScene/Monster/" + name + "/New Atlas")) as AtlasAsset;
        Material          material  = GameObject.Instantiate(Resources.Load <Material>("FightScene/Monster/" + name + "/New Material")) as Material;

        if (!skeleton || !assetData || !material)
        {
            return(false);
        }
        skeleton.atlasAsset    = assetData;
        assetData.materials[0] = material;
        go.GetComponent <SkeletonAnimation>().skeletonDataAsset = skeleton;
        go.GetComponent <SkeletonAnimation>().Reset();

        return(true);
    }
Example #11
0
        void SetDepth()
        {
            return;

            if (target == null || atlasMaterial == null)
            {
                return;
            }

            GameObject spineObj = target;
            int        _rendQ   = mDepth;

            SkeletonAnimation spineObjSkel = spineObj.GetComponent <SkeletonAnimation>();
            AtlasAsset        atlasAsset   = ScriptableObject.CreateInstance <AtlasAsset>();

            atlasAsset.atlasFile      = spineObjSkel.skeletonDataAsset.atlasAssets[0].atlasFile;
            atlasMaterial.renderQueue = finalRenderQueue;
            atlasAsset.materials      = new[] { atlasMaterial };


            SkeletonDataAsset skeletonDataAsset
                = Instantiate(spineObj.GetComponent <SkeletonAnimation>().skeletonDataAsset) as SkeletonDataAsset;

            skeletonDataAsset.atlasAssets[0] = atlasAsset;

            spineObjSkel.skeletonDataAsset = skeletonDataAsset;

            spineObjSkel.Initialize(true);
        }
Example #12
0
    public AtlasAsset LoadPartAtlas(string atlasResName)
    {
        string     path  = "Assets/Res/Char_Equipment/Atlas/" + atlasResName + "/" + atlasResName + "_Atlas.asset";
        AtlasAsset asset = LoadAsset <AtlasAsset>(atlasResName, "char_equipment_atlas_" + atlasResName, path);

        return(asset);
    }
Example #13
0
    void Awake()
    {
        GetComponent <CrowdControl>().CrowdFeedbackController = this;
        if (targetObj == null)
        {
            targetObj = gameObject;
        }

        SkeletonDataAsset data = targetObj.GetComponentInChildren <SkeletonAnimation>().skeletonDataAsset;

        Material          spineMat = data.atlasAssets[0].materials[0];
        Material          newMat   = Instantiate(Instantiate(spineMat));
        AtlasAsset        newAtlas = Instantiate(data.atlasAssets[0]);
        SkeletonDataAsset newData  = Instantiate(data);

        newData.atlasAssets[0] = newAtlas;
        newAtlas.materials[0]  = newMat;
        GetComponentInChildren <SkeletonAnimation>().skeletonDataAsset = newData;
        GetComponentInChildren <SkeletonAnimation>().Initialize(true);

        mats.Add(newMat);

        foreach (Material mat in mats)
        {
            mat.SetFloat(OVERLAY_FACTOR_STRING, overlayFactor);
            mat.SetFloat(OUTLINE_FACTOR_STRING, outlineFactor);
        }
    }
Example #14
0
        void UpdateBakedList()
        {
            AtlasAsset asset = (AtlasAsset)target;

            baked        = new List <bool>();
            bakedObjects = new List <GameObject>();
            if (atlasFile.objectReferenceValue != null)
            {
                Atlas              atlas             = asset.GetAtlas();
                FieldInfo          field             = typeof(Atlas).GetField("regions", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.NonPublic);
                List <AtlasRegion> regions           = (List <AtlasRegion>)field.GetValue(atlas);
                string             atlasAssetPath    = AssetDatabase.GetAssetPath(atlasAsset);
                string             atlasAssetDirPath = Path.GetDirectoryName(atlasAssetPath);
                string             bakedDirPath      = Path.Combine(atlasAssetDirPath, atlasAsset.name);


                for (int i = 0; i < regions.Count; i++)
                {
                    AtlasRegion region          = regions[i];
                    string      bakedPrefabPath = Path.Combine(bakedDirPath, SpineEditorUtilities.GetPathSafeRegionName(region) + ".prefab").Replace("\\", "/");
                    GameObject  prefab          = (GameObject)AssetDatabase.LoadAssetAtPath(bakedPrefabPath, typeof(GameObject));
                    baked.Add(prefab != null);
                    bakedObjects.Add(prefab);
                }
            }
        }
Example #15
0
        public void GetTexture()
        {
            if (!(texture == null))
            {
                return;
            }
            SkeletonRenderer component = GetComponent <SkeletonRenderer>();

            if (component == null)
            {
                return;
            }
            SkeletonDataAsset skeletonDataAsset = component.skeletonDataAsset;

            if (skeletonDataAsset == null)
            {
                return;
            }
            AtlasAsset atlasAsset = skeletonDataAsset.atlasAssets[0];

            if (!(atlasAsset == null))
            {
                Material material = atlasAsset.materials[0];
                if (!(material == null))
                {
                    texture = (material.mainTexture as Texture2D);
                }
            }
        }
Example #16
0
    // Create SkeAnim from File
    public static SkeletonAnimation CreateSkeAnimFromFile()
    {
        AtlasAsset        atlasAsset        = SpineFileReader.IngestSpineAtlas("man_ok.atlas");
        SkeletonDataAsset skeletonDataAsset = SpineFileReader.IngestSpineProject("man_ok.json", atlasAsset);

        return(SpineFileReader.SpawnAnimatedSkeleton(skeletonDataAsset));
    }
Example #17
0
    public static void DoIt()
    {
        string dirName       = "Assets/Animation";
        string spineFileName = "hounv";
        string textureName   = dirName + "/" + spineFileName + "/" + spineFileName + ".png";
        string atlasFileName = dirName + "/" + spineFileName + "/" + spineFileName + ".atlas.txt";
        string jsonFileName  = dirName + "/" + spineFileName + "/" + spineFileName + ".json.txt";


        string atlasAssetName        = dirName + "/" + spineFileName + "/" + spineFileName + ".asset";
        string skeletonDataAssetName = dirName + "/" + spineFileName + "/" + spineFileName + "skeltonData" + ".asset";

        ///1、 创建材质,并指贴图和shader
        Shader   shader = Shader.Find("Spine/SkeletonGhost");
        Material mat    = new Material(shader);
        Texture  tex    = Resources.LoadAssetAtPath(textureName, typeof(Texture)) as Texture;

        mat.SetTexture("_MainTex", tex);
        AssetDatabase.CreateAsset(mat, dirName + "/" + spineFileName + "/" + spineFileName + ".mat");
        AssetDatabase.SaveAssets();

        ///2、 创建atlas,并指xx
        AtlasAsset m_AtlasAsset = AtlasAsset.CreateInstance <AtlasAsset>();

        AssetDatabase.CreateAsset(m_AtlasAsset, atlasAssetName);
        Selection.activeObject = m_AtlasAsset;

        TextAsset textAsset = Resources.LoadAssetAtPath(atlasFileName, typeof(TextAsset)) as TextAsset;

        m_AtlasAsset.atlasFile    = textAsset;
        m_AtlasAsset.materials    = new Material[1];
        m_AtlasAsset.materials[0] = mat;
        AssetDatabase.SaveAssets();

        ///3、 创建SkeletonDataAsset,并指相关
        SkeletonDataAsset m_skeltonDataAsset = SkeletonDataAsset.CreateInstance <SkeletonDataAsset>();

        AssetDatabase.CreateAsset(m_skeltonDataAsset, skeletonDataAssetName);
        Selection.activeObject = m_skeltonDataAsset;

        m_skeltonDataAsset.atlasAssets    = new AtlasAsset[1];
        m_skeltonDataAsset.atlasAssets[0] = m_AtlasAsset;
        TextAsset m_jsonAsset = Resources.LoadAssetAtPath(jsonFileName, typeof(TextAsset)) as TextAsset;

        m_skeltonDataAsset.skeletonJSON = m_jsonAsset;
        AssetDatabase.SaveAssets();


        /// 创建场景物件
        GameObject gameObject = new GameObject(spineFileName, typeof(SkeletonAnimation));

        EditorUtility.FocusProjectWindow();
        Selection.activeObject = gameObject;

        SkeletonAnimation m_skelAnim = gameObject.GetComponent <SkeletonAnimation>();

        m_skelAnim.skeletonDataAsset = m_skeltonDataAsset;
        //m_skelAnim.initialSkinName = "normal";
    }
Example #18
0
        IEnumerator SetUISpineDo()
        {
            yield return(new WaitForEndOfFrame());

            target.SetActive(true);
            GameObject spineObj = target;
            int        _rendQ   = mDepth;


            SkeletonAnimation spineObjSkel = spineObj.GetComponent <SkeletonAnimation>();

            if (spineObjSkel == null)
            {
                yield break;
            }

            AtlasAsset atlasAsset = ScriptableObject.CreateInstance <AtlasAsset>();

            atlasAsset.atlasFile = spineObjSkel.skeletonDataAsset.atlasAssets[0].atlasFile;

            atlasMaterial = new Material(Shader.Find("Custom/Spine/UnlitTransparent Colored/One-OneMinusAlpha"));
            if (clipping)
            {
                _UpdateClipValue(atlasMaterial);
            }
            else
            {
                atlasMaterial.SetVector("_ClipRange0", new Vector4(0.0f, 0.0f, 2000.0f, 2000.0f));
                //mat.SetVector("_ClipArgs0", Vector4.one * 10000.0f);
                atlasMaterial.SetColor("_Color", color);
            }
            //if (!isStencil)
            //{
            //    atlasMaterial = new Material(Shader.Find("Spine/Skeleton"));
            //}
            //else
            //{
            //    atlasMaterial = new Material(Shader.Find("Spine/SkeletonSpriteMaskable"));
            //}

            atlasMaterial.mainTexture
                = spineObjSkel.skeletonDataAsset.atlasAssets[0].materials[0].mainTexture;
            atlasMaterial.name        = "SpineUI_Mat";
            atlasMaterial.renderQueue = 3000 + _rendQ;

            atlasAsset.materials = new[] { atlasMaterial };


            SkeletonDataAsset skeletonDataAsset
                = Instantiate(spineObj.GetComponent <SkeletonAnimation>().skeletonDataAsset) as SkeletonDataAsset;

            skeletonDataAsset.atlasAssets[0] = atlasAsset;

            spineObjSkel.skeletonDataAsset = skeletonDataAsset;

            spineObjSkel.Initialize(true);

            skeletonAnimation.state.Complete += AnimationComplete;
        }
Example #19
0
        /// <summary>
        /// 通过TextAsset,Texture2D[],Material 获取AtlasRegion集合
        /// </summary>
        /// <returns>The equipment atlas regions.</returns>
        /// <param name="textAsset">Text asset.</param>
        /// <param name="textures">Textures.</param>
        /// <param name="material">Material.</param>

        public List <AtlasRegion> GetEquipmentAtlasRegions(EquipmentObject eo, Material material)
        {
            #if UNITY_ANDROID
            return(AtlasAsset.CreateRuntimeInstance(eo.equipmentTxtAsset, eo.equipmentTexture_Alpha, eo.equipmentTexture_RGB, material, true, true).GetAtlas(true).AtlasRegionList);
            #elif UNITY_IPHONE || UNITY_EDITOR
            return(AtlasAsset.CreateRuntimeInstance(eo.equipmentTxtAsset, new Texture2D[] { eo.equipmentTexture }, material, true).GetAtlas().AtlasRegionList);
            #endif
        }
 void OnEnable()
 {
     SpineEditorUtilities.ConfirmInitialization();
     atlasFile  = serializedObject.FindProperty("atlasFile");
     materials  = serializedObject.FindProperty("materials");
     atlasAsset = (AtlasAsset)target;
     UpdateBakedList();
 }
Example #21
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;


                    string dir        = Path.GetDirectoryName(Path.GetDirectoryName(AssetDatabase.GetAssetPath(data)));
                    string prefabPath = Path.Combine(dir, data.skeletonJSON.name + ".prefab").Replace("\\", "/");

                    if (File.Exists(prefabPath) == false)
                    {
                        SkeletonAnimation anim = SpawnAnimatedSkeleton(data);
                        PrefabUtility.CreatePrefab(prefabPath, anim.gameObject, ReplacePrefabOptions.ReplaceNameBased);
                        if (EditorApplication.isPlaying)
                        {
                            GameObject.Destroy(anim.gameObject);
                        }
                        else
                        {
                            GameObject.DestroyImmediate(anim.gameObject);
                        }
                    }
                    else
                    {
                    }
                }
            }
        }
    }
Example #22
0
    static SkeletonDataAsset AutoIngestSpineProject(TextAsset spineJson, Object atlasSource = null)
    {
        TextAsset  atlasText  = null;
        AtlasAsset atlasAsset = null;

        if (atlasSource != null)
        {
            if (atlasSource.GetType() == typeof(TextAsset))
            {
                atlasText = (TextAsset)atlasSource;
            }
            else if (atlasSource.GetType() == typeof(AtlasAsset))
            {
                atlasAsset = (AtlasAsset)atlasSource;
            }
        }

        if (atlasText == null && atlasAsset == null)
        {
            string primaryName = Path.GetFileNameWithoutExtension(spineJson.name);
            string assetPath   = Path.GetDirectoryName(AssetDatabase.GetAssetPath(spineJson));

            if (atlasText == null)
            {
                string atlasPath = assetPath + "/" + primaryName + ".atlas.txt";
                atlasText = (TextAsset)AssetDatabase.LoadAssetAtPath(atlasPath, typeof(TextAsset));

                if (atlasText == null)
                {
                    //can't find atlas, likely because using a shared atlas
                    bool abort = !EditorUtility.DisplayDialog("Atlas not Found", "Expecting " + spineJson.name + ".atlas\n" + "Press OK to select Atlas", "OK", "Abort");
                    if (abort)
                    {
                        //do nothing, let it error later
                    }
                    else
                    {
                        string path = EditorUtility.OpenFilePanel("Find Atlas source...", Path.GetDirectoryName(Application.dataPath) + "/" + assetPath, "txt");
                        if (path != "")
                        {
                            path      = path.Replace("\\", "/");
                            path      = path.Replace(Application.dataPath.Replace("\\", "/"), "Assets");
                            atlasText = (TextAsset)AssetDatabase.LoadAssetAtPath(path, typeof(TextAsset));
//							Debug.Log("Atlas Path: " + path);
                        }
                    }
                }
            }
        }

        if (atlasAsset == null)
        {
            atlasAsset = IngestSpineAtlas(atlasText);
        }

        return(IngestSpineProject(spineJson, atlasAsset));
    }
        void CreateRuntimeAssetsAndGameObject()
        {
            // 1. Create the AtlasAsset (needs atlas text asset and textures, and materials/shader);
            // 2. Create SkeletonDataAsset (needs json or binary asset file, and an AtlasAsset)
            // 3. Create SkeletonAnimation (needs a valid SkeletonDataAsset)

            runtimeAtlasAsset        = AtlasAsset.CreateRuntimeInstance(atlasText, textures, materialPropertySource, true);
            runtimeSkeletonDataAsset = SkeletonDataAsset.CreateRuntimeInstance(skeletonJson, runtimeAtlasAsset, true);
        }
		void OnEnable () {
			SpineEditorUtilities.ConfirmInitialization();
			atlasFile = serializedObject.FindProperty("atlasFile");
			materials = serializedObject.FindProperty("materials");
			materials.isExpanded = true;
			atlasAsset = (AtlasAsset)target;
			#if REGION_BAKING_MESH
			UpdateBakedList();
			#endif
		}
    override public void OnInspectorGUI()
    {
        serializedObject.Update();
        AtlasAsset asset = (AtlasAsset)target;

        EditorGUI.BeginChangeCheck();
        EditorGUILayout.PropertyField(atlasFile);
        EditorGUILayout.PropertyField(materials, true);
        if (EditorGUI.EndChangeCheck())
        {
            serializedObject.ApplyModifiedProperties();
        }

        if (materials.arraySize == 0)
        {
            EditorGUILayout.LabelField(new GUIContent("Error:  Missing materials", SpineEditorUtilities.Icons.warning));
            return;
        }

        for (int i = 0; i < materials.arraySize; i++)
        {
            SerializedProperty prop = materials.GetArrayElementAtIndex(i);
            Material           mat  = (Material)prop.objectReferenceValue;
            if (mat == null)
            {
                EditorGUILayout.LabelField(new GUIContent("Error:  Materials cannot be null", SpineEditorUtilities.Icons.warning));
                return;
            }
        }



        if (atlasFile.objectReferenceValue != null)
        {
            Atlas              atlas   = asset.GetAtlas();
            FieldInfo          field   = typeof(Atlas).GetField("regions", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.NonPublic);
            List <AtlasRegion> regions = (List <AtlasRegion>)field.GetValue(atlas);
            EditorGUILayout.LabelField("Regions");
            EditorGUI.indentLevel++;
            for (int i = 0; i < regions.Count; i++)
            {
                EditorGUILayout.LabelField(regions[i].name);
            }
            EditorGUI.indentLevel--;
        }


        if (serializedObject.ApplyModifiedProperties() ||
            (UnityEngine.Event.current.type == EventType.ValidateCommand && UnityEngine.Event.current.commandName == "UndoRedoPerformed")
            )
        {
            asset.Reset();
        }
    }
Example #26
0
 void OnEnable()
 {
     SpineEditorUtilities.ConfirmInitialization();
     atlasFile            = serializedObject.FindProperty("atlasFile");
     materials            = serializedObject.FindProperty("materials");
     materials.isExpanded = true;
     atlasAsset           = (AtlasAsset)target;
                 #if REGION_BAKING_MESH
     UpdateBakedList();
                 #endif
 }
    public static GameObject BakeRegion(AtlasAsset atlasAsset, AtlasRegion region, bool autoSave = true)
    {
        Atlas  atlas             = atlasAsset.GetAtlas();
        string atlasAssetPath    = AssetDatabase.GetAssetPath(atlasAsset);
        string atlasAssetDirPath = Path.GetDirectoryName(atlasAssetPath);
        string bakedDirPath      = Path.Combine(atlasAssetDirPath, atlasAsset.name);
        string bakedPrefabPath   = Path.Combine(bakedDirPath, GetPathSafeRegionName(region) + ".prefab").Replace("\\", "/");

        GameObject prefab = (GameObject)AssetDatabase.LoadAssetAtPath(bakedPrefabPath, typeof(GameObject));
        GameObject root;
        Mesh       mesh;
        bool       isNewPrefab = false;

        if (!Directory.Exists(bakedDirPath))
        {
            Directory.CreateDirectory(bakedDirPath);
        }

        if (prefab == null)
        {
            root        = new GameObject("temp", typeof(MeshFilter), typeof(MeshRenderer));
            prefab      = (GameObject)PrefabUtility.CreatePrefab(bakedPrefabPath, root);
            isNewPrefab = true;
            Object.DestroyImmediate(root);
        }

        mesh = (Mesh)AssetDatabase.LoadAssetAtPath(bakedPrefabPath, typeof(Mesh));

        Material mat = null;

        mesh = atlasAsset.GenerateMesh(region.name, mesh, out mat);
        if (isNewPrefab)
        {
            AssetDatabase.AddObjectToAsset(mesh, prefab);
            prefab.GetComponent <MeshFilter>().sharedMesh = mesh;
        }

        EditorUtility.SetDirty(mesh);
        EditorUtility.SetDirty(prefab);

        if (autoSave)
        {
            AssetDatabase.SaveAssets();
            AssetDatabase.Refresh();
        }


        prefab.GetComponent <MeshRenderer>().sharedMaterial = mat;

        return(prefab);
    }
Example #28
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 #29
0
    public void ChangeWeapon(AtlasAsset atlasAsset, SkeletonRenderer skeletonRenderer, string slotname, string spritename)
    {
        AtlasAttachmentLoader loader = new AtlasAttachmentLoader(atlasAsset.GetAtlas());
        float scaleMultiplier        = skeletonRenderer.skeletonDataAsset.scale;
        var   regionAttachment       = loader.NewRegionAttachment(null, slotname, spritename);

        regionAttachment.Width  = regionAttachment.RegionOriginalWidth * scaleMultiplier;
        regionAttachment.Height = regionAttachment.RegionOriginalHeight * scaleMultiplier;
        regionAttachment.SetColor(new Color(1, 1, 1, 1));
        regionAttachment.UpdateOffset();
        var slot = skeletonRenderer.skeleton.FindSlot(slotname);

        slot.Attachment = regionAttachment;
    }
Example #30
0
    override public void OnInspectorGUI()
    {
        serializedObject.Update();
        AtlasAsset asset = (AtlasAsset)target;

        EditorGUILayout.PropertyField(atlasFile);
        EditorGUILayout.PropertyField(materials, true);

        if (serializedObject.ApplyModifiedProperties() ||
            (Event.current.type == EventType.ValidateCommand && Event.current.commandName == "UndoRedoPerformed")
            )
        {
            asset.Clear();
        }
    }
Example #31
0
        void Selector(SerializedProperty property)
        {
            GenericMenu        menu       = new GenericMenu();
            AtlasAsset         atlasAsset = (AtlasAsset)atlasProp.objectReferenceValue;
            Atlas              atlas      = atlasAsset.GetAtlas();
            FieldInfo          field      = typeof(Atlas).GetField("regions", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
            List <AtlasRegion> regions    = (List <AtlasRegion>)field.GetValue(atlas);

            for (int i = 0; i < regions.Count; i++)
            {
                string name = regions[i].name;
                menu.AddItem(new GUIContent(name), name == property.stringValue, HandleSelect, new SpineDrawerValuePair(name, property));
            }

            menu.ShowAsContext();
        }
Example #32
0
        public static void GenerateAllAtlasMapping()
        {
            var files = AssetDatabase.GetAllAssetPaths().Where(p =>
                                                               p.EndsWith(".asset")
                                                               ).ToArray();

            List <int>    allSprites = new List <int>();
            List <string> atlasNames = new List <string>();

            for (int i = 0; i < files.Length; i++)
            {
                var o  = AssetDatabase.LoadAssetAtPath <AtlasAsset>(files[i]);
                var ti = AssetImporter.GetAtPath(files[i]);
                if (o != null)
                {
                    var assetBundleName = ti.assetBundleName;
                    EditorUtility.DisplayProgressBar("Processing...", "生成中... (" + i + " / " + files.Length + ")", (float)i / (float)files.Length);
                    for (int j = 0; j < o.names.Count; j++)
                    {
                        allSprites.Add(o.names[j]);
                        atlasNames.Add(assetBundleName);
                    }
                }
            }

            EditorUtility.ClearProgressBar();

            string atlas_path = Path.Combine(AtlasConfig.ATLAS_MAPPING_ROOT, AtlasManager.ATLAS_MAPPING_ROOT_NAME + ".asset");
            //生成或者替换资源
            AssetBundleMappingAsset atlas = AssetDatabase.LoadAssetAtPath <AssetBundleMappingAsset>(atlas_path);

            if (atlas == null)
            {
                atlas = AtlasAsset.CreateInstance <AssetBundleMappingAsset>();
                AssetDatabase.CreateAsset(atlas, atlas_path);
            }

            atlas.assetNames = allSprites.ToArray();
            atlas.abNames    = atlasNames.ToArray();
            EditorUtility.SetDirty(atlas);
            var import = AssetImporter.GetAtPath(atlas_path);

            import.assetBundleName = AtlasManager.ATLAS_MAPPING_ROOT_NAME + Common.CHECK_ASSETBUNDLE_SUFFIX;
            AssetDatabase.SaveAssets();
            Debug.LogFormat(" save {0}  count = {1} ", atlas_path, atlasNames.Count);
        }
		override public void OnInspectorGUI () {
			if (serializedObject.isEditingMultipleObjects) {
				DrawDefaultInspector();
				return;
			}

			serializedObject.Update();
			atlasAsset = atlasAsset ?? (AtlasAsset)target;
			EditorGUI.BeginChangeCheck();
			EditorGUILayout.PropertyField(atlasFile);
			EditorGUILayout.PropertyField(materials, true);
			if (EditorGUI.EndChangeCheck()) {
				serializedObject.ApplyModifiedProperties();
				atlasAsset.Clear();
				atlasAsset.GetAtlas();
			}

			if (materials.arraySize == 0) {
				EditorGUILayout.LabelField(new GUIContent("Error:  Missing materials", SpineEditorUtilities.Icons.warning));
				return;
			}

			for (int i = 0; i < materials.arraySize; i++) {
				SerializedProperty prop = materials.GetArrayElementAtIndex(i);
				Material mat = (Material)prop.objectReferenceValue;
				if (mat == null) {
					EditorGUILayout.LabelField(new GUIContent("Error:  Materials cannot be null", SpineEditorUtilities.Icons.warning));
					return;
				}
			}

			EditorGUILayout.Space();
			if (atlasFile.objectReferenceValue != null) {
				if (SpineInspectorUtility.LargeCenteredButton(SpriteSlicesLabel)) {
					var atlas = atlasAsset.GetAtlas();
					foreach (var m in atlasAsset.materials)
						UpdateSpriteSlices(m.mainTexture, atlas);
				}
			}

			#if REGION_BAKING_MESH
			if (atlasFile.objectReferenceValue != null) {
				Atlas atlas = asset.GetAtlas();
				FieldInfo field = typeof(Atlas).GetField("regions", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.NonPublic);
				List<AtlasRegion> regions = (List<AtlasRegion>)field.GetValue(atlas);
				EditorGUILayout.LabelField(new GUIContent("Region Baking", SpineEditorUtilities.Icons.unityIcon));
				EditorGUI.indentLevel++;
				AtlasPage lastPage = null;
				for (int i = 0; i < regions.Count; i++) {
					if (lastPage != regions[i].page) {
						if (lastPage != null) {
							EditorGUILayout.Separator();
							EditorGUILayout.Separator();
						}
						lastPage = regions[i].page;
						Material mat = ((Material)lastPage.rendererObject);
						if (mat != null) {
							GUILayout.BeginHorizontal();
							{
								EditorGUI.BeginDisabledGroup(true);
								EditorGUILayout.ObjectField(mat, typeof(Material), false, GUILayout.Width(250));
								EditorGUI.EndDisabledGroup();
							}
							GUILayout.EndHorizontal();

						} else {
							EditorGUILayout.LabelField(new GUIContent("Page missing material!", SpineEditorUtilities.Icons.warning));
						}
					}
					GUILayout.BeginHorizontal();
					{
						//EditorGUILayout.ToggleLeft(baked[i] ? "" : regions[i].name, baked[i]);
						bool result = baked[i] ? EditorGUILayout.ToggleLeft("", baked[i], GUILayout.Width(24)) : EditorGUILayout.ToggleLeft("    " + regions[i].name, baked[i]);
						if(baked[i]){
							EditorGUILayout.ObjectField(bakedObjects[i], typeof(GameObject), false, GUILayout.Width(250));
						}
						if (result && !baked[i]) {
							//bake
							baked[i] = true;
							bakedObjects[i] = SpineEditorUtilities.BakeRegion(atlasAsset, regions[i]);
							EditorGUIUtility.PingObject(bakedObjects[i]);
						} else if (!result && baked[i]) {
							//unbake
							bool unbakeResult = EditorUtility.DisplayDialog("Delete Baked Region", "Do you want to delete the prefab for " + regions[i].name, "Yes", "Cancel");
							switch (unbakeResult) {
							case true:
								//delete
								string atlasAssetPath = AssetDatabase.GetAssetPath(atlasAsset);
								string atlasAssetDirPath = Path.GetDirectoryName(atlasAssetPath);
								string bakedDirPath = Path.Combine(atlasAssetDirPath, atlasAsset.name);
								string bakedPrefabPath = Path.Combine(bakedDirPath, SpineEditorUtilities.GetPathSafeRegionName(regions[i]) + ".prefab").Replace("\\", "/");
								AssetDatabase.DeleteAsset(bakedPrefabPath);
								baked[i] = false;
								break;
							case false:
								//do nothing
								break;
							}
						}
					}
					GUILayout.EndHorizontal();
				}
				EditorGUI.indentLevel--;

				#if BAKE_ALL_BUTTON
				// Check state
				bool allBaked = true;
				bool allUnbaked = true;
				for (int i = 0; i < regions.Count; i++) {
					allBaked &= baked[i];
					allUnbaked &= !baked[i];
				}

				if (!allBaked && GUILayout.Button("Bake All")) {
					for (int i = 0; i < regions.Count; i++) {
						if (!baked[i]) {
							baked[i] = true;
							bakedObjects[i] = SpineEditorUtilities.BakeRegion(atlasAsset, regions[i]);
						}
					}

				} else if (!allUnbaked && GUILayout.Button("Unbake All")) {
					bool unbakeResult = EditorUtility.DisplayDialog("Delete All Baked Regions", "Are you sure you want to unbake all region prefabs? This cannot be undone.", "Yes", "Cancel");
					switch (unbakeResult) {
					case true:
						//delete
						for (int i = 0; i < regions.Count; i++) {
							if (baked[i]) {
								string atlasAssetPath = AssetDatabase.GetAssetPath(atlasAsset);
								string atlasAssetDirPath = Path.GetDirectoryName(atlasAssetPath);
								string bakedDirPath = Path.Combine(atlasAssetDirPath, atlasAsset.name);
								string bakedPrefabPath = Path.Combine(bakedDirPath, SpineEditorUtilities.GetPathSafeRegionName(regions[i]) + ".prefab").Replace("\\", "/");
								AssetDatabase.DeleteAsset(bakedPrefabPath);
								baked[i] = false;
							}
						}
						break;
					case false:
						//do nothing
						break;
					}

				}
				#endif
				
			}
			#else
			if (atlasFile.objectReferenceValue != null) {
				EditorGUILayout.LabelField("Atlas Regions", EditorStyles.boldLabel);
				int baseIndent = EditorGUI.indentLevel;

				var regions = AtlasAssetInspector.GetRegions(atlasAsset.GetAtlas());
				AtlasPage lastPage = null;
				for (int i = 0; i < regions.Count; i++) {
					if (lastPage != regions[i].page) {
						if (lastPage != null) {
							EditorGUILayout.Separator();
							EditorGUILayout.Separator();
						}
						lastPage = regions[i].page;
						Material mat = ((Material)lastPage.rendererObject);
						if (mat != null) {
							EditorGUI.indentLevel = baseIndent;
							using (new GUILayout.HorizontalScope())
							using (new EditorGUI.DisabledGroupScope(true))
								EditorGUILayout.ObjectField(mat, typeof(Material), false, GUILayout.Width(250));
							EditorGUI.indentLevel = baseIndent + 1;
						} else {
							EditorGUILayout.HelpBox("Page missing material!", MessageType.Warning);
						}
					}

					EditorGUILayout.LabelField(new GUIContent(regions[i].name, SpineEditorUtilities.Icons.image));
				}
				EditorGUI.indentLevel = baseIndent;
			}
			#endif

			if (serializedObject.ApplyModifiedProperties() || SpineInspectorUtility.UndoRedoPerformed(Event.current))
				atlasAsset.Clear();
		}
Example #34
0
 public MaterialsTextureLoader(AtlasAsset atlasAsset)
 {
     this.atlasAsset = atlasAsset;
 }
Example #35
0
	public static GameObject BakeRegion (AtlasAsset atlasAsset, AtlasRegion region, bool autoSave = true) {
		Atlas atlas = atlasAsset.GetAtlas();
		string atlasAssetPath = AssetDatabase.GetAssetPath(atlasAsset);
		string atlasAssetDirPath = Path.GetDirectoryName(atlasAssetPath);
		string bakedDirPath = Path.Combine(atlasAssetDirPath, atlasAsset.name);
		string bakedPrefabPath = Path.Combine(bakedDirPath, GetPathSafeRegionName(region) + ".prefab").Replace("\\", "/");

		GameObject prefab = (GameObject)AssetDatabase.LoadAssetAtPath(bakedPrefabPath, typeof(GameObject));
		GameObject root;
		Mesh mesh;
		bool isNewPrefab = false;

		if (!Directory.Exists(bakedDirPath))
			Directory.CreateDirectory(bakedDirPath);

		if (prefab == null) {
			root = new GameObject("temp", typeof(MeshFilter), typeof(MeshRenderer));
			prefab = (GameObject)PrefabUtility.CreatePrefab(bakedPrefabPath, root);
			isNewPrefab = true;
			Object.DestroyImmediate(root);
		}

		mesh = (Mesh)AssetDatabase.LoadAssetAtPath(bakedPrefabPath, typeof(Mesh));

		Material mat = null;
		mesh = atlasAsset.GenerateMesh(region.name, mesh, out mat);
		if (isNewPrefab) {
			AssetDatabase.AddObjectToAsset(mesh, prefab);
			prefab.GetComponent<MeshFilter>().sharedMesh = mesh;
		}

		EditorUtility.SetDirty(mesh);
		EditorUtility.SetDirty(prefab);

		if (autoSave) {
			AssetDatabase.SaveAssets();
			AssetDatabase.Refresh();
		}


		prefab.GetComponent<MeshRenderer>().sharedMaterial = mat;

		return prefab;
	}
		override public void OnInspectorGUI () {
			serializedObject.Update();
			atlasAsset = atlasAsset ?? (AtlasAsset)target;
			EditorGUI.BeginChangeCheck();
			EditorGUILayout.PropertyField(atlasFile);

			EditorGUILayout.PropertyField(materials, true);
			if (EditorGUI.EndChangeCheck())
				serializedObject.ApplyModifiedProperties();

			if (materials.arraySize == 0) {
				EditorGUILayout.LabelField(new GUIContent("Error:  Missing materials", SpineEditorUtilities.Icons.warning));
				return;
			}

			for (int i = 0; i < materials.arraySize; i++) {
				SerializedProperty prop = materials.GetArrayElementAtIndex(i);
				Material mat = (Material)prop.objectReferenceValue;
				if (mat == null) {
					EditorGUILayout.LabelField(new GUIContent("Error:  Materials cannot be null", SpineEditorUtilities.Icons.warning));
					return;
				}
			}

			if (atlasFile.objectReferenceValue != null) {
				if (GUILayout.Button(
					new GUIContent(
						"Apply Regions as Texture Sprite Slices",
						"Adds Sprite slices to atlas texture(s). " +
						"Updates existing slices if ones with matching names exist. \n\n" +
						"If your atlas was exported with Premultiply Alpha, " +
						"your SpriteRenderer should use the generated Spine _Material asset (or any Material with a PMA shader) instead of Sprites-Default.")
					, GUILayout.Height(70f))) {
					var atlas = atlasAsset.GetAtlas();
					foreach (var m in atlasAsset.materials)
						UpdateSpriteSlices(m.mainTexture, atlas);
				}
			}

			#if REGION_BAKING_MESH
			if (atlasFile.objectReferenceValue != null) {
				Atlas atlas = asset.GetAtlas();
				FieldInfo field = typeof(Atlas).GetField("regions", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.NonPublic);
				List<AtlasRegion> regions = (List<AtlasRegion>)field.GetValue(atlas);
				EditorGUILayout.LabelField(new GUIContent("Region Baking", SpineEditorUtilities.Icons.unityIcon));
				EditorGUI.indentLevel++;
				AtlasPage lastPage = null;
				for (int i = 0; i < regions.Count; i++) {
					if (lastPage != regions[i].page) {
						if (lastPage != null) {
							EditorGUILayout.Separator();
							EditorGUILayout.Separator();
						}
						lastPage = regions[i].page;
						Material mat = ((Material)lastPage.rendererObject);
						if (mat != null) {
							GUILayout.BeginHorizontal();
							{
								EditorGUI.BeginDisabledGroup(true);
								EditorGUILayout.ObjectField(mat, typeof(Material), false, GUILayout.Width(250));
								EditorGUI.EndDisabledGroup();
							}
							GUILayout.EndHorizontal();

						} else {
							EditorGUILayout.LabelField(new GUIContent("Page missing material!", SpineEditorUtilities.Icons.warning));
						}
					}
					GUILayout.BeginHorizontal();
					{
						//EditorGUILayout.ToggleLeft(baked[i] ? "" : regions[i].name, baked[i]);
						bool result = baked[i] ? EditorGUILayout.ToggleLeft("", baked[i], GUILayout.Width(24)) : EditorGUILayout.ToggleLeft("    " + regions[i].name, baked[i]);
						if(baked[i]){
							EditorGUILayout.ObjectField(bakedObjects[i], typeof(GameObject), false, GUILayout.Width(250));
						}
						if (result && !baked[i]) {
							//bake
							baked[i] = true;
							bakedObjects[i] = SpineEditorUtilities.BakeRegion(atlasAsset, regions[i]);
							EditorGUIUtility.PingObject(bakedObjects[i]);
						} else if (!result && baked[i]) {
							//unbake
							bool unbakeResult = EditorUtility.DisplayDialog("Delete Baked Region", "Do you want to delete the prefab for " + regions[i].name, "Yes", "Cancel");
							switch (unbakeResult) {
							case true:
								//delete
								string atlasAssetPath = AssetDatabase.GetAssetPath(atlasAsset);
								string atlasAssetDirPath = Path.GetDirectoryName(atlasAssetPath);
								string bakedDirPath = Path.Combine(atlasAssetDirPath, atlasAsset.name);
								string bakedPrefabPath = Path.Combine(bakedDirPath, SpineEditorUtilities.GetPathSafeRegionName(regions[i]) + ".prefab").Replace("\\", "/");
								AssetDatabase.DeleteAsset(bakedPrefabPath);
								baked[i] = false;
								break;
							case false:
								//do nothing
								break;
							}
						}
					}
					GUILayout.EndHorizontal();
				}
				EditorGUI.indentLevel--;

				#if BAKE_ALL_BUTTON
				// Check state
				bool allBaked = true;
				bool allUnbaked = true;
				for (int i = 0; i < regions.Count; i++) {
					allBaked &= baked[i];
					allUnbaked &= !baked[i];
				}

				if (!allBaked && GUILayout.Button("Bake All")) {
					for (int i = 0; i < regions.Count; i++) {
						if (!baked[i]) {
							baked[i] = true;
							bakedObjects[i] = SpineEditorUtilities.BakeRegion(atlasAsset, regions[i]);
						}
					}

				} else if (!allUnbaked && GUILayout.Button("Unbake All")) {
					bool unbakeResult = EditorUtility.DisplayDialog("Delete All Baked Regions", "Are you sure you want to unbake all region prefabs? This cannot be undone.", "Yes", "Cancel");
					switch (unbakeResult) {
					case true:
						//delete
						for (int i = 0; i < regions.Count; i++) {
							if (baked[i]) {
								string atlasAssetPath = AssetDatabase.GetAssetPath(atlasAsset);
								string atlasAssetDirPath = Path.GetDirectoryName(atlasAssetPath);
								string bakedDirPath = Path.Combine(atlasAssetDirPath, atlasAsset.name);
								string bakedPrefabPath = Path.Combine(bakedDirPath, SpineEditorUtilities.GetPathSafeRegionName(regions[i]) + ".prefab").Replace("\\", "/");
								AssetDatabase.DeleteAsset(bakedPrefabPath);
								baked[i] = false;
							}
						}
						break;
					case false:
						//do nothing
						break;
					}

				}
				#endif
				
			}
			#endif

			if (serializedObject.ApplyModifiedProperties() ||
				(UnityEngine.Event.current.type == EventType.ValidateCommand && UnityEngine.Event.current.commandName == "UndoRedoPerformed")
			) {
				atlasAsset.Reset();
			}
		}
	static SkeletonDataAsset IngestSpineProject(TextAsset spineJson, AtlasAsset atlasAsset = null){

		string primaryName = Path.GetFileNameWithoutExtension(spineJson.name);
		string assetPath = Path.GetDirectoryName( AssetDatabase.GetAssetPath(spineJson));
		string filePath = assetPath + "/" + primaryName + "_SkeletonData.asset";

		if(spineJson != null && atlasAsset != null){

			SkeletonDataAsset skelDataAsset = (SkeletonDataAsset)AssetDatabase.LoadAssetAtPath(filePath, typeof(SkeletonDataAsset));
			if(skelDataAsset == null){
				skelDataAsset = SkeletonDataAsset.CreateInstance<SkeletonDataAsset>();
				skelDataAsset.atlasAsset = atlasAsset;
				skelDataAsset.skeletonJSON = spineJson;
				skelDataAsset.fromAnimation = new string[0];
				skelDataAsset.toAnimation = new string[0];
				skelDataAsset.duration = new float[0];
				skelDataAsset.defaultMix = defaultMix;
				skelDataAsset.scale = defaultScale;
				
				AssetDatabase.CreateAsset(skelDataAsset, filePath);
				AssetDatabase.SaveAssets();
			}

			return skelDataAsset;
		}
		else{
			EditorUtility.DisplayDialog("Error!", "Must specify both Spine JSON and Atlas TextAsset", "OK");
			return null;
		}
	}