mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-03-26 22:49:01 +08:00
[unity] Rearrange SpineEditorUtilities classes.
This commit is contained in:
parent
d336712ccc
commit
6187e2b89e
@ -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);
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user