mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-02-06 23:34:53 +08:00
Merge branch '3.8' into 3.9-beta
This commit is contained in:
commit
3bdd39a409
@ -357,6 +357,9 @@
|
||||
4) Assign this *_Outline* material at the `RenderExistingMesh` component under *Replacement Materials*.
|
||||
* Added `Outline Shaders URP` example scene to URP extension module to demonstrate the above additions.
|
||||
* Added support for Unity's [`SpriteAtlas`](https://docs.unity3d.com/Manual/class-SpriteAtlas.html) as atlas provider (as an alternative to `.atlas.txt` and `.png` files) alongside a skeleton data file. There is now an additional `Spine SpriteAtlas Import` tool window accessible via `Window - Spine - SpriteAtlas Import`. Additional information can be found in a new section on the [spine-unity documentation page](http://esotericsoftware.com/spine-unity#Advanced---Using-Unity-SpriteAtlas-as-Atlas-Provider).
|
||||
* Added support for **multiple atlas textures at `SkeletonGraphic`**. You can enable this feature by enabling the parameter `Multiple CanvasRenders` in the `Advanced` section of the `SkeletonGraphic` Inspector. This automatically creates the required number of child `CanvasRenderer` GameObjects for each required draw call (submesh).
|
||||
* Added support for **Render Separator Slots** at `SkeletonGraphic`. Render separation can be enabled directly in the `Advanced` section of the `SkeletonGraphic` Inspector, it does not require any additional components (like `SkeletonRenderSeparator` or `SkeletonPartsRenderer` for `SkeletonRenderer` components). When enabled, additional separator GameObjects will be created automatically for each separation part, and `CanvasRenderer` GameObjects re-parented to them accordingly. The separator GameObjects can be moved around and re-parented in the hierarchy according to your requirements to achieve the desired draw order within your `Canvas`. A usage example can be found in the updated `Spine Examples/Other Examples/SkeletonRenderSeparator` scene.
|
||||
* Added `SkeletonGraphicCustomMaterials` component, providing functionality to override materials and textures of a `SkeletonGraphic`, similar to `SkeletonRendererCustomMaterials`. Note: overriding materials or textures per slot is not provided due to structural limitations.
|
||||
|
||||
* **Changes of default values**
|
||||
* `SkeletonMecanim`'s `Layer Mix Mode` now defaults to `MixMode.MixNext` instead of `MixMode.MixAlways`.
|
||||
|
||||
Binary file not shown.
@ -143,6 +143,8 @@ package spine {
|
||||
var prx : Number = 0;
|
||||
if (s > 0.0001) {
|
||||
s = Math.abs(pa * pd - pb * pc) / s;
|
||||
pa /= this.skeleton.scaleX;
|
||||
pc /= this.skeleton.scaleY;
|
||||
pb = pc * s;
|
||||
pd = pa * s;
|
||||
prx = Math.atan2(pc, pa) * MathUtils.radDeg;
|
||||
@ -161,7 +163,7 @@ package spine {
|
||||
this.b = pa * lb - pb * ld;
|
||||
this.c = pc * la + pd * lc;
|
||||
this.d = pc * lb + pd * ld;
|
||||
return;
|
||||
break;
|
||||
}
|
||||
case TransformMode.noScale:
|
||||
case TransformMode.noScaleOrReflection: {
|
||||
|
||||
@ -385,6 +385,7 @@ int spAnimationState_apply (spAnimationState* self, spSkeleton* skeleton) {
|
||||
timelines = current->animation->timelines;
|
||||
if ((i == 0 && mix == 1) || blend == SP_MIX_BLEND_ADD) {
|
||||
for (ii = 0; ii < timelineCount; ii++) {
|
||||
timeline = timelines[ii];
|
||||
if (timeline->type == SP_TIMELINE_ATTACHMENT) {
|
||||
_spAnimationState_applyAttachmentTimeline(self, timeline, skeleton, animationTime, blend, -1);
|
||||
} else {
|
||||
|
||||
@ -144,6 +144,8 @@ function Bone:updateWorldTransformWith (x, y, rotation, scaleX, scaleY, shearX,
|
||||
local prx = 0
|
||||
if s > 0.0001 then
|
||||
s = math_abs(pa * pd - pb * pc) / s
|
||||
pa = pa / self.skeleton.scaleX
|
||||
pc = pc / self.skeleton.scaleY
|
||||
pb = pc * s
|
||||
pd = pa * s
|
||||
prx = math_deg(math_atan2(pc, pa));
|
||||
|
||||
Binary file not shown.
@ -108,6 +108,42 @@ NavMeshSettings:
|
||||
tileSize: 256
|
||||
accuratePlacement: 0
|
||||
m_NavMeshData: {fileID: 0}
|
||||
--- !u!1 &33325432
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
serializedVersion: 5
|
||||
m_Component:
|
||||
- component: {fileID: 33325433}
|
||||
m_Layer: 5
|
||||
m_Name: SkeletonGraphic with Separator
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &33325433
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
m_GameObject: {fileID: 33325432}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children:
|
||||
- {fileID: 835737018}
|
||||
- {fileID: 1738423300}
|
||||
- {fileID: 1185404038}
|
||||
m_Father: {fileID: 624843597}
|
||||
m_RootOrder: 3
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0.5, y: 0.5}
|
||||
m_AnchorMax: {x: 0.5, y: 0.5}
|
||||
m_AnchoredPosition: {x: 314.43, y: -527.6}
|
||||
m_SizeDelta: {x: 176.7, y: 265.7}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!1 &51877969
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@ -202,6 +238,74 @@ RectTransform:
|
||||
m_AnchoredPosition: {x: 6.56, y: -2.09}
|
||||
m_SizeDelta: {x: 452.17, y: 108.32}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!1 &84997716
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
serializedVersion: 5
|
||||
m_Component:
|
||||
- component: {fileID: 84997717}
|
||||
- component: {fileID: 84997719}
|
||||
- component: {fileID: 84997718}
|
||||
m_Layer: 5
|
||||
m_Name: GreenBar1
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &84997717
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
m_GameObject: {fileID: 84997716}
|
||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 1738423300}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0.5, y: 0.5}
|
||||
m_AnchorMax: {x: 0.5, y: 0.5}
|
||||
m_AnchoredPosition: {x: -0.0000038146973, y: -0.00012207031}
|
||||
m_SizeDelta: {x: 36.8, y: 183.94}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!114 &84997718
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
m_GameObject: {fileID: 84997716}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 0.3529412, g: 0.56078434, b: 0.10980393, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
|
||||
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
m_Sprite: {fileID: 0}
|
||||
m_Type: 0
|
||||
m_PreserveAspect: 0
|
||||
m_FillCenter: 1
|
||||
m_FillMethod: 4
|
||||
m_FillAmount: 1
|
||||
m_FillClockwise: 1
|
||||
m_FillOrigin: 0
|
||||
--- !u!222 &84997719
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
m_GameObject: {fileID: 84997716}
|
||||
--- !u!1 &93048074
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@ -328,6 +432,90 @@ Transform:
|
||||
m_Father: {fileID: 0}
|
||||
m_RootOrder: 4
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!1 &105238416
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
serializedVersion: 5
|
||||
m_Component:
|
||||
- component: {fileID: 105238417}
|
||||
- component: {fileID: 105238419}
|
||||
- component: {fileID: 105238418}
|
||||
m_Layer: 5
|
||||
m_Name: Text SkeletonGraphic
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &105238417
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
m_GameObject: {fileID: 105238416}
|
||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 0.99999994}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 624843597}
|
||||
m_RootOrder: 1
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 1, y: 1}
|
||||
m_AnchoredPosition: {x: -101, y: -527.6}
|
||||
m_SizeDelta: {x: 256.3, y: 63}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!114 &105238418
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
m_GameObject: {fileID: 105238416}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 708705254, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
|
||||
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
m_FontData:
|
||||
m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
|
||||
m_FontSize: 18
|
||||
m_FontStyle: 0
|
||||
m_BestFit: 0
|
||||
m_MinSize: 1
|
||||
m_MaxSize: 77
|
||||
m_Alignment: 0
|
||||
m_AlignByGeometry: 0
|
||||
m_RichText: 1
|
||||
m_HorizontalOverflow: 0
|
||||
m_VerticalOverflow: 1
|
||||
m_LineSpacing: 1
|
||||
m_Text: 'Spineboy to the right is an example of SkeletonGraphics render separation
|
||||
functionality.
|
||||
|
||||
The separator slots are setup via the SkeletonGraphics Advanced Inspector section.
|
||||
|
||||
|
||||
The separator can be enabled via ''SkeletonGraphic.enableSeparatorSlots''.
|
||||
|
||||
Please note that ''Multiple Canvas Renderers'' must be enabled.
|
||||
|
||||
'
|
||||
--- !u!222 &105238419
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
m_GameObject: {fileID: 105238416}
|
||||
--- !u!1 &122287539
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@ -409,6 +597,40 @@ Transform:
|
||||
m_Father: {fileID: 1918225119}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!1 &415442239
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
serializedVersion: 5
|
||||
m_Component:
|
||||
- component: {fileID: 415442240}
|
||||
m_Layer: 0
|
||||
m_Name: Part[1]
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &415442240
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
m_GameObject: {fileID: 415442239}
|
||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children:
|
||||
- {fileID: 1211557619}
|
||||
m_Father: {fileID: 1185404038}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0.5, y: 0.5}
|
||||
m_AnchorMax: {x: 0.5, y: 0.5}
|
||||
m_AnchoredPosition: {x: 35.678116, y: -357.22165}
|
||||
m_SizeDelta: {x: 100, y: 100}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!1 &565117361
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@ -3791,7 +4013,7 @@ GameObject:
|
||||
- component: {fileID: 624843595}
|
||||
- component: {fileID: 624843594}
|
||||
m_Layer: 5
|
||||
m_Name: World Canvas
|
||||
m_Name: World Canvas With Spineboy
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
@ -3865,6 +4087,9 @@ RectTransform:
|
||||
m_LocalScale: {x: 0.02, y: 0.02, z: 0.1}
|
||||
m_Children:
|
||||
- {fileID: 1618699050}
|
||||
- {fileID: 105238417}
|
||||
- {fileID: 1055098057}
|
||||
- {fileID: 33325433}
|
||||
m_Father: {fileID: 0}
|
||||
m_RootOrder: 3
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
@ -3938,12 +4163,124 @@ Transform:
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
m_GameObject: {fileID: 774732875}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 5.5483284, y: 48.482475, z: 1}
|
||||
m_LocalPosition: {x: 0, y: 2.175, z: 0}
|
||||
m_LocalScale: {x: 5.5483284, y: 34.887302, z: 1}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 1675659861}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!1 &835737017
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
serializedVersion: 5
|
||||
m_Component:
|
||||
- component: {fileID: 835737018}
|
||||
m_Layer: 0
|
||||
m_Name: Part[0]
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &835737018
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
m_GameObject: {fileID: 835737017}
|
||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 0.25, y: 0.25, z: 0.25}
|
||||
m_Children:
|
||||
- {fileID: 1882323273}
|
||||
m_Father: {fileID: 33325433}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0.5, y: 0.5}
|
||||
m_AnchorMax: {x: 0.5, y: 0.5}
|
||||
m_AnchoredPosition: {x: -32.299957, y: -63.99994}
|
||||
m_SizeDelta: {x: 100, y: 100}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!1 &1055098056
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
serializedVersion: 5
|
||||
m_Component:
|
||||
- component: {fileID: 1055098057}
|
||||
- component: {fileID: 1055098059}
|
||||
- component: {fileID: 1055098058}
|
||||
m_Layer: 5
|
||||
m_Name: Text SkeletonGraphic Location
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &1055098057
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
m_GameObject: {fileID: 1055098056}
|
||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 0.99999994}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 624843597}
|
||||
m_RootOrder: 2
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 1, y: 1}
|
||||
m_AnchoredPosition: {x: 577, y: -513.5}
|
||||
m_SizeDelta: {x: -54.3, y: 63}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!114 &1055098058
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
m_GameObject: {fileID: 1055098056}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 708705254, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
|
||||
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
m_FontData:
|
||||
m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
|
||||
m_FontSize: 18
|
||||
m_FontStyle: 0
|
||||
m_BestFit: 0
|
||||
m_MinSize: 1
|
||||
m_MaxSize: 77
|
||||
m_Alignment: 0
|
||||
m_AlignByGeometry: 0
|
||||
m_RichText: 1
|
||||
m_HorizontalOverflow: 0
|
||||
m_VerticalOverflow: 1
|
||||
m_LineSpacing: 1
|
||||
m_Text: 'The Part[0] GameObject was re-parented above the GreenBar object to render
|
||||
in the desired order
|
||||
|
||||
The SkeletonGraphic''s ''Update Part Location'' parameter lets the re-parented
|
||||
parts follow the main SkeletonGraphic location.'
|
||||
--- !u!222 &1055098059
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
m_GameObject: {fileID: 1055098056}
|
||||
--- !u!1 &1149289853
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@ -3967,8 +4304,8 @@ Transform:
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
m_GameObject: {fileID: 1149289853}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0.06, y: 0, z: 0}
|
||||
m_LocalScale: {x: 4.661441, y: 48.482475, z: 1}
|
||||
m_LocalPosition: {x: 0.06, y: 2.175, z: 0}
|
||||
m_LocalScale: {x: 4.661441, y: 34.887302, z: 1}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 1675659861}
|
||||
m_RootOrder: 1
|
||||
@ -4015,6 +4352,153 @@ SpriteRenderer:
|
||||
m_SpriteTileMode: 0
|
||||
m_WasSpriteAssigned: 1
|
||||
m_MaskInteraction: 0
|
||||
--- !u!1 &1185404037
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
serializedVersion: 5
|
||||
m_Component:
|
||||
- component: {fileID: 1185404038}
|
||||
- component: {fileID: 1185404040}
|
||||
- component: {fileID: 1185404039}
|
||||
- component: {fileID: 1185404041}
|
||||
m_Layer: 0
|
||||
m_Name: SkeletonGraphic (spineboy-unity)
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &1185404038
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
m_GameObject: {fileID: 1185404037}
|
||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 0.25, y: 0.25, z: 0.25}
|
||||
m_Children:
|
||||
- {fileID: 415442240}
|
||||
m_Father: {fileID: 33325433}
|
||||
m_RootOrder: 2
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0.5, y: 0.5}
|
||||
m_AnchorMax: {x: 0.5, y: 0.5}
|
||||
m_AnchoredPosition: {x: -32.3, y: -64}
|
||||
m_SizeDelta: {x: 371.0865, y: 731.54474}
|
||||
m_Pivot: {x: 0.59614486, y: 0.011688247}
|
||||
--- !u!114 &1185404039
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
m_GameObject: {fileID: 1185404037}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: d85b887af7e6c3f45a2e2d2920d641bc, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 2100000, guid: b66cf7a186d13054989b33a5c90044e4, type: 2}
|
||||
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
|
||||
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
skeletonDataAsset: {fileID: 11400000, guid: a467507a4ffb1d542a558739b2fede77, type: 2}
|
||||
initialSkinName: base
|
||||
initialFlipX: 0
|
||||
initialFlipY: 0
|
||||
startingAnimation:
|
||||
startingLoop: 1
|
||||
timeScale: 1
|
||||
freeze: 0
|
||||
unscaledTime: 0
|
||||
allowMultipleCanvasRenderers: 1
|
||||
canvasRenderers:
|
||||
- {fileID: 1882323272}
|
||||
- {fileID: 1211557620}
|
||||
separatorSlotNames:
|
||||
- --A
|
||||
enableSeparatorSlots: 1
|
||||
separatorParts:
|
||||
- {fileID: 835737018}
|
||||
- {fileID: 415442240}
|
||||
updateSeparatorPartLocation: 1
|
||||
meshGenerator:
|
||||
settings:
|
||||
useClipping: 1
|
||||
zSpacing: 0
|
||||
pmaVertexColors: 1
|
||||
tintBlack: 0
|
||||
calculateTangents: 0
|
||||
addNormals: 0
|
||||
immutableTriangles: 0
|
||||
--- !u!222 &1185404040
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
m_GameObject: {fileID: 1185404037}
|
||||
--- !u!114 &1185404041
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
m_GameObject: {fileID: 1185404037}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: d6bb29eb283767441a398ce2a7be27c3, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
skeletonGraphic: {fileID: 1185404039}
|
||||
run: {fileID: 11400000, guid: 2d841d20c203ff24a859b8c73f9c3817, type: 2}
|
||||
pole: {fileID: 11400000, guid: dff7c26e6e007e748b47240522cff0c8, type: 2}
|
||||
startX: -600
|
||||
endX: 0
|
||||
--- !u!1 &1211557618
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
serializedVersion: 5
|
||||
m_Component:
|
||||
- component: {fileID: 1211557619}
|
||||
- component: {fileID: 1211557620}
|
||||
m_Layer: 0
|
||||
m_Name: Renderer1
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &1211557619
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
m_GameObject: {fileID: 1211557618}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 415442240}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0.5, y: 0.5}
|
||||
m_AnchorMax: {x: 0.5, y: 0.5}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 100, y: 100}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &1211557620
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
m_GameObject: {fileID: 1211557618}
|
||||
--- !u!1 &1406277772
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@ -4038,8 +4522,8 @@ Transform:
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
m_GameObject: {fileID: 1406277772}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0.44, y: 0, z: 0}
|
||||
m_LocalScale: {x: 0.44441086, y: 48.482475, z: 1}
|
||||
m_LocalPosition: {x: 0.44, y: 2.175, z: 0}
|
||||
m_LocalScale: {x: 0.44441086, y: 34.887302, z: 1}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 1675659861}
|
||||
m_RootOrder: 2
|
||||
@ -4439,6 +4923,42 @@ Transform:
|
||||
m_Father: {fileID: 1918225119}
|
||||
m_RootOrder: 1
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!1 &1738423299
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
serializedVersion: 5
|
||||
m_Component:
|
||||
- component: {fileID: 1738423300}
|
||||
m_Layer: 5
|
||||
m_Name: GreenBar
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &1738423300
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
m_GameObject: {fileID: 1738423299}
|
||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children:
|
||||
- {fileID: 84997717}
|
||||
- {fileID: 1983276686}
|
||||
- {fileID: 2132214121}
|
||||
m_Father: {fileID: 33325433}
|
||||
m_RootOrder: 1
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0.5, y: 0.5}
|
||||
m_AnchorMax: {x: 0.5, y: 0.5}
|
||||
m_AnchoredPosition: {x: 6.700018, y: 24.610062}
|
||||
m_SizeDelta: {x: 100, y: 100}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!1 &1769987559
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@ -4520,6 +5040,46 @@ Transform:
|
||||
m_Father: {fileID: 93048079}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!1 &1882323271
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
serializedVersion: 5
|
||||
m_Component:
|
||||
- component: {fileID: 1882323273}
|
||||
- component: {fileID: 1882323272}
|
||||
m_Layer: 0
|
||||
m_Name: Renderer0
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!222 &1882323272
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
m_GameObject: {fileID: 1882323271}
|
||||
--- !u!224 &1882323273
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
m_GameObject: {fileID: 1882323271}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 835737018}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0.5, y: 0.5}
|
||||
m_AnchorMax: {x: 0.5, y: 0.5}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 100, y: 100}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!1 &1918225114
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@ -4663,6 +5223,142 @@ MonoBehaviour:
|
||||
pole: {fileID: 11400000, guid: dff7c26e6e007e748b47240522cff0c8, type: 2}
|
||||
startX: -11.5
|
||||
endX: 2.8
|
||||
--- !u!1 &1983276685
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
serializedVersion: 5
|
||||
m_Component:
|
||||
- component: {fileID: 1983276686}
|
||||
- component: {fileID: 1983276688}
|
||||
- component: {fileID: 1983276687}
|
||||
m_Layer: 5
|
||||
m_Name: GreenBar2
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &1983276686
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
m_GameObject: {fileID: 1983276685}
|
||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 1738423300}
|
||||
m_RootOrder: 1
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0.5, y: 0.5}
|
||||
m_AnchorMax: {x: 0.5, y: 0.5}
|
||||
m_AnchoredPosition: {x: -14.800003, y: -0.000061035156}
|
||||
m_SizeDelta: {x: 7.2, y: 183.98}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!114 &1983276687
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
m_GameObject: {fileID: 1983276685}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 0.3647059, g: 0.4901961, b: 0.17254902, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
|
||||
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
m_Sprite: {fileID: 0}
|
||||
m_Type: 0
|
||||
m_PreserveAspect: 0
|
||||
m_FillCenter: 1
|
||||
m_FillMethod: 4
|
||||
m_FillAmount: 1
|
||||
m_FillClockwise: 1
|
||||
m_FillOrigin: 0
|
||||
--- !u!222 &1983276688
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
m_GameObject: {fileID: 1983276685}
|
||||
--- !u!1 &2132214120
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
serializedVersion: 5
|
||||
m_Component:
|
||||
- component: {fileID: 2132214121}
|
||||
- component: {fileID: 2132214123}
|
||||
- component: {fileID: 2132214122}
|
||||
m_Layer: 5
|
||||
m_Name: GreenBar3
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &2132214121
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
m_GameObject: {fileID: 2132214120}
|
||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 1738423300}
|
||||
m_RootOrder: 2
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0.5, y: 0.5}
|
||||
m_AnchorMax: {x: 0.5, y: 0.5}
|
||||
m_AnchoredPosition: {x: 6.7999954, y: -0.000061035156}
|
||||
m_SizeDelta: {x: 7.2, y: 183.98}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!114 &2132214122
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
m_GameObject: {fileID: 2132214120}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 0.4784314, g: 0.9686275, b: 0.007843138, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
|
||||
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
m_Sprite: {fileID: 0}
|
||||
m_Type: 0
|
||||
m_PreserveAspect: 0
|
||||
m_FillCenter: 1
|
||||
m_FillMethod: 4
|
||||
m_FillAmount: 1
|
||||
m_FillClockwise: 1
|
||||
m_FillOrigin: 0
|
||||
--- !u!222 &2132214123
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
m_GameObject: {fileID: 2132214120}
|
||||
--- !u!1 &2142418130
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
|
||||
@ -0,0 +1,80 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated January 1, 2020. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2020, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "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 LLC 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
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using Spine.Unity;
|
||||
|
||||
using Spine.Unity.Examples;
|
||||
|
||||
namespace Spine.Unity.Examples {
|
||||
public class SpineboyPoleGraphic : MonoBehaviour {
|
||||
public SkeletonGraphic skeletonGraphic;
|
||||
|
||||
[Space(18)]
|
||||
public AnimationReferenceAsset run;
|
||||
public AnimationReferenceAsset pole;
|
||||
public float startX;
|
||||
public float endX;
|
||||
|
||||
const float Speed = 18f;
|
||||
const float RunTimeScale = 1.5f;
|
||||
|
||||
IEnumerator Start () {
|
||||
var state = skeletonGraphic.AnimationState;
|
||||
|
||||
while (true) {
|
||||
// Run phase
|
||||
SetXPosition(startX);
|
||||
skeletonGraphic.enableSeparatorSlots = false; // Disable Separator during run.
|
||||
state.SetAnimation(0, run, true);
|
||||
state.TimeScale = RunTimeScale;
|
||||
|
||||
while (transform.localPosition.x < endX) {
|
||||
transform.Translate(Vector3.right * Speed * Time.deltaTime);
|
||||
yield return null;
|
||||
}
|
||||
|
||||
// Hit phase
|
||||
SetXPosition(endX);
|
||||
skeletonGraphic.enableSeparatorSlots = true; // Enable Separator when hit
|
||||
var poleTrack = state.SetAnimation(0, pole, false);
|
||||
yield return new WaitForSpineAnimationComplete(poleTrack);
|
||||
yield return new WaitForSeconds(1f);
|
||||
}
|
||||
}
|
||||
|
||||
void SetXPosition (float x) {
|
||||
var tp = transform.localPosition;
|
||||
tp.x = x;
|
||||
transform.localPosition = tp;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d6bb29eb283767441a398ce2a7be27c3
|
||||
timeCreated: 1458684804
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,159 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated January 1, 2020. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2020, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "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 LLC 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
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using Spine.Unity.Examples;
|
||||
|
||||
namespace Spine.Unity.Editor {
|
||||
|
||||
// This script is not intended for use with code. See spine-unity documentation page for additional information.
|
||||
[CustomEditor(typeof(SkeletonGraphicCustomMaterials))]
|
||||
public class SkeletonGraphicCustomMaterialsInspector : UnityEditor.Editor {
|
||||
List<SkeletonGraphicCustomMaterials.AtlasMaterialOverride> componentCustomMaterialOverrides, _customMaterialOverridesPrev;
|
||||
List<SkeletonGraphicCustomMaterials.AtlasTextureOverride> componentCustomTextureOverrides, _customTextureOverridesPrev;
|
||||
SkeletonGraphicCustomMaterials component;
|
||||
|
||||
const BindingFlags PrivateInstance = BindingFlags.Instance | BindingFlags.NonPublic;
|
||||
MethodInfo RemoveCustomMaterialOverrides, RemoveCustomTextureOverrides, SetCustomMaterialOverrides, SetCustomTextureOverrides;
|
||||
|
||||
#region SkeletonGraphic context menu
|
||||
[MenuItem("CONTEXT/SkeletonGraphic/Add Basic Serialized Custom Materials")]
|
||||
static void AddSkeletonGraphicCustomMaterials (MenuCommand menuCommand) {
|
||||
var skeletonGraphic = (SkeletonGraphic)menuCommand.context;
|
||||
var newComponent = skeletonGraphic.gameObject.AddComponent<SkeletonGraphicCustomMaterials>();
|
||||
Undo.RegisterCreatedObjectUndo(newComponent, "Add Basic Serialized Custom Materials");
|
||||
}
|
||||
|
||||
[MenuItem("CONTEXT/SkeletonGraphic/Add Basic Serialized Custom Materials", true)]
|
||||
static bool AddSkeletonGraphicCustomMaterials_Validate (MenuCommand menuCommand) {
|
||||
var skeletonGraphic = (SkeletonGraphic)menuCommand.context;
|
||||
return (skeletonGraphic.GetComponent<SkeletonGraphicCustomMaterials>() == null);
|
||||
}
|
||||
#endregion
|
||||
|
||||
void OnEnable () {
|
||||
Type cm = typeof(SkeletonGraphicCustomMaterials);
|
||||
RemoveCustomMaterialOverrides = cm.GetMethod("RemoveCustomMaterialOverrides", PrivateInstance);
|
||||
RemoveCustomTextureOverrides = cm.GetMethod("RemoveCustomTextureOverrides", PrivateInstance);
|
||||
SetCustomMaterialOverrides = cm.GetMethod("SetCustomMaterialOverrides", PrivateInstance);
|
||||
SetCustomTextureOverrides = cm.GetMethod("SetCustomTextureOverrides", PrivateInstance);
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI () {
|
||||
component = (SkeletonGraphicCustomMaterials)target;
|
||||
var skeletonGraphic = component.skeletonGraphic;
|
||||
|
||||
// Draw the default inspector
|
||||
DrawDefaultInspector();
|
||||
|
||||
if (serializedObject.isEditingMultipleObjects)
|
||||
return;
|
||||
|
||||
if (componentCustomMaterialOverrides == null) {
|
||||
Type cm = typeof(SkeletonGraphicCustomMaterials);
|
||||
componentCustomMaterialOverrides = cm.GetField("customMaterialOverrides", PrivateInstance).GetValue(component) as List<SkeletonGraphicCustomMaterials.AtlasMaterialOverride>;
|
||||
componentCustomTextureOverrides = cm.GetField("customTextureOverrides", PrivateInstance).GetValue(component) as List<SkeletonGraphicCustomMaterials.AtlasTextureOverride>;
|
||||
if (componentCustomMaterialOverrides == null) {
|
||||
Debug.Log("Reflection failed.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Fill with current values at start
|
||||
if (_customMaterialOverridesPrev == null || _customTextureOverridesPrev == null) {
|
||||
_customMaterialOverridesPrev = CopyList(componentCustomMaterialOverrides);
|
||||
_customTextureOverridesPrev = CopyList(componentCustomTextureOverrides);
|
||||
}
|
||||
|
||||
// Compare new values with saved. If change is detected:
|
||||
// store new values, restore old values, remove overrides, restore new values, restore overrides.
|
||||
|
||||
// 1. Store new values
|
||||
var customMaterialOverridesNew = CopyList(componentCustomMaterialOverrides);
|
||||
var customTextureOverridesNew = CopyList(componentCustomTextureOverrides);
|
||||
|
||||
// Detect changes
|
||||
if (!_customMaterialOverridesPrev.SequenceEqual(customMaterialOverridesNew) ||
|
||||
!_customTextureOverridesPrev.SequenceEqual(customTextureOverridesNew)) {
|
||||
// 2. Restore old values
|
||||
componentCustomMaterialOverrides.Clear();
|
||||
componentCustomTextureOverrides.Clear();
|
||||
componentCustomMaterialOverrides.AddRange(_customMaterialOverridesPrev);
|
||||
componentCustomTextureOverrides.AddRange(_customTextureOverridesPrev);
|
||||
|
||||
// 3. Remove overrides
|
||||
RemoveCustomMaterials();
|
||||
|
||||
// 4. Restore new values
|
||||
componentCustomMaterialOverrides.Clear();
|
||||
componentCustomTextureOverrides.Clear();
|
||||
componentCustomMaterialOverrides.AddRange(customMaterialOverridesNew);
|
||||
componentCustomTextureOverrides.AddRange(customTextureOverridesNew);
|
||||
|
||||
// 5. Restore overrides
|
||||
SetCustomMaterials();
|
||||
|
||||
if (skeletonGraphic != null)
|
||||
skeletonGraphic.LateUpdate();
|
||||
}
|
||||
|
||||
_customMaterialOverridesPrev = CopyList(componentCustomMaterialOverrides);
|
||||
_customTextureOverridesPrev = CopyList(componentCustomTextureOverrides);
|
||||
|
||||
if (SpineInspectorUtility.LargeCenteredButton(SpineInspectorUtility.TempContent("Clear and Reapply Changes", tooltip: "Removes all non-serialized overrides in the SkeletonGraphic and reapplies the overrides on this component."))) {
|
||||
if (skeletonGraphic != null) {
|
||||
skeletonGraphic.CustomMaterialOverride.Clear();
|
||||
skeletonGraphic.CustomTextureOverride.Clear();
|
||||
RemoveCustomMaterials();
|
||||
SetCustomMaterials();
|
||||
skeletonGraphic.LateUpdate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RemoveCustomMaterials () {
|
||||
RemoveCustomMaterialOverrides.Invoke(component, null);
|
||||
RemoveCustomTextureOverrides.Invoke(component, null);
|
||||
}
|
||||
|
||||
void SetCustomMaterials () {
|
||||
SetCustomMaterialOverrides.Invoke(component, null);
|
||||
SetCustomTextureOverrides.Invoke(component, null);
|
||||
}
|
||||
|
||||
static List<T> CopyList<T> (List<T> list) {
|
||||
return list.GetRange(0, list.Count);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 349bf125947e3aa4bb78690fec69ea17
|
||||
timeCreated: 1588789940
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -42,15 +42,20 @@ namespace Spine.Unity.Editor {
|
||||
[CustomEditor(typeof(SkeletonGraphic))]
|
||||
[CanEditMultipleObjects]
|
||||
public class SkeletonGraphicInspector : UnityEditor.Editor {
|
||||
|
||||
const string SeparatorSlotNamesFieldName = "separatorSlotNames";
|
||||
|
||||
SerializedProperty material, color;
|
||||
SerializedProperty skeletonDataAsset, initialSkinName;
|
||||
SerializedProperty startingAnimation, startingLoop, timeScale, freeze, unscaledTime, tintBlack;
|
||||
SerializedProperty initialFlipX, initialFlipY;
|
||||
SerializedProperty meshGeneratorSettings;
|
||||
SerializedProperty allowMultipleCanvasRenderers, separatorSlotNames, enableSeparatorSlots, updateSeparatorPartLocation;
|
||||
SerializedProperty raycastTarget;
|
||||
|
||||
SkeletonGraphic thisSkeletonGraphic;
|
||||
protected bool isInspectingPrefab;
|
||||
protected bool slotsReapplyRequired = false;
|
||||
|
||||
protected bool TargetIsValid {
|
||||
get {
|
||||
@ -100,9 +105,17 @@ namespace Spine.Unity.Editor {
|
||||
|
||||
meshGeneratorSettings = so.FindProperty("meshGenerator").FindPropertyRelative("settings");
|
||||
meshGeneratorSettings.isExpanded = SkeletonRendererInspector.advancedFoldout;
|
||||
|
||||
allowMultipleCanvasRenderers = so.FindProperty("allowMultipleCanvasRenderers");
|
||||
updateSeparatorPartLocation = so.FindProperty("updateSeparatorPartLocation");
|
||||
enableSeparatorSlots = so.FindProperty("enableSeparatorSlots");
|
||||
|
||||
separatorSlotNames = so.FindProperty("separatorSlotNames");
|
||||
separatorSlotNames.isExpanded = true;
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI () {
|
||||
bool wasChanged = false;
|
||||
EditorGUI.BeginChangeCheck();
|
||||
|
||||
EditorGUILayout.PropertyField(skeletonDataAsset);
|
||||
@ -115,9 +128,56 @@ namespace Spine.Unity.Editor {
|
||||
serializedObject.Update();
|
||||
return;
|
||||
}
|
||||
|
||||
bool isSingleRendererOnly = (!allowMultipleCanvasRenderers.hasMultipleDifferentValues && allowMultipleCanvasRenderers.boolValue == false);
|
||||
bool isSeparationEnabledButNotMultipleRenderers =
|
||||
isSingleRendererOnly && (!enableSeparatorSlots.hasMultipleDifferentValues && enableSeparatorSlots.boolValue == true);
|
||||
bool meshRendersIncorrectlyWithSingleRenderer =
|
||||
isSingleRendererOnly && SkeletonHasMultipleSubmeshes();
|
||||
|
||||
if (isSeparationEnabledButNotMultipleRenderers || meshRendersIncorrectlyWithSingleRenderer)
|
||||
meshGeneratorSettings.isExpanded = true;
|
||||
|
||||
using (new SpineInspectorUtility.BoxScope()) {
|
||||
EditorGUILayout.PropertyField(meshGeneratorSettings, SpineInspectorUtility.TempContent("Advanced..."), includeChildren: true);
|
||||
SkeletonRendererInspector.advancedFoldout = meshGeneratorSettings.isExpanded;
|
||||
|
||||
if (meshGeneratorSettings.isExpanded) {
|
||||
EditorGUILayout.Space();
|
||||
using (new SpineInspectorUtility.IndentScope()) {
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.PropertyField(allowMultipleCanvasRenderers, SpineInspectorUtility.TempContent("Multiple CanvasRenderers"));
|
||||
|
||||
if (GUILayout.Button(new GUIContent("Trim Renderers", "Remove currently unused CanvasRenderer GameObjects. These will be regenerated whenever needed."),
|
||||
EditorStyles.miniButton, GUILayout.Width(100f))) {
|
||||
|
||||
foreach (var skeletonGraphic in targets) {
|
||||
((SkeletonGraphic)skeletonGraphic).TrimRenderers();
|
||||
}
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
// warning box
|
||||
if (isSeparationEnabledButNotMultipleRenderers) {
|
||||
using (new SpineInspectorUtility.BoxScope()) {
|
||||
meshGeneratorSettings.isExpanded = true;
|
||||
EditorGUILayout.LabelField(SpineInspectorUtility.TempContent("'Multiple Canvas Renderers' must be enabled\nwhen 'Enable Separation' is enabled.", Icons.warning), GUILayout.Height(42), GUILayout.Width(340));
|
||||
}
|
||||
}
|
||||
else if (meshRendersIncorrectlyWithSingleRenderer) {
|
||||
using (new SpineInspectorUtility.BoxScope()) {
|
||||
meshGeneratorSettings.isExpanded = true;
|
||||
EditorGUILayout.LabelField(SpineInspectorUtility.TempContent("This mesh uses multiple atlas pages. You\n" +
|
||||
"need to enable 'Multiple Canvas Renderers'\n" +
|
||||
"for correct rendering. Consider packing\n" +
|
||||
"attachments to a single atlas page if possible.", Icons.warning), GUILayout.Height(60), GUILayout.Width(340));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EditorGUILayout.Space();
|
||||
SeparatorsField(separatorSlotNames, enableSeparatorSlots, updateSeparatorPartLocation);
|
||||
}
|
||||
}
|
||||
|
||||
EditorGUILayout.Space();
|
||||
@ -164,10 +224,82 @@ namespace Spine.Unity.Editor {
|
||||
}
|
||||
}
|
||||
|
||||
bool wasChanged = EditorGUI.EndChangeCheck();
|
||||
wasChanged |= EditorGUI.EndChangeCheck();
|
||||
|
||||
if (wasChanged)
|
||||
if (wasChanged) {
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
slotsReapplyRequired = true;
|
||||
}
|
||||
|
||||
if (slotsReapplyRequired && UnityEngine.Event.current.type == EventType.Repaint) {
|
||||
foreach (var target in targets) {
|
||||
var skeletonGraphic = (SkeletonGraphic)target;
|
||||
skeletonGraphic.ReapplySeparatorSlotNames();
|
||||
skeletonGraphic.LateUpdate();
|
||||
SceneView.RepaintAll();
|
||||
}
|
||||
slotsReapplyRequired = false;
|
||||
}
|
||||
}
|
||||
|
||||
protected bool SkeletonHasMultipleSubmeshes () {
|
||||
foreach (var target in targets) {
|
||||
var skeletonGraphic = (SkeletonGraphic)target;
|
||||
if (skeletonGraphic.HasMultipleSubmeshInstructions())
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void SetSeparatorSlotNames (SkeletonRenderer skeletonRenderer, string[] newSlotNames) {
|
||||
var field = SpineInspectorUtility.GetNonPublicField(typeof(SkeletonRenderer), SeparatorSlotNamesFieldName);
|
||||
field.SetValue(skeletonRenderer, newSlotNames);
|
||||
}
|
||||
|
||||
public static string[] GetSeparatorSlotNames (SkeletonRenderer skeletonRenderer) {
|
||||
var field = SpineInspectorUtility.GetNonPublicField(typeof(SkeletonRenderer), SeparatorSlotNamesFieldName);
|
||||
return field.GetValue(skeletonRenderer) as string[];
|
||||
}
|
||||
|
||||
public static void SeparatorsField (SerializedProperty separatorSlotNames, SerializedProperty enableSeparatorSlots,
|
||||
SerializedProperty updateSeparatorPartLocation) {
|
||||
|
||||
bool multi = separatorSlotNames.serializedObject.isEditingMultipleObjects;
|
||||
bool hasTerminalSlot = false;
|
||||
if (!multi) {
|
||||
var sr = separatorSlotNames.serializedObject.targetObject as ISkeletonComponent;
|
||||
var skeleton = sr.Skeleton;
|
||||
int lastSlot = skeleton.Slots.Count - 1;
|
||||
if (skeleton != null) {
|
||||
for (int i = 0, n = separatorSlotNames.arraySize; i < n; i++) {
|
||||
int index = skeleton.FindSlotIndex(separatorSlotNames.GetArrayElementAtIndex(i).stringValue);
|
||||
if (index == 0 || index == lastSlot) {
|
||||
hasTerminalSlot = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
string terminalSlotWarning = hasTerminalSlot ? " (!)" : "";
|
||||
|
||||
using (new EditorGUILayout.VerticalScope(EditorStyles.helpBox)) {
|
||||
const string SeparatorsDescription = "Stored names of slots where the Skeleton's render will be split into different batches. This is used by separate components that split the render into different MeshRenderers or GameObjects.";
|
||||
if (separatorSlotNames.isExpanded) {
|
||||
EditorGUILayout.PropertyField(separatorSlotNames, SpineInspectorUtility.TempContent(separatorSlotNames.displayName + terminalSlotWarning, Icons.slotRoot, SeparatorsDescription), true);
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.FlexibleSpace();
|
||||
if (GUILayout.Button("+", GUILayout.MaxWidth(28f), GUILayout.MaxHeight(15f))) {
|
||||
separatorSlotNames.arraySize++;
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
else
|
||||
EditorGUILayout.PropertyField(separatorSlotNames, new GUIContent(separatorSlotNames.displayName + string.Format("{0} [{1}]", terminalSlotWarning, separatorSlotNames.arraySize), SeparatorsDescription), true);
|
||||
|
||||
EditorGUILayout.PropertyField(enableSeparatorSlots, SpineInspectorUtility.TempContent("Enable Separation", tooltip: "Whether to enable separation at the above separator slots."));
|
||||
EditorGUILayout.PropertyField(updateSeparatorPartLocation, SpineInspectorUtility.TempContent("Update Part Location", tooltip:"Update separator part GameObject location to match the position of the SkeletonGraphic. This can be helpful when re-parenting parts to a different GameObject."));
|
||||
}
|
||||
}
|
||||
|
||||
#region Menus
|
||||
|
||||
@ -31,6 +31,7 @@
|
||||
#define NEW_PREFAB_SYSTEM
|
||||
#endif
|
||||
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
@ -58,6 +59,20 @@ namespace Spine.Unity {
|
||||
public float timeScale = 1f;
|
||||
public bool freeze;
|
||||
public bool unscaledTime;
|
||||
public bool allowMultipleCanvasRenderers = false;
|
||||
public List<CanvasRenderer> canvasRenderers = new List<CanvasRenderer>();
|
||||
|
||||
// Submesh Separation
|
||||
public const string SeparatorPartGameObjectName = "Part";
|
||||
/// <summary>Slot names used to populate separatorSlots list when the Skeleton is initialized. Changing this after initialization does nothing.</summary>
|
||||
[SerializeField] [SpineSlot] protected string[] separatorSlotNames = new string[0];
|
||||
|
||||
/// <summary>Slots that determine where the render is split. This is used by components such as SkeletonRenderSeparator so that the skeleton can be rendered by two separate renderers on different GameObjects.</summary>
|
||||
[System.NonSerialized] public readonly List<Slot> separatorSlots = new List<Slot>();
|
||||
public bool enableSeparatorSlots = false;
|
||||
[SerializeField] protected List<Transform> separatorParts = new List<Transform>();
|
||||
public List<Transform> SeparatorParts { get { return separatorParts; } }
|
||||
public bool updateSeparatorPartLocation = true;
|
||||
|
||||
private bool wasUpdatedAfterInit = true;
|
||||
private Texture baseTexture = null;
|
||||
@ -74,8 +89,8 @@ namespace Spine.Unity {
|
||||
} else if (skeletonDataAsset.GetSkeletonData(true) != skeleton.data) {
|
||||
Clear();
|
||||
Initialize(true);
|
||||
if (skeletonDataAsset.atlasAssets.Length > 1 || skeletonDataAsset.atlasAssets[0].MaterialCount > 1)
|
||||
Debug.LogError("Unity UI does not support multiple textures per Renderer. Your skeleton will not be rendered correctly. Recommend using SkeletonAnimation instead. This requires the use of a Screen space camera canvas.");
|
||||
if (!allowMultipleCanvasRenderers && (skeletonDataAsset.atlasAssets.Length > 1 || skeletonDataAsset.atlasAssets[0].MaterialCount > 1))
|
||||
Debug.LogError("Unity UI does not support multiple textures per Renderer. Please enable 'Advanced - Multiple CanvasRenderers' to generate the required CanvasRenderer GameObjects. Otherwise your skeleton will not be rendered correctly.", this);
|
||||
} else {
|
||||
if (freeze) return;
|
||||
|
||||
@ -143,7 +158,15 @@ namespace Spine.Unity {
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Internals
|
||||
#region Overrides
|
||||
[System.NonSerialized] readonly Dictionary<Texture, Texture> customTextureOverride = new Dictionary<Texture, Texture>();
|
||||
/// <summary>Use this Dictionary to override a Texture with a different Texture.</summary>
|
||||
public Dictionary<Texture, Texture> CustomTextureOverride { get { return customTextureOverride; } }
|
||||
|
||||
[System.NonSerialized] readonly Dictionary<Texture, Material> customMaterialOverride = new Dictionary<Texture, Material>();
|
||||
/// <summary>Use this Dictionary to override the Material where the Texture was used at the original atlas.</summary>
|
||||
public Dictionary<Texture, Material> CustomMaterialOverride { get { return customMaterialOverride; } }
|
||||
|
||||
// This is used by the UI system to determine what to put in the MaterialPropertyBlock.
|
||||
Texture overrideTexture;
|
||||
public Texture OverrideTexture {
|
||||
@ -153,6 +176,9 @@ namespace Spine.Unity {
|
||||
canvasRenderer.SetTexture(this.mainTexture); // Refresh canvasRenderer's texture. Make sure it handles null.
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Internals
|
||||
public override Texture mainTexture {
|
||||
get {
|
||||
if (overrideTexture != null) return overrideTexture;
|
||||
@ -181,6 +207,7 @@ namespace Spine.Unity {
|
||||
base.Rebuild(update);
|
||||
if (canvasRenderer.cull) return;
|
||||
if (update == CanvasUpdate.PreRender) UpdateMesh();
|
||||
if (allowMultipleCanvasRenderers) canvasRenderer.Clear();
|
||||
}
|
||||
|
||||
public virtual void Update () {
|
||||
@ -223,6 +250,29 @@ namespace Spine.Unity {
|
||||
//this.SetVerticesDirty(); // Which is better?
|
||||
UpdateMesh();
|
||||
}
|
||||
|
||||
public void ReapplySeparatorSlotNames () {
|
||||
if (!IsValid)
|
||||
return;
|
||||
|
||||
separatorSlots.Clear();
|
||||
for (int i = 0, n = separatorSlotNames.Length; i < n; i++) {
|
||||
string slotName = separatorSlotNames[i];
|
||||
if (slotName == "")
|
||||
continue;
|
||||
var slot = skeleton.FindSlot(slotName);
|
||||
if (slot != null) {
|
||||
separatorSlots.Add(slot);
|
||||
}
|
||||
#if UNITY_EDITOR
|
||||
else
|
||||
{
|
||||
Debug.LogWarning(slotName + " is not a slot in " + skeletonDataAsset.skeletonJSON.name);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
UpdateSeparatorPartParents();
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region API
|
||||
@ -247,6 +297,7 @@ namespace Spine.Unity {
|
||||
public Spine.Unity.MeshGenerator MeshGenerator { get { return this.meshGenerator; } }
|
||||
DoubleBuffered<Spine.Unity.MeshRendererBuffers.SmartMesh> meshBuffers;
|
||||
SkeletonRendererInstruction currentInstructions = new SkeletonRendererInstruction();
|
||||
readonly ExposedList<Mesh> meshes = new ExposedList<Mesh>();
|
||||
|
||||
public Mesh GetLastMesh () {
|
||||
return meshBuffers.GetCurrent().mesh;
|
||||
@ -255,21 +306,62 @@ namespace Spine.Unity {
|
||||
public bool MatchRectTransformWithBounds () {
|
||||
UpdateMesh();
|
||||
|
||||
if (!this.allowMultipleCanvasRenderers)
|
||||
return MatchRectTransformSingleRenderer();
|
||||
else
|
||||
return MatchRectTransformMultipleRenderers();
|
||||
}
|
||||
|
||||
protected bool MatchRectTransformSingleRenderer () {
|
||||
Mesh mesh = this.GetLastMesh();
|
||||
if (mesh == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mesh.vertexCount == 0) {
|
||||
this.rectTransform.sizeDelta = new Vector2(50f, 50f);
|
||||
this.rectTransform.pivot = new Vector2(0.5f, 0.5f);
|
||||
return false;
|
||||
}
|
||||
|
||||
mesh.RecalculateBounds();
|
||||
var bounds = mesh.bounds;
|
||||
var size = bounds.size;
|
||||
var center = bounds.center;
|
||||
SetRectTransformBounds(mesh.bounds);
|
||||
return true;
|
||||
}
|
||||
|
||||
protected bool MatchRectTransformMultipleRenderers () {
|
||||
bool anyBoundsAdded = false;
|
||||
Bounds combinedBounds = new Bounds();
|
||||
for (int i = 0; i < canvasRenderers.Count; ++i) {
|
||||
var canvasRenderer = canvasRenderers[i];
|
||||
if (!canvasRenderer.gameObject.activeSelf)
|
||||
continue;
|
||||
|
||||
Mesh mesh = meshes.Items[i];
|
||||
if (mesh == null || mesh.vertexCount == 0)
|
||||
continue;
|
||||
|
||||
mesh.RecalculateBounds();
|
||||
var bounds = mesh.bounds;
|
||||
if (anyBoundsAdded)
|
||||
combinedBounds.Encapsulate(bounds);
|
||||
else {
|
||||
anyBoundsAdded = true;
|
||||
combinedBounds = bounds;
|
||||
}
|
||||
}
|
||||
|
||||
if (!anyBoundsAdded) {
|
||||
this.rectTransform.sizeDelta = new Vector2(50f, 50f);
|
||||
this.rectTransform.pivot = new Vector2(0.5f, 0.5f);
|
||||
return false;
|
||||
}
|
||||
|
||||
SetRectTransformBounds(combinedBounds);
|
||||
return true;
|
||||
}
|
||||
|
||||
private void SetRectTransformBounds (Bounds combinedBounds) {
|
||||
var size = combinedBounds.size;
|
||||
var center = combinedBounds.center;
|
||||
var p = new Vector2(
|
||||
0.5f - (center.x / size.x),
|
||||
0.5f - (center.y / size.y)
|
||||
@ -277,7 +369,6 @@ namespace Spine.Unity {
|
||||
|
||||
this.rectTransform.sizeDelta = size;
|
||||
this.rectTransform.pivot = p;
|
||||
return true;
|
||||
}
|
||||
|
||||
public event UpdateBonesDelegate UpdateLocal;
|
||||
@ -290,6 +381,28 @@ namespace Spine.Unity {
|
||||
public void Clear () {
|
||||
skeleton = null;
|
||||
canvasRenderer.Clear();
|
||||
|
||||
for (int i = 0; i < canvasRenderers.Count; ++i)
|
||||
canvasRenderers[i].Clear();
|
||||
foreach (var mesh in meshes)
|
||||
Destroy(mesh);
|
||||
meshes.Clear();
|
||||
}
|
||||
|
||||
public void TrimRenderers () {
|
||||
var newList = new List<CanvasRenderer>();
|
||||
foreach (var canvasRenderer in canvasRenderers) {
|
||||
if (canvasRenderer.gameObject.activeSelf) {
|
||||
newList.Add(canvasRenderer);
|
||||
}
|
||||
else {
|
||||
if (Application.isEditor && !Application.isPlaying)
|
||||
DestroyImmediate(canvasRenderer.gameObject);
|
||||
else
|
||||
Destroy(canvasRenderer.gameObject);
|
||||
}
|
||||
}
|
||||
canvasRenderers = newList;
|
||||
}
|
||||
|
||||
public void Initialize (bool overwrite) {
|
||||
@ -321,6 +434,10 @@ namespace Spine.Unity {
|
||||
if (!string.IsNullOrEmpty(initialSkinName))
|
||||
skeleton.SetSkin(initialSkinName);
|
||||
|
||||
separatorSlots.Clear();
|
||||
for (int i = 0; i < separatorSlotNames.Length; i++)
|
||||
separatorSlots.Add(skeleton.FindSlot(separatorSlotNames[i]));
|
||||
|
||||
wasUpdatedAfterInit = false;
|
||||
if (!string.IsNullOrEmpty(startingAnimation)) {
|
||||
var animationObject = skeletonDataAsset.GetSkeletonData(false).FindAnimation(startingAnimation);
|
||||
@ -341,15 +458,39 @@ namespace Spine.Unity {
|
||||
if (!this.IsValid) return;
|
||||
|
||||
skeleton.SetColor(this.color);
|
||||
var smartMesh = meshBuffers.GetNext();
|
||||
|
||||
var currentInstructions = this.currentInstructions;
|
||||
if (!this.allowMultipleCanvasRenderers) {
|
||||
UpdateMeshSingleCanvasRenderer();
|
||||
}
|
||||
else {
|
||||
UpdateMeshMultipleCanvasRenderers(currentInstructions);
|
||||
}
|
||||
|
||||
if (OnMeshAndMaterialsUpdated != null)
|
||||
OnMeshAndMaterialsUpdated(this);
|
||||
}
|
||||
|
||||
public bool HasMultipleSubmeshInstructions () {
|
||||
if (!IsValid)
|
||||
return false;
|
||||
return MeshGenerator.RequiresMultipleSubmeshesByDrawOrder(skeleton);
|
||||
}
|
||||
#endregion
|
||||
|
||||
protected void UpdateMeshSingleCanvasRenderer () {
|
||||
if (canvasRenderers.Count > 0)
|
||||
DisableUnusedCanvasRenderers(usedCount : 0);
|
||||
|
||||
var smartMesh = meshBuffers.GetNext();
|
||||
MeshGenerator.GenerateSingleSubmeshInstruction(currentInstructions, skeleton, null);
|
||||
bool updateTriangles = SkeletonRendererInstruction.GeometryNotEqual(currentInstructions, smartMesh.instructionUsed);
|
||||
|
||||
meshGenerator.Begin();
|
||||
if (currentInstructions.hasActiveClipping && currentInstructions.submeshInstructions.Count > 0) {
|
||||
meshGenerator.AddSubmesh(currentInstructions.submeshInstructions.Items[0], updateTriangles);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
meshGenerator.BuildMeshWithArrays(currentInstructions, updateTriangles);
|
||||
}
|
||||
|
||||
@ -373,10 +514,180 @@ namespace Spine.Unity {
|
||||
}
|
||||
}
|
||||
|
||||
//this.UpdateMaterial(); // TODO: This allocates memory.
|
||||
if (OnMeshAndMaterialsUpdated != null)
|
||||
OnMeshAndMaterialsUpdated(this);
|
||||
//this.UpdateMaterial(); // note: This would allocate memory.
|
||||
}
|
||||
#endregion
|
||||
|
||||
protected void UpdateMeshMultipleCanvasRenderers (SkeletonRendererInstruction currentInstructions) {
|
||||
MeshGenerator.GenerateSkeletonRendererInstruction(currentInstructions, skeleton, null,
|
||||
enableSeparatorSlots ? separatorSlots : null,
|
||||
enableSeparatorSlots ? separatorSlots.Count > 0 : false,
|
||||
false);
|
||||
|
||||
int submeshCount = currentInstructions.submeshInstructions.Count;
|
||||
EnsureCanvasRendererCount(submeshCount);
|
||||
EnsureMeshesCount(submeshCount);
|
||||
EnsureSeparatorPartCount();
|
||||
|
||||
var c = canvas;
|
||||
float scale = (c == null) ? 100 : c.referencePixelsPerUnit;
|
||||
|
||||
// Generate meshes.
|
||||
var meshesItems = meshes.Items;
|
||||
bool useOriginalTextureAndMaterial = (customMaterialOverride.Count == 0 && customTextureOverride.Count == 0);
|
||||
int separatorSlotGroupIndex = 0;
|
||||
Transform parent = this.separatorSlots.Count == 0 ? this.transform : this.separatorParts[0];
|
||||
|
||||
if (updateSeparatorPartLocation) {
|
||||
for (int p = 0; p < this.separatorParts.Count; ++p) {
|
||||
separatorParts[p].position = this.transform.position;
|
||||
separatorParts[p].rotation = this.transform.rotation;
|
||||
}
|
||||
}
|
||||
|
||||
int targetSiblingIndex = 0;
|
||||
for (int i = 0; i < submeshCount; i++) {
|
||||
var submeshInstructionItem = currentInstructions.submeshInstructions.Items[i];
|
||||
meshGenerator.Begin();
|
||||
meshGenerator.AddSubmesh(submeshInstructionItem);
|
||||
|
||||
var targetMesh = meshesItems[i];
|
||||
meshGenerator.ScaleVertexData(scale);
|
||||
if (OnPostProcessVertices != null) OnPostProcessVertices.Invoke(this.meshGenerator.Buffers);
|
||||
meshGenerator.FillVertexData(targetMesh);
|
||||
meshGenerator.FillTriangles(targetMesh);
|
||||
meshGenerator.FillLateVertexData(targetMesh);
|
||||
|
||||
var submeshMaterial = submeshInstructionItem.material;
|
||||
var canvasRenderer = canvasRenderers[i];
|
||||
canvasRenderer.gameObject.SetActive(true);
|
||||
canvasRenderer.SetMesh(targetMesh);
|
||||
canvasRenderer.materialCount = 1;
|
||||
|
||||
if (canvasRenderer.transform.parent != parent.transform) {
|
||||
canvasRenderer.transform.SetParent(parent.transform, false);
|
||||
canvasRenderer.transform.localPosition = Vector3.zero;
|
||||
}
|
||||
canvasRenderer.transform.SetSiblingIndex(targetSiblingIndex++);
|
||||
if (submeshInstructionItem.forceSeparate) {
|
||||
targetSiblingIndex = 0;
|
||||
parent = separatorParts[++separatorSlotGroupIndex];
|
||||
}
|
||||
|
||||
if (useOriginalTextureAndMaterial)
|
||||
canvasRenderer.SetMaterial(this.materialForRendering, submeshMaterial.mainTexture);
|
||||
else {
|
||||
var originalTexture = submeshMaterial.mainTexture;
|
||||
Material usedMaterial;
|
||||
Texture usedTexture;
|
||||
if (!customMaterialOverride.TryGetValue(originalTexture, out usedMaterial))
|
||||
usedMaterial = material;
|
||||
if (!customTextureOverride.TryGetValue(originalTexture, out usedTexture))
|
||||
usedTexture = originalTexture;
|
||||
canvasRenderer.SetMaterial(usedMaterial, usedTexture);
|
||||
}
|
||||
}
|
||||
|
||||
DisableUnusedCanvasRenderers(usedCount : submeshCount);
|
||||
}
|
||||
|
||||
protected void EnsureCanvasRendererCount (int targetCount) {
|
||||
#if UNITY_EDITOR
|
||||
RemoveNullCanvasRenderers();
|
||||
#endif
|
||||
int currentCount = canvasRenderers.Count;
|
||||
for (int i = currentCount; i < targetCount; ++i) {
|
||||
var go = new GameObject(string.Format("Renderer{0}", i), typeof(RectTransform));
|
||||
go.transform.SetParent(this.transform, false);
|
||||
go.transform.localPosition = Vector3.zero;
|
||||
var canvasRenderer = go.AddComponent<CanvasRenderer>();
|
||||
canvasRenderers.Add(canvasRenderer);
|
||||
}
|
||||
}
|
||||
|
||||
protected void DisableUnusedCanvasRenderers (int usedCount) {
|
||||
#if UNITY_EDITOR
|
||||
RemoveNullCanvasRenderers();
|
||||
#endif
|
||||
for (int i = usedCount; i < canvasRenderers.Count; i++) {
|
||||
canvasRenderers[i].Clear();
|
||||
canvasRenderers[i].gameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
private void RemoveNullCanvasRenderers () {
|
||||
if (Application.isEditor && !Application.isPlaying) {
|
||||
for (int i = canvasRenderers.Count - 1; i >= 0; --i) {
|
||||
if (canvasRenderers[i] == null) {
|
||||
canvasRenderers.RemoveAt(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
protected void EnsureMeshesCount (int targetCount) {
|
||||
int oldCount = meshes.Count;
|
||||
meshes.EnsureCapacity(targetCount);
|
||||
var meshesItems = meshes.Items;
|
||||
for (int i = oldCount; i < targetCount; i++)
|
||||
if (meshesItems[i] == null) meshesItems[i] = new Mesh();
|
||||
}
|
||||
|
||||
protected void EnsureSeparatorPartCount () {
|
||||
#if UNITY_EDITOR
|
||||
RemoveNullSeparatorParts();
|
||||
#endif
|
||||
int targetCount = separatorSlots.Count + 1;
|
||||
if (targetCount == 1)
|
||||
return;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
if (Application.isEditor && !Application.isPlaying) {
|
||||
for (int i = separatorParts.Count-1; i >= 0; --i) {
|
||||
if (separatorParts[i] == null) {
|
||||
separatorParts.RemoveAt(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
int currentCount = separatorParts.Count;
|
||||
for (int i = currentCount; i < targetCount; ++i) {
|
||||
var go = new GameObject(string.Format("{0}[{1}]", SeparatorPartGameObjectName, i), typeof(RectTransform));
|
||||
go.transform.SetParent(this.transform, false);
|
||||
go.transform.localPosition = Vector3.zero;
|
||||
separatorParts.Add(go.transform);
|
||||
}
|
||||
}
|
||||
|
||||
protected void UpdateSeparatorPartParents () {
|
||||
int usedCount = separatorSlots.Count + 1;
|
||||
if (usedCount == 1) {
|
||||
usedCount = 0; // placed directly at the SkeletonGraphic parent
|
||||
for (int i = 0; i < canvasRenderers.Count; ++i) {
|
||||
var canvasRenderer = canvasRenderers[i];
|
||||
if (canvasRenderer.transform.parent.name.Contains(SeparatorPartGameObjectName)) {
|
||||
canvasRenderer.transform.SetParent(this.transform, false);
|
||||
canvasRenderer.transform.localPosition = Vector3.zero;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < separatorParts.Count; ++i) {
|
||||
bool isUsed = i < usedCount;
|
||||
separatorParts[i].gameObject.SetActive(isUsed);
|
||||
}
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
private void RemoveNullSeparatorParts () {
|
||||
if (Application.isEditor && !Application.isPlaying) {
|
||||
for (int i = separatorParts.Count - 1; i >= 0; --i) {
|
||||
if (separatorParts[i] == null) {
|
||||
separatorParts.RemoveAt(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@ -269,14 +269,14 @@ namespace Spine.Unity {
|
||||
var info = clipInfo[c]; float weight = info.weight * layerWeight; if (weight == 0) continue;
|
||||
var clip = GetAnimation(info.clip);
|
||||
if (clip != null)
|
||||
clip.Apply(skeleton, 0, AnimationTime(stateInfo.normalizedTime, info.clip.length, stateInfo.loop, stateInfo.speed < 0), stateInfo.loop, null, weight, layerBlendMode, MixDirection.In);
|
||||
clip.Apply(skeleton, 0, AnimationTime(stateInfo.normalizedTime, info.clip.length, info.clip.isLooping, stateInfo.speed < 0), info.clip.isLooping, null, weight, layerBlendMode, MixDirection.In);
|
||||
}
|
||||
if (hasNext) {
|
||||
for (int c = 0; c < nextClipInfoCount; c++) {
|
||||
var info = nextClipInfo[c]; float weight = info.weight * layerWeight; if (weight == 0) continue;
|
||||
var clip = GetAnimation(info.clip);
|
||||
if (clip != null)
|
||||
clip.Apply(skeleton, 0, AnimationTime(nextStateInfo.normalizedTime, info.clip.length, nextStateInfo.speed < 0), nextStateInfo.loop, null, weight, layerBlendMode, MixDirection.In);
|
||||
clip.Apply(skeleton, 0, AnimationTime(nextStateInfo.normalizedTime, info.clip.length, nextStateInfo.speed < 0), info.clip.isLooping, null, weight, layerBlendMode, MixDirection.In);
|
||||
}
|
||||
}
|
||||
if (isInterruptionActive) {
|
||||
@ -288,7 +288,7 @@ namespace Spine.Unity {
|
||||
var clip = GetAnimation(info.clip);
|
||||
if (clip != null)
|
||||
clip.Apply(skeleton, 0, AnimationTime(interruptingStateInfo.normalizedTime + interruptingClipTimeAddition, info.clip.length, interruptingStateInfo.speed < 0),
|
||||
interruptingStateInfo.loop, null, weight, layerBlendMode, MixDirection.In);
|
||||
info.clip.isLooping, null, weight, layerBlendMode, MixDirection.In);
|
||||
}
|
||||
}
|
||||
} else { // case MixNext || Hard
|
||||
@ -298,7 +298,7 @@ namespace Spine.Unity {
|
||||
var info = clipInfo[c]; float weight = info.weight * layerWeight; if (weight == 0) continue;
|
||||
var clip = GetAnimation(info.clip);
|
||||
if (clip != null)
|
||||
clip.Apply(skeleton, 0, AnimationTime(stateInfo.normalizedTime, info.clip.length, stateInfo.loop, stateInfo.speed < 0), stateInfo.loop, null, 1f, layerBlendMode, MixDirection.In);
|
||||
clip.Apply(skeleton, 0, AnimationTime(stateInfo.normalizedTime, info.clip.length, info.clip.isLooping, stateInfo.speed < 0), info.clip.isLooping, null, 1f, layerBlendMode, MixDirection.In);
|
||||
++c; break;
|
||||
}
|
||||
// Mix the rest
|
||||
@ -306,7 +306,7 @@ namespace Spine.Unity {
|
||||
var info = clipInfo[c]; float weight = info.weight * layerWeight; if (weight == 0) continue;
|
||||
var clip = GetAnimation(info.clip);
|
||||
if (clip != null)
|
||||
clip.Apply(skeleton, 0, AnimationTime(stateInfo.normalizedTime, info.clip.length, stateInfo.loop, stateInfo.speed < 0), stateInfo.loop, null, weight, layerBlendMode, MixDirection.In);
|
||||
clip.Apply(skeleton, 0, AnimationTime(stateInfo.normalizedTime, info.clip.length, info.clip.isLooping, stateInfo.speed < 0), info.clip.isLooping, null, weight, layerBlendMode, MixDirection.In);
|
||||
}
|
||||
|
||||
c = 0;
|
||||
@ -317,7 +317,7 @@ namespace Spine.Unity {
|
||||
var info = nextClipInfo[c]; float weight = info.weight * layerWeight; if (weight == 0) continue;
|
||||
var clip = GetAnimation(info.clip);
|
||||
if (clip != null)
|
||||
clip.Apply(skeleton, 0, AnimationTime(nextStateInfo.normalizedTime, info.clip.length, nextStateInfo.speed < 0), nextStateInfo.loop, null, 1f, layerBlendMode, MixDirection.In);
|
||||
clip.Apply(skeleton, 0, AnimationTime(nextStateInfo.normalizedTime, info.clip.length, nextStateInfo.speed < 0), info.clip.isLooping, null, 1f, layerBlendMode, MixDirection.In);
|
||||
++c; break;
|
||||
}
|
||||
}
|
||||
@ -326,7 +326,7 @@ namespace Spine.Unity {
|
||||
var info = nextClipInfo[c]; float weight = info.weight * layerWeight; if (weight == 0) continue;
|
||||
var clip = GetAnimation(info.clip);
|
||||
if (clip != null)
|
||||
clip.Apply(skeleton, 0, AnimationTime(nextStateInfo.normalizedTime, info.clip.length, nextStateInfo.speed < 0), nextStateInfo.loop, null, weight, layerBlendMode, MixDirection.In);
|
||||
clip.Apply(skeleton, 0, AnimationTime(nextStateInfo.normalizedTime, info.clip.length, nextStateInfo.speed < 0), info.clip.isLooping, null, weight, layerBlendMode, MixDirection.In);
|
||||
}
|
||||
}
|
||||
|
||||
@ -340,7 +340,7 @@ namespace Spine.Unity {
|
||||
float weight = clipWeight * layerWeight; if (weight == 0) continue;
|
||||
var clip = GetAnimation(info.clip);
|
||||
if (clip != null)
|
||||
clip.Apply(skeleton, 0, AnimationTime(interruptingStateInfo.normalizedTime + interruptingClipTimeAddition, info.clip.length, interruptingStateInfo.speed < 0), interruptingStateInfo.loop, null, 1f, layerBlendMode, MixDirection.In);
|
||||
clip.Apply(skeleton, 0, AnimationTime(interruptingStateInfo.normalizedTime + interruptingClipTimeAddition, info.clip.length, interruptingStateInfo.speed < 0), info.clip.isLooping, null, 1f, layerBlendMode, MixDirection.In);
|
||||
++c; break;
|
||||
}
|
||||
}
|
||||
@ -351,7 +351,7 @@ namespace Spine.Unity {
|
||||
float weight = clipWeight * layerWeight; if (weight == 0) continue;
|
||||
var clip = GetAnimation(info.clip);
|
||||
if (clip != null)
|
||||
clip.Apply(skeleton, 0, AnimationTime(interruptingStateInfo.normalizedTime + interruptingClipTimeAddition, info.clip.length, interruptingStateInfo.speed < 0), interruptingStateInfo.loop, null, weight, layerBlendMode, MixDirection.In);
|
||||
clip.Apply(skeleton, 0, AnimationTime(interruptingStateInfo.normalizedTime + interruptingClipTimeAddition, info.clip.length, interruptingStateInfo.speed < 0), info.clip.isLooping, null, weight, layerBlendMode, MixDirection.In);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +0,0 @@
|
||||
SkeletonRenderSeparator
|
||||
=======================
|
||||
|
||||
Dependencies:
|
||||
- SkeletonPartsRenderer uses the `ArraysMeshGenerator` class in `Spine.Unity.MeshGeneration`
|
||||
- It requires `SPINE_OPTIONAL_RENDEROVERRIDE` to be #defined in `SkeletonRenderer.cs`.
|
||||
@ -1,8 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f0e413eeb00eabc46bde6dbd7aaaa76c
|
||||
timeCreated: 1469110129
|
||||
licenseType: Free
|
||||
TextScriptImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,210 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated January 1, 2020. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2020, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "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 LLC 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
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#if UNITY_2018_3 || UNITY_2019 || UNITY_2018_3_OR_NEWER
|
||||
#define NEW_PREFAB_SYSTEM
|
||||
#endif
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Spine.Unity {
|
||||
#if NEW_PREFAB_SYSTEM
|
||||
[ExecuteAlways]
|
||||
#else
|
||||
[ExecuteInEditMode]
|
||||
#endif
|
||||
public class SkeletonGraphicCustomMaterials : MonoBehaviour {
|
||||
|
||||
#region Inspector
|
||||
public SkeletonGraphic skeletonGraphic;
|
||||
[SerializeField] protected List<AtlasMaterialOverride> customMaterialOverrides = new List<AtlasMaterialOverride>();
|
||||
[SerializeField] protected List<AtlasTextureOverride> customTextureOverrides = new List<AtlasTextureOverride>();
|
||||
|
||||
#if UNITY_EDITOR
|
||||
void Reset () {
|
||||
skeletonGraphic = GetComponent<SkeletonGraphic>();
|
||||
|
||||
// Populate material list
|
||||
if (skeletonGraphic != null && skeletonGraphic.skeletonDataAsset != null) {
|
||||
var atlasAssets = skeletonGraphic.skeletonDataAsset.atlasAssets;
|
||||
|
||||
var initialAtlasMaterialOverrides = new List<AtlasMaterialOverride>();
|
||||
foreach (AtlasAssetBase atlasAsset in atlasAssets) {
|
||||
foreach (Material atlasMaterial in atlasAsset.Materials) {
|
||||
var atlasMaterialOverride = new AtlasMaterialOverride {
|
||||
overrideEnabled = false,
|
||||
originalTexture = atlasMaterial.mainTexture
|
||||
};
|
||||
|
||||
initialAtlasMaterialOverrides.Add(atlasMaterialOverride);
|
||||
}
|
||||
}
|
||||
customMaterialOverrides = initialAtlasMaterialOverrides;
|
||||
}
|
||||
|
||||
// Populate texture list
|
||||
if (skeletonGraphic != null && skeletonGraphic.skeletonDataAsset != null) {
|
||||
var atlasAssets = skeletonGraphic.skeletonDataAsset.atlasAssets;
|
||||
|
||||
var initialAtlasTextureOverrides = new List<AtlasTextureOverride>();
|
||||
foreach (AtlasAssetBase atlasAsset in atlasAssets) {
|
||||
foreach (Material atlasMaterial in atlasAsset.Materials) {
|
||||
var atlasTextureOverride = new AtlasTextureOverride {
|
||||
overrideEnabled = false,
|
||||
originalTexture = atlasMaterial.mainTexture
|
||||
};
|
||||
|
||||
initialAtlasTextureOverrides.Add(atlasTextureOverride);
|
||||
}
|
||||
}
|
||||
customTextureOverrides = initialAtlasTextureOverrides;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endregion
|
||||
|
||||
void SetCustomMaterialOverrides () {
|
||||
if (skeletonGraphic == null) {
|
||||
Debug.LogError("skeletonGraphic == null");
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < customMaterialOverrides.Count; i++) {
|
||||
AtlasMaterialOverride atlasMaterialOverride = customMaterialOverrides[i];
|
||||
if (atlasMaterialOverride.overrideEnabled)
|
||||
skeletonGraphic.CustomMaterialOverride[atlasMaterialOverride.originalTexture] = atlasMaterialOverride.replacementMaterial;
|
||||
}
|
||||
}
|
||||
|
||||
void RemoveCustomMaterialOverrides () {
|
||||
if (skeletonGraphic == null) {
|
||||
Debug.LogError("skeletonGraphic == null");
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < customMaterialOverrides.Count; i++) {
|
||||
AtlasMaterialOverride atlasMaterialOverride = customMaterialOverrides[i];
|
||||
Material currentMaterial;
|
||||
|
||||
if (!skeletonGraphic.CustomMaterialOverride.TryGetValue(atlasMaterialOverride.originalTexture, out currentMaterial))
|
||||
continue;
|
||||
|
||||
// Do not revert the material if it was changed by something else
|
||||
if (currentMaterial != atlasMaterialOverride.replacementMaterial)
|
||||
continue;
|
||||
|
||||
skeletonGraphic.CustomMaterialOverride.Remove(atlasMaterialOverride.originalTexture);
|
||||
}
|
||||
}
|
||||
|
||||
void SetCustomTextureOverrides () {
|
||||
if (skeletonGraphic == null) {
|
||||
Debug.LogError("skeletonGraphic == null");
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < customTextureOverrides.Count; i++) {
|
||||
AtlasTextureOverride atlasTextureOverride = customTextureOverrides[i];
|
||||
if (atlasTextureOverride.overrideEnabled)
|
||||
skeletonGraphic.CustomTextureOverride[atlasTextureOverride.originalTexture] = atlasTextureOverride.replacementTexture;
|
||||
}
|
||||
}
|
||||
|
||||
void RemoveCustomTextureOverrides () {
|
||||
if (skeletonGraphic == null) {
|
||||
Debug.LogError("skeletonGraphic == null");
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < customTextureOverrides.Count; i++) {
|
||||
AtlasTextureOverride atlasTextureOverride = customTextureOverrides[i];
|
||||
Texture currentTexture;
|
||||
|
||||
if (!skeletonGraphic.CustomTextureOverride.TryGetValue(atlasTextureOverride.originalTexture, out currentTexture))
|
||||
continue;
|
||||
|
||||
// Do not revert the material if it was changed by something else
|
||||
if (currentTexture != atlasTextureOverride.replacementTexture)
|
||||
continue;
|
||||
|
||||
skeletonGraphic.CustomTextureOverride.Remove(atlasTextureOverride.originalTexture);
|
||||
}
|
||||
}
|
||||
|
||||
// OnEnable applies the overrides at runtime, and when the editor loads.
|
||||
void OnEnable () {
|
||||
if (skeletonGraphic == null)
|
||||
skeletonGraphic = GetComponent<SkeletonGraphic>();
|
||||
|
||||
if (skeletonGraphic == null) {
|
||||
Debug.LogError("skeletonGraphic == null");
|
||||
return;
|
||||
}
|
||||
|
||||
skeletonGraphic.Initialize(false);
|
||||
SetCustomMaterialOverrides();
|
||||
SetCustomTextureOverrides();
|
||||
}
|
||||
|
||||
// OnDisable removes the overrides at runtime, and in the editor when the component is disabled or destroyed.
|
||||
void OnDisable () {
|
||||
if (skeletonGraphic == null) {
|
||||
Debug.LogError("skeletonGraphic == null");
|
||||
return;
|
||||
}
|
||||
|
||||
RemoveCustomMaterialOverrides();
|
||||
RemoveCustomTextureOverrides();
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public struct AtlasMaterialOverride : IEquatable<AtlasMaterialOverride> {
|
||||
public bool overrideEnabled;
|
||||
public Texture originalTexture;
|
||||
public Material replacementMaterial;
|
||||
|
||||
public bool Equals (AtlasMaterialOverride other) {
|
||||
return overrideEnabled == other.overrideEnabled && originalTexture == other.originalTexture && replacementMaterial == other.replacementMaterial;
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public struct AtlasTextureOverride : IEquatable<AtlasTextureOverride> {
|
||||
public bool overrideEnabled;
|
||||
public Texture originalTexture;
|
||||
public Texture replacementTexture;
|
||||
|
||||
public bool Equals (AtlasTextureOverride other) {
|
||||
return overrideEnabled == other.overrideEnabled && originalTexture == other.originalTexture && replacementTexture == other.replacementTexture;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6c8717e10b272bf42b05d363ac2679a6
|
||||
timeCreated: 1588789074
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -1,11 +0,0 @@
|
||||
SkeletonRendererCustomMaterials by LostPolygon
|
||||
===============================
|
||||
This is a basic serialization and inspector implementation for custom material overrides for SkeletonRenderer and its derived classes (SkeletonAnimation, SkeletonAnimator).
|
||||
|
||||
## How to use
|
||||
Right-click on your SkeletonRenderer and select "Add Basic Serialized Custom Materials". This will add and initialize the SkeletonRendererCustomMaterials to the same object.
|
||||
|
||||
You can use this to store material override settings for SkeletonRenderer instances/prefabs so they will be applied automatically when your scene starts or when the prefab is instantiated.
|
||||
|
||||
This script is not intended for use with code.
|
||||
To dynamically set materials for your SkeletonRenderer through code, you can directly access `SkeletonRenderer.CustomMaterialOverride` for material array overrides and `SkeletonRenderer.CustomSlotMaterials` for slot material overrides.
|
||||
@ -1,8 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3d4db6c367e463c4cb5566afc490163c
|
||||
timeCreated: 1460572571
|
||||
licenseType: Free
|
||||
TextScriptImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -227,6 +227,35 @@ namespace Spine.Unity {
|
||||
}
|
||||
}
|
||||
|
||||
public static bool RequiresMultipleSubmeshesByDrawOrder (Skeleton skeleton) {
|
||||
|
||||
#if SPINE_TK2D
|
||||
return false;
|
||||
#endif
|
||||
ExposedList<Slot> drawOrder = skeleton.drawOrder;
|
||||
int drawOrderCount = drawOrder.Count;
|
||||
var drawOrderItems = drawOrder.Items;
|
||||
|
||||
Material lastRendererMaterial = null;
|
||||
for (int i = 0; i < drawOrderCount; i++) {
|
||||
Slot slot = drawOrderItems[i];
|
||||
if (!slot.bone.active) continue;
|
||||
Attachment attachment = slot.attachment;
|
||||
var rendererAttachment = attachment as IHasRendererObject;
|
||||
if (rendererAttachment != null) {
|
||||
AtlasRegion atlasRegion = (AtlasRegion)rendererAttachment.RendererObject;
|
||||
Material material = (Material)atlasRegion.page.rendererObject;
|
||||
if (lastRendererMaterial != material) {
|
||||
if (lastRendererMaterial != null)
|
||||
return true;
|
||||
else
|
||||
lastRendererMaterial = material;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void GenerateSkeletonRendererInstruction (SkeletonRendererInstruction instructionOutput, Skeleton skeleton, Dictionary<Slot, Material> customSlotMaterials, List<Slot> separatorSlots, bool generateMeshOverride, bool immutableTriangles = false) {
|
||||
// if (skeleton == null) throw new ArgumentNullException("skeleton");
|
||||
// if (instructionOutput == null) throw new ArgumentNullException("instructionOutput");
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user