mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-03-26 22:49:01 +08:00
Merge branch '3.6' into 3.7-beta
This commit is contained in:
commit
4c104ef885
@ -174,7 +174,7 @@ namespace Spine {
|
||||
protected const float LINEAR = 0, STEPPED = 1, BEZIER = 2;
|
||||
protected const int BEZIER_SIZE = 10 * 2 - 1;
|
||||
|
||||
private float[] curves; // type, x, y, ...
|
||||
internal float[] curves; // type, x, y, ...
|
||||
public int FrameCount { get { return curves.Length / BEZIER_SIZE + 1; } }
|
||||
|
||||
public CurveTimeline (int frameCount) {
|
||||
@ -689,18 +689,20 @@ namespace Spine {
|
||||
protected const int PREV_R2 = -3, PREV_G2 = -2, PREV_B2 = -1;
|
||||
protected const int R = 1, G = 2, B = 3, A = 4, R2 = 5, G2 = 6, B2 = 7;
|
||||
|
||||
internal float[] frames; // time, r, g, b, a, r2, g2, b2, ...
|
||||
public float[] Frames { get { return frames; } }
|
||||
|
||||
internal int slotIndex;
|
||||
internal float[] frames; // time, r, g, b, a, r2, g2, b2, ...
|
||||
|
||||
public int SlotIndex {
|
||||
get { return slotIndex; }
|
||||
set {
|
||||
if (value < 0) throw new ArgumentOutOfRangeException("index must be >= 0.");
|
||||
if (value < 0)
|
||||
throw new ArgumentOutOfRangeException("index must be >= 0.");
|
||||
slotIndex = value;
|
||||
}
|
||||
}
|
||||
|
||||
public float[] Frames { get { return frames; } }
|
||||
|
||||
override public int PropertyId {
|
||||
get { return ((int)TimelineType.TwoColor << 24) + slotIndex; }
|
||||
}
|
||||
@ -827,11 +829,11 @@ namespace Spine {
|
||||
public class AttachmentTimeline : Timeline {
|
||||
internal int slotIndex;
|
||||
internal float[] frames;
|
||||
private String[] attachmentNames;
|
||||
internal string[] attachmentNames;
|
||||
|
||||
public int SlotIndex { get { return slotIndex; } set { slotIndex = value; } }
|
||||
public float[] Frames { get { return frames; } set { frames = value; } } // time, ...
|
||||
public String[] AttachmentNames { get { return attachmentNames; } set { attachmentNames = value; } }
|
||||
public string[] AttachmentNames { get { return attachmentNames; } set { attachmentNames = value; } }
|
||||
public int FrameCount { get { return frames.Length; } }
|
||||
|
||||
public int PropertyId {
|
||||
|
||||
@ -79,14 +79,22 @@ namespace Spine {
|
||||
public void UpdateOffset () {
|
||||
float width = this.width;
|
||||
float height = this.height;
|
||||
float localX2 = width * 0.5f;
|
||||
float localY2 = height * 0.5f;
|
||||
float localX = -localX2;
|
||||
float localY = -localY2;
|
||||
if (regionOriginalWidth != 0) { // if (region != null)
|
||||
localX += regionOffsetX / regionOriginalWidth * width;
|
||||
localY += regionOffsetY / regionOriginalHeight * height;
|
||||
localX2 -= (regionOriginalWidth - regionOffsetX - regionWidth) / regionOriginalWidth * width;
|
||||
localY2 -= (regionOriginalHeight - regionOffsetY - regionHeight) / regionOriginalHeight * height;
|
||||
}
|
||||
float scaleX = this.scaleX;
|
||||
float scaleY = this.scaleY;
|
||||
float regionScaleX = width / regionOriginalWidth * scaleX;
|
||||
float regionScaleY = height / regionOriginalHeight * scaleY;
|
||||
float localX = -width / 2 * scaleX + regionOffsetX * regionScaleX;
|
||||
float localY = -height / 2 * scaleY + regionOffsetY * regionScaleY;
|
||||
float localX2 = localX + regionWidth * regionScaleX;
|
||||
float localY2 = localY + regionHeight * regionScaleY;
|
||||
localX *= scaleX;
|
||||
localY *= scaleY;
|
||||
localX2 *= scaleX;
|
||||
localY2 *= scaleY;
|
||||
float rotation = this.rotation;
|
||||
float cos = MathUtils.CosDeg(rotation);
|
||||
float sin = MathUtils.SinDeg(rotation);
|
||||
|
||||
@ -69,11 +69,11 @@ namespace Spine {
|
||||
}
|
||||
}
|
||||
|
||||
public SkeletonData ReadSkeletonData (String path) {
|
||||
public SkeletonData ReadSkeletonData (string path) {
|
||||
return this.ReadFile(path).Result;
|
||||
}
|
||||
#else
|
||||
public SkeletonData ReadSkeletonData (String path) {
|
||||
public SkeletonData ReadSkeletonData (string path) {
|
||||
#if WINDOWS_PHONE
|
||||
using (var reader = new StreamReader(Microsoft.Xna.Framework.TitleContainer.OpenStream(path))) {
|
||||
#else
|
||||
@ -89,17 +89,17 @@ namespace Spine {
|
||||
public SkeletonData ReadSkeletonData (TextReader reader) {
|
||||
if (reader == null) throw new ArgumentNullException("reader", "reader cannot be null.");
|
||||
|
||||
var scale = this.Scale;
|
||||
float scale = this.Scale;
|
||||
var skeletonData = new SkeletonData();
|
||||
|
||||
var root = Json.Deserialize(reader) as Dictionary<String, Object>;
|
||||
var root = Json.Deserialize(reader) as Dictionary<string, Object>;
|
||||
if (root == null) throw new Exception("Invalid JSON.");
|
||||
|
||||
// Skeleton.
|
||||
if (root.ContainsKey("skeleton")) {
|
||||
var skeletonMap = (Dictionary<String, Object>)root["skeleton"];
|
||||
skeletonData.hash = (String)skeletonMap["hash"];
|
||||
skeletonData.version = (String)skeletonMap["spine"];
|
||||
var skeletonMap = (Dictionary<string, Object>)root["skeleton"];
|
||||
skeletonData.hash = (string)skeletonMap["hash"];
|
||||
skeletonData.version = (string)skeletonMap["spine"];
|
||||
skeletonData.width = GetFloat(skeletonMap, "width", 0);
|
||||
skeletonData.height = GetFloat(skeletonMap, "height", 0);
|
||||
skeletonData.fps = GetFloat(skeletonMap, "fps", 0);
|
||||
@ -108,14 +108,14 @@ namespace Spine {
|
||||
}
|
||||
|
||||
// Bones.
|
||||
foreach (Dictionary<String, Object> boneMap in (List<Object>)root["bones"]) {
|
||||
foreach (Dictionary<string, Object> boneMap in (List<Object>)root["bones"]) {
|
||||
BoneData parent = null;
|
||||
if (boneMap.ContainsKey("parent")) {
|
||||
parent = skeletonData.FindBone((String)boneMap["parent"]);
|
||||
parent = skeletonData.FindBone((string)boneMap["parent"]);
|
||||
if (parent == null)
|
||||
throw new Exception("Parent bone not found: " + boneMap["parent"]);
|
||||
}
|
||||
var data = new BoneData(skeletonData.Bones.Count, (String)boneMap["name"], parent);
|
||||
var data = new BoneData(skeletonData.Bones.Count, (string)boneMap["name"], parent);
|
||||
data.length = GetFloat(boneMap, "length", 0) * scale;
|
||||
data.x = GetFloat(boneMap, "x", 0) * scale;
|
||||
data.y = GetFloat(boneMap, "y", 0) * scale;
|
||||
@ -133,15 +133,15 @@ namespace Spine {
|
||||
|
||||
// Slots.
|
||||
if (root.ContainsKey("slots")) {
|
||||
foreach (Dictionary<String, Object> slotMap in (List<Object>)root["slots"]) {
|
||||
var slotName = (String)slotMap["name"];
|
||||
var boneName = (String)slotMap["bone"];
|
||||
foreach (Dictionary<string, Object> slotMap in (List<Object>)root["slots"]) {
|
||||
var slotName = (string)slotMap["name"];
|
||||
var boneName = (string)slotMap["bone"];
|
||||
BoneData boneData = skeletonData.FindBone(boneName);
|
||||
if (boneData == null) throw new Exception("Slot bone not found: " + boneName);
|
||||
var data = new SlotData(skeletonData.Slots.Count, slotName, boneData);
|
||||
|
||||
if (slotMap.ContainsKey("color")) {
|
||||
var color = (String)slotMap["color"];
|
||||
string color = (string)slotMap["color"];
|
||||
data.r = ToColor(color, 0);
|
||||
data.g = ToColor(color, 1);
|
||||
data.b = ToColor(color, 2);
|
||||
@ -149,7 +149,7 @@ namespace Spine {
|
||||
}
|
||||
|
||||
if (slotMap.ContainsKey("dark")) {
|
||||
var color2 = (String)slotMap["dark"];
|
||||
var color2 = (string)slotMap["dark"];
|
||||
data.r2 = ToColor(color2, 0, 6); // expectedLength = 6. ie. "RRGGBB"
|
||||
data.g2 = ToColor(color2, 1, 6);
|
||||
data.b2 = ToColor(color2, 2, 6);
|
||||
@ -158,7 +158,7 @@ namespace Spine {
|
||||
|
||||
data.attachmentName = GetString(slotMap, "attachment", null);
|
||||
if (slotMap.ContainsKey("blend"))
|
||||
data.blendMode = (BlendMode)Enum.Parse(typeof(BlendMode), (String)slotMap["blend"], true);
|
||||
data.blendMode = (BlendMode)Enum.Parse(typeof(BlendMode), (string)slotMap["blend"], true);
|
||||
else
|
||||
data.blendMode = BlendMode.Normal;
|
||||
skeletonData.slots.Add(data);
|
||||
@ -167,17 +167,17 @@ namespace Spine {
|
||||
|
||||
// IK constraints.
|
||||
if (root.ContainsKey("ik")) {
|
||||
foreach (Dictionary<String, Object> constraintMap in (List<Object>)root["ik"]) {
|
||||
IkConstraintData data = new IkConstraintData((String)constraintMap["name"]);
|
||||
foreach (Dictionary<string, Object> constraintMap in (List<Object>)root["ik"]) {
|
||||
IkConstraintData data = new IkConstraintData((string)constraintMap["name"]);
|
||||
data.order = GetInt(constraintMap, "order", 0);
|
||||
|
||||
foreach (String boneName in (List<Object>)constraintMap["bones"]) {
|
||||
foreach (string boneName in (List<Object>)constraintMap["bones"]) {
|
||||
BoneData bone = skeletonData.FindBone(boneName);
|
||||
if (bone == null) throw new Exception("IK constraint bone not found: " + boneName);
|
||||
data.bones.Add(bone);
|
||||
}
|
||||
|
||||
String targetName = (String)constraintMap["target"];
|
||||
string targetName = (string)constraintMap["target"];
|
||||
data.target = skeletonData.FindBone(targetName);
|
||||
if (data.target == null) throw new Exception("Target bone not found: " + targetName);
|
||||
|
||||
@ -190,17 +190,17 @@ namespace Spine {
|
||||
|
||||
// Transform constraints.
|
||||
if (root.ContainsKey("transform")) {
|
||||
foreach (Dictionary<String, Object> constraintMap in (List<Object>)root["transform"]) {
|
||||
TransformConstraintData data = new TransformConstraintData((String)constraintMap["name"]);
|
||||
foreach (Dictionary<string, Object> constraintMap in (List<Object>)root["transform"]) {
|
||||
TransformConstraintData data = new TransformConstraintData((string)constraintMap["name"]);
|
||||
data.order = GetInt(constraintMap, "order", 0);
|
||||
|
||||
foreach (String boneName in (List<Object>)constraintMap["bones"]) {
|
||||
foreach (string boneName in (List<Object>)constraintMap["bones"]) {
|
||||
BoneData bone = skeletonData.FindBone(boneName);
|
||||
if (bone == null) throw new Exception("Transform constraint bone not found: " + boneName);
|
||||
data.bones.Add(bone);
|
||||
}
|
||||
|
||||
String targetName = (String)constraintMap["target"];
|
||||
string targetName = (string)constraintMap["target"];
|
||||
data.target = skeletonData.FindBone(targetName);
|
||||
if (data.target == null) throw new Exception("Target bone not found: " + targetName);
|
||||
|
||||
@ -225,17 +225,17 @@ namespace Spine {
|
||||
|
||||
// Path constraints.
|
||||
if(root.ContainsKey("path")) {
|
||||
foreach (Dictionary<String, Object> constraintMap in (List<Object>)root["path"]) {
|
||||
PathConstraintData data = new PathConstraintData((String)constraintMap["name"]);
|
||||
foreach (Dictionary<string, Object> constraintMap in (List<Object>)root["path"]) {
|
||||
PathConstraintData data = new PathConstraintData((string)constraintMap["name"]);
|
||||
data.order = GetInt(constraintMap, "order", 0);
|
||||
|
||||
foreach (String boneName in (List<Object>)constraintMap["bones"]) {
|
||||
foreach (string boneName in (List<Object>)constraintMap["bones"]) {
|
||||
BoneData bone = skeletonData.FindBone(boneName);
|
||||
if (bone == null) throw new Exception("Path bone not found: " + boneName);
|
||||
data.bones.Add(bone);
|
||||
}
|
||||
|
||||
String targetName = (String)constraintMap["target"];
|
||||
string targetName = (string)constraintMap["target"];
|
||||
data.target = skeletonData.FindSlot(targetName);
|
||||
if (data.target == null) throw new Exception("Target slot not found: " + targetName);
|
||||
|
||||
@ -256,13 +256,13 @@ namespace Spine {
|
||||
|
||||
// Skins.
|
||||
if (root.ContainsKey("skins")) {
|
||||
foreach (KeyValuePair<String, Object> skinMap in (Dictionary<String, Object>)root["skins"]) {
|
||||
foreach (KeyValuePair<string, Object> skinMap in (Dictionary<string, Object>)root["skins"]) {
|
||||
var skin = new Skin(skinMap.Key);
|
||||
foreach (KeyValuePair<String, Object> slotEntry in (Dictionary<String, Object>)skinMap.Value) {
|
||||
foreach (KeyValuePair<string, Object> slotEntry in (Dictionary<string, Object>)skinMap.Value) {
|
||||
int slotIndex = skeletonData.FindSlotIndex(slotEntry.Key);
|
||||
foreach (KeyValuePair<String, Object> entry in ((Dictionary<String, Object>)slotEntry.Value)) {
|
||||
foreach (KeyValuePair<string, Object> entry in ((Dictionary<string, Object>)slotEntry.Value)) {
|
||||
try {
|
||||
Attachment attachment = ReadAttachment((Dictionary<String, Object>)entry.Value, skin, slotIndex, entry.Key, skeletonData);
|
||||
Attachment attachment = ReadAttachment((Dictionary<string, Object>)entry.Value, skin, slotIndex, entry.Key, skeletonData);
|
||||
if (attachment != null) skin.AddAttachment(slotIndex, entry.Key, attachment);
|
||||
} catch (Exception e) {
|
||||
throw new Exception("Error reading attachment: " + entry.Key + ", skin: " + skin, e);
|
||||
@ -288,8 +288,8 @@ namespace Spine {
|
||||
|
||||
// Events.
|
||||
if (root.ContainsKey("events")) {
|
||||
foreach (KeyValuePair<String, Object> entry in (Dictionary<String, Object>)root["events"]) {
|
||||
var entryMap = (Dictionary<String, Object>)entry.Value;
|
||||
foreach (KeyValuePair<string, Object> entry in (Dictionary<string, Object>)root["events"]) {
|
||||
var entryMap = (Dictionary<string, Object>)entry.Value;
|
||||
var data = new EventData(entry.Key);
|
||||
data.Int = GetInt(entryMap, "int", 0);
|
||||
data.Float = GetFloat(entryMap, "float", 0);
|
||||
@ -301,9 +301,9 @@ namespace Spine {
|
||||
|
||||
// Animations.
|
||||
if (root.ContainsKey("animations")) {
|
||||
foreach (KeyValuePair<String, Object> entry in (Dictionary<String, Object>)root["animations"]) {
|
||||
foreach (KeyValuePair<string, Object> entry in (Dictionary<string, Object>)root["animations"]) {
|
||||
try {
|
||||
ReadAnimation((Dictionary<String, Object>)entry.Value, entry.Key, skeletonData);
|
||||
ReadAnimation((Dictionary<string, Object>)entry.Value, entry.Key, skeletonData);
|
||||
} catch (Exception e) {
|
||||
throw new Exception("Error reading animation: " + entry.Key, e);
|
||||
}
|
||||
@ -319,8 +319,8 @@ namespace Spine {
|
||||
return skeletonData;
|
||||
}
|
||||
|
||||
private Attachment ReadAttachment (Dictionary<String, Object> map, Skin skin, int slotIndex, String name, SkeletonData skeletonData) {
|
||||
var scale = this.Scale;
|
||||
private Attachment ReadAttachment (Dictionary<string, Object> map, Skin skin, int slotIndex, string name, SkeletonData skeletonData) {
|
||||
float scale = this.Scale;
|
||||
name = GetString(map, "name", name);
|
||||
|
||||
var typeName = GetString(map, "type", "region");
|
||||
@ -329,7 +329,7 @@ namespace Spine {
|
||||
if (typeName == "weightedlinkedmesh") typeName = "linkedmesh";
|
||||
var type = (AttachmentType)Enum.Parse(typeof(AttachmentType), typeName, true);
|
||||
|
||||
String path = GetString(map, "path", name);
|
||||
string path = GetString(map, "path", name);
|
||||
|
||||
switch (type) {
|
||||
case AttachmentType.Region:
|
||||
@ -343,10 +343,9 @@ namespace Spine {
|
||||
region.rotation = GetFloat(map, "rotation", 0);
|
||||
region.width = GetFloat(map, "width", 32) * scale;
|
||||
region.height = GetFloat(map, "height", 32) * scale;
|
||||
region.UpdateOffset();
|
||||
|
||||
if (map.ContainsKey("color")) {
|
||||
var color = (String)map["color"];
|
||||
var color = (string)map["color"];
|
||||
region.r = ToColor(color, 0);
|
||||
region.g = ToColor(color, 1);
|
||||
region.b = ToColor(color, 2);
|
||||
@ -367,7 +366,7 @@ namespace Spine {
|
||||
mesh.Path = path;
|
||||
|
||||
if (map.ContainsKey("color")) {
|
||||
var color = (String)map["color"];
|
||||
var color = (string)map["color"];
|
||||
mesh.r = ToColor(color, 0);
|
||||
mesh.g = ToColor(color, 1);
|
||||
mesh.b = ToColor(color, 2);
|
||||
@ -377,7 +376,7 @@ namespace Spine {
|
||||
mesh.Width = GetFloat(map, "width", 0) * scale;
|
||||
mesh.Height = GetFloat(map, "height", 0) * scale;
|
||||
|
||||
String parent = GetString(map, "parent", null);
|
||||
string parent = GetString(map, "parent", null);
|
||||
if (parent != null) {
|
||||
mesh.InheritDeform = GetBoolean(map, "deform", true);
|
||||
linkedMeshes.Add(new LinkedMesh(mesh, GetString(map, "skin", null), slotIndex, parent));
|
||||
@ -439,7 +438,7 @@ namespace Spine {
|
||||
return null;
|
||||
}
|
||||
|
||||
private void ReadVertices (Dictionary<String, Object> map, VertexAttachment attachment, int verticesLength) {
|
||||
private void ReadVertices (Dictionary<string, Object> map, VertexAttachment attachment, int verticesLength) {
|
||||
attachment.WorldVerticesLength = verticesLength;
|
||||
float[] vertices = GetFloatArray(map, "vertices", 1);
|
||||
float scale = Scale;
|
||||
@ -468,28 +467,28 @@ namespace Spine {
|
||||
attachment.vertices = weights.ToArray();
|
||||
}
|
||||
|
||||
private void ReadAnimation (Dictionary<String, Object> map, String name, SkeletonData skeletonData) {
|
||||
private void ReadAnimation (Dictionary<string, Object> map, string name, SkeletonData skeletonData) {
|
||||
var scale = this.Scale;
|
||||
var timelines = new ExposedList<Timeline>();
|
||||
float duration = 0;
|
||||
|
||||
// Slot timelines.
|
||||
if (map.ContainsKey("slots")) {
|
||||
foreach (KeyValuePair<String, Object> entry in (Dictionary<String, Object>)map["slots"]) {
|
||||
String slotName = entry.Key;
|
||||
foreach (KeyValuePair<string, Object> entry in (Dictionary<string, Object>)map["slots"]) {
|
||||
string slotName = entry.Key;
|
||||
int slotIndex = skeletonData.FindSlotIndex(slotName);
|
||||
var timelineMap = (Dictionary<String, Object>)entry.Value;
|
||||
foreach (KeyValuePair<String, Object> timelineEntry in timelineMap) {
|
||||
var timelineMap = (Dictionary<string, Object>)entry.Value;
|
||||
foreach (KeyValuePair<string, Object> timelineEntry in timelineMap) {
|
||||
var values = (List<Object>)timelineEntry.Value;
|
||||
var timelineName = (String)timelineEntry.Key;
|
||||
var timelineName = (string)timelineEntry.Key;
|
||||
if (timelineName == "attachment") {
|
||||
var timeline = new AttachmentTimeline(values.Count);
|
||||
timeline.slotIndex = slotIndex;
|
||||
|
||||
int frameIndex = 0;
|
||||
foreach (Dictionary<String, Object> valueMap in values) {
|
||||
foreach (Dictionary<string, Object> valueMap in values) {
|
||||
float time = (float)valueMap["time"];
|
||||
timeline.SetFrame(frameIndex++, time, (String)valueMap["name"]);
|
||||
timeline.SetFrame(frameIndex++, time, (string)valueMap["name"]);
|
||||
}
|
||||
timelines.Add(timeline);
|
||||
duration = Math.Max(duration, timeline.frames[timeline.FrameCount - 1]);
|
||||
@ -534,20 +533,20 @@ namespace Spine {
|
||||
|
||||
// Bone timelines.
|
||||
if (map.ContainsKey("bones")) {
|
||||
foreach (KeyValuePair<String, Object> entry in (Dictionary<String, Object>)map["bones"]) {
|
||||
String boneName = entry.Key;
|
||||
foreach (KeyValuePair<string, Object> entry in (Dictionary<string, Object>)map["bones"]) {
|
||||
string boneName = entry.Key;
|
||||
int boneIndex = skeletonData.FindBoneIndex(boneName);
|
||||
if (boneIndex == -1) throw new Exception("Bone not found: " + boneName);
|
||||
var timelineMap = (Dictionary<String, Object>)entry.Value;
|
||||
foreach (KeyValuePair<String, Object> timelineEntry in timelineMap) {
|
||||
var timelineMap = (Dictionary<string, Object>)entry.Value;
|
||||
foreach (KeyValuePair<string, Object> timelineEntry in timelineMap) {
|
||||
var values = (List<Object>)timelineEntry.Value;
|
||||
var timelineName = (String)timelineEntry.Key;
|
||||
var timelineName = (string)timelineEntry.Key;
|
||||
if (timelineName == "rotate") {
|
||||
var timeline = new RotateTimeline(values.Count);
|
||||
timeline.boneIndex = boneIndex;
|
||||
|
||||
int frameIndex = 0;
|
||||
foreach (Dictionary<String, Object> valueMap in values) {
|
||||
foreach (Dictionary<string, Object> valueMap in values) {
|
||||
timeline.SetFrame(frameIndex, (float)valueMap["time"], (float)valueMap["angle"]);
|
||||
ReadCurve(valueMap, timeline, frameIndex);
|
||||
frameIndex++;
|
||||
@ -569,7 +568,7 @@ namespace Spine {
|
||||
timeline.boneIndex = boneIndex;
|
||||
|
||||
int frameIndex = 0;
|
||||
foreach (Dictionary<String, Object> valueMap in values) {
|
||||
foreach (Dictionary<string, Object> valueMap in values) {
|
||||
float time = (float)valueMap["time"];
|
||||
float x = GetFloat(valueMap, "x", 0);
|
||||
float y = GetFloat(valueMap, "y", 0);
|
||||
@ -588,13 +587,13 @@ namespace Spine {
|
||||
|
||||
// IK constraint timelines.
|
||||
if (map.ContainsKey("ik")) {
|
||||
foreach (KeyValuePair<String, Object> constraintMap in (Dictionary<String, Object>)map["ik"]) {
|
||||
foreach (KeyValuePair<string, Object> constraintMap in (Dictionary<string, Object>)map["ik"]) {
|
||||
IkConstraintData constraint = skeletonData.FindIkConstraint(constraintMap.Key);
|
||||
var values = (List<Object>)constraintMap.Value;
|
||||
var timeline = new IkConstraintTimeline(values.Count);
|
||||
timeline.ikConstraintIndex = skeletonData.ikConstraints.IndexOf(constraint);
|
||||
int frameIndex = 0;
|
||||
foreach (Dictionary<String, Object> valueMap in values) {
|
||||
foreach (Dictionary<string, Object> valueMap in values) {
|
||||
float time = (float)valueMap["time"];
|
||||
float mix = GetFloat(valueMap, "mix", 1);
|
||||
bool bendPositive = GetBoolean(valueMap, "bendPositive", true);
|
||||
@ -609,13 +608,13 @@ namespace Spine {
|
||||
|
||||
// Transform constraint timelines.
|
||||
if (map.ContainsKey("transform")) {
|
||||
foreach (KeyValuePair<String, Object> constraintMap in (Dictionary<String, Object>)map["transform"]) {
|
||||
foreach (KeyValuePair<string, Object> constraintMap in (Dictionary<string, Object>)map["transform"]) {
|
||||
TransformConstraintData constraint = skeletonData.FindTransformConstraint(constraintMap.Key);
|
||||
var values = (List<Object>)constraintMap.Value;
|
||||
var timeline = new TransformConstraintTimeline(values.Count);
|
||||
timeline.transformConstraintIndex = skeletonData.transformConstraints.IndexOf(constraint);
|
||||
int frameIndex = 0;
|
||||
foreach (Dictionary<String, Object> valueMap in values) {
|
||||
foreach (Dictionary<string, Object> valueMap in values) {
|
||||
float time = (float)valueMap["time"];
|
||||
float rotateMix = GetFloat(valueMap, "rotateMix", 1);
|
||||
float translateMix = GetFloat(valueMap, "translateMix", 1);
|
||||
@ -632,14 +631,14 @@ namespace Spine {
|
||||
|
||||
// Path constraint timelines.
|
||||
if (map.ContainsKey("paths")) {
|
||||
foreach (KeyValuePair<String, Object> constraintMap in (Dictionary<String, Object>)map["paths"]) {
|
||||
foreach (KeyValuePair<string, Object> constraintMap in (Dictionary<string, Object>)map["paths"]) {
|
||||
int index = skeletonData.FindPathConstraintIndex(constraintMap.Key);
|
||||
if (index == -1) throw new Exception("Path constraint not found: " + constraintMap.Key);
|
||||
PathConstraintData data = skeletonData.pathConstraints.Items[index];
|
||||
var timelineMap = (Dictionary<String, Object>)constraintMap.Value;
|
||||
foreach (KeyValuePair<String, Object> timelineEntry in timelineMap) {
|
||||
var timelineMap = (Dictionary<string, Object>)constraintMap.Value;
|
||||
foreach (KeyValuePair<string, Object> timelineEntry in timelineMap) {
|
||||
var values = (List<Object>)timelineEntry.Value;
|
||||
var timelineName = (String)timelineEntry.Key;
|
||||
var timelineName = (string)timelineEntry.Key;
|
||||
if (timelineName == "position" || timelineName == "spacing") {
|
||||
PathConstraintPositionTimeline timeline;
|
||||
float timelineScale = 1;
|
||||
@ -653,7 +652,7 @@ namespace Spine {
|
||||
}
|
||||
timeline.pathConstraintIndex = index;
|
||||
int frameIndex = 0;
|
||||
foreach (Dictionary<String, Object> valueMap in values) {
|
||||
foreach (Dictionary<string, Object> valueMap in values) {
|
||||
timeline.SetFrame(frameIndex, (float)valueMap["time"], GetFloat(valueMap, timelineName, 0) * timelineScale);
|
||||
ReadCurve(valueMap, timeline, frameIndex);
|
||||
frameIndex++;
|
||||
@ -665,7 +664,7 @@ namespace Spine {
|
||||
PathConstraintMixTimeline timeline = new PathConstraintMixTimeline(values.Count);
|
||||
timeline.pathConstraintIndex = index;
|
||||
int frameIndex = 0;
|
||||
foreach (Dictionary<String, Object> valueMap in values) {
|
||||
foreach (Dictionary<string, Object> valueMap in values) {
|
||||
timeline.SetFrame(frameIndex, (float)valueMap["time"], GetFloat(valueMap, "rotateMix", 1), GetFloat(valueMap, "translateMix", 1));
|
||||
ReadCurve(valueMap, timeline, frameIndex);
|
||||
frameIndex++;
|
||||
@ -679,12 +678,12 @@ namespace Spine {
|
||||
|
||||
// Deform timelines.
|
||||
if (map.ContainsKey("deform")) {
|
||||
foreach (KeyValuePair<String, Object> deformMap in (Dictionary<String, Object>)map["deform"]) {
|
||||
foreach (KeyValuePair<string, Object> deformMap in (Dictionary<string, Object>)map["deform"]) {
|
||||
Skin skin = skeletonData.FindSkin(deformMap.Key);
|
||||
foreach (KeyValuePair<String, Object> slotMap in (Dictionary<String, Object>)deformMap.Value) {
|
||||
foreach (KeyValuePair<string, Object> slotMap in (Dictionary<string, Object>)deformMap.Value) {
|
||||
int slotIndex = skeletonData.FindSlotIndex(slotMap.Key);
|
||||
if (slotIndex == -1) throw new Exception("Slot not found: " + slotMap.Key);
|
||||
foreach (KeyValuePair<String, Object> timelineMap in (Dictionary<String, Object>)slotMap.Value) {
|
||||
foreach (KeyValuePair<string, Object> timelineMap in (Dictionary<string, Object>)slotMap.Value) {
|
||||
var values = (List<Object>)timelineMap.Value;
|
||||
VertexAttachment attachment = (VertexAttachment)skin.GetAttachment(slotIndex, timelineMap.Key);
|
||||
if (attachment == null) throw new Exception("Deform attachment not found: " + timelineMap.Key);
|
||||
@ -697,7 +696,7 @@ namespace Spine {
|
||||
timeline.attachment = attachment;
|
||||
|
||||
int frameIndex = 0;
|
||||
foreach (Dictionary<String, Object> valueMap in values) {
|
||||
foreach (Dictionary<string, Object> valueMap in values) {
|
||||
float[] deform;
|
||||
if (!valueMap.ContainsKey("vertices")) {
|
||||
deform = weighted ? new float[deformLength] : vertices;
|
||||
@ -734,7 +733,7 @@ namespace Spine {
|
||||
var timeline = new DrawOrderTimeline(values.Count);
|
||||
int slotCount = skeletonData.slots.Count;
|
||||
int frameIndex = 0;
|
||||
foreach (Dictionary<String, Object> drawOrderMap in values) {
|
||||
foreach (Dictionary<string, Object> drawOrderMap in values) {
|
||||
int[] drawOrder = null;
|
||||
if (drawOrderMap.ContainsKey("offsets")) {
|
||||
drawOrder = new int[slotCount];
|
||||
@ -743,8 +742,8 @@ namespace Spine {
|
||||
var offsets = (List<Object>)drawOrderMap["offsets"];
|
||||
int[] unchanged = new int[slotCount - offsets.Count];
|
||||
int originalIndex = 0, unchangedIndex = 0;
|
||||
foreach (Dictionary<String, Object> offsetMap in offsets) {
|
||||
int slotIndex = skeletonData.FindSlotIndex((String)offsetMap["slot"]);
|
||||
foreach (Dictionary<string, Object> offsetMap in offsets) {
|
||||
int slotIndex = skeletonData.FindSlotIndex((string)offsetMap["slot"]);
|
||||
if (slotIndex == -1) throw new Exception("Slot not found: " + offsetMap["slot"]);
|
||||
// Collect unchanged items.
|
||||
while (originalIndex != slotIndex)
|
||||
@ -771,8 +770,8 @@ namespace Spine {
|
||||
var eventsMap = (List<Object>)map["events"];
|
||||
var timeline = new EventTimeline(eventsMap.Count);
|
||||
int frameIndex = 0;
|
||||
foreach (Dictionary<String, Object> eventMap in eventsMap) {
|
||||
EventData eventData = skeletonData.FindEvent((String)eventMap["name"]);
|
||||
foreach (Dictionary<string, Object> eventMap in eventsMap) {
|
||||
EventData eventData = skeletonData.FindEvent((string)eventMap["name"]);
|
||||
if (eventData == null) throw new Exception("Event not found: " + eventMap["name"]);
|
||||
var e = new Event((float)eventMap["time"], eventData);
|
||||
e.Int = GetInt(eventMap, "int", eventData.Int);
|
||||
@ -788,7 +787,7 @@ namespace Spine {
|
||||
skeletonData.animations.Add(new Animation(name, timelines, duration));
|
||||
}
|
||||
|
||||
static void ReadCurve (Dictionary<String, Object> valueMap, CurveTimeline timeline, int frameIndex) {
|
||||
static void ReadCurve (Dictionary<string, Object> valueMap, CurveTimeline timeline, int frameIndex) {
|
||||
if (!valueMap.ContainsKey("curve"))
|
||||
return;
|
||||
Object curveObject = valueMap["curve"];
|
||||
@ -802,11 +801,11 @@ namespace Spine {
|
||||
}
|
||||
|
||||
internal class LinkedMesh {
|
||||
internal String parent, skin;
|
||||
internal string parent, skin;
|
||||
internal int slotIndex;
|
||||
internal MeshAttachment mesh;
|
||||
|
||||
public LinkedMesh (MeshAttachment mesh, String skin, int slotIndex, String parent) {
|
||||
public LinkedMesh (MeshAttachment mesh, string skin, int slotIndex, string parent) {
|
||||
this.mesh = mesh;
|
||||
this.skin = skin;
|
||||
this.slotIndex = slotIndex;
|
||||
@ -814,7 +813,7 @@ namespace Spine {
|
||||
}
|
||||
}
|
||||
|
||||
static float[] GetFloatArray(Dictionary<String, Object> map, String name, float scale) {
|
||||
static float[] GetFloatArray(Dictionary<string, Object> map, string name, float scale) {
|
||||
var list = (List<Object>)map[name];
|
||||
var values = new float[list.Count];
|
||||
if (scale == 1) {
|
||||
@ -827,7 +826,7 @@ namespace Spine {
|
||||
return values;
|
||||
}
|
||||
|
||||
static int[] GetIntArray(Dictionary<String, Object> map, String name) {
|
||||
static int[] GetIntArray(Dictionary<string, Object> map, string name) {
|
||||
var list = (List<Object>)map[name];
|
||||
var values = new int[list.Count];
|
||||
for (int i = 0, n = list.Count; i < n; i++)
|
||||
@ -835,31 +834,31 @@ namespace Spine {
|
||||
return values;
|
||||
}
|
||||
|
||||
static float GetFloat(Dictionary<String, Object> map, String name, float defaultValue) {
|
||||
static float GetFloat(Dictionary<string, Object> map, string name, float defaultValue) {
|
||||
if (!map.ContainsKey(name))
|
||||
return defaultValue;
|
||||
return (float)map[name];
|
||||
}
|
||||
|
||||
static int GetInt(Dictionary<String, Object> map, String name, int defaultValue) {
|
||||
static int GetInt(Dictionary<string, Object> map, string name, int defaultValue) {
|
||||
if (!map.ContainsKey(name))
|
||||
return defaultValue;
|
||||
return (int)(float)map[name];
|
||||
}
|
||||
|
||||
static bool GetBoolean(Dictionary<String, Object> map, String name, bool defaultValue) {
|
||||
static bool GetBoolean(Dictionary<string, Object> map, string name, bool defaultValue) {
|
||||
if (!map.ContainsKey(name))
|
||||
return defaultValue;
|
||||
return (bool)map[name];
|
||||
}
|
||||
|
||||
static String GetString(Dictionary<String, Object> map, String name, String defaultValue) {
|
||||
static string GetString(Dictionary<string, Object> map, string name, string defaultValue) {
|
||||
if (!map.ContainsKey(name))
|
||||
return defaultValue;
|
||||
return (String)map[name];
|
||||
return (string)map[name];
|
||||
}
|
||||
|
||||
static float ToColor(String hexString, int colorIndex, int expectedLength = 8) {
|
||||
static float ToColor(string hexString, int colorIndex, int expectedLength = 8) {
|
||||
if (hexString.Length != expectedLength)
|
||||
throw new ArgumentException("Color hexidecimal length must be " + expectedLength + ", recieved: " + hexString, "hexString");
|
||||
return Convert.ToInt32(hexString.Substring(colorIndex * 2, 2), 16) / (float)255;
|
||||
|
||||
@ -114,7 +114,7 @@ namespace Spine {
|
||||
internal static readonly AttachmentKeyTupleComparer Instance = new AttachmentKeyTupleComparer();
|
||||
|
||||
bool IEqualityComparer<AttachmentKeyTuple>.Equals (AttachmentKeyTuple o1, AttachmentKeyTuple o2) {
|
||||
return o1.slotIndex == o2.slotIndex && o1.nameHashCode == o2.nameHashCode && o1.name == o2.name;
|
||||
return o1.slotIndex == o2.slotIndex && o1.nameHashCode == o2.nameHashCode && string.Equals(o1.name, o2.name, StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
int IEqualityComparer<AttachmentKeyTuple>.GetHashCode (AttachmentKeyTuple o) {
|
||||
|
||||
@ -0,0 +1,84 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes Software License v2.5
|
||||
*
|
||||
* Copyright (c) 2013-2016, Esoteric Software
|
||||
* All rights reserved.
|
||||
*
|
||||
* You are granted a perpetual, non-exclusive, non-sublicensable, and
|
||||
* non-transferable license to use, install, execute, and perform the Spine
|
||||
* Runtimes software and derivative works solely for personal or internal
|
||||
* use. Without the written permission of Esoteric Software (see Section 2 of
|
||||
* the Spine Software License Agreement), you may not (a) modify, translate,
|
||||
* adapt, or develop new applications using the Spine Runtimes or otherwise
|
||||
* create derivative works or improvements of the Spine Runtimes or (b) remove,
|
||||
* delete, alter, or obscure any trademarks or any copyright, trademark, patent,
|
||||
* or other intellectual property or proprietary rights notices on or in the
|
||||
* Software, including any copy thereof. Redistributions in binary or source
|
||||
* form must include this license and terms.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL ESOTERIC SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS INTERRUPTION, OR LOSS OF
|
||||
* USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Spine.Unity {
|
||||
|
||||
public class RegionlessAttachmentLoader : AttachmentLoader {
|
||||
|
||||
static AtlasRegion emptyRegion;
|
||||
static AtlasRegion EmptyRegion {
|
||||
get {
|
||||
if (emptyRegion == null) {
|
||||
emptyRegion = new AtlasRegion {
|
||||
name = "Empty AtlasRegion",
|
||||
page = new AtlasPage {
|
||||
name = "Empty AtlasPage",
|
||||
rendererObject = new Material(Shader.Find("Spine/Special/HiddenPass")) { name = "NoRender Material" }
|
||||
}
|
||||
};
|
||||
}
|
||||
return emptyRegion;
|
||||
}
|
||||
}
|
||||
|
||||
public RegionAttachment NewRegionAttachment (Skin skin, string name, string path) {
|
||||
RegionAttachment attachment = new RegionAttachment(name) {
|
||||
RendererObject = EmptyRegion
|
||||
};
|
||||
return attachment;
|
||||
}
|
||||
|
||||
public MeshAttachment NewMeshAttachment (Skin skin, string name, string path) {
|
||||
MeshAttachment attachment = new MeshAttachment(name) {
|
||||
RendererObject = EmptyRegion
|
||||
};
|
||||
return attachment;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 15f0f78b87720c047a320c5e0e3f91b7
|
||||
timeCreated: 1520505662
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -126,7 +126,7 @@ namespace Spine.Unity {
|
||||
Atlas[] atlasArray = this.GetAtlasArray();
|
||||
|
||||
#if !SPINE_TK2D
|
||||
attachmentLoader = new AtlasAttachmentLoader(atlasArray);
|
||||
attachmentLoader = (atlasArray.Length == 0) ? (AttachmentLoader)new RegionlessAttachmentLoader() : (AttachmentLoader)new AtlasAttachmentLoader(atlasArray);
|
||||
skeletonDataScale = scale;
|
||||
#else
|
||||
if (spriteCollection != null) {
|
||||
|
||||
9
spine-unity/Assets/spine-unity/Components.meta
Normal file
9
spine-unity/Assets/spine-unity/Components.meta
Normal file
@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 954179821df28404683b8289f05d0c6f
|
||||
folderAsset: yes
|
||||
timeCreated: 1518344191
|
||||
licenseType: Free
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -274,6 +274,9 @@ namespace Spine.Unity.Editor {
|
||||
EditorGUILayout.LabelField("spine-tk2d", EditorStyles.boldLabel);
|
||||
EditorGUILayout.PropertyField(spriteCollection, true);
|
||||
#endif
|
||||
|
||||
if (atlasAssets.arraySize == 0)
|
||||
EditorGUILayout.HelpBox("AtlasAssets array is empty. Skeleton's attachments will load without being mapped to images.", MessageType.Info);
|
||||
}
|
||||
|
||||
void HandleAtlasAssetsNulls () {
|
||||
@ -485,7 +488,7 @@ namespace Spine.Unity.Editor {
|
||||
}
|
||||
|
||||
void DrawWarningList () {
|
||||
foreach (var line in warnings)
|
||||
foreach (string line in warnings)
|
||||
EditorGUILayout.LabelField(SpineInspectorUtility.TempContent(line, Icons.warning));
|
||||
}
|
||||
|
||||
@ -525,7 +528,9 @@ namespace Spine.Unity.Editor {
|
||||
if (detectedNullAtlasEntry) {
|
||||
warnings.Add("AtlasAsset elements should not be null.");
|
||||
} else {
|
||||
var missingPaths = SpineEditorUtilities.GetRequiredAtlasRegions(AssetDatabase.GetAssetPath(skeletonJSON.objectReferenceValue));
|
||||
List<string> missingPaths = null;
|
||||
if (atlasAssets.arraySize > 0) {
|
||||
missingPaths = SpineEditorUtilities.GetRequiredAtlasRegions(AssetDatabase.GetAssetPath(skeletonJSON.objectReferenceValue));
|
||||
|
||||
foreach (var atlas in atlasList) {
|
||||
for (int i = 0; i < missingPaths.Count; i++) {
|
||||
@ -540,9 +545,12 @@ namespace Spine.Unity.Editor {
|
||||
if (missingPaths.Count > 0)
|
||||
warnings.Add("Missing regions. SkeletonDataAsset requires tk2DSpriteCollectionData or Spine AtlasAssets.");
|
||||
#endif
|
||||
}
|
||||
|
||||
foreach (var str in missingPaths)
|
||||
if (missingPaths != null) {
|
||||
foreach (string str in missingPaths)
|
||||
warnings.Add("Missing Region: '" + str + "'");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@ -629,7 +637,10 @@ namespace Spine.Unity.Editor {
|
||||
PreviewRenderUtility previewRenderUtility;
|
||||
Camera PreviewUtilityCamera {
|
||||
get {
|
||||
if (previewRenderUtility == null) return null;
|
||||
if (previewRenderUtility == null) {
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
#if UNITY_2017_1_OR_NEWER
|
||||
return previewRenderUtility.camera;
|
||||
@ -770,7 +781,7 @@ namespace Spine.Unity.Editor {
|
||||
skeleton.SetToSetupPose();
|
||||
animationState.SetAnimation(0, targetAnimation, loop);
|
||||
} else {
|
||||
var sameAnimation = (currentTrack.Animation == targetAnimation);
|
||||
bool sameAnimation = (currentTrack.Animation == targetAnimation);
|
||||
if (sameAnimation) {
|
||||
currentTrack.TimeScale = (currentTrack.TimeScale == 0) ? 1f : 0f; // pause/play
|
||||
} else {
|
||||
@ -974,18 +985,19 @@ namespace Spine.Unity.Editor {
|
||||
|
||||
for (int i = 0; i < currentAnimationEvents.Count; i++) {
|
||||
float fr = currentAnimationEventTimes[i];
|
||||
var evRect = new Rect(barRect);
|
||||
evRect.x = Mathf.Clamp(((fr / t.Animation.Duration) * width) - (Icons.userEvent.width / 2), barRect.x, float.MaxValue);
|
||||
evRect.width = Icons.userEvent.width;
|
||||
evRect.height = Icons.userEvent.height;
|
||||
evRect.y += Icons.userEvent.height;
|
||||
var evRect = new Rect(barRect) {
|
||||
x = Mathf.Clamp(((fr / t.Animation.Duration) * width) - (Icons.userEvent.width / 2), barRect.x, float.MaxValue),
|
||||
y = barRect.y + Icons.userEvent.height,
|
||||
width = Icons.userEvent.width,
|
||||
height = Icons.userEvent.height
|
||||
};
|
||||
GUI.DrawTexture(evRect, Icons.userEvent);
|
||||
|
||||
Event ev = Event.current;
|
||||
if (ev.type == EventType.Repaint) {
|
||||
if (evRect.Contains(ev.mousePosition)) {
|
||||
Rect tooltipRect = new Rect(evRect);
|
||||
GUIStyle tooltipStyle = EditorStyles.helpBox;
|
||||
Rect tooltipRect = new Rect(evRect);
|
||||
tooltipRect.width = tooltipStyle.CalcSize(new GUIContent(currentAnimationEvents[i].Data.Name)).x;
|
||||
tooltipRect.y -= 4;
|
||||
tooltipRect.x += 4;
|
||||
|
||||
@ -155,16 +155,15 @@ namespace Spine.Unity.Editor {
|
||||
public static string editorGUIPath = "";
|
||||
public static bool initialized;
|
||||
|
||||
/// This list keeps the asset reference temporarily during importing.
|
||||
/// HACK: This list keeps the asset reference temporarily during importing.
|
||||
///
|
||||
/// In cases of very large projects/sufficient RAM pressure, when AssetDatabase.SaveAssets is called,
|
||||
/// Unity can mistakenly unload assets whose references are only on the stack.
|
||||
/// This leads to MissingReferenceException and other errors.
|
||||
static readonly List<ScriptableObject> protectFromStackGarbageCollection = new List<ScriptableObject>();
|
||||
static HashSet<string> assetsImportedInWrongState;
|
||||
static Dictionary<int, GameObject> skeletonRendererTable;
|
||||
static Dictionary<int, SkeletonUtilityBone> skeletonUtilityBoneTable;
|
||||
static Dictionary<int, BoundingBoxFollower> boundingBoxFollowerTable;
|
||||
static HashSet<string> assetsImportedInWrongState = new HashSet<string>();
|
||||
|
||||
|
||||
|
||||
#if SPINE_TK2D
|
||||
const float DEFAULT_DEFAULT_SCALE = 1f;
|
||||
@ -220,29 +219,23 @@ namespace Spine.Unity.Editor {
|
||||
|
||||
Icons.Initialize();
|
||||
|
||||
assetsImportedInWrongState = new HashSet<string>();
|
||||
skeletonRendererTable = new Dictionary<int, GameObject>();
|
||||
skeletonUtilityBoneTable = new Dictionary<int, SkeletonUtilityBone>();
|
||||
boundingBoxFollowerTable = new Dictionary<int, BoundingBoxFollower>();
|
||||
|
||||
// Drag and Drop
|
||||
SceneView.onSceneGUIDelegate -= SceneViewDragAndDrop;
|
||||
SceneView.onSceneGUIDelegate += SceneViewDragAndDrop;
|
||||
EditorApplication.hierarchyWindowItemOnGUI -= HierarchyDragAndDrop;
|
||||
EditorApplication.hierarchyWindowItemOnGUI += HierarchyDragAndDrop;
|
||||
EditorApplication.hierarchyWindowItemOnGUI -= SpineEditorHierarchyHandler.HierarchyDragAndDrop;
|
||||
EditorApplication.hierarchyWindowItemOnGUI += SpineEditorHierarchyHandler.HierarchyDragAndDrop;
|
||||
|
||||
// Hierarchy Icons
|
||||
#if UNITY_2017_2_OR_NEWER
|
||||
EditorApplication.playModeStateChanged -= HierarchyIconsOnPlaymodeStateChanged;
|
||||
EditorApplication.playModeStateChanged += HierarchyIconsOnPlaymodeStateChanged;
|
||||
HierarchyIconsOnPlaymodeStateChanged(PlayModeStateChange.EnteredEditMode);
|
||||
EditorApplication.playModeStateChanged -= SpineEditorHierarchyHandler.HierarchyIconsOnPlaymodeStateChanged;
|
||||
EditorApplication.playModeStateChanged += SpineEditorHierarchyHandler.HierarchyIconsOnPlaymodeStateChanged;
|
||||
SpineEditorHierarchyHandler.HierarchyIconsOnPlaymodeStateChanged(PlayModeStateChange.EnteredEditMode);
|
||||
#else
|
||||
EditorApplication.playmodeStateChanged -= HierarchyIconsOnPlaymodeStateChanged;
|
||||
EditorApplication.playmodeStateChanged += HierarchyIconsOnPlaymodeStateChanged;
|
||||
HierarchyIconsOnPlaymodeStateChanged();
|
||||
EditorApplication.playmodeStateChanged -= SpineEditorHierarchyHandler.HierarchyIconsOnPlaymodeStateChanged;
|
||||
EditorApplication.playmodeStateChanged += SpineEditorHierarchyHandler.HierarchyIconsOnPlaymodeStateChanged;
|
||||
SpineEditorHierarchyHandler.HierarchyIconsOnPlaymodeStateChanged();
|
||||
#endif
|
||||
|
||||
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
@ -265,9 +258,9 @@ namespace Spine.Unity.Editor {
|
||||
if (EditorGUI.EndChangeCheck()) {
|
||||
EditorPrefs.SetBool(SHOW_HIERARCHY_ICONS_KEY, showHierarchyIcons);
|
||||
#if UNITY_2017_2_OR_NEWER
|
||||
HierarchyIconsOnPlaymodeStateChanged(PlayModeStateChange.EnteredEditMode);
|
||||
SpineEditorHierarchyHandler.HierarchyIconsOnPlaymodeStateChanged(PlayModeStateChange.EnteredEditMode);
|
||||
#else
|
||||
HierarchyIconsOnPlaymodeStateChanged();
|
||||
SpineEditorHierarchyHandler.HierarchyIconsOnPlaymodeStateChanged();
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -323,10 +316,9 @@ namespace Spine.Unity.Editor {
|
||||
#endregion
|
||||
|
||||
#region Drag and Drop Instantiation
|
||||
|
||||
public delegate Component InstantiateDelegate (SkeletonDataAsset skeletonDataAsset);
|
||||
|
||||
struct SpawnMenuData {
|
||||
public struct SpawnMenuData {
|
||||
public Vector3 spawnPoint;
|
||||
public SkeletonDataAsset skeletonDataAsset;
|
||||
public InstantiateDelegate instantiateDelegate;
|
||||
@ -339,7 +331,7 @@ namespace Spine.Unity.Editor {
|
||||
public bool isUI;
|
||||
}
|
||||
|
||||
public static readonly List<SkeletonComponentSpawnType> additionalSpawnTypes = new List<SkeletonComponentSpawnType>();
|
||||
internal static readonly List<SkeletonComponentSpawnType> additionalSpawnTypes = new List<SkeletonComponentSpawnType>();
|
||||
|
||||
static void SceneViewDragAndDrop (SceneView sceneview) {
|
||||
var current = UnityEngine.Event.current;
|
||||
@ -378,45 +370,6 @@ namespace Spine.Unity.Editor {
|
||||
}
|
||||
}
|
||||
|
||||
static void HierarchyDragAndDrop (int instanceId, Rect selectionRect) {
|
||||
// HACK: Uses EditorApplication.hierarchyWindowItemOnGUI.
|
||||
// Only works when there is at least one item in the scene.
|
||||
var current = UnityEngine.Event.current;
|
||||
var eventType = current.type;
|
||||
bool isDraggingEvent = eventType == EventType.DragUpdated;
|
||||
bool isDropEvent = eventType == EventType.DragPerform;
|
||||
if (isDraggingEvent || isDropEvent) {
|
||||
var mouseOverWindow = EditorWindow.mouseOverWindow;
|
||||
if (mouseOverWindow != null) {
|
||||
|
||||
// One, existing, valid SkeletonDataAsset
|
||||
var references = DragAndDrop.objectReferences;
|
||||
if (references.Length == 1) {
|
||||
var skeletonDataAsset = references[0] as SkeletonDataAsset;
|
||||
if (skeletonDataAsset != null && skeletonDataAsset.GetSkeletonData(true) != null) {
|
||||
|
||||
// Allow drag-and-dropping anywhere in the Hierarchy Window.
|
||||
// HACK: string-compare because we can't get its type via reflection.
|
||||
const string HierarchyWindow = "UnityEditor.SceneHierarchyWindow";
|
||||
if (HierarchyWindow.Equals(mouseOverWindow.GetType().ToString(), System.StringComparison.Ordinal)) {
|
||||
if (isDraggingEvent) {
|
||||
DragAndDrop.visualMode = DragAndDropVisualMode.Copy;
|
||||
current.Use();
|
||||
} else if (isDropEvent) {
|
||||
ShowInstantiateContextMenu(skeletonDataAsset, Vector3.zero);
|
||||
DragAndDrop.AcceptDrag();
|
||||
current.Use();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void ShowInstantiateContextMenu (SkeletonDataAsset skeletonDataAsset, Vector3 spawnPoint) {
|
||||
var menu = new GenericMenu();
|
||||
|
||||
@ -454,8 +407,8 @@ namespace Spine.Unity.Editor {
|
||||
menu.ShowAsContext();
|
||||
}
|
||||
|
||||
public static void HandleSkeletonComponentDrop (object menuData) {
|
||||
var data = (SpawnMenuData)menuData;
|
||||
public static void HandleSkeletonComponentDrop (object spawnMenuData) {
|
||||
var data = (SpawnMenuData)spawnMenuData;
|
||||
|
||||
if (data.skeletonDataAsset.GetSkeletonData(true) == null) {
|
||||
EditorUtility.DisplayDialog("Invalid SkeletonDataAsset", "Unable to create Spine GameObject.\n\nPlease check your SkeletonDataAsset.", "Ok");
|
||||
@ -464,16 +417,15 @@ namespace Spine.Unity.Editor {
|
||||
|
||||
bool isUI = data.isUI;
|
||||
|
||||
GameObject newGameObject = null;
|
||||
Component newSkeletonComponent = data.instantiateDelegate.Invoke(data.skeletonDataAsset);
|
||||
newGameObject = newSkeletonComponent.gameObject;
|
||||
var transform = newGameObject.transform;
|
||||
GameObject newGameObject = newSkeletonComponent.gameObject;
|
||||
Transform newTransform = newGameObject.transform;
|
||||
|
||||
var activeGameObject = Selection.activeGameObject;
|
||||
if (isUI && activeGameObject != null)
|
||||
transform.SetParent(activeGameObject.transform, false);
|
||||
newTransform.SetParent(activeGameObject.transform, false);
|
||||
|
||||
newGameObject.transform.position = isUI ? data.spawnPoint : RoundVector(data.spawnPoint, 2);
|
||||
newTransform.position = isUI ? data.spawnPoint : RoundVector(data.spawnPoint, 2);
|
||||
|
||||
if (isUI && (activeGameObject == null || activeGameObject.GetComponent<RectTransform>() == null))
|
||||
Debug.Log("Created a UI Skeleton GameObject not under a RectTransform. It may not be visible until you parent it to a canvas.");
|
||||
@ -509,10 +461,15 @@ namespace Spine.Unity.Editor {
|
||||
#endregion
|
||||
|
||||
#region Hierarchy
|
||||
static class SpineEditorHierarchyHandler {
|
||||
static Dictionary<int, GameObject> skeletonRendererTable = new Dictionary<int, GameObject>();
|
||||
static Dictionary<int, SkeletonUtilityBone> skeletonUtilityBoneTable = new Dictionary<int, SkeletonUtilityBone>();
|
||||
static Dictionary<int, BoundingBoxFollower> boundingBoxFollowerTable = new Dictionary<int, BoundingBoxFollower>();
|
||||
|
||||
#if UNITY_2017_2_OR_NEWER
|
||||
static void HierarchyIconsOnPlaymodeStateChanged (PlayModeStateChange stateChange) {
|
||||
internal static void HierarchyIconsOnPlaymodeStateChanged (PlayModeStateChange stateChange) {
|
||||
#else
|
||||
static void HierarchyIconsOnPlaymodeStateChanged () {
|
||||
internal static void HierarchyIconsOnPlaymodeStateChanged () {
|
||||
#endif
|
||||
skeletonRendererTable.Clear();
|
||||
skeletonUtilityBoneTable.Clear();
|
||||
@ -528,25 +485,25 @@ namespace Spine.Unity.Editor {
|
||||
}
|
||||
}
|
||||
|
||||
static void HierarchyIconsOnChanged () {
|
||||
internal static void HierarchyIconsOnChanged () {
|
||||
skeletonRendererTable.Clear();
|
||||
skeletonUtilityBoneTable.Clear();
|
||||
boundingBoxFollowerTable.Clear();
|
||||
|
||||
SkeletonRenderer[] arr = Object.FindObjectsOfType<SkeletonRenderer>();
|
||||
foreach (SkeletonRenderer r in arr)
|
||||
skeletonRendererTable.Add(r.gameObject.GetInstanceID(), r.gameObject);
|
||||
skeletonRendererTable[r.gameObject.GetInstanceID()] = r.gameObject;
|
||||
|
||||
SkeletonUtilityBone[] boneArr = Object.FindObjectsOfType<SkeletonUtilityBone>();
|
||||
foreach (SkeletonUtilityBone b in boneArr)
|
||||
skeletonUtilityBoneTable.Add(b.gameObject.GetInstanceID(), b);
|
||||
skeletonUtilityBoneTable[b.gameObject.GetInstanceID()] = b;
|
||||
|
||||
BoundingBoxFollower[] bbfArr = Object.FindObjectsOfType<BoundingBoxFollower>();
|
||||
foreach (BoundingBoxFollower bbf in bbfArr)
|
||||
boundingBoxFollowerTable.Add(bbf.gameObject.GetInstanceID(), bbf);
|
||||
boundingBoxFollowerTable[bbf.gameObject.GetInstanceID()] = bbf;
|
||||
}
|
||||
|
||||
static void HierarchyIconsOnGUI (int instanceId, Rect selectionRect) {
|
||||
internal static void HierarchyIconsOnGUI (int instanceId, Rect selectionRect) {
|
||||
Rect r = new Rect(selectionRect);
|
||||
if (skeletonRendererTable.ContainsKey(instanceId)) {
|
||||
r.x = r.width - 15;
|
||||
@ -577,6 +534,46 @@ namespace Spine.Unity.Editor {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static void HierarchyDragAndDrop (int instanceId, Rect selectionRect) {
|
||||
// HACK: Uses EditorApplication.hierarchyWindowItemOnGUI.
|
||||
// Only works when there is at least one item in the scene.
|
||||
var current = UnityEngine.Event.current;
|
||||
var eventType = current.type;
|
||||
bool isDraggingEvent = eventType == EventType.DragUpdated;
|
||||
bool isDropEvent = eventType == EventType.DragPerform;
|
||||
if (isDraggingEvent || isDropEvent) {
|
||||
var mouseOverWindow = EditorWindow.mouseOverWindow;
|
||||
if (mouseOverWindow != null) {
|
||||
|
||||
// One, existing, valid SkeletonDataAsset
|
||||
var references = DragAndDrop.objectReferences;
|
||||
if (references.Length == 1) {
|
||||
var skeletonDataAsset = references[0] as SkeletonDataAsset;
|
||||
if (skeletonDataAsset != null && skeletonDataAsset.GetSkeletonData(true) != null) {
|
||||
|
||||
// Allow drag-and-dropping anywhere in the Hierarchy Window.
|
||||
// HACK: string-compare because we can't get its type via reflection.
|
||||
const string HierarchyWindow = "UnityEditor.SceneHierarchyWindow";
|
||||
if (HierarchyWindow.Equals(mouseOverWindow.GetType().ToString(), System.StringComparison.Ordinal)) {
|
||||
if (isDraggingEvent) {
|
||||
DragAndDrop.visualMode = DragAndDropVisualMode.Copy;
|
||||
current.Use();
|
||||
} else if (isDropEvent) {
|
||||
ShowInstantiateContextMenu(skeletonDataAsset, Vector3.zero);
|
||||
DragAndDrop.AcceptDrag();
|
||||
current.Use();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Auto-Import Entry Point
|
||||
@ -669,7 +666,7 @@ namespace Spine.Unity.Editor {
|
||||
bool resolved = false;
|
||||
while (!resolved) {
|
||||
|
||||
var filename = Path.GetFileNameWithoutExtension(sp);
|
||||
string filename = Path.GetFileNameWithoutExtension(sp);
|
||||
int result = EditorUtility.DisplayDialogComplex(
|
||||
string.Format("AtlasAsset for \"{0}\"", filename),
|
||||
string.Format("Could not automatically set the AtlasAsset for \"{0}\". You may set it manually.", filename),
|
||||
@ -1243,7 +1240,8 @@ namespace Spine.Unity.Editor {
|
||||
#endregion
|
||||
|
||||
#region Checking Methods
|
||||
static int[][] compatibleVersions = { new[] {3, 6, 0}, new[] {3, 5, 0} };
|
||||
static int[][] compatibleBinaryVersions = { new[] {3, 6, 0}, new[] {3, 5, 0} };
|
||||
static int[][] compatibleJsonVersions = { new[] { 3, 6, 0 }, new[] { 3, 7, 0 }, new[] { 3, 5, 0 } };
|
||||
//static bool isFixVersionRequired = false;
|
||||
|
||||
static bool CheckForValidSkeletonData (string skeletonJSONPath) {
|
||||
@ -1269,17 +1267,18 @@ namespace Spine.Unity.Editor {
|
||||
bool isSpineData = false;
|
||||
string rawVersion = null;
|
||||
|
||||
int[][] compatibleVersions;
|
||||
if (asset.name.Contains(".skel")) {
|
||||
try {
|
||||
rawVersion = SkeletonBinary.GetVersionString(new MemoryStream(asset.bytes));
|
||||
//Debug.Log(rawVersion);
|
||||
isSpineData = !(string.IsNullOrEmpty(rawVersion));
|
||||
compatibleVersions = compatibleBinaryVersions;
|
||||
} catch (System.Exception e) {
|
||||
Debug.LogErrorFormat("Failed to read '{0}'. It is likely not a binary Spine SkeletonData file.\n{1}", asset.name, e);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
var obj = Json.Deserialize(new StringReader(asset.text));
|
||||
object obj = Json.Deserialize(new StringReader(asset.text));
|
||||
if (obj == null) {
|
||||
Debug.LogErrorFormat("'{0}' is not valid JSON.", asset.name);
|
||||
return false;
|
||||
@ -1298,14 +1297,16 @@ namespace Spine.Unity.Editor {
|
||||
skeletonInfo.TryGetValue("spine", out jv);
|
||||
rawVersion = jv as string;
|
||||
}
|
||||
|
||||
compatibleVersions = compatibleJsonVersions;
|
||||
}
|
||||
|
||||
// Version warning
|
||||
if (isSpineData) {
|
||||
string runtimeVersionDebugString = compatibleVersions[0][0] + "." + compatibleVersions[0][1];
|
||||
string primaryRuntimeVersionDebugString = compatibleVersions[0][0] + "." + compatibleVersions[0][1];
|
||||
|
||||
if (string.IsNullOrEmpty(rawVersion)) {
|
||||
Debug.LogWarningFormat("Skeleton '{0}' has no version information. It may be incompatible with your runtime version: spine-unity v{1}", asset.name, runtimeVersionDebugString);
|
||||
Debug.LogWarningFormat("Skeleton '{0}' has no version information. It may be incompatible with your runtime version: spine-unity v{1}", asset.name, primaryRuntimeVersionDebugString);
|
||||
} else {
|
||||
string[] versionSplit = rawVersion.Split('.');
|
||||
bool match = false;
|
||||
@ -1322,7 +1323,7 @@ namespace Spine.Unity.Editor {
|
||||
}
|
||||
|
||||
if (!match)
|
||||
Debug.LogWarningFormat("Skeleton '{0}' (exported with Spine {1}) may be incompatible with your runtime version: spine-unity v{2}", asset.name, rawVersion, runtimeVersionDebugString);
|
||||
Debug.LogWarningFormat("Skeleton '{0}' (exported with Spine {1}) may be incompatible with your runtime version: spine-unity v{2}", asset.name, rawVersion, primaryRuntimeVersionDebugString);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1657,11 +1658,12 @@ namespace Spine.Unity.Editor {
|
||||
public static GUIStyle BoneNameStyle {
|
||||
get {
|
||||
if (_boneNameStyle == null) {
|
||||
_boneNameStyle = new GUIStyle(EditorStyles.whiteMiniLabel);
|
||||
_boneNameStyle.alignment = TextAnchor.MiddleCenter;
|
||||
_boneNameStyle.stretchWidth = true;
|
||||
_boneNameStyle.padding = new RectOffset(0, 0, 0, 0);
|
||||
_boneNameStyle.contentOffset = new Vector2(-5f, 0f);
|
||||
_boneNameStyle = new GUIStyle(EditorStyles.whiteMiniLabel) {
|
||||
alignment = TextAnchor.MiddleCenter,
|
||||
stretchWidth = true,
|
||||
padding = new RectOffset(0, 0, 0, 0),
|
||||
contentOffset = new Vector2(-5f, 0f)
|
||||
};
|
||||
}
|
||||
return _boneNameStyle;
|
||||
}
|
||||
@ -1983,7 +1985,7 @@ namespace Spine.Unity.Editor {
|
||||
}
|
||||
|
||||
static void DrawArrowhead (Matrix4x4 m) {
|
||||
var s = SpineHandles.handleScale;
|
||||
float s = SpineHandles.handleScale;
|
||||
m.m00 *= s;
|
||||
m.m01 *= s;
|
||||
m.m02 *= s;
|
||||
|
||||
@ -86,13 +86,34 @@ namespace Spine.Unity.Editor {
|
||||
#region SerializedProperty Helpers
|
||||
public static SerializedProperty FindBaseOrSiblingProperty (this SerializedProperty property, string propertyName) {
|
||||
if (string.IsNullOrEmpty(propertyName)) return null;
|
||||
|
||||
SerializedProperty relativeProperty = property.serializedObject.FindProperty(propertyName); // baseProperty
|
||||
if (relativeProperty == null) { // If no baseProperty, find sibling property.
|
||||
int nameLength = property.name.Length;
|
||||
|
||||
// If base property is not found, look for the sibling property.
|
||||
if (relativeProperty == null) {
|
||||
string propertyPath = property.propertyPath;
|
||||
propertyPath = propertyPath.Remove(propertyPath.Length - nameLength, nameLength) + propertyName;
|
||||
int localPathLength = 0;
|
||||
|
||||
if (property.isArray) {
|
||||
const int internalArrayPathLength = 14; // int arrayPathLength = ".Array.data[x]".Length;
|
||||
int propertyPathLength = propertyPath.Length;
|
||||
int n = propertyPathLength - internalArrayPathLength;
|
||||
// Find the dot before the array property name and
|
||||
// store the total length from the name of the array until the end of the propertyPath.
|
||||
for (int i = internalArrayPathLength + 1; i < n; i++) {
|
||||
if (propertyPath[propertyPathLength - i] == '.') {
|
||||
localPathLength = i - 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
localPathLength = property.name.Length;
|
||||
}
|
||||
|
||||
propertyPath = propertyPath.Remove(propertyPath.Length - localPathLength, localPathLength) + propertyName;
|
||||
relativeProperty = property.serializedObject.FindProperty(propertyPath);
|
||||
}
|
||||
|
||||
return relativeProperty;
|
||||
}
|
||||
#endregion
|
||||
|
||||
@ -113,6 +113,7 @@ Shader "Spine/Skeleton Lit" {
|
||||
float3 eyePos = UnityObjectToViewPos(float4(v.pos, 1)).xyz; //mul(UNITY_MATRIX_MV, float4(v.pos,1)).xyz;
|
||||
half3 fixedNormal = half3(0,0,-1);
|
||||
half3 eyeNormal = normalize(mul((float3x3)UNITY_MATRIX_IT_MV, fixedNormal));
|
||||
//half3 eyeNormal = half3(0,0,1);
|
||||
half3 viewDir = 0.0;
|
||||
|
||||
// Lights
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user