|
@@ -68,8 +68,29 @@ namespace Spine.Unity {
|
|
|
public float timeScale = 1f;
|
|
|
public bool freeze;
|
|
|
|
|
|
- /// <summary>Update mode to optionally limit updates to e.g. only apply animations but not update the mesh.</summary>
|
|
|
- public UpdateMode UpdateMode { get { return updateMode; } set { updateMode = value; } }
|
|
|
+ public enum LayoutMode {
|
|
|
+ None = 0,
|
|
|
+ WidthControlsHeight,
|
|
|
+ HeightControlsWidth,
|
|
|
+ FitInParent,
|
|
|
+ EnvelopeParent
|
|
|
+ }
|
|
|
+ public LayoutMode layoutScaleMode = LayoutMode.None;
|
|
|
+ [SerializeField] protected Vector2 referenceSize = Vector2.one;
|
|
|
+ [SerializeField] protected float referenceScale = 1f;
|
|
|
+#if UNITY_EDITOR
|
|
|
+ protected LayoutMode previousLayoutScaleMode = LayoutMode.None;
|
|
|
+ [SerializeField] protected Vector2 rectTransformSize = Vector2.zero;
|
|
|
+ [SerializeField] protected bool editReferenceRect = false;
|
|
|
+ protected bool previousEditReferenceRect = false;
|
|
|
+
|
|
|
+ public bool EditReferenceRect { get { return editReferenceRect; } set { editReferenceRect = value; } }
|
|
|
+ public Vector2 RectTransformSize { get { return rectTransformSize; } }
|
|
|
+#else
|
|
|
+ protected const bool EditReferenceRect = false;
|
|
|
+#endif
|
|
|
+/// <summary>Update mode to optionally limit updates to e.g. only apply animations but not update the mesh.</summary>
|
|
|
+public UpdateMode UpdateMode { get { return updateMode; } set { updateMode = value; } }
|
|
|
protected UpdateMode updateMode = UpdateMode.FullUpdate;
|
|
|
|
|
|
/// <summary>Update mode used when the MeshRenderer becomes invisible
|
|
@@ -273,6 +294,10 @@ namespace Spine.Unity {
|
|
|
Initialize(false);
|
|
|
Rebuild(CanvasUpdate.PreRender);
|
|
|
}
|
|
|
+
|
|
|
+#if UNITY_EDITOR
|
|
|
+ InitLayoutScaleParameters();
|
|
|
+#endif
|
|
|
}
|
|
|
|
|
|
protected override void OnDestroy () {
|
|
@@ -297,6 +322,7 @@ namespace Spine.Unity {
|
|
|
public virtual void Update () {
|
|
|
#if UNITY_EDITOR
|
|
|
if (!Application.isPlaying) {
|
|
|
+ UpdateReferenceRectSizes();
|
|
|
Update(0f);
|
|
|
return;
|
|
|
}
|
|
@@ -316,7 +342,6 @@ namespace Spine.Unity {
|
|
|
wasUpdatedAfterInit = true;
|
|
|
if (updateMode < UpdateMode.OnlyAnimationStatus)
|
|
|
return;
|
|
|
-
|
|
|
UpdateAnimationStatus(deltaTime);
|
|
|
|
|
|
if (updateMode == UpdateMode.OnlyAnimationStatus) {
|
|
@@ -547,15 +572,26 @@ namespace Spine.Unity {
|
|
|
0.5f - (center.y / size.y)
|
|
|
);
|
|
|
|
|
|
- this.rectTransform.sizeDelta = size;
|
|
|
+ SetRectTransformSize(this, size);
|
|
|
this.rectTransform.pivot = p;
|
|
|
|
|
|
foreach (SkeletonSubmeshGraphic submeshGraphic in submeshGraphics) {
|
|
|
- submeshGraphic.rectTransform.sizeDelta = size;
|
|
|
+ SetRectTransformSize(submeshGraphic, size);
|
|
|
submeshGraphic.rectTransform.pivot = p;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ public static void SetRectTransformSize (Graphic target, Vector2 size) {
|
|
|
+ Vector2 parentSize = Vector2.zero;
|
|
|
+ if (target.rectTransform.parent != null) {
|
|
|
+ RectTransform parentTransform = target.rectTransform.parent.GetComponent<RectTransform>();
|
|
|
+ if (parentTransform)
|
|
|
+ parentSize = parentTransform.rect.size;
|
|
|
+ }
|
|
|
+ Vector2 anchorAreaSize = target.rectTransform.anchorMax * parentSize - target.rectTransform.anchorMin * parentSize;
|
|
|
+ target.rectTransform.sizeDelta = size - anchorAreaSize;
|
|
|
+ }
|
|
|
+
|
|
|
/// <summary>OnAnimationRebuild is raised after the SkeletonAnimation component is successfully initialized.</summary>
|
|
|
public event ISkeletonAnimationDelegate OnAnimationRebuild;
|
|
|
public event UpdateBonesDelegate BeforeApply;
|
|
@@ -731,7 +767,13 @@ namespace Spine.Unity {
|
|
|
meshGenerator.BuildMeshWithArrays(currentInstructions, updateTriangles);
|
|
|
}
|
|
|
|
|
|
- if (canvas != null) meshGenerator.ScaleVertexData(canvas.referencePixelsPerUnit);
|
|
|
+ float scale = (canvas == null) ? 100 : canvas.referencePixelsPerUnit;
|
|
|
+ if (layoutScaleMode != LayoutMode.None) {
|
|
|
+ scale *= referenceScale;
|
|
|
+ if (!EditReferenceRect)
|
|
|
+ scale *= GetLayoutScale(layoutScaleMode);
|
|
|
+ }
|
|
|
+ meshGenerator.ScaleVertexData(scale);
|
|
|
if (OnPostProcessVertices != null) OnPostProcessVertices.Invoke(this.meshGenerator.Buffers);
|
|
|
|
|
|
Mesh mesh = smartMesh.mesh;
|
|
@@ -803,9 +845,12 @@ namespace Spine.Unity {
|
|
|
}
|
|
|
|
|
|
protected void UpdateMeshMultipleCanvasRenderers (SkeletonRendererInstruction currentInstructions) {
|
|
|
- Canvas c = canvas;
|
|
|
- float scale = (c == null) ? 100 : c.referencePixelsPerUnit;
|
|
|
-
|
|
|
+ float scale = (canvas == null) ? 100 : canvas.referencePixelsPerUnit;
|
|
|
+ if (layoutScaleMode != LayoutMode.None) {
|
|
|
+ scale *= referenceScale;
|
|
|
+ if (!EditReferenceRect)
|
|
|
+ scale *= GetLayoutScale(layoutScaleMode);
|
|
|
+ }
|
|
|
// Generate meshes.
|
|
|
int submeshCount = currentInstructions.submeshInstructions.Count;
|
|
|
Mesh[] meshesItems = meshes.Items;
|
|
@@ -893,14 +938,19 @@ namespace Spine.Unity {
|
|
|
|
|
|
for (int i = 0; i < submeshCount; i++) {
|
|
|
CanvasRenderer canvasRenderer = canvasRenderers[i];
|
|
|
- if (i >= usedRenderersCount) {
|
|
|
+ if (i >= usedRenderersCount)
|
|
|
canvasRenderer.gameObject.SetActive(true);
|
|
|
- }
|
|
|
- if (canvasRenderer.transform.parent != parent.transform) {
|
|
|
+
|
|
|
+ if (canvasRenderer.transform.parent != parent.transform)
|
|
|
canvasRenderer.transform.SetParent(parent.transform, false);
|
|
|
- canvasRenderer.transform.localPosition = Vector3.zero;
|
|
|
- }
|
|
|
+
|
|
|
canvasRenderer.transform.SetSiblingIndex(targetSiblingIndex++);
|
|
|
+ RectTransform dstTransform = submeshGraphics[i].rectTransform;
|
|
|
+ dstTransform.localPosition = Vector3.zero;
|
|
|
+ dstTransform.pivot = rectTransform.pivot;
|
|
|
+ dstTransform.anchorMin = Vector2.zero;
|
|
|
+ dstTransform.anchorMax = Vector2.one;
|
|
|
+ dstTransform.sizeDelta = Vector2.zero;
|
|
|
|
|
|
SubmeshInstruction submeshInstructionItem = currentInstructions.submeshInstructions.Items[i];
|
|
|
if (submeshInstructionItem.forceSeparate) {
|
|
@@ -1027,6 +1077,87 @@ namespace Spine.Unity {
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ protected void InitLayoutScaleParameters () {
|
|
|
+ previousLayoutScaleMode = layoutScaleMode;
|
|
|
+ }
|
|
|
+
|
|
|
+ protected void UpdateReferenceRectSizes () {
|
|
|
+ if (rectTransformSize == Vector2.zero)
|
|
|
+ rectTransformSize = GetCurrentRectSize();
|
|
|
+
|
|
|
+ HandleChangedEditReferenceRect();
|
|
|
+
|
|
|
+ if (layoutScaleMode != previousLayoutScaleMode) {
|
|
|
+ if (layoutScaleMode != LayoutMode.None) {
|
|
|
+ SetRectTransformSize(this, rectTransformSize);
|
|
|
+ } else {
|
|
|
+ rectTransformSize = referenceSize / referenceScale;
|
|
|
+ referenceScale = 1f;
|
|
|
+ SetRectTransformSize(this, rectTransformSize);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (editReferenceRect || layoutScaleMode == LayoutMode.None) {
|
|
|
+ referenceSize = GetCurrentRectSize();
|
|
|
+ }
|
|
|
+ previousLayoutScaleMode = layoutScaleMode;
|
|
|
+ }
|
|
|
+
|
|
|
+ protected void HandleChangedEditReferenceRect () {
|
|
|
+ if (editReferenceRect == previousEditReferenceRect) return;
|
|
|
+ previousEditReferenceRect = editReferenceRect;
|
|
|
+
|
|
|
+ if (editReferenceRect) {
|
|
|
+ rectTransformSize = GetCurrentRectSize();
|
|
|
+ ResetRectToReferenceRectSize();
|
|
|
+ } else {
|
|
|
+ SetRectTransformSize(this, rectTransformSize);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public void ResetRectToReferenceRectSize () {
|
|
|
+ referenceScale = referenceScale * GetLayoutScale(previousLayoutScaleMode);
|
|
|
+ float referenceAspect = referenceSize.x / referenceSize.y;
|
|
|
+ Vector2 newSize = GetCurrentRectSize();
|
|
|
+
|
|
|
+ LayoutMode mode = previousLayoutScaleMode;
|
|
|
+ float frameAspect = newSize.x / newSize.y;
|
|
|
+ if (mode == LayoutMode.FitInParent)
|
|
|
+ mode = frameAspect > referenceAspect ? LayoutMode.HeightControlsWidth : LayoutMode.WidthControlsHeight;
|
|
|
+ else if (mode == LayoutMode.EnvelopeParent)
|
|
|
+ mode = frameAspect > referenceAspect ? LayoutMode.WidthControlsHeight : LayoutMode.HeightControlsWidth;
|
|
|
+
|
|
|
+ if (mode == LayoutMode.WidthControlsHeight)
|
|
|
+ newSize.y = newSize.x / referenceAspect;
|
|
|
+ else if (mode == LayoutMode.HeightControlsWidth)
|
|
|
+ newSize.x = newSize.y * referenceAspect;
|
|
|
+ SetRectTransformSize(this, newSize);
|
|
|
+ }
|
|
|
+
|
|
|
+ public Vector2 GetReferenceRectSize () {
|
|
|
+ return referenceSize * GetLayoutScale(layoutScaleMode);
|
|
|
+ }
|
|
|
#endif
|
|
|
+
|
|
|
+ protected float GetLayoutScale (LayoutMode mode) {
|
|
|
+ Vector2 currentSize = GetCurrentRectSize();
|
|
|
+ float referenceAspect = referenceSize.x / referenceSize.y;
|
|
|
+ float frameAspect = currentSize.x / currentSize.y;
|
|
|
+ if (mode == LayoutMode.FitInParent)
|
|
|
+ mode = frameAspect > referenceAspect ? LayoutMode.HeightControlsWidth : LayoutMode.WidthControlsHeight;
|
|
|
+ else if (mode == LayoutMode.EnvelopeParent)
|
|
|
+ mode = frameAspect > referenceAspect ? LayoutMode.WidthControlsHeight : LayoutMode.HeightControlsWidth;
|
|
|
+
|
|
|
+ if (mode == LayoutMode.WidthControlsHeight) {
|
|
|
+ return currentSize.x / referenceSize.x;
|
|
|
+ } else if (mode == LayoutMode.HeightControlsWidth) {
|
|
|
+ return currentSize.y / referenceSize.y;
|
|
|
+ }
|
|
|
+ return 1f;
|
|
|
+ }
|
|
|
+
|
|
|
+ private Vector2 GetCurrentRectSize () {
|
|
|
+ return this.rectTransform.rect.size;
|
|
|
+ }
|
|
|
}
|
|
|
}
|