Merge pull request #8 from EsotericSoftware/master

Merging with official runtime.
This commit is contained in:
John 2015-12-19 15:24:36 +08:00
commit 55136345ae
11 changed files with 207 additions and 107 deletions

View File

@ -86,7 +86,13 @@ namespace Spine {
using (var input = new BufferedStream(Microsoft.Xna.Framework.TitleContainer.OpenStream(path))) using (var input = new BufferedStream(Microsoft.Xna.Framework.TitleContainer.OpenStream(path)))
{ {
#else #else
using (var input = new BufferedStream(new FileStream(path, FileMode.Open))) { #if UNITY_WP8 || UNITY_WP8_1
using (var input = new FileStream(path, FileMode.Open))
{
#else
using (var input = new BufferedStream(new FileStream(path, FileMode.Open)))
{
#endif
#endif #endif
SkeletonData skeletonData = ReadSkeletonData(input); SkeletonData skeletonData = ReadSkeletonData(input);
skeletonData.name = Path.GetFileNameWithoutExtension(path); skeletonData.name = Path.GetFileNameWithoutExtension(path);

View File

@ -18,7 +18,11 @@ public class RaggedySpineboy : MonoBehaviour {
void AddRigidbody () { void AddRigidbody () {
var rb = gameObject.AddComponent<Rigidbody2D>(); var rb = gameObject.AddComponent<Rigidbody2D>();
#if UNITY_5_1
rb.freezeRotation = true;
#else
rb.fixedAngle = true; rb.fixedAngle = true;
#endif
naturalCollider.enabled = true; naturalCollider.enabled = true;
} }

View File

@ -0,0 +1,21 @@
using UnityEngine;
namespace Spine {
public static class AssetDatabaseAvailabilityDetector {
const string MARKER_RESOURCE_NAME = "SpineAssetDatabaseMarker";
private static bool _isMarkerLoaded;
public static bool IsAssetDatabaseAvailable (bool forceCheck = false) {
if (!forceCheck && _isMarkerLoaded)
return true;
TextAsset markerTextAsset = Resources.Load<TextAsset>(MARKER_RESOURCE_NAME);
_isMarkerLoaded = markerTextAsset != null;
if (markerTextAsset != null) {
Resources.UnloadAsset(markerTextAsset);
}
return _isMarkerLoaded;
}
}
}

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 25086cd81e3158b439761b73d7366c47
timeCreated: 1444587791
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 24903fdac57ee784b9597fcb751ec22f
folderAsset: yes
timeCreated: 1444565388
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1 @@
DO NOT MOVE OR DELETE THIS FILE

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 57281c00bdd90ad4392f811f2b9f0da1
timeCreated: 1444565392
licenseType: Pro
TextScriptImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@ -149,6 +149,7 @@ public class SpineEditorUtilities : AssetPostprocessor {
public static string editorPath = ""; public static string editorPath = "";
public static string editorGUIPath = ""; public static string editorGUIPath = "";
static HashSet<string> assetsImportedInWrongState;
static Dictionary<int, GameObject> skeletonRendererTable; static Dictionary<int, GameObject> skeletonRendererTable;
static Dictionary<int, SkeletonUtilityBone> skeletonUtilityBoneTable; static Dictionary<int, SkeletonUtilityBone> skeletonUtilityBoneTable;
static Dictionary<int, BoundingBoxFollower> boundingBoxFollowerTable; static Dictionary<int, BoundingBoxFollower> boundingBoxFollowerTable;
@ -173,6 +174,7 @@ public class SpineEditorUtilities : AssetPostprocessor {
Icons.Initialize(); Icons.Initialize();
assetsImportedInWrongState = new HashSet<string>();
skeletonRendererTable = new Dictionary<int, GameObject>(); skeletonRendererTable = new Dictionary<int, GameObject>();
skeletonUtilityBoneTable = new Dictionary<int, SkeletonUtilityBone>(); skeletonUtilityBoneTable = new Dictionary<int, SkeletonUtilityBone>();
boundingBoxFollowerTable = new Dictionary<int, BoundingBoxFollower>(); boundingBoxFollowerTable = new Dictionary<int, BoundingBoxFollower>();
@ -254,8 +256,34 @@ public class SpineEditorUtilities : AssetPostprocessor {
} }
static void OnPostprocessAllAssets (string[] imported, string[] deleted, string[] moved, string[] movedFromAssetPaths) { static void OnPostprocessAllAssets (string[] imported, string[] deleted, string[] moved, string[] movedFromAssetPaths) {
ImportSpineContent(imported, false); if (imported.Length == 0)
return;
// In case user used "Assets -> Reimport All", during the import process,
// asset database is not initialized until some point. During that period,
// all attempts to load any assets using API (i.e. AssetDatabase.LoadAssetAtPath)
// will return null, and as result, assets won't be loaded even if they actually exists,
// which may lead to numerous importing errors.
// This situation also happens if Library folder is deleted from the project, which is a pretty
// common case, since when using version control systems, the Library folder must be excluded.
//
// So to avoid this, in case asset database is not available, we delay loading the assets
// until next time.
//
// Unity *always* reimports some internal assets after the process is done, so this method
// is always called once again in a state when asset database is available.
//
// Checking whether AssetDatabase is initialized is done by attempting to load
// a known "marker" asset that should always be available. Failing to load this asset
// means that AssetDatabase is not initialized.
assetsImportedInWrongState.UnionWith(imported);
if (AssetDatabaseAvailabilityDetector.IsAssetDatabaseAvailable()) {
string[] combinedAssets = assetsImportedInWrongState.ToArray();
assetsImportedInWrongState.Clear();
ImportSpineContent(combinedAssets);
}
} }
public static void ImportSpineContent (string[] imported, bool reimport = false) { public static void ImportSpineContent (string[] imported, bool reimport = false) {
List<string> atlasPaths = new List<string>(); List<string> atlasPaths = new List<string>();
List<string> imagePaths = new List<string>(); List<string> imagePaths = new List<string>();
@ -410,12 +438,32 @@ public class SpineEditorUtilities : AssetPostprocessor {
string guid = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(skeletonDataAsset)); string guid = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(skeletonDataAsset));
string lastHash = EditorPrefs.GetString(guid + "_hash"); string lastHash = EditorPrefs.GetString(guid + "_hash");
if (lastHash != skeletonDataAsset.GetSkeletonData(true).Hash) { // For some weird reason sometimes Unity loses the internal Object pointer,
// and as a result, all comparisons with null returns true.
// But the C# wrapper is still alive, so we can "restore" the object
// by reloading it from its Instance ID.
AtlasAsset[] skeletonDataAtlasAssets = skeletonDataAsset.atlasAssets;
if (skeletonDataAtlasAssets != null) {
for (int i = 0; i < skeletonDataAtlasAssets.Length; i++) {
if (!ReferenceEquals(null, skeletonDataAtlasAssets[i]) &&
skeletonDataAtlasAssets[i].Equals(null) &&
skeletonDataAtlasAssets[i].GetInstanceID() != 0
) {
skeletonDataAtlasAssets[i] = EditorUtility.InstanceIDToObject(skeletonDataAtlasAssets[i].GetInstanceID()) as AtlasAsset;
}
}
}
SkeletonData skeletonData = skeletonDataAsset.GetSkeletonData(true);
string currentHash = skeletonData != null ? skeletonData.Hash : null;
if (currentHash == null || lastHash != currentHash) {
//do any upkeep on synchronized assets //do any upkeep on synchronized assets
UpdateMecanimClips(skeletonDataAsset); UpdateMecanimClips(skeletonDataAsset);
} }
EditorPrefs.SetString(guid + "_hash", skeletonDataAsset.GetSkeletonData(true).Hash); if (currentHash != null) {
EditorPrefs.SetString(guid + "_hash", currentHash);
}
} }
} }
} }

View File

@ -102,7 +102,8 @@ public class SkeletonAnimator : SkeletonRenderer, ISkeletonAnimation {
if (mode == MixMode.AlwaysMix) { if (mode == MixMode.AlwaysMix) {
//always use Mix instead of Applying the first non-zero weighted clip //always use Mix instead of Applying the first non-zero weighted clip
foreach (var info in clipInfo) { for (int c = 0; c < clipInfo.Length; c++) {
var info = clipInfo[c];
float weight = info.weight * layerWeight; float weight = info.weight * layerWeight;
if (weight == 0) if (weight == 0)
continue; continue;
@ -111,13 +112,16 @@ public class SkeletonAnimator : SkeletonRenderer, ISkeletonAnimation {
animationTable[GetAnimationClipNameHashCode(info.clip)].Mix(skeleton, Mathf.Max(0, time - deltaTime), time, stateInfo.loop, null, weight); animationTable[GetAnimationClipNameHashCode(info.clip)].Mix(skeleton, Mathf.Max(0, time - deltaTime), time, stateInfo.loop, null, weight);
} }
foreach (var info in nextClipInfo) { if (nextStateInfo.fullPathHash != 0) {
float weight = info.weight * layerWeight; for (int c = 0; c < nextClipInfo.Length; c++) {
if (weight == 0) var info = nextClipInfo[c];
continue; float weight = info.weight * layerWeight;
if (weight == 0)
continue;
float time = nextStateInfo.normalizedTime * info.clip.length; float time = nextStateInfo.normalizedTime * info.clip.length;
animationTable[GetAnimationClipNameHashCode(info.clip)].Mix(skeleton, Mathf.Max(0, time - deltaTime), time, nextStateInfo.loop, null, weight); animationTable[GetAnimationClipNameHashCode(info.clip)].Mix(skeleton, Mathf.Max(0, time - deltaTime), time, nextStateInfo.loop, null, weight);
}
} }
} else if (mode >= MixMode.MixNext) { } else if (mode >= MixMode.MixNext) {
//apply first non-zero weighted clip //apply first non-zero weighted clip
@ -147,8 +151,22 @@ public class SkeletonAnimator : SkeletonRenderer, ISkeletonAnimation {
c = 0; c = 0;
//apply next clip directly instead of mixing (ie: no crossfade, ignores mecanim transition weights) if (nextStateInfo.fullPathHash != 0) {
if (mode == MixMode.SpineStyle) { //apply next clip directly instead of mixing (ie: no crossfade, ignores mecanim transition weights)
if (mode == MixMode.SpineStyle) {
for (; c < nextClipInfo.Length; c++) {
var info = nextClipInfo[c];
float weight = info.weight * layerWeight;
if (weight == 0)
continue;
float time = nextStateInfo.normalizedTime * info.clip.length;
animationTable[GetAnimationClipNameHashCode(info.clip)].Apply(skeleton, Mathf.Max(0, time - deltaTime), time, nextStateInfo.loop, null);
break;
}
}
//mix the rest
for (; c < nextClipInfo.Length; c++) { for (; c < nextClipInfo.Length; c++) {
var info = nextClipInfo[c]; var info = nextClipInfo[c];
float weight = info.weight * layerWeight; float weight = info.weight * layerWeight;
@ -156,21 +174,9 @@ public class SkeletonAnimator : SkeletonRenderer, ISkeletonAnimation {
continue; continue;
float time = nextStateInfo.normalizedTime * info.clip.length; float time = nextStateInfo.normalizedTime * info.clip.length;
animationTable[GetAnimationClipNameHashCode(info.clip)].Apply(skeleton, Mathf.Max(0, time - deltaTime), time, nextStateInfo.loop, null); animationTable[GetAnimationClipNameHashCode(info.clip)].Mix(skeleton, Mathf.Max(0, time - deltaTime), time, nextStateInfo.loop, null, weight);
break;
} }
} }
//mix the rest
for (; c < nextClipInfo.Length; c++) {
var info = nextClipInfo[c];
float weight = info.weight * layerWeight;
if (weight == 0)
continue;
float time = nextStateInfo.normalizedTime * info.clip.length;
animationTable[GetAnimationClipNameHashCode(info.clip)].Mix(skeleton, Mathf.Max(0, time - deltaTime), time, nextStateInfo.loop, null, weight);
}
} }
} }

View File

@ -71,7 +71,7 @@ public class SkeletonRenderer : MonoBehaviour {
private readonly ExposedList<Material> submeshMaterials = new ExposedList<Material>(); private readonly ExposedList<Material> submeshMaterials = new ExposedList<Material>();
private readonly ExposedList<Submesh> submeshes = new ExposedList<Submesh>(); private readonly ExposedList<Submesh> submeshes = new ExposedList<Submesh>();
private SkeletonUtilitySubmeshRenderer[] submeshRenderers; private SkeletonUtilitySubmeshRenderer[] submeshRenderers;
private LastState lastState = new LastState(); private MeshState meshState = new MeshState();
public virtual void Reset () { public virtual void Reset () {
if (meshFilter != null) if (meshFilter != null)
@ -94,7 +94,7 @@ public class SkeletonRenderer : MonoBehaviour {
DestroyImmediate(mesh2); DestroyImmediate(mesh2);
} }
lastState = new LastState(); meshState = new MeshState();
mesh1 = null; mesh1 = null;
mesh2 = null; mesh2 = null;
vertices = null; vertices = null;
@ -193,15 +193,11 @@ public class SkeletonRenderer : MonoBehaviour {
bool renderMeshes = this.renderMeshes; bool renderMeshes = this.renderMeshes;
// Clear last state of attachments and submeshes // Clear last state of attachments and submeshes
ExposedList<int> attachmentsTriangleCountTemp = lastState.attachmentsTriangleCountTemp; MeshState.SingleMeshState stateTemp = meshState.stateTemp;
attachmentsTriangleCountTemp.GrowIfNeeded(drawOrderCount); stateTemp.attachments.Clear(true);
attachmentsTriangleCountTemp.Count = drawOrderCount; stateTemp.UpdateDrawOrderCount(drawOrderCount);
ExposedList<bool> attachmentsFlipStateTemp = lastState.attachmentsFlipStateTemp;
attachmentsFlipStateTemp.GrowIfNeeded(drawOrderCount);
attachmentsFlipStateTemp.Count = drawOrderCount;
ExposedList<LastState.AddSubmeshArguments> addSubmeshArgumentsTemp = lastState.addSubmeshArgumentsTemp; stateTemp.addSubmeshArguments.Clear(false);
addSubmeshArgumentsTemp.Clear(false);
for (int i = 0; i < drawOrderCount; i++) { for (int i = 0; i < drawOrderCount; i++) {
Slot slot = drawOrder.Items[i]; Slot slot = drawOrder.Items[i];
Bone bone = slot.bone; Bone bone = slot.bone;
@ -214,9 +210,9 @@ public class SkeletonRenderer : MonoBehaviour {
bool worldScaleIsSameSigns = (worldScaleXIsPositive && worldScaleYIsPositive) || bool worldScaleIsSameSigns = (worldScaleXIsPositive && worldScaleYIsPositive) ||
(!worldScaleXIsPositive && !worldScaleYIsPositive); (!worldScaleXIsPositive && !worldScaleYIsPositive);
bool flip = frontFacing && ((bone.worldFlipX != bone.worldFlipY) == worldScaleIsSameSigns); bool flip = frontFacing && ((bone.worldFlipX != bone.worldFlipY) == worldScaleIsSameSigns);
attachmentsFlipStateTemp.Items[i] = flip; stateTemp.attachmentsFlipState.Items[i] = flip;
attachmentsTriangleCountTemp.Items[i] = -1; stateTemp.attachments.Items[i] = attachment;
RegionAttachment regionAttachment = attachment as RegionAttachment; RegionAttachment regionAttachment = attachment as RegionAttachment;
if (regionAttachment != null) { if (regionAttachment != null) {
rendererObject = regionAttachment.RendererObject; rendererObject = regionAttachment.RendererObject;
@ -249,8 +245,8 @@ public class SkeletonRenderer : MonoBehaviour {
#endif #endif
if ((lastMaterial != null && lastMaterial.GetInstanceID() != material.GetInstanceID()) || if ((lastMaterial != null && lastMaterial.GetInstanceID() != material.GetInstanceID()) ||
(submeshSeparatorSlotsCount > 0 && submeshSeparatorSlots.Contains(slot))) { (submeshSeparatorSlotsCount > 0 && submeshSeparatorSlots.Contains(slot))) {
addSubmeshArgumentsTemp.Add( stateTemp.addSubmeshArguments.Add(
new LastState.AddSubmeshArguments(lastMaterial, submeshStartSlotIndex, i, submeshTriangleCount, submeshFirstVertex, false) new MeshState.AddSubmeshArguments(lastMaterial, submeshStartSlotIndex, i, submeshTriangleCount, submeshFirstVertex, false)
); );
submeshTriangleCount = 0; submeshTriangleCount = 0;
submeshFirstVertex = vertexCount; submeshFirstVertex = vertexCount;
@ -260,18 +256,16 @@ public class SkeletonRenderer : MonoBehaviour {
submeshTriangleCount += attachmentTriangleCount; submeshTriangleCount += attachmentTriangleCount;
vertexCount += attachmentVertexCount; vertexCount += attachmentVertexCount;
attachmentsTriangleCountTemp.Items[i] = attachmentTriangleCount;
} }
addSubmeshArgumentsTemp.Add( stateTemp.addSubmeshArguments.Add(
new LastState.AddSubmeshArguments(lastMaterial, submeshStartSlotIndex, drawOrderCount, submeshTriangleCount, submeshFirstVertex, true) new MeshState.AddSubmeshArguments(lastMaterial, submeshStartSlotIndex, drawOrderCount, submeshTriangleCount, submeshFirstVertex, true)
); );
bool mustUpdateMeshStructure = CheckIfMustUpdateMeshStructure(attachmentsTriangleCountTemp, attachmentsFlipStateTemp, addSubmeshArgumentsTemp); bool mustUpdateMeshStructure = CheckIfMustUpdateMeshStructure(stateTemp.attachments, stateTemp.attachmentsFlipState, stateTemp.addSubmeshArguments);
if (mustUpdateMeshStructure) { if (mustUpdateMeshStructure) {
submeshMaterials.Clear(); submeshMaterials.Clear();
for (int i = 0, n = addSubmeshArgumentsTemp.Count; i < n; i++) { for (int i = 0, n = stateTemp.addSubmeshArguments.Count; i < n; i++) {
LastState.AddSubmeshArguments arguments = addSubmeshArgumentsTemp.Items[i]; MeshState.AddSubmeshArguments arguments = stateTemp.addSubmeshArguments.Items[i];
AddSubmesh( AddSubmesh(
arguments.material, arguments.material,
arguments.startSlot, arguments.startSlot,
@ -279,7 +273,7 @@ public class SkeletonRenderer : MonoBehaviour {
arguments.triangleCount, arguments.triangleCount,
arguments.firstVertex, arguments.firstVertex,
arguments.lastSubmesh, arguments.lastSubmesh,
attachmentsFlipStateTemp stateTemp.attachmentsFlipState
); );
} }
@ -305,10 +299,10 @@ public class SkeletonRenderer : MonoBehaviour {
} else { } else {
// Too many vertices, zero the extra. // Too many vertices, zero the extra.
Vector3 zero = Vector3.zero; Vector3 zero = Vector3.zero;
for (int i = vertexCount, n = lastState.vertexCount; i < n; i++) for (int i = vertexCount, n = meshState.vertexCount; i < n; i++)
vertices[i] = zero; vertices[i] = zero;
} }
lastState.vertexCount = vertexCount; meshState.vertexCount = vertexCount;
// Setup mesh. // Setup mesh.
float zSpacing = this.zSpacing; float zSpacing = this.zSpacing;
@ -534,32 +528,21 @@ public class SkeletonRenderer : MonoBehaviour {
} }
// Update previous state // Update previous state
ExposedList<int> attachmentsTriangleCountCurrentMesh; MeshState.SingleMeshState currentMeshState = useMesh1 ? meshState.stateMesh1 : meshState.stateMesh2;
ExposedList<bool> attachmentsFlipStateCurrentMesh; currentMeshState.immutableTriangles = immutableTriangles;
ExposedList<LastState.AddSubmeshArguments> addSubmeshArgumentsCurrentMesh;
if (useMesh1) {
attachmentsTriangleCountCurrentMesh = lastState.attachmentsTriangleCountMesh1;
addSubmeshArgumentsCurrentMesh = lastState.addSubmeshArgumentsMesh1;
attachmentsFlipStateCurrentMesh = lastState.attachmentsFlipStateMesh1;
lastState.immutableTrianglesMesh1 = immutableTriangles;
} else {
attachmentsTriangleCountCurrentMesh = lastState.attachmentsTriangleCountMesh2;
addSubmeshArgumentsCurrentMesh = lastState.addSubmeshArgumentsMesh2;
attachmentsFlipStateCurrentMesh = lastState.attachmentsFlipStateMesh2;
lastState.immutableTrianglesMesh2 = immutableTriangles;
}
attachmentsTriangleCountCurrentMesh.GrowIfNeeded(attachmentsTriangleCountTemp.Capacity); currentMeshState.attachments.Clear(true);
attachmentsTriangleCountCurrentMesh.Count = attachmentsTriangleCountTemp.Count; currentMeshState.attachments.GrowIfNeeded(stateTemp.attachments.Capacity);
attachmentsTriangleCountTemp.CopyTo(attachmentsTriangleCountCurrentMesh.Items, 0); currentMeshState.attachments.Count = stateTemp.attachments.Count;
stateTemp.attachments.CopyTo(currentMeshState.attachments.Items);
attachmentsFlipStateCurrentMesh.GrowIfNeeded(attachmentsFlipStateTemp.Capacity); currentMeshState.attachmentsFlipState.GrowIfNeeded(stateTemp.attachmentsFlipState.Capacity);
attachmentsFlipStateCurrentMesh.Count = attachmentsFlipStateTemp.Count; currentMeshState.attachmentsFlipState.Count = stateTemp.attachmentsFlipState.Count;
attachmentsFlipStateTemp.CopyTo(attachmentsFlipStateCurrentMesh.Items, 0); stateTemp.attachmentsFlipState.CopyTo(currentMeshState.attachmentsFlipState.Items);
addSubmeshArgumentsCurrentMesh.GrowIfNeeded(addSubmeshArgumentsTemp.Count); currentMeshState.addSubmeshArguments.GrowIfNeeded(stateTemp.addSubmeshArguments.Capacity);
addSubmeshArgumentsCurrentMesh.Count = addSubmeshArgumentsTemp.Count; currentMeshState.addSubmeshArguments.Count = stateTemp.addSubmeshArguments.Count;
addSubmeshArgumentsTemp.CopyTo(addSubmeshArgumentsCurrentMesh.Items); stateTemp.addSubmeshArguments.CopyTo(currentMeshState.addSubmeshArguments.Items);
if (submeshRenderers.Length > 0) { if (submeshRenderers.Length > 0) {
for (int i = 0; i < submeshRenderers.Length; i++) { for (int i = 0; i < submeshRenderers.Length; i++) {
@ -575,39 +558,33 @@ public class SkeletonRenderer : MonoBehaviour {
useMesh1 = !useMesh1; useMesh1 = !useMesh1;
} }
private bool CheckIfMustUpdateMeshStructure (ExposedList<int> attachmentsTriangleCountTemp, ExposedList<bool> attachmentsFlipStateTemp, ExposedList<LastState.AddSubmeshArguments> addSubmeshArgumentsTemp) { private bool CheckIfMustUpdateMeshStructure (ExposedList<Attachment> attachmentsTemp, ExposedList<bool> attachmentsFlipStateTemp, ExposedList<MeshState.AddSubmeshArguments> addSubmeshArgumentsTemp) {
#if UNITY_EDITOR
if (!Application.isPlaying)
return true;
#endif
// Check if any mesh settings were changed // Check if any mesh settings were changed
bool mustUpdateMeshStructure = bool mustUpdateMeshStructure =
immutableTriangles != (useMesh1 ? lastState.immutableTrianglesMesh1 : lastState.immutableTrianglesMesh2); immutableTriangles != (useMesh1 ? meshState.stateMesh1.immutableTriangles : meshState.stateMesh2.immutableTriangles);
#if UNITY_EDITOR
mustUpdateMeshStructure |= !Application.isPlaying;
#endif
if (mustUpdateMeshStructure) if (mustUpdateMeshStructure)
return true; return true;
// Check if any attachments were enabled/disabled // Check if any attachments were enabled/disabled
// or submesh structures has changed // or submesh structures has changed
ExposedList<int> attachmentsTriangleCountCurrentMesh; MeshState.SingleMeshState currentMeshState = useMesh1 ? meshState.stateMesh1 : meshState.stateMesh2;
ExposedList<bool> attachmentsFlipStateCurrentMesh; ExposedList<Attachment> attachmentsCurrentMesh = currentMeshState.attachments;
ExposedList<LastState.AddSubmeshArguments> addSubmeshArgumentsCurrentMesh; ExposedList<MeshState.AddSubmeshArguments> addSubmeshArgumentsCurrentMesh = currentMeshState.addSubmeshArguments;
if (useMesh1) { ExposedList<bool> attachmentsFlipStateCurrentMesh = currentMeshState.attachmentsFlipState;
attachmentsTriangleCountCurrentMesh = lastState.attachmentsTriangleCountMesh1;
addSubmeshArgumentsCurrentMesh = lastState.addSubmeshArgumentsMesh1;
attachmentsFlipStateCurrentMesh = lastState.attachmentsFlipStateMesh1;
} else {
attachmentsTriangleCountCurrentMesh = lastState.attachmentsTriangleCountMesh2;
addSubmeshArgumentsCurrentMesh = lastState.addSubmeshArgumentsMesh2;
attachmentsFlipStateCurrentMesh = lastState.attachmentsFlipStateMesh2;
}
// Check attachments // Check attachments
int attachmentCount = attachmentsTriangleCountTemp.Count; int attachmentCount = attachmentsTemp.Count;
if (attachmentsTriangleCountCurrentMesh.Count != attachmentCount) if (attachmentsCurrentMesh.Count != attachmentCount)
return true; return true;
for (int i = 0; i < attachmentCount; i++) { for (int i = 0; i < attachmentCount; i++) {
if (attachmentsTriangleCountCurrentMesh.Items[i] != attachmentsTriangleCountTemp.Items[i]) if (attachmentsCurrentMesh.Items[i] != attachmentsTemp.Items[i])
return true; return true;
} }
@ -749,19 +726,26 @@ public class SkeletonRenderer : MonoBehaviour {
} }
#endif #endif
private class LastState { private class MeshState {
public bool immutableTrianglesMesh1;
public bool immutableTrianglesMesh2;
public int vertexCount; public int vertexCount;
public readonly ExposedList<bool> attachmentsFlipStateTemp = new ExposedList<bool>(); public readonly SingleMeshState stateTemp = new SingleMeshState();
public readonly ExposedList<bool> attachmentsFlipStateMesh1 = new ExposedList<bool>(); public readonly SingleMeshState stateMesh1 = new SingleMeshState();
public readonly ExposedList<bool> attachmentsFlipStateMesh2 = new ExposedList<bool>(); public readonly SingleMeshState stateMesh2 = new SingleMeshState();
public readonly ExposedList<int> attachmentsTriangleCountTemp = new ExposedList<int>();
public readonly ExposedList<int> attachmentsTriangleCountMesh1 = new ExposedList<int>(); public class SingleMeshState {
public readonly ExposedList<int> attachmentsTriangleCountMesh2 = new ExposedList<int>(); public bool immutableTriangles;
public readonly ExposedList<AddSubmeshArguments> addSubmeshArgumentsTemp = new ExposedList<AddSubmeshArguments>(); public readonly ExposedList<Attachment> attachments = new ExposedList<Attachment>();
public readonly ExposedList<AddSubmeshArguments> addSubmeshArgumentsMesh1 = new ExposedList<AddSubmeshArguments>(); public readonly ExposedList<bool> attachmentsFlipState = new ExposedList<bool>();
public readonly ExposedList<AddSubmeshArguments> addSubmeshArgumentsMesh2 = new ExposedList<AddSubmeshArguments>(); public readonly ExposedList<AddSubmeshArguments> addSubmeshArguments = new ExposedList<AddSubmeshArguments>();
public void UpdateDrawOrderCount(int drawOrderCount) {
attachmentsFlipState.GrowIfNeeded(drawOrderCount);
attachmentsFlipState.Count = drawOrderCount;
attachments.GrowIfNeeded(drawOrderCount);
attachments.Count = drawOrderCount;
}
}
public struct AddSubmeshArguments { public struct AddSubmeshArguments {
public Material material; public Material material;

View File

@ -71,6 +71,7 @@ public class SkeletonUtilityGroundConstraint : SkeletonUtilityConstraint {
protected override void OnEnable () { protected override void OnEnable () {
base.OnEnable(); base.OnEnable();
lastHitY = transform.position.y;
} }
protected override void OnDisable () { protected override void OnDisable () {