mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-02-04 22:34:53 +08:00
Merge branch '3.8' into 4.0-beta
This commit is contained in:
commit
c9e52024f5
@ -625,9 +625,12 @@ namespace Spine.Unity.Editor {
|
||||
warnings.Add("Missing Skeleton JSON");
|
||||
} else {
|
||||
var fieldValue = (TextAsset)skeletonJSON.objectReferenceValue;
|
||||
|
||||
if (!AssetUtility.IsSpineData(fieldValue, out compatibilityProblemInfo)) {
|
||||
warnings.Add("Skeleton data file is not a valid Spine JSON or binary file.");
|
||||
string problemDescription = null;
|
||||
if (!AssetUtility.IsSpineData(fieldValue, out compatibilityProblemInfo, ref problemDescription)) {
|
||||
if (problemDescription != null)
|
||||
warnings.Add(problemDescription);
|
||||
else
|
||||
warnings.Add("Skeleton data file is not a valid Spine JSON or binary file.");
|
||||
} else {
|
||||
#if SPINE_TK2D
|
||||
bool searchForSpineAtlasAssets = (compatibilityProblemInfo == null);
|
||||
@ -644,11 +647,12 @@ namespace Spine.Unity.Editor {
|
||||
var actualAtlasAssets = targetSkeletonDataAsset.atlasAssets;
|
||||
|
||||
for (int i = 0; i < actualAtlasAssets.Length; i++) {
|
||||
if (targetSkeletonDataAsset.atlasAssets[i] == null) {
|
||||
if (actualAtlasAssets[i] == null) {
|
||||
detectedNullAtlasEntry = true;
|
||||
break;
|
||||
} else {
|
||||
atlasList.Add(actualAtlasAssets[i].GetAtlas());
|
||||
if (actualAtlasAssets[i].MaterialCount > 0)
|
||||
atlasList.Add(actualAtlasAssets[i].GetAtlas());
|
||||
}
|
||||
}
|
||||
|
||||
@ -658,8 +662,9 @@ namespace Spine.Unity.Editor {
|
||||
List<string> missingPaths = null;
|
||||
if (atlasAssets.arraySize > 0) {
|
||||
missingPaths = AssetUtility.GetRequiredAtlasRegions(AssetDatabase.GetAssetPath(skeletonJSON.objectReferenceValue));
|
||||
|
||||
foreach (var atlas in atlasList) {
|
||||
if (atlas == null)
|
||||
continue;
|
||||
for (int i = 0; i < missingPaths.Count; i++) {
|
||||
if (atlas.FindRegion(missingPaths[i]) != null) {
|
||||
missingPaths.RemoveAt(i);
|
||||
|
||||
@ -58,7 +58,18 @@ using System.Reflection;
|
||||
using CompatibilityProblemInfo = Spine.Unity.SkeletonDataCompatibility.CompatibilityProblemInfo;
|
||||
|
||||
namespace Spine.Unity.Editor {
|
||||
using PathAndProblemInfo = System.Collections.Generic.KeyValuePair<string, CompatibilityProblemInfo>;
|
||||
|
||||
public class PathAndProblemInfo {
|
||||
public string path;
|
||||
public CompatibilityProblemInfo compatibilityProblems;
|
||||
public string otherProblemDescription;
|
||||
|
||||
public PathAndProblemInfo (string path, CompatibilityProblemInfo compatibilityInfo, string otherProblemDescription) {
|
||||
this.path = path;
|
||||
this.compatibilityProblems = compatibilityInfo;
|
||||
this.otherProblemDescription = otherProblemDescription;
|
||||
}
|
||||
}
|
||||
|
||||
public static class AssetUtility {
|
||||
|
||||
@ -276,17 +287,26 @@ namespace Spine.Unity.Editor {
|
||||
case ".jpg":
|
||||
imagePaths.Add(str);
|
||||
break;
|
||||
case ".json":
|
||||
case ".json": {
|
||||
var jsonAsset = AssetDatabase.LoadAssetAtPath<TextAsset>(str);
|
||||
if (jsonAsset != null && IsSpineData(jsonAsset, out compatibilityProblemInfo))
|
||||
skeletonPaths.Add(new PathAndProblemInfo(str, compatibilityProblemInfo));
|
||||
string problemDescription = null;
|
||||
if (jsonAsset != null && IsSpineData(jsonAsset, out compatibilityProblemInfo, ref problemDescription))
|
||||
skeletonPaths.Add(new PathAndProblemInfo(str, compatibilityProblemInfo, problemDescription));
|
||||
if (problemDescription != null)
|
||||
Debug.LogError(problemDescription, jsonAsset);
|
||||
break;
|
||||
case ".bytes":
|
||||
}
|
||||
case ".bytes": {
|
||||
if (str.ToLower().EndsWith(".skel.bytes", System.StringComparison.Ordinal)) {
|
||||
if (IsSpineData(AssetDatabase.LoadAssetAtPath<TextAsset>(str), out compatibilityProblemInfo))
|
||||
skeletonPaths.Add(new PathAndProblemInfo(str, compatibilityProblemInfo));
|
||||
var binaryAsset = AssetDatabase.LoadAssetAtPath<TextAsset>(str);
|
||||
string problemDescription = null;
|
||||
if (IsSpineData(binaryAsset, out compatibilityProblemInfo, ref problemDescription))
|
||||
skeletonPaths.Add(new PathAndProblemInfo(str, compatibilityProblemInfo, problemDescription));
|
||||
if (problemDescription != null)
|
||||
Debug.LogError(problemDescription, binaryAsset);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -304,8 +324,9 @@ namespace Spine.Unity.Editor {
|
||||
// Import skeletons and match them with atlases.
|
||||
bool abortSkeletonImport = false;
|
||||
foreach (var skeletonPathEntry in skeletonPaths) {
|
||||
string skeletonPath = skeletonPathEntry.Key;
|
||||
var compatibilityProblems = skeletonPathEntry.Value;
|
||||
string skeletonPath = skeletonPathEntry.path;
|
||||
var compatibilityProblems = skeletonPathEntry.compatibilityProblems;
|
||||
string otherProblemDescription = skeletonPathEntry.otherProblemDescription;
|
||||
if (skeletonPath.StartsWith("Packages"))
|
||||
continue;
|
||||
if (!reimport && CheckForValidSkeletonData(skeletonPath)) {
|
||||
@ -318,6 +339,9 @@ namespace Spine.Unity.Editor {
|
||||
IngestIncompatibleSpineProject(loadedAsset, compatibilityProblems);
|
||||
continue;
|
||||
}
|
||||
if (otherProblemDescription != null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
string dir = Path.GetDirectoryName(skeletonPath).Replace('\\', '/');
|
||||
|
||||
@ -378,8 +402,12 @@ namespace Spine.Unity.Editor {
|
||||
if (usedSkeletonPath == null)
|
||||
continue;
|
||||
|
||||
if (skeletonPaths.FindIndex(p => { return p.Key == usedSkeletonPath; } ) < 0) {
|
||||
skeletonPaths.Add(new PathAndProblemInfo(usedSkeletonPath, null));
|
||||
if (skeletonPaths.FindIndex(p => { return p.path == usedSkeletonPath; } ) < 0) {
|
||||
string problemDescription = null;
|
||||
CompatibilityProblemInfo compatibilityProblemInfo = null;
|
||||
TextAsset textAsset = AssetDatabase.LoadAssetAtPath<TextAsset>(usedSkeletonPath);
|
||||
if (textAsset != null && IsSpineData(textAsset, out compatibilityProblemInfo, ref problemDescription))
|
||||
skeletonPaths.Add(new PathAndProblemInfo(usedSkeletonPath, compatibilityProblemInfo, problemDescription));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -427,7 +455,8 @@ namespace Spine.Unity.Editor {
|
||||
}
|
||||
|
||||
SkeletonData skeletonData = skeletonDataAsset.GetSkeletonData(true);
|
||||
BlendModeMaterialsUtility.UpdateBlendModeMaterials(skeletonDataAsset, ref skeletonData);
|
||||
if (skeletonData != null)
|
||||
BlendModeMaterialsUtility.UpdateBlendModeMaterials(skeletonDataAsset, ref skeletonData);
|
||||
|
||||
string currentHash = skeletonData != null ? skeletonData.Hash : null;
|
||||
|
||||
@ -831,11 +860,10 @@ namespace Spine.Unity.Editor {
|
||||
internal static SkeletonDataAsset IngestIncompatibleSpineProject(TextAsset spineJson,
|
||||
CompatibilityProblemInfo compatibilityProblemInfo) {
|
||||
|
||||
string filePath = GetSkeletonDataAssetFilePath(spineJson);
|
||||
|
||||
if (spineJson == null)
|
||||
return null;
|
||||
|
||||
string filePath = GetSkeletonDataAssetFilePath(spineJson);
|
||||
SkeletonDataAsset skeletonDataAsset = (SkeletonDataAsset)AssetDatabase.LoadAssetAtPath(filePath, typeof(SkeletonDataAsset));
|
||||
if (skeletonDataAsset == null) {
|
||||
skeletonDataAsset = SkeletonDataAsset.CreateInstance<SkeletonDataAsset>();
|
||||
@ -921,14 +949,14 @@ namespace Spine.Unity.Editor {
|
||||
if (skeletonDataAsset != null && skeletonDataAsset.skeletonJSON == textAsset)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool IsSpineData (TextAsset asset, out CompatibilityProblemInfo compatibilityProblemInfo) {
|
||||
SkeletonDataCompatibility.VersionInfo fileVersion = SkeletonDataCompatibility.GetVersionInfo(asset);
|
||||
public static bool IsSpineData (TextAsset asset, out CompatibilityProblemInfo compatibilityProblemInfo, ref string problemDescription) {
|
||||
bool isSpineSkeletonData;
|
||||
SkeletonDataCompatibility.VersionInfo fileVersion = SkeletonDataCompatibility.GetVersionInfo(asset, out isSpineSkeletonData, ref problemDescription);
|
||||
compatibilityProblemInfo = SkeletonDataCompatibility.GetCompatibilityProblemInfo(fileVersion);
|
||||
return fileVersion != null;
|
||||
return isSpineSkeletonData;
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
@ -163,22 +163,29 @@ namespace Spine.Unity {
|
||||
}
|
||||
#endif
|
||||
|
||||
bool isBinary = skeletonJSON.name.ToLower().Contains(".skel");
|
||||
bool hasBinaryExtension = skeletonJSON.name.ToLower().Contains(".skel");
|
||||
SkeletonData loadedSkeletonData = null;
|
||||
|
||||
try {
|
||||
if (isBinary)
|
||||
if (hasBinaryExtension)
|
||||
loadedSkeletonData = SkeletonDataAsset.ReadSkeletonData(skeletonJSON.bytes, attachmentLoader, skeletonDataScale);
|
||||
else
|
||||
loadedSkeletonData = SkeletonDataAsset.ReadSkeletonData(skeletonJSON.text, attachmentLoader, skeletonDataScale);
|
||||
} catch (Exception ex) {
|
||||
if (!quiet)
|
||||
Debug.LogError("Error reading skeleton JSON file for SkeletonData asset: " + name + "\n" + ex.Message + "\n" + ex.StackTrace, this);
|
||||
Debug.LogError("Error reading skeleton JSON file for SkeletonData asset: " + name + "\n" + ex.Message + "\n" + ex.StackTrace, skeletonJSON);
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
if (loadedSkeletonData == null && !quiet && skeletonJSON != null) {
|
||||
SkeletonDataCompatibility.VersionInfo fileVersion = SkeletonDataCompatibility.GetVersionInfo(skeletonJSON);
|
||||
string problemDescription = null;
|
||||
bool isSpineSkeletonData;
|
||||
SkeletonDataCompatibility.VersionInfo fileVersion = SkeletonDataCompatibility.GetVersionInfo(skeletonJSON, out isSpineSkeletonData, ref problemDescription);
|
||||
if (problemDescription != null) {
|
||||
if (!quiet)
|
||||
Debug.LogError(problemDescription, skeletonJSON);
|
||||
return null;
|
||||
}
|
||||
CompatibilityProblemInfo compatibilityProblemInfo = SkeletonDataCompatibility.GetCompatibilityProblemInfo(fileVersion);
|
||||
if (compatibilityProblemInfo != null) {
|
||||
SkeletonDataCompatibility.DisplayCompatibilityProblem(compatibilityProblemInfo.DescriptionString(), skeletonJSON);
|
||||
@ -250,7 +257,6 @@ namespace Spine.Unity {
|
||||
};
|
||||
return json.ReadSkeletonData(input);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -30,6 +30,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using UnityEngine;
|
||||
using System;
|
||||
#if UNITY_EDITOR
|
||||
using System.Globalization;
|
||||
using System.Text.RegularExpressions;
|
||||
@ -63,8 +64,12 @@ namespace Spine.Unity {
|
||||
public class CompatibilityProblemInfo {
|
||||
public VersionInfo actualVersion;
|
||||
public int[][] compatibleVersions;
|
||||
public string explicitProblemDescription = null;
|
||||
|
||||
public string DescriptionString () {
|
||||
if (!string.IsNullOrEmpty(explicitProblemDescription))
|
||||
return explicitProblemDescription;
|
||||
|
||||
string compatibleVersionString = "";
|
||||
string optionalOr = null;
|
||||
foreach (int[] version in compatibleVersions) {
|
||||
@ -77,12 +82,28 @@ namespace Spine.Unity {
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
public static VersionInfo GetVersionInfo (TextAsset asset) {
|
||||
public static VersionInfo GetVersionInfo (TextAsset asset, out bool isSpineSkeletonData, ref string problemDescription) {
|
||||
isSpineSkeletonData = false;
|
||||
if (asset == null)
|
||||
return null;
|
||||
|
||||
VersionInfo fileVersion = new VersionInfo();
|
||||
fileVersion.sourceType = asset.name.Contains(".skel") ? SourceType.Binary : SourceType.Json;
|
||||
bool hasBinaryExtension = asset.name.Contains(".skel");
|
||||
fileVersion.sourceType = hasBinaryExtension ? SourceType.Binary : SourceType.Json;
|
||||
|
||||
bool isJsonFileByContent = IsJsonFile(asset);
|
||||
if (hasBinaryExtension == isJsonFileByContent) {
|
||||
if (hasBinaryExtension) {
|
||||
problemDescription = string.Format("Failed to read '{0}'. Extension is '.skel.bytes' but content looks like a '.json' file.\n"
|
||||
+ "Did you choose the wrong extension upon export?\n", asset.name);
|
||||
}
|
||||
else {
|
||||
problemDescription = string.Format("Failed to read '{0}'. Extension is '.json' but content looks like binary 'skel.bytes' file.\n"
|
||||
+ "Did you choose the wrong extension upon export?\n", asset.name);
|
||||
}
|
||||
isSpineSkeletonData = false;
|
||||
return null;
|
||||
}
|
||||
|
||||
if (fileVersion.sourceType == SourceType.Binary) {
|
||||
try {
|
||||
@ -91,8 +112,8 @@ namespace Spine.Unity {
|
||||
}
|
||||
}
|
||||
catch (System.Exception e) {
|
||||
Debug.LogError(string.Format("Failed to read '{0}'. It is likely not a binary Spine SkeletonData file.\n{1}",
|
||||
asset.name, e), asset);
|
||||
problemDescription = string.Format("Failed to read '{0}'. It is likely not a binary Spine SkeletonData file.\n{1}", asset.name, e);
|
||||
isSpineSkeletonData = false;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@ -104,13 +125,15 @@ namespace Spine.Unity {
|
||||
else {
|
||||
object obj = Json.Deserialize(new StringReader(asset.text));
|
||||
if (obj == null) {
|
||||
Debug.LogError(string.Format("'{0}' is not valid JSON.", asset.name), asset);
|
||||
problemDescription = string.Format("'{0}' is not valid JSON.", asset.name);
|
||||
isSpineSkeletonData = false;
|
||||
return null;
|
||||
}
|
||||
|
||||
var root = obj as Dictionary<string, object>;
|
||||
if (root == null) {
|
||||
Debug.LogError(string.Format("'{0}' is not compatible JSON. Parser returned an incorrect type while parsing version info.", asset.name), asset);
|
||||
problemDescription = string.Format("'{0}' is not compatible JSON. Parser returned an incorrect type while parsing version info.", asset.name);
|
||||
isSpineSkeletonData = false;
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -124,7 +147,8 @@ namespace Spine.Unity {
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(fileVersion.rawVersion)) {
|
||||
// very likely not a Spine skeleton json file at all.
|
||||
// very likely not a Spine skeleton json file at all. Could be another valid json file, don't report errors.
|
||||
isSpineSkeletonData = false;
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -134,16 +158,39 @@ namespace Spine.Unity {
|
||||
int.Parse(versionSplit[1], CultureInfo.InvariantCulture) };
|
||||
}
|
||||
catch (System.Exception e) {
|
||||
Debug.LogError(string.Format("Failed to read version info at skeleton '{0}'. It is likely not a valid Spine SkeletonData file.\n{1}",
|
||||
asset.name, e), asset);
|
||||
problemDescription = string.Format("Failed to read version info at skeleton '{0}'. It is likely not a valid Spine SkeletonData file.\n{1}", asset.name, e);
|
||||
isSpineSkeletonData = false;
|
||||
return null;
|
||||
}
|
||||
isSpineSkeletonData = true;
|
||||
return fileVersion;
|
||||
}
|
||||
|
||||
public static bool IsJsonFile (TextAsset file) {
|
||||
string fileText = file.text;
|
||||
const int maxCharsToCheck = 256;
|
||||
int numCharsToCheck = Math.Min(fileText.Length, maxCharsToCheck);
|
||||
if (fileText.IndexOf("\"skeleton\"", 0, numCharsToCheck) != -1 ||
|
||||
fileText.IndexOf("\"hash\"", 0, numCharsToCheck) != -1 ||
|
||||
fileText.IndexOf("\"spine\"", 0, numCharsToCheck) != -1)
|
||||
return true;
|
||||
|
||||
int jsonCharCount = 0;
|
||||
const string jsonChars = "{}:\",";
|
||||
for (int i = 0; i < numCharsToCheck; ++i) {
|
||||
char c = fileText[i];
|
||||
if (jsonChars.IndexOf(c) != -1 || char.IsWhiteSpace(c))
|
||||
++jsonCharCount;
|
||||
}
|
||||
if (jsonCharCount > numCharsToCheck / 10)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
public static CompatibilityProblemInfo GetCompatibilityProblemInfo (VersionInfo fileVersion) {
|
||||
if (fileVersion == null)
|
||||
return null;
|
||||
if (fileVersion == null) {
|
||||
return null; // it's most likely not a Spine skeleton file, e.g. another json file. don't report problems.
|
||||
}
|
||||
|
||||
CompatibilityProblemInfo info = new CompatibilityProblemInfo();
|
||||
info.actualVersion = fileVersion;
|
||||
|
||||
@ -142,6 +142,9 @@ namespace Spine.Unity {
|
||||
|
||||
[System.Serializable]
|
||||
public class MecanimTranslator {
|
||||
|
||||
const float WeightEpsilon = 0.0001f;
|
||||
|
||||
#region Inspector
|
||||
public bool autoReset = true;
|
||||
public bool useCustomMixMode = true;
|
||||
@ -220,7 +223,7 @@ namespace Spine.Unity {
|
||||
private bool ApplyAnimation (Skeleton skeleton, AnimatorClipInfo info, AnimatorStateInfo stateInfo,
|
||||
int layerIndex, float layerWeight, MixBlend layerBlendMode, bool useClipWeight1 = false) {
|
||||
float weight = info.weight * layerWeight;
|
||||
if (weight == 0)
|
||||
if (weight < WeightEpsilon)
|
||||
return false;
|
||||
|
||||
var clip = GetAnimation(info.clip);
|
||||
@ -244,7 +247,7 @@ namespace Spine.Unity {
|
||||
|
||||
float clipWeight = interpolateWeightTo1 ? (info.weight + 1.0f) * 0.5f : info.weight;
|
||||
float weight = clipWeight * layerWeight;
|
||||
if (weight == 0)
|
||||
if (weight < WeightEpsilon)
|
||||
return false;
|
||||
|
||||
var clip = GetAnimation(info.clip);
|
||||
@ -320,7 +323,7 @@ namespace Spine.Unity {
|
||||
|
||||
for (int c = 0; c < clipInfoCount; c++) {
|
||||
var info = clipInfo[c];
|
||||
float weight = info.weight * layerWeight; if (weight == 0) continue;
|
||||
float weight = info.weight * layerWeight; if (weight < WeightEpsilon) continue;
|
||||
var clip = GetAnimation(info.clip);
|
||||
if (clip != null)
|
||||
previousAnimations.Add(clip);
|
||||
@ -329,7 +332,7 @@ namespace Spine.Unity {
|
||||
if (hasNext) {
|
||||
for (int c = 0; c < nextClipInfoCount; c++) {
|
||||
var info = nextClipInfo[c];
|
||||
float weight = info.weight * layerWeight; if (weight == 0) continue;
|
||||
float weight = info.weight * layerWeight; if (weight < WeightEpsilon) continue;
|
||||
var clip = GetAnimation(info.clip);
|
||||
if (clip != null)
|
||||
previousAnimations.Add(clip);
|
||||
@ -341,7 +344,7 @@ namespace Spine.Unity {
|
||||
{
|
||||
var info = interruptingClipInfo[c];
|
||||
float clipWeight = shallInterpolateWeightTo1 ? (info.weight + 1.0f) * 0.5f : info.weight;
|
||||
float weight = clipWeight * layerWeight; if (weight == 0) continue;
|
||||
float weight = clipWeight * layerWeight; if (weight < WeightEpsilon) continue;
|
||||
var clip = GetAnimation(info.clip);
|
||||
if (clip != null)
|
||||
previousAnimations.Add(clip);
|
||||
|
||||
@ -363,7 +363,7 @@ namespace Spine.Unity {
|
||||
#if UNITY_EDITOR
|
||||
if (!Application.isPlaying) {
|
||||
string errorMessage = null;
|
||||
if (quiet || MaterialChecks.IsMaterialSetupProblematic(this, ref errorMessage))
|
||||
if (!quiet && MaterialChecks.IsMaterialSetupProblematic(this, ref errorMessage))
|
||||
Debug.LogWarningFormat(this, "Problematic material setup at {0}: {1}", this.name, errorMessage);
|
||||
}
|
||||
#endif
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user