[unity] Rearrange SpineEditorUtilities classes.

This commit is contained in:
pharan 2018-07-12 18:08:05 +08:00
parent d336712ccc
commit 6187e2b89e
3 changed files with 609 additions and 598 deletions

View File

@ -80,7 +80,7 @@ namespace Spine.Unity.Editor {
}
string dataPath = AssetDatabase.GetAssetPath(skeletonDataAsset);
string controllerPath = dataPath.Replace(SpineEditorUtilities.SkeletonDataSuffix, "_Controller").Replace(".asset", ".controller");
string controllerPath = dataPath.Replace(SpineEditorUtilities.AssetUtility.SkeletonDataSuffix, "_Controller").Replace(".asset", ".controller");
UnityEditor.Animations.AnimatorController controller;
if (skeletonDataAsset.controller != null) {
controller = (UnityEditor.Animations.AnimatorController)skeletonDataAsset.controller;
@ -1406,6 +1406,53 @@ namespace Spine.Unity.Editor {
#endregion
#endregion
#region Region Baking
public static GameObject BakeRegion (SpineAtlasAsset atlasAsset, AtlasRegion region, bool autoSave = true) {
atlasAsset.GetAtlas(); // Initializes atlasAsset.
string atlasAssetPath = AssetDatabase.GetAssetPath(atlasAsset);
string atlasAssetDirPath = Path.GetDirectoryName(atlasAssetPath);
string bakedDirPath = Path.Combine(atlasAssetDirPath, atlasAsset.name);
string bakedPrefabPath = Path.Combine(bakedDirPath, SpineEditorUtilities.GetPathSafeName(region.name) + ".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 = 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;
}
#endregion
static string GetPath (BoneData b) {
return GetPathRecurse(b).Substring(1);
}

View File

@ -28,7 +28,7 @@
* POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
#define SPINE_SKELETON_ANIMATOR
#define SPINE_SKELETON_MECANIM
using System;
using System.Reflection;
@ -55,7 +55,7 @@ namespace Spine.Unity.Editor {
SerializedProperty spriteCollection;
#endif
#if SPINE_SKELETON_ANIMATOR
#if SPINE_SKELETON_MECANIM
static bool isMecanimExpanded = false;
SerializedProperty controller;
#endif
@ -100,7 +100,7 @@ namespace Spine.Unity.Editor {
duration = serializedObject.FindProperty("duration");
defaultMix = serializedObject.FindProperty("defaultMix");
#if SPINE_SKELETON_ANIMATOR
#if SPINE_SKELETON_MECANIM
controller = serializedObject.FindProperty("controller");
#endif
@ -494,7 +494,7 @@ namespace Spine.Unity.Editor {
}
void DrawUnityTools () {
#if SPINE_SKELETON_ANIMATOR
#if SPINE_SKELETON_MECANIM
using (new SpineInspectorUtility.BoxScope()) {
isMecanimExpanded = EditorGUILayout.Foldout(isMecanimExpanded, SpineInspectorUtility.TempContent("SkeletonAnimator", SpineInspectorUtility.UnityIcon<SceneAsset>()));
if (isMecanimExpanded) {
@ -569,7 +569,7 @@ namespace Spine.Unity.Editor {
} else {
List<string> missingPaths = null;
if (atlasAssets.arraySize > 0) {
missingPaths = SpineEditorUtilities.GetRequiredAtlasRegions(AssetDatabase.GetAssetPath(skeletonJSON.objectReferenceValue));
missingPaths = SpineEditorUtilities.AssetUtility.GetRequiredAtlasRegions(AssetDatabase.GetAssetPath(skeletonJSON.objectReferenceValue));
foreach (var atlas in atlasList) {
for (int i = 0; i < missingPaths.Count; i++) {
@ -587,8 +587,8 @@ namespace Spine.Unity.Editor {
}
if (missingPaths != null) {
foreach (string str in missingPaths)
warnings.Add("Missing Region: '" + str + "'");
foreach (string missingRegion in missingPaths)
warnings.Add(string.Format("Missing Region: '{0}'", missingRegion));
}
}
@ -599,7 +599,7 @@ namespace Spine.Unity.Editor {
}
void DoReimport () {
SpineEditorUtilities.ImportSpineContent(new [] { AssetDatabase.GetAssetPath(skeletonJSON.objectReferenceValue) }, true);
SpineEditorUtilities.AssetUtility.ImportSpineContent(new [] { AssetDatabase.GetAssetPath(skeletonJSON.objectReferenceValue) }, true);
preview.Clear();
InitializeEditor();
EditorUtility.SetDirty(targetSkeletonDataAsset);

View File

@ -622,10 +622,133 @@ namespace Spine.Unity.Editor {
if (AssetDatabaseAvailabilityDetector.IsAssetDatabaseAvailable()) {
string[] combinedAssets = assetsImportedInWrongState.ToArray();
assetsImportedInWrongState.Clear();
ImportSpineContent(combinedAssets);
AssetUtility.ImportSpineContent(combinedAssets);
}
}
#endregion
public static class AssetUtility {
#region Match SkeletonData with Atlases
static readonly AttachmentType[] AtlasTypes = { AttachmentType.Region, AttachmentType.Linkedmesh, AttachmentType.Mesh };
static void AddRequiredAtlasRegionsFromBinary (string skeletonDataPath, List<string> requiredPaths) {
SkeletonBinary binary = new SkeletonBinary(new AtlasRequirementLoader(requiredPaths));
TextAsset data = (TextAsset)AssetDatabase.LoadAssetAtPath(skeletonDataPath, typeof(TextAsset));
MemoryStream input = new MemoryStream(data.bytes);
binary.ReadSkeletonData(input);
binary = null;
}
public static List<string> GetRequiredAtlasRegions (string skeletonDataPath) {
List<string> requiredPaths = new List<string>();
if (skeletonDataPath.Contains(".skel")) {
AddRequiredAtlasRegionsFromBinary(skeletonDataPath, requiredPaths);
return requiredPaths;
}
TextAsset spineJson = (TextAsset)AssetDatabase.LoadAssetAtPath(skeletonDataPath, typeof(TextAsset));
StringReader reader = new StringReader(spineJson.text);
var root = Json.Deserialize(reader) as Dictionary<string, object>;
if (!root.ContainsKey("skins"))
return requiredPaths;
foreach (var skin in (Dictionary<string, object>)root["skins"]) {
foreach (var slot in (Dictionary<string, object>)skin.Value) {
foreach (var attachment in ((Dictionary<string, object>)slot.Value)) {
var data = ((Dictionary<string, object>)attachment.Value);
// Ignore non-atlas-requiring types.
if (data.ContainsKey("type")) {
AttachmentType attachmentType;
string typeString = (string)data["type"];
try {
attachmentType = (AttachmentType)System.Enum.Parse(typeof(AttachmentType), typeString, true);
} catch (System.ArgumentException e) {
// For more info, visit: http://esotericsoftware.com/forum/Spine-editor-and-runtime-version-management-6534
Debug.LogWarning(string.Format("Unidentified Attachment type: \"{0}\". Skeleton may have been exported from an incompatible Spine version.", typeString));
throw e;
}
if (!AtlasTypes.Contains(attachmentType))
continue;
}
if (data.ContainsKey("path"))
requiredPaths.Add((string)data["path"]);
else if (data.ContainsKey("name"))
requiredPaths.Add((string)data["name"]);
//else
// requiredPaths.Add(attachmentEntry.Key);
}
}
}
return requiredPaths;
}
static AtlasAssetBase GetMatchingAtlas (List<string> requiredPaths, List<AtlasAssetBase> atlasAssets) {
AtlasAssetBase atlasAssetMatch = null;
foreach (AtlasAssetBase 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;
}
public class AtlasRequirementLoader : AttachmentLoader {
List<string> requirementList;
public AtlasRequirementLoader (List<string> requirementList) {
this.requirementList = requirementList;
}
public RegionAttachment NewRegionAttachment (Skin skin, string name, string path) {
requirementList.Add(path);
return new RegionAttachment(name);
}
public MeshAttachment NewMeshAttachment (Skin skin, string name, string path) {
requirementList.Add(path);
return new MeshAttachment(name);
}
public BoundingBoxAttachment NewBoundingBoxAttachment (Skin skin, string name) {
return new BoundingBoxAttachment(name);
}
public PathAttachment NewPathAttachment (Skin skin, string name) {
return new PathAttachment(name);
}
public PointAttachment NewPointAttachment (Skin skin, string name) {
return new PointAttachment(name);
}
public ClippingAttachment NewClippingAttachment (Skin skin, string name) {
return new ClippingAttachment(name);
}
}
#endregion
public static void ImportSpineContent (string[] imported, bool reimport = false) {
var atlasPaths = new List<string>();
var imagePaths = new List<string>();
@ -696,7 +819,7 @@ namespace Spine.Unity.Editor {
switch (result) {
case -1:
//Debug.Log("Select Atlas");
AtlasAssetBase selectedAtlas = GetAtlasDialog(Path.GetDirectoryName(sp));
AtlasAssetBase selectedAtlas = AssetEditorGUI.GetAtlasDialog(Path.GetDirectoryName(sp));
if (selectedAtlas != null) {
localAtlases.Clear();
localAtlases.Add(selectedAtlas);
@ -708,7 +831,7 @@ namespace Spine.Unity.Editor {
}
break;
case 0: // Choose AtlasAssets...
var atlasList = MultiAtlasDialog(requiredPaths, Path.GetDirectoryName(sp), Path.GetFileNameWithoutExtension(sp));
var atlasList = AssetEditorGUI.MultiAtlasDialog(requiredPaths, Path.GetDirectoryName(sp), Path.GetFileNameWithoutExtension(sp));
if (atlasList != null)
IngestSpineProject(AssetDatabase.LoadAssetAtPath(sp, typeof(TextAsset)) as TextAsset, atlasList.ToArray());
@ -787,220 +910,6 @@ namespace Spine.Unity.Editor {
}
}
}
#endregion
#region Match SkeletonData with Atlases
static readonly AttachmentType[] AtlasTypes = { AttachmentType.Region, AttachmentType.Linkedmesh, AttachmentType.Mesh };
static List<AtlasAssetBase> MultiAtlasDialog (List<string> requiredPaths, string initialDirectory, string filename = "") {
List<AtlasAssetBase> atlasAssets = new List<AtlasAssetBase>();
bool resolved = false;
string lastAtlasPath = initialDirectory;
while (!resolved) {
// Build dialog box message.
var missingRegions = new List<string>(requiredPaths);
var dialogText = new StringBuilder();
{
dialogText.AppendLine(string.Format("SkeletonDataAsset for \"{0}\"", filename));
dialogText.AppendLine("has missing regions.");
dialogText.AppendLine();
dialogText.AppendLine("Current Atlases:");
if (atlasAssets.Count == 0)
dialogText.AppendLine("\t--none--");
for (int i = 0; i < atlasAssets.Count; i++)
dialogText.AppendLine("\t" + atlasAssets[i].name);
dialogText.AppendLine();
dialogText.AppendLine("Missing Regions:");
foreach (var atlasAsset in atlasAssets) {
var atlas = atlasAsset.GetAtlas();
for (int i = 0; i < missingRegions.Count; i++) {
if (atlas.FindRegion(missingRegions[i]) != null) {
missingRegions.RemoveAt(i);
i--;
}
}
}
int n = missingRegions.Count;
if (n == 0) break;
const int MaxListLength = 15;
for (int i = 0; (i < n && i < MaxListLength); i++)
dialogText.AppendLine("\t" + missingRegions[i]);
if (n > MaxListLength) dialogText.AppendLine(string.Format("\t... {0} more...", n - MaxListLength));
}
// Show dialog box.
int result = EditorUtility.DisplayDialogComplex(
"SkeletonDataAsset has missing Atlas.",
dialogText.ToString(),
"Browse...", "Import anyway", "Cancel"
);
switch (result) {
case 0: // Browse...
AtlasAssetBase selectedAtlasAsset = GetAtlasDialog(lastAtlasPath);
if (selectedAtlasAsset != null) {
var atlas = selectedAtlasAsset.GetAtlas();
bool hasValidRegion = false;
foreach (string str in missingRegions) {
if (atlas.FindRegion(str) != null) {
hasValidRegion = true;
break;
}
}
atlasAssets.Add(selectedAtlasAsset);
}
break;
case 1: // Import anyway
resolved = true;
break;
case 2: // Cancel
atlasAssets = null;
resolved = true;
break;
}
}
return atlasAssets;
}
static AtlasAssetBase GetAtlasDialog (string dirPath) {
string path = EditorUtility.OpenFilePanel("Select AtlasAsset...", dirPath, "asset");
if (path == "") return null; // Canceled or closed by user.
int subLen = Application.dataPath.Length - 6;
string assetRelativePath = path.Substring(subLen, path.Length - subLen).Replace("\\", "/");
Object obj = AssetDatabase.LoadAssetAtPath(assetRelativePath, typeof(AtlasAssetBase));
if (obj == null || obj.GetType() != typeof(AtlasAssetBase))
return null;
return (AtlasAssetBase)obj;
}
static void AddRequiredAtlasRegionsFromBinary (string skeletonDataPath, List<string> requiredPaths) {
SkeletonBinary binary = new SkeletonBinary(new AtlasRequirementLoader(requiredPaths));
TextAsset data = (TextAsset)AssetDatabase.LoadAssetAtPath(skeletonDataPath, typeof(TextAsset));
MemoryStream input = new MemoryStream(data.bytes);
binary.ReadSkeletonData(input);
binary = null;
}
public static List<string> GetRequiredAtlasRegions (string skeletonDataPath) {
List<string> requiredPaths = new List<string>();
if (skeletonDataPath.Contains(".skel")) {
AddRequiredAtlasRegionsFromBinary(skeletonDataPath, requiredPaths);
return requiredPaths;
}
TextAsset spineJson = (TextAsset)AssetDatabase.LoadAssetAtPath(skeletonDataPath, typeof(TextAsset));
StringReader reader = new StringReader(spineJson.text);
var root = Json.Deserialize(reader) as Dictionary<string, object>;
if (!root.ContainsKey("skins"))
return requiredPaths;
foreach (KeyValuePair<string, object> entry in (Dictionary<string, object>)root["skins"]) {
foreach (KeyValuePair<string, object> slotEntry in (Dictionary<string, object>)entry.Value) {
foreach (KeyValuePair<string, object> attachmentEntry in ((Dictionary<string, object>)slotEntry.Value)) {
var data = ((Dictionary<string, object>)attachmentEntry.Value);
// Ignore non-atlas-requiring types.
if (data.ContainsKey("type")) {
AttachmentType attachmentType;
string typeString = (string)data["type"];
try {
attachmentType = (AttachmentType)System.Enum.Parse(typeof(AttachmentType), typeString, true);
} catch (System.ArgumentException e) {
// For more info, visit: http://esotericsoftware.com/forum/Spine-editor-and-runtime-version-management-6534
Debug.LogWarning(string.Format("Unidentified Attachment type: \"{0}\". Skeleton may have been exported from an incompatible Spine version.", typeString));
throw e;
}
if (!AtlasTypes.Contains(attachmentType))
continue;
}
if (data.ContainsKey("path"))
requiredPaths.Add((string)data["path"]);
else if (data.ContainsKey("name"))
requiredPaths.Add((string)data["name"]);
else
requiredPaths.Add(attachmentEntry.Key);
}
}
}
return requiredPaths;
}
static AtlasAssetBase GetMatchingAtlas (List<string> requiredPaths, List<AtlasAssetBase> atlasAssets) {
AtlasAssetBase atlasAssetMatch = null;
foreach (AtlasAssetBase 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;
}
public class AtlasRequirementLoader : AttachmentLoader {
List<string> requirementList;
public AtlasRequirementLoader (List<string> requirementList) {
this.requirementList = requirementList;
}
public RegionAttachment NewRegionAttachment (Skin skin, string name, string path) {
requirementList.Add(path);
return new RegionAttachment(name);
}
public MeshAttachment NewMeshAttachment (Skin skin, string name, string path) {
requirementList.Add(path);
return new MeshAttachment(name);
}
public BoundingBoxAttachment NewBoundingBoxAttachment (Skin skin, string name) {
return new BoundingBoxAttachment(name);
}
public PathAttachment NewPathAttachment (Skin skin, string name) {
return new PathAttachment(name);
}
public PointAttachment NewPointAttachment (Skin skin, string name) {
return new PointAttachment(name);
}
public ClippingAttachment NewClippingAttachment (Skin skin, string name) {
return new ClippingAttachment(name);
}
}
#endregion
#region Import Atlases
static List<AtlasAssetBase> FindAtlasesAtPath (string path) {
@ -1135,7 +1044,7 @@ namespace Spine.Unity.Editor {
string bakedPrefabPath = Path.Combine(bakedDirPath, SpineEditorUtilities.GetPathSafeName(region.name) + ".prefab").Replace("\\", "/");
GameObject prefab = (GameObject)AssetDatabase.LoadAssetAtPath(bakedPrefabPath, typeof(GameObject));
if (prefab != null) {
BakeRegion(atlasAsset, region, false);
SkeletonBaker.BakeRegion(atlasAsset, region, false);
hasBakedRegions = true;
}
}
@ -1150,52 +1059,6 @@ namespace Spine.Unity.Editor {
}
#endregion
#region Bake Atlas Region
public static GameObject BakeRegion (SpineAtlasAsset 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, GetPathSafeName(region.name) + ".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 = 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;
}
#endregion
#region Import SkeletonData (json or binary)
public const string SkeletonDataSuffix = "_SkeletonData";
static SkeletonDataAsset IngestSpineProject (TextAsset spineJson, params AtlasAssetBase[] atlasAssets) {
@ -1232,7 +1095,8 @@ namespace Spine.Unity.Editor {
if (spineJson != null && atlasAssets != null) {
SkeletonDataAsset skeletonDataAsset = (SkeletonDataAsset)AssetDatabase.LoadAssetAtPath(filePath, typeof(SkeletonDataAsset));
if (skeletonDataAsset == null) {
skeletonDataAsset = ScriptableObject.CreateInstance<SkeletonDataAsset>(); {
skeletonDataAsset = ScriptableObject.CreateInstance<SkeletonDataAsset>();
{
skeletonDataAsset.atlasAssets = atlasAssets;
skeletonDataAsset.skeletonJSON = spineJson;
skeletonDataAsset.defaultMix = defaultMix;
@ -1255,6 +1119,106 @@ namespace Spine.Unity.Editor {
#endif
}
#endregion
}
public static class AssetEditorGUI {
public static List<AtlasAssetBase> MultiAtlasDialog (List<string> requiredPaths, string initialDirectory, string filename = "") {
List<AtlasAssetBase> atlasAssets = new List<AtlasAssetBase>();
bool resolved = false;
string lastAtlasPath = initialDirectory;
while (!resolved) {
// Build dialog box message.
var missingRegions = new List<string>(requiredPaths);
var dialogText = new StringBuilder();
{
dialogText.AppendLine(string.Format("SkeletonDataAsset for \"{0}\"", filename));
dialogText.AppendLine("has missing regions.");
dialogText.AppendLine();
dialogText.AppendLine("Current Atlases:");
if (atlasAssets.Count == 0)
dialogText.AppendLine("\t--none--");
for (int i = 0; i < atlasAssets.Count; i++)
dialogText.AppendLine("\t" + atlasAssets[i].name);
dialogText.AppendLine();
dialogText.AppendLine("Missing Regions:");
foreach (var atlasAsset in atlasAssets) {
var atlas = atlasAsset.GetAtlas();
for (int i = 0; i < missingRegions.Count; i++) {
if (atlas.FindRegion(missingRegions[i]) != null) {
missingRegions.RemoveAt(i);
i--;
}
}
}
int n = missingRegions.Count;
if (n == 0)
break;
const int MaxListLength = 15;
for (int i = 0; (i < n && i < MaxListLength); i++)
dialogText.AppendLine("\t" + missingRegions[i]);
if (n > MaxListLength)
dialogText.AppendLine(string.Format("\t... {0} more...", n - MaxListLength));
}
// Show dialog box.
int result = EditorUtility.DisplayDialogComplex(
"SkeletonDataAsset has missing Atlas.",
dialogText.ToString(),
"Browse...", "Import anyway", "Cancel"
);
switch (result) {
case 0: // Browse...
AtlasAssetBase selectedAtlasAsset = GetAtlasDialog(lastAtlasPath);
if (selectedAtlasAsset != null) {
var atlas = selectedAtlasAsset.GetAtlas();
bool hasValidRegion = false;
foreach (string str in missingRegions) {
if (atlas.FindRegion(str) != null) {
hasValidRegion = true;
break;
}
}
atlasAssets.Add(selectedAtlasAsset);
}
break;
case 1: // Import anyway
resolved = true;
break;
case 2: // Cancel
atlasAssets = null;
resolved = true;
break;
}
}
return atlasAssets;
}
public static AtlasAssetBase GetAtlasDialog (string dirPath) {
string path = EditorUtility.OpenFilePanel("Select AtlasAsset...", dirPath, "asset");
if (path == "")
return null; // Canceled or closed by user.
int subLen = Application.dataPath.Length - 6;
string assetRelativePath = path.Substring(subLen, path.Length - subLen).Replace("\\", "/");
Object obj = AssetDatabase.LoadAssetAtPath(assetRelativePath, typeof(AtlasAssetBase));
if (obj == null || obj.GetType() != typeof(AtlasAssetBase))
return null;
return (AtlasAssetBase)obj;
}
}
#region SkeletonDataFileValidator
internal static class SkeletonDataFileValidator {
@ -1363,9 +1327,9 @@ namespace Spine.Unity.Editor {
bool pmaVertexColors = false;
bool tintBlack = false;
foreach (var atlasAsset in skeletonDataAsset.atlasAssets) {
foreach (SpineAtlasAsset atlasAsset in skeletonDataAsset.atlasAssets) {
if (!pmaVertexColors) {
foreach (Material m in atlasAsset.Materials) {
foreach (Material m in atlasAsset.materials) {
if (m.shader.name.Contains(PMAShaderQuery)) {
pmaVertexColors = true;
break;
@ -1374,7 +1338,7 @@ namespace Spine.Unity.Editor {
}
if (!tintBlack) {
foreach (Material m in atlasAsset.Materials) {
foreach (Material m in atlasAsset.materials) {
if (m.shader.name.Contains(TintBlackShaderQuery)) {
tintBlack = true;
break;