mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-03-09 20:26:58 +08:00
[unity] Added example component SkeletonGraphicRenderTexture. Closes #2130. Added additional render callback delegates at SkeletonGraphic.
This commit is contained in:
parent
787af434ff
commit
6ef7df4be6
@ -316,6 +316,8 @@
|
|||||||
* Added example component `SkeletonRenderTexture` to render a `SkeletonRenderer` to a `RenderTexture`, mainly for proper transparency. Added an example scene named `RenderTexture FadeOut Transparency` that demonstrates usage for a fadeout transparency effect.
|
* Added example component `SkeletonRenderTexture` to render a `SkeletonRenderer` to a `RenderTexture`, mainly for proper transparency. Added an example scene named `RenderTexture FadeOut Transparency` that demonstrates usage for a fadeout transparency effect.
|
||||||
* Added another fadeout example component named `SkeletonRenderTextureFadeout` which takes over transparency fadeout when enabled. You can use this component as-is, attach it in disabled state and enable it to start a fadeout effect.
|
* Added another fadeout example component named `SkeletonRenderTextureFadeout` which takes over transparency fadeout when enabled. You can use this component as-is, attach it in disabled state and enable it to start a fadeout effect.
|
||||||
* Timeline clips now offer an additional `Alpha` parameter for setting a custom constant mix alpha value other than 1.0, just as `TrackEntry.Alpha`. Defaults to 1.0.
|
* Timeline clips now offer an additional `Alpha` parameter for setting a custom constant mix alpha value other than 1.0, just as `TrackEntry.Alpha`. Defaults to 1.0.
|
||||||
|
* `SkeletonGraphic` now provides additional render callback delegates `OnInstructionsPrepared`, `AssignMeshOverrideSingleRenderer` and `AssignMeshOverrideMultipleRenderers`. `OnInstructionsPrepared` is raised at the end of LateUpdate after render instructions are done, target renderers are prepared, and the mesh is ready to be generated. The two `AssignMeshOverride` delegates allow separate code to take over mesh and material assignment of a `SkeletonGraphic` component.
|
||||||
|
* Added example component `SkeletonGraphicRenderTexture` to render a `SkeletonGraphic` to a `RenderTexture` (similar as `SkeletonRenderTexture`), mainly for proper transparency. Extended example scene `RenderTexture FadeOut Transparency` accordingly.
|
||||||
|
|
||||||
* **Changes of default values**
|
* **Changes of default values**
|
||||||
|
|
||||||
|
|||||||
@ -153,7 +153,7 @@ RectTransform:
|
|||||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||||
m_Children: []
|
m_Children: []
|
||||||
m_Father: {fileID: 592567554}
|
m_Father: {fileID: 592567554}
|
||||||
m_RootOrder: 0
|
m_RootOrder: 1
|
||||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
m_AnchorMin: {x: 1, y: 1}
|
m_AnchorMin: {x: 1, y: 1}
|
||||||
m_AnchorMax: {x: 1, y: 1}
|
m_AnchorMax: {x: 1, y: 1}
|
||||||
@ -256,6 +256,8 @@ MonoBehaviour:
|
|||||||
materialsInsideMask: []
|
materialsInsideMask: []
|
||||||
materialsOutsideMask: []
|
materialsOutsideMask: []
|
||||||
disableRenderingOnOverride: 1
|
disableRenderingOnOverride: 1
|
||||||
|
updateTiming: 1
|
||||||
|
unscaledTime: 0
|
||||||
_animationName: run
|
_animationName: run
|
||||||
loop: 1
|
loop: 1
|
||||||
timeScale: 1
|
timeScale: 1
|
||||||
@ -316,11 +318,11 @@ Transform:
|
|||||||
m_PrefabAsset: {fileID: 0}
|
m_PrefabAsset: {fileID: 0}
|
||||||
m_GameObject: {fileID: 334034152}
|
m_GameObject: {fileID: 334034152}
|
||||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||||
m_LocalPosition: {x: -5.93, y: 0, z: 5.66}
|
m_LocalPosition: {x: -7.83, y: 0, z: 5.66}
|
||||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||||
m_Children: []
|
m_Children: []
|
||||||
m_Father: {fileID: 0}
|
m_Father: {fileID: 0}
|
||||||
m_RootOrder: 4
|
m_RootOrder: 3
|
||||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
--- !u!1 &541830406
|
--- !u!1 &541830406
|
||||||
GameObject:
|
GameObject:
|
||||||
@ -352,7 +354,7 @@ RectTransform:
|
|||||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||||
m_Children: []
|
m_Children: []
|
||||||
m_Father: {fileID: 592567554}
|
m_Father: {fileID: 592567554}
|
||||||
m_RootOrder: 1
|
m_RootOrder: 2
|
||||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
m_AnchorMin: {x: 1, y: 1}
|
m_AnchorMin: {x: 1, y: 1}
|
||||||
m_AnchorMax: {x: 1, y: 1}
|
m_AnchorMax: {x: 1, y: 1}
|
||||||
@ -433,9 +435,11 @@ RectTransform:
|
|||||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||||
m_LocalScale: {x: 0, y: 0, z: 0}
|
m_LocalScale: {x: 0, y: 0, z: 0}
|
||||||
m_Children:
|
m_Children:
|
||||||
|
- {fileID: 1911967440}
|
||||||
- {fileID: 71621967}
|
- {fileID: 71621967}
|
||||||
- {fileID: 541830407}
|
- {fileID: 541830407}
|
||||||
- {fileID: 1682675646}
|
- {fileID: 1682675646}
|
||||||
|
- {fileID: 1735507358}
|
||||||
m_Father: {fileID: 1799507978}
|
m_Father: {fileID: 1799507978}
|
||||||
m_RootOrder: 0
|
m_RootOrder: 0
|
||||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
@ -488,6 +492,41 @@ Canvas:
|
|||||||
m_SortingLayerID: 0
|
m_SortingLayerID: 0
|
||||||
m_SortingOrder: 0
|
m_SortingOrder: 0
|
||||||
m_TargetDisplay: 0
|
m_TargetDisplay: 0
|
||||||
|
--- !u!1 &1089682726
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 1089682727}
|
||||||
|
m_Layer: 0
|
||||||
|
m_Name: CustomRenderRect
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!224 &1089682727
|
||||||
|
RectTransform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1089682726}
|
||||||
|
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: 1911967440}
|
||||||
|
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: 126.27, y: 7.130005}
|
||||||
|
m_SizeDelta: {x: 1893.1, y: 1654.617}
|
||||||
|
m_Pivot: {x: 0.5, y: 0.5}
|
||||||
--- !u!1 &1368805070
|
--- !u!1 &1368805070
|
||||||
GameObject:
|
GameObject:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
@ -532,6 +571,7 @@ MonoBehaviour:
|
|||||||
m_Name:
|
m_Name:
|
||||||
m_EditorClassIdentifier:
|
m_EditorClassIdentifier:
|
||||||
renderTextureFadeout: {fileID: 1786065619}
|
renderTextureFadeout: {fileID: 1786065619}
|
||||||
|
renderTextureFadeoutCanvas: {fileID: 1911967443}
|
||||||
normalSkeletonRenderer: {fileID: 334034153}
|
normalSkeletonRenderer: {fileID: 334034153}
|
||||||
--- !u!1 &1369381599
|
--- !u!1 &1369381599
|
||||||
GameObject:
|
GameObject:
|
||||||
@ -805,12 +845,12 @@ RectTransform:
|
|||||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||||
m_Children: []
|
m_Children: []
|
||||||
m_Father: {fileID: 592567554}
|
m_Father: {fileID: 592567554}
|
||||||
m_RootOrder: 2
|
m_RootOrder: 3
|
||||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
m_AnchorMin: {x: 0.5, y: 0}
|
m_AnchorMin: {x: 0, y: 0}
|
||||||
m_AnchorMax: {x: 0.5, y: 0.5}
|
m_AnchorMax: {x: 0.6932292, y: 0.18750001}
|
||||||
m_AnchoredPosition: {x: -331.4, y: -186}
|
m_AnchoredPosition: {x: 18.079224, y: 1.5001221}
|
||||||
m_SizeDelta: {x: 1176.1, y: -365}
|
m_SizeDelta: {x: -44.942017, y: 10}
|
||||||
m_Pivot: {x: 0.5, y: 0.5}
|
m_Pivot: {x: 0.5, y: 0.5}
|
||||||
--- !u!114 &1682675647
|
--- !u!114 &1682675647
|
||||||
MonoBehaviour:
|
MonoBehaviour:
|
||||||
@ -847,12 +887,13 @@ MonoBehaviour:
|
|||||||
m_LineSpacing: 1
|
m_LineSpacing: 1
|
||||||
m_Text: 'This scene demonstrates the problems of using conventional alpha transparency
|
m_Text: 'This scene demonstrates the problems of using conventional alpha transparency
|
||||||
for a fadeout effect (left), and how this problem can be fixed by using a RenderTexture
|
for a fadeout effect (left), and how this problem can be fixed by using a RenderTexture
|
||||||
(right).
|
(center and right).
|
||||||
|
|
||||||
|
|
||||||
Spineboy on the right uses a SkeletonRenderTexture component to
|
The two Spineboys on the right use SkeletonRenderTexture
|
||||||
render the overlapping mesh to a RenderTexture first and then draw this texture
|
and SkeletonGraphicRenderTexture components to render the overlapping mesh to
|
||||||
to the scene at once using a single quad.'
|
a RenderTexture first and then draw this texture to the scene at once using a
|
||||||
|
single quad.'
|
||||||
--- !u!222 &1682675648
|
--- !u!222 &1682675648
|
||||||
CanvasRenderer:
|
CanvasRenderer:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
@ -861,6 +902,87 @@ CanvasRenderer:
|
|||||||
m_PrefabAsset: {fileID: 0}
|
m_PrefabAsset: {fileID: 0}
|
||||||
m_GameObject: {fileID: 1682675645}
|
m_GameObject: {fileID: 1682675645}
|
||||||
m_CullTransparentMesh: 1
|
m_CullTransparentMesh: 1
|
||||||
|
--- !u!1 &1735507357
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 1735507358}
|
||||||
|
- component: {fileID: 1735507360}
|
||||||
|
- component: {fileID: 1735507359}
|
||||||
|
m_Layer: 5
|
||||||
|
m_Name: SkeletonGraphic Notes
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!224 &1735507358
|
||||||
|
RectTransform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1735507357}
|
||||||
|
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: 592567554}
|
||||||
|
m_RootOrder: 4
|
||||||
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
|
m_AnchorMin: {x: 0.6932292, y: 0}
|
||||||
|
m_AnchorMax: {x: 1, y: 0.18750001}
|
||||||
|
m_AnchoredPosition: {x: 6.5009766, y: -2.5753784}
|
||||||
|
m_SizeDelta: {x: -49.462, y: 1.8482}
|
||||||
|
m_Pivot: {x: 0.5, y: 0.5}
|
||||||
|
--- !u!114 &1735507359
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1735507357}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
m_Material: {fileID: 0}
|
||||||
|
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||||
|
m_RaycastTarget: 1
|
||||||
|
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
|
||||||
|
m_Maskable: 1
|
||||||
|
m_OnCullStateChanged:
|
||||||
|
m_PersistentCalls:
|
||||||
|
m_Calls: []
|
||||||
|
m_FontData:
|
||||||
|
m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
|
||||||
|
m_FontSize: 26
|
||||||
|
m_FontStyle: 0
|
||||||
|
m_BestFit: 0
|
||||||
|
m_MinSize: 2
|
||||||
|
m_MaxSize: 40
|
||||||
|
m_Alignment: 2
|
||||||
|
m_AlignByGeometry: 0
|
||||||
|
m_RichText: 1
|
||||||
|
m_HorizontalOverflow: 0
|
||||||
|
m_VerticalOverflow: 1
|
||||||
|
m_LineSpacing: 1
|
||||||
|
m_Text: SkeletonGraphicRenderTexture supports setting a RectTransform as 'Custom
|
||||||
|
Render Rect' to define render texture bounds different from the SkeletonGraphic
|
||||||
|
rect.
|
||||||
|
--- !u!222 &1735507360
|
||||||
|
CanvasRenderer:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1735507357}
|
||||||
|
m_CullTransparentMesh: 1
|
||||||
--- !u!1 &1786065613
|
--- !u!1 &1786065613
|
||||||
GameObject:
|
GameObject:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
@ -895,11 +1017,11 @@ MonoBehaviour:
|
|||||||
m_Name:
|
m_Name:
|
||||||
m_EditorClassIdentifier:
|
m_EditorClassIdentifier:
|
||||||
color: {r: 1, g: 1, b: 1, a: 1}
|
color: {r: 1, g: 1, b: 1, a: 1}
|
||||||
quadMaterial: {fileID: 2100000, guid: 4c507f887c6274a44a603d96e0eabf2a, type: 2}
|
|
||||||
targetCamera: {fileID: 0}
|
|
||||||
maxRenderTextureSize: 1024
|
maxRenderTextureSize: 1024
|
||||||
quad: {fileID: 0}
|
quad: {fileID: 0}
|
||||||
renderTexture: {fileID: 0}
|
renderTexture: {fileID: 0}
|
||||||
|
targetCamera: {fileID: 0}
|
||||||
|
quadMaterial: {fileID: 2100000, guid: 4c507f887c6274a44a603d96e0eabf2a, type: 2}
|
||||||
--- !u!114 &1786065615
|
--- !u!114 &1786065615
|
||||||
MonoBehaviour:
|
MonoBehaviour:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
@ -935,6 +1057,8 @@ MonoBehaviour:
|
|||||||
materialsInsideMask: []
|
materialsInsideMask: []
|
||||||
materialsOutsideMask: []
|
materialsOutsideMask: []
|
||||||
disableRenderingOnOverride: 1
|
disableRenderingOnOverride: 1
|
||||||
|
updateTiming: 1
|
||||||
|
unscaledTime: 0
|
||||||
_animationName: run
|
_animationName: run
|
||||||
loop: 1
|
loop: 1
|
||||||
timeScale: 1
|
timeScale: 1
|
||||||
@ -995,11 +1119,11 @@ Transform:
|
|||||||
m_PrefabAsset: {fileID: 0}
|
m_PrefabAsset: {fileID: 0}
|
||||||
m_GameObject: {fileID: 1786065613}
|
m_GameObject: {fileID: 1786065613}
|
||||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||||
m_LocalPosition: {x: 3.32, y: 0, z: 5.66}
|
m_LocalPosition: {x: 2.38, y: 0, z: 5.66}
|
||||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||||
m_Children: []
|
m_Children: []
|
||||||
m_Father: {fileID: 0}
|
m_Father: {fileID: 0}
|
||||||
m_RootOrder: 3
|
m_RootOrder: 4
|
||||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
--- !u!114 &1786065619
|
--- !u!114 &1786065619
|
||||||
MonoBehaviour:
|
MonoBehaviour:
|
||||||
@ -1045,3 +1169,136 @@ Transform:
|
|||||||
m_Father: {fileID: 0}
|
m_Father: {fileID: 0}
|
||||||
m_RootOrder: 6
|
m_RootOrder: 6
|
||||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
|
--- !u!1 &1911967439
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 1911967440}
|
||||||
|
- component: {fileID: 1911967442}
|
||||||
|
- component: {fileID: 1911967441}
|
||||||
|
- component: {fileID: 1911967444}
|
||||||
|
- component: {fileID: 1911967443}
|
||||||
|
m_Layer: 0
|
||||||
|
m_Name: SkeletonGraphic (spineboy-pro)
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!224 &1911967440
|
||||||
|
RectTransform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1911967439}
|
||||||
|
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||||
|
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||||
|
m_LocalScale: {x: 0.3, y: 0.3, z: 0.3}
|
||||||
|
m_Children:
|
||||||
|
- {fileID: 1089682727}
|
||||||
|
m_Father: {fileID: 592567554}
|
||||||
|
m_RootOrder: 0
|
||||||
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
|
m_AnchorMin: {x: 0.5, y: 0.5}
|
||||||
|
m_AnchorMax: {x: 1, y: 0.5}
|
||||||
|
m_AnchoredPosition: {x: 84, y: -317.51}
|
||||||
|
m_SizeDelta: {x: 1185.6, y: 1302.059}
|
||||||
|
m_Pivot: {x: 0.63858336, y: 0.010301443}
|
||||||
|
--- !u!114 &1911967441
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1911967439}
|
||||||
|
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_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
|
||||||
|
m_Maskable: 1
|
||||||
|
m_OnCullStateChanged:
|
||||||
|
m_PersistentCalls:
|
||||||
|
m_Calls: []
|
||||||
|
skeletonDataAsset: {fileID: 11400000, guid: af38a3de26ed9b84abc2fe7c7f3b209d, type: 2}
|
||||||
|
additiveMaterial: {fileID: 2100000, guid: 2e8245019faeb8c43b75f9ca3ac8ee34, type: 2}
|
||||||
|
multiplyMaterial: {fileID: 2100000, guid: e74a1f8978a7da348a721508d0d58834, type: 2}
|
||||||
|
screenMaterial: {fileID: 2100000, guid: bab24c479f34eec45be6ea8595891569, type: 2}
|
||||||
|
initialSkinName: default
|
||||||
|
initialFlipX: 0
|
||||||
|
initialFlipY: 0
|
||||||
|
startingAnimation: run
|
||||||
|
startingLoop: 1
|
||||||
|
timeScale: 1
|
||||||
|
freeze: 0
|
||||||
|
updateWhenInvisible: 3
|
||||||
|
allowMultipleCanvasRenderers: 0
|
||||||
|
canvasRenderers: []
|
||||||
|
separatorSlotNames: []
|
||||||
|
enableSeparatorSlots: 0
|
||||||
|
separatorParts: []
|
||||||
|
updateSeparatorPartLocation: 1
|
||||||
|
disableMeshAssignmentOnOverride: 1
|
||||||
|
meshGenerator:
|
||||||
|
settings:
|
||||||
|
useClipping: 1
|
||||||
|
zSpacing: 0
|
||||||
|
pmaVertexColors: 1
|
||||||
|
tintBlack: 0
|
||||||
|
canvasGroupTintBlack: 0
|
||||||
|
calculateTangents: 0
|
||||||
|
addNormals: 0
|
||||||
|
immutableTriangles: 0
|
||||||
|
updateTiming: 1
|
||||||
|
unscaledTime: 0
|
||||||
|
--- !u!222 &1911967442
|
||||||
|
CanvasRenderer:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1911967439}
|
||||||
|
m_CullTransparentMesh: 0
|
||||||
|
--- !u!114 &1911967443
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1911967439}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 5fc94f89310427643babb41e000a8462, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
fadeoutSeconds: 2
|
||||||
|
--- !u!114 &1911967444
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1911967439}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 6cbe1f11426513d49ad8e21e9d6643f7, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
color: {r: 1, g: 1, b: 1, a: 1}
|
||||||
|
maxRenderTextureSize: 1024
|
||||||
|
quad: {fileID: 0}
|
||||||
|
renderTexture: {fileID: 0}
|
||||||
|
targetCamera: {fileID: 0}
|
||||||
|
customRenderRect: {fileID: 1089682727}
|
||||||
|
meshRendererMaterialForTexture:
|
||||||
|
- texture: {fileID: 2800000, guid: 4ea2c33e839afb34c98f66e892b3b2d2, type: 3}
|
||||||
|
material: {fileID: 2100000, guid: f89bbf05902e77242a3ad20f3c927353, type: 2}
|
||||||
|
|||||||
@ -39,6 +39,7 @@ namespace Spine.Unity.Examples {
|
|||||||
public class RenderTextureFadeoutExample : MonoBehaviour {
|
public class RenderTextureFadeoutExample : MonoBehaviour {
|
||||||
|
|
||||||
public SkeletonRenderTextureFadeout renderTextureFadeout;
|
public SkeletonRenderTextureFadeout renderTextureFadeout;
|
||||||
|
public SkeletonRenderTextureFadeout renderTextureFadeoutCanvas;
|
||||||
public SkeletonRenderer normalSkeletonRenderer;
|
public SkeletonRenderer normalSkeletonRenderer;
|
||||||
|
|
||||||
float fadeoutSeconds = 2.0f;
|
float fadeoutSeconds = 2.0f;
|
||||||
@ -47,8 +48,9 @@ namespace Spine.Unity.Examples {
|
|||||||
IEnumerator Start () {
|
IEnumerator Start () {
|
||||||
while (true) {
|
while (true) {
|
||||||
StartFadeoutBad();
|
StartFadeoutBad();
|
||||||
StartFadeoutGood();
|
StartFadeoutGood(renderTextureFadeout);
|
||||||
yield return new WaitForSeconds(5.0f);
|
StartFadeoutGood(renderTextureFadeoutCanvas);
|
||||||
|
yield return new WaitForSeconds(fadeoutSeconds + 1.0f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void Update () {
|
void Update () {
|
||||||
@ -75,12 +77,12 @@ namespace Spine.Unity.Examples {
|
|||||||
fadeoutSecondsRemaining = fadeoutSeconds;
|
fadeoutSecondsRemaining = fadeoutSeconds;
|
||||||
}
|
}
|
||||||
|
|
||||||
void StartFadeoutGood () {
|
void StartFadeoutGood (SkeletonRenderTextureFadeout fadeoutComponent) {
|
||||||
renderTextureFadeout.gameObject.SetActive(true);
|
fadeoutComponent.gameObject.SetActive(true);
|
||||||
// enabling the SkeletonRenderTextureFadeout component starts the fadeout.
|
// enabling the SkeletonRenderTextureFadeout component starts the fadeout.
|
||||||
renderTextureFadeout.enabled = true;
|
fadeoutComponent.enabled = true;
|
||||||
renderTextureFadeout.OnFadeoutComplete -= DisableGameObject;
|
fadeoutComponent.OnFadeoutComplete -= DisableGameObject;
|
||||||
renderTextureFadeout.OnFadeoutComplete += DisableGameObject;
|
fadeoutComponent.OnFadeoutComplete += DisableGameObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DisableGameObject (SkeletonRenderTextureFadeout target) {
|
void DisableGameObject (SkeletonRenderTextureFadeout target) {
|
||||||
|
|||||||
@ -0,0 +1,253 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Spine Runtimes License Agreement
|
||||||
|
* Last updated January 1, 2020. Replaces all prior versions.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013-2022, 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.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.Rendering;
|
||||||
|
using UnityEngine.UI;
|
||||||
|
|
||||||
|
namespace Spine.Unity.Examples {
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// When enabled, this component renders a skeleton to a RenderTexture and
|
||||||
|
/// then draws this RenderTexture at a UI RawImage quad of the same size.
|
||||||
|
/// This allows changing transparency at a single quad, which produces a more
|
||||||
|
/// natural fadeout effect.
|
||||||
|
/// Note: It is recommended to keep this component disabled as much as possible
|
||||||
|
/// because of the additional rendering overhead. Only enable it when alpha blending is required.
|
||||||
|
/// </summary>
|
||||||
|
[RequireComponent(typeof(SkeletonGraphic))]
|
||||||
|
public class SkeletonGraphicRenderTexture : SkeletonRenderTextureBase {
|
||||||
|
[System.Serializable]
|
||||||
|
public struct TextureMaterialPair {
|
||||||
|
public Texture texture;
|
||||||
|
public Material material;
|
||||||
|
|
||||||
|
public TextureMaterialPair (Texture texture, Material material) {
|
||||||
|
this.texture = texture;
|
||||||
|
this.material = material;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public RectTransform customRenderRect;
|
||||||
|
protected SkeletonGraphic skeletonGraphic;
|
||||||
|
public List<TextureMaterialPair> meshRendererMaterialForTexture = new List<TextureMaterialPair>();
|
||||||
|
protected CanvasRenderer quadCanvasRenderer;
|
||||||
|
protected RawImage quadRawImage;
|
||||||
|
protected readonly Vector3[] worldCorners = new Vector3[4];
|
||||||
|
|
||||||
|
protected override void Awake () {
|
||||||
|
base.Awake();
|
||||||
|
skeletonGraphic = this.GetComponent<SkeletonGraphic>();
|
||||||
|
if (targetCamera == null) {
|
||||||
|
targetCamera = skeletonGraphic.canvas.worldCamera;
|
||||||
|
if (targetCamera == null)
|
||||||
|
targetCamera = Camera.main;
|
||||||
|
}
|
||||||
|
CreateQuadChild();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CreateQuadChild () {
|
||||||
|
quad = new GameObject(this.name + " RenderTexture", typeof(CanvasRenderer), typeof(RawImage));
|
||||||
|
quad.transform.SetParent(this.transform.parent, false);
|
||||||
|
quadCanvasRenderer = quad.GetComponent<CanvasRenderer>();
|
||||||
|
quadRawImage = quad.GetComponent<RawImage>();
|
||||||
|
|
||||||
|
quadMesh = new Mesh();
|
||||||
|
quadMesh.MarkDynamic();
|
||||||
|
quadMesh.name = "RenderTexture Quad";
|
||||||
|
quadMesh.hideFlags = HideFlags.DontSaveInBuild | HideFlags.DontSaveInEditor;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Reset () {
|
||||||
|
skeletonGraphic = this.GetComponent<SkeletonGraphic>();
|
||||||
|
AtlasAssetBase[] atlasAssets = skeletonGraphic.SkeletonDataAsset.atlasAssets;
|
||||||
|
for (int i = 0; i < atlasAssets.Length; ++i) {
|
||||||
|
foreach (var material in atlasAssets[i].Materials) {
|
||||||
|
if (material.mainTexture != null) {
|
||||||
|
meshRendererMaterialForTexture.Add(
|
||||||
|
new TextureMaterialPair(material.mainTexture, material));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnEnable () {
|
||||||
|
skeletonGraphic.OnInstructionsPrepared += PrepareQuad;
|
||||||
|
skeletonGraphic.AssignMeshOverrideSingleRenderer += RenderSingleMeshToRenderTexture;
|
||||||
|
skeletonGraphic.AssignMeshOverrideMultipleRenderers += RenderMultipleMeshesToRenderTexture;
|
||||||
|
skeletonGraphic.disableMeshAssignmentOnOverride = true;
|
||||||
|
skeletonGraphic.OnMeshAndMaterialsUpdated += RenderOntoQuad;
|
||||||
|
var canvasRenderers = skeletonGraphic.canvasRenderers;
|
||||||
|
for (int i = 0; i < canvasRenderers.Count; ++i)
|
||||||
|
canvasRenderers[i].cull = true;
|
||||||
|
|
||||||
|
if (quadCanvasRenderer)
|
||||||
|
quadCanvasRenderer.gameObject.SetActive(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnDisable () {
|
||||||
|
skeletonGraphic.OnInstructionsPrepared -= PrepareQuad;
|
||||||
|
skeletonGraphic.AssignMeshOverrideSingleRenderer -= RenderSingleMeshToRenderTexture;
|
||||||
|
skeletonGraphic.AssignMeshOverrideMultipleRenderers -= RenderMultipleMeshesToRenderTexture;
|
||||||
|
skeletonGraphic.disableMeshAssignmentOnOverride = false;
|
||||||
|
skeletonGraphic.OnMeshAndMaterialsUpdated -= RenderOntoQuad;
|
||||||
|
var canvasRenderers = skeletonGraphic.canvasRenderers;
|
||||||
|
for (int i = 0; i < canvasRenderers.Count; ++i)
|
||||||
|
canvasRenderers[i].cull = false;
|
||||||
|
|
||||||
|
if (quadCanvasRenderer)
|
||||||
|
quadCanvasRenderer.gameObject.SetActive(false);
|
||||||
|
if (renderTexture)
|
||||||
|
RenderTexture.ReleaseTemporary(renderTexture);
|
||||||
|
allocatedRenderTextureSize = Vector2Int.zero;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrepareQuad (SkeletonRendererInstruction instruction) {
|
||||||
|
PrepareForMesh();
|
||||||
|
SetupQuad();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderOntoQuad (SkeletonGraphic skeletonRenderer) {
|
||||||
|
AssignAtQuad();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void PrepareForMesh () {
|
||||||
|
// We need to get the min/max of all four corners, rotation of the skeleton
|
||||||
|
// in combination with perspective projection otherwise might lead to incorrect
|
||||||
|
// screen space min/max.
|
||||||
|
RectTransform rectTransform = customRenderRect ? customRenderRect : skeletonGraphic.rectTransform;
|
||||||
|
rectTransform.GetWorldCorners(worldCorners);
|
||||||
|
|
||||||
|
RenderMode canvasRenderMode = skeletonGraphic.canvas.renderMode;
|
||||||
|
Vector3 screenCorner0, screenCorner1, screenCorner2, screenCorner3;
|
||||||
|
// note: world corners are ordered bottom left, top left, top right, bottom right.
|
||||||
|
// This corresponds to 0, 3, 1, 2 in our desired order.
|
||||||
|
if (canvasRenderMode == RenderMode.ScreenSpaceOverlay) {
|
||||||
|
screenCorner0 = worldCorners[0];
|
||||||
|
screenCorner1 = worldCorners[3];
|
||||||
|
screenCorner2 = worldCorners[1];
|
||||||
|
screenCorner3 = worldCorners[2];
|
||||||
|
} else {
|
||||||
|
screenCorner0 = targetCamera.WorldToScreenPoint(worldCorners[0]);
|
||||||
|
screenCorner1 = targetCamera.WorldToScreenPoint(worldCorners[3]);
|
||||||
|
screenCorner2 = targetCamera.WorldToScreenPoint(worldCorners[1]);
|
||||||
|
screenCorner3 = targetCamera.WorldToScreenPoint(worldCorners[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// To avoid perspective distortion when rotated, we project all vertices
|
||||||
|
// onto a plane parallel to the view frustum near plane.
|
||||||
|
// Avoids the requirement of 'noperspective' vertex attribute interpolation modifier in shaders.
|
||||||
|
float averageScreenDepth = (screenCorner0.z + screenCorner1.z + screenCorner2.z + screenCorner3.z) / 4.0f;
|
||||||
|
screenCorner0.z = screenCorner1.z = screenCorner2.z = screenCorner3.z = averageScreenDepth;
|
||||||
|
|
||||||
|
if (canvasRenderMode == RenderMode.ScreenSpaceOverlay) {
|
||||||
|
worldCornerNoDistortion0 = screenCorner0;
|
||||||
|
worldCornerNoDistortion1 = screenCorner1;
|
||||||
|
worldCornerNoDistortion2 = screenCorner2;
|
||||||
|
worldCornerNoDistortion3 = screenCorner3;
|
||||||
|
} else {
|
||||||
|
worldCornerNoDistortion0 = targetCamera.ScreenToWorldPoint(screenCorner0);
|
||||||
|
worldCornerNoDistortion1 = targetCamera.ScreenToWorldPoint(screenCorner1);
|
||||||
|
worldCornerNoDistortion2 = targetCamera.ScreenToWorldPoint(screenCorner2);
|
||||||
|
worldCornerNoDistortion3 = targetCamera.ScreenToWorldPoint(screenCorner3);
|
||||||
|
}
|
||||||
|
Vector3 screenSpaceMin, screenSpaceMax;
|
||||||
|
PrepareTextureMapping(out screenSpaceMin, out screenSpaceMax,
|
||||||
|
screenCorner0, screenCorner1, screenCorner2, screenCorner3);
|
||||||
|
PrepareCommandBuffer(targetCamera, screenSpaceMin, screenSpaceMax);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Material MeshRendererMaterialForTexture (Texture texture) {
|
||||||
|
return meshRendererMaterialForTexture.Find(x => x.texture == texture).material;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void RenderSingleMeshToRenderTexture (Mesh mesh, Material graphicMaterial, Texture texture) {
|
||||||
|
Material meshRendererMaterial = MeshRendererMaterialForTexture(texture);
|
||||||
|
commandBuffer.DrawMesh(mesh, transform.localToWorldMatrix, meshRendererMaterial, 0, -1);
|
||||||
|
Graphics.ExecuteCommandBuffer(commandBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void RenderMultipleMeshesToRenderTexture (int meshCount,
|
||||||
|
Mesh[] meshes, Material[] graphicMaterials, Texture[] textures) {
|
||||||
|
|
||||||
|
for (int i = 0; i < meshCount; ++i) {
|
||||||
|
Material meshRendererMaterial = MeshRendererMaterialForTexture(textures[i]);
|
||||||
|
commandBuffer.DrawMesh(meshes[i], transform.localToWorldMatrix, meshRendererMaterial, 0, -1);
|
||||||
|
}
|
||||||
|
Graphics.ExecuteCommandBuffer(commandBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void SetupQuad () {
|
||||||
|
quadRawImage.texture = this.renderTexture;
|
||||||
|
quadRawImage.color = color;
|
||||||
|
quadCanvasRenderer.SetColor(color);
|
||||||
|
|
||||||
|
var srcRectTransform = skeletonGraphic.rectTransform;
|
||||||
|
var dstRectTransform = quadRawImage.rectTransform;
|
||||||
|
|
||||||
|
dstRectTransform.anchorMin = srcRectTransform.anchorMin;
|
||||||
|
dstRectTransform.anchorMax = srcRectTransform.anchorMax;
|
||||||
|
dstRectTransform.anchoredPosition = srcRectTransform.anchoredPosition;
|
||||||
|
dstRectTransform.pivot = srcRectTransform.pivot;
|
||||||
|
dstRectTransform.localScale = srcRectTransform.localScale;
|
||||||
|
dstRectTransform.sizeDelta = srcRectTransform.sizeDelta;
|
||||||
|
dstRectTransform.rotation = srcRectTransform.rotation;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void PrepareCommandBuffer (Camera targetCamera, Vector3 screenSpaceMin, Vector3 screenSpaceMax) {
|
||||||
|
commandBuffer.Clear();
|
||||||
|
commandBuffer.SetRenderTarget(renderTexture);
|
||||||
|
commandBuffer.ClearRenderTarget(true, true, Color.clear);
|
||||||
|
|
||||||
|
Rect canvasRect = skeletonGraphic.canvas.pixelRect;
|
||||||
|
|
||||||
|
Matrix4x4 projectionMatrix = Matrix4x4.Ortho(
|
||||||
|
canvasRect.x, canvasRect.x + canvasRect.width,
|
||||||
|
canvasRect.y, canvasRect.y + canvasRect.height,
|
||||||
|
float.MinValue, float.MaxValue);
|
||||||
|
|
||||||
|
RenderMode canvasRenderMode = skeletonGraphic.canvas.renderMode;
|
||||||
|
if (canvasRenderMode == RenderMode.ScreenSpaceOverlay) {
|
||||||
|
commandBuffer.SetViewMatrix(Matrix4x4.identity);
|
||||||
|
commandBuffer.SetProjectionMatrix(projectionMatrix);
|
||||||
|
} else {
|
||||||
|
commandBuffer.SetViewMatrix(targetCamera.worldToCameraMatrix);
|
||||||
|
commandBuffer.SetProjectionMatrix(targetCamera.projectionMatrix);
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector2 targetCameraViewportSize = targetCamera.pixelRect.size;
|
||||||
|
commandBuffer.SetViewport(new Rect(-screenSpaceMin, targetCameraViewportSize));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void AssignMeshAtRenderer () {
|
||||||
|
quadCanvasRenderer.SetMesh(quadMesh);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 6cbe1f11426513d49ad8e21e9d6643f7
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@ -35,7 +35,6 @@
|
|||||||
#define HAS_GET_SHARED_MATERIALS
|
#define HAS_GET_SHARED_MATERIALS
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.Rendering;
|
using UnityEngine.Rendering;
|
||||||
@ -54,20 +53,11 @@ namespace Spine.Unity.Examples {
|
|||||||
public class SkeletonRenderTexture : SkeletonRenderTextureBase {
|
public class SkeletonRenderTexture : SkeletonRenderTextureBase {
|
||||||
#if HAS_GET_SHARED_MATERIALS
|
#if HAS_GET_SHARED_MATERIALS
|
||||||
public Material quadMaterial;
|
public Material quadMaterial;
|
||||||
public Camera targetCamera;
|
|
||||||
protected SkeletonRenderer skeletonRenderer;
|
protected SkeletonRenderer skeletonRenderer;
|
||||||
protected MeshRenderer meshRenderer;
|
protected MeshRenderer meshRenderer;
|
||||||
protected MeshFilter meshFilter;
|
protected MeshFilter meshFilter;
|
||||||
protected MeshRenderer quadMeshRenderer;
|
protected MeshRenderer quadMeshRenderer;
|
||||||
protected MeshFilter quadMeshFilter;
|
protected MeshFilter quadMeshFilter;
|
||||||
protected Vector3 worldCornerNoDistortion0;
|
|
||||||
protected Vector3 worldCornerNoDistortion1;
|
|
||||||
protected Vector3 worldCornerNoDistortion2;
|
|
||||||
protected Vector3 worldCornerNoDistortion3;
|
|
||||||
protected Vector2 uvCorner0;
|
|
||||||
protected Vector2 uvCorner1;
|
|
||||||
protected Vector2 uvCorner2;
|
|
||||||
protected Vector2 uvCorner3;
|
|
||||||
|
|
||||||
private MaterialPropertyBlock propertyBlock;
|
private MaterialPropertyBlock propertyBlock;
|
||||||
private readonly List<Material> materials = new List<Material>();
|
private readonly List<Material> materials = new List<Material>();
|
||||||
@ -160,40 +150,13 @@ namespace Spine.Unity.Examples {
|
|||||||
worldCornerNoDistortion2 = targetCamera.ScreenToWorldPoint(screenCorner2);
|
worldCornerNoDistortion2 = targetCamera.ScreenToWorldPoint(screenCorner2);
|
||||||
worldCornerNoDistortion3 = targetCamera.ScreenToWorldPoint(screenCorner3);
|
worldCornerNoDistortion3 = targetCamera.ScreenToWorldPoint(screenCorner3);
|
||||||
|
|
||||||
Vector3 screenSpaceMin =
|
Vector3 screenSpaceMin, screenSpaceMax;
|
||||||
Vector3.Min(screenCorner0, Vector3.Min(screenCorner1,
|
PrepareTextureMapping(out screenSpaceMin, out screenSpaceMax,
|
||||||
Vector3.Min(screenCorner2, screenCorner3)));
|
screenCorner0, screenCorner1, screenCorner2, screenCorner3);
|
||||||
Vector3 screenSpaceMax =
|
|
||||||
Vector3.Max(screenCorner0, Vector3.Max(screenCorner1,
|
|
||||||
Vector3.Max(screenCorner2, screenCorner3)));
|
|
||||||
// ensure we are on whole pixel borders
|
|
||||||
screenSpaceMin.x = Mathf.Floor(screenSpaceMin.x);
|
|
||||||
screenSpaceMin.y = Mathf.Floor(screenSpaceMin.y);
|
|
||||||
screenSpaceMax.x = Mathf.Ceil(screenSpaceMax.x);
|
|
||||||
screenSpaceMax.y = Mathf.Ceil(screenSpaceMax.y);
|
|
||||||
|
|
||||||
// inverse-map screenCornerN to screenSpaceMin/screenSpaceMax area to get UV coordinates
|
|
||||||
uvCorner0 = InverseLerp(screenSpaceMin, screenSpaceMax, screenCorner0);
|
|
||||||
uvCorner1 = InverseLerp(screenSpaceMin, screenSpaceMax, screenCorner1);
|
|
||||||
uvCorner2 = InverseLerp(screenSpaceMin, screenSpaceMax, screenCorner2);
|
|
||||||
uvCorner3 = InverseLerp(screenSpaceMin, screenSpaceMax, screenCorner3);
|
|
||||||
|
|
||||||
requiredRenderTextureSize = new Vector2Int(
|
|
||||||
Math.Min(maxRenderTextureSize, Math.Abs((int)screenSpaceMax.x - (int)screenSpaceMin.x)),
|
|
||||||
Math.Min(maxRenderTextureSize, Math.Abs((int)screenSpaceMax.y - (int)screenSpaceMin.y)));
|
|
||||||
|
|
||||||
PrepareRenderTexture();
|
|
||||||
PrepareCommandBuffer(targetCamera, screenSpaceMin, screenSpaceMax);
|
PrepareCommandBuffer(targetCamera, screenSpaceMin, screenSpaceMax);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Vector2 InverseLerp (Vector2 a, Vector2 b, Vector2 value) {
|
|
||||||
return new Vector2(
|
|
||||||
(value.x - a.x) / (b.x - a.x),
|
|
||||||
(value.y - a.y) / (b.y - a.y));
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void PrepareCommandBuffer (Camera targetCamera, Vector3 screenSpaceMin, Vector3 screenSpaceMax) {
|
protected void PrepareCommandBuffer (Camera targetCamera, Vector3 screenSpaceMin, Vector3 screenSpaceMax) {
|
||||||
|
|
||||||
commandBuffer.Clear();
|
commandBuffer.Clear();
|
||||||
commandBuffer.SetRenderTarget(renderTexture);
|
commandBuffer.SetRenderTarget(renderTexture);
|
||||||
commandBuffer.ClearRenderTarget(true, true, Color.clear);
|
commandBuffer.ClearRenderTarget(true, true, Color.clear);
|
||||||
@ -214,40 +177,7 @@ namespace Spine.Unity.Examples {
|
|||||||
Graphics.ExecuteCommandBuffer(commandBuffer);
|
Graphics.ExecuteCommandBuffer(commandBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void AssignAtQuad () {
|
protected override void AssignMeshAtRenderer () {
|
||||||
Transform quadTransform = quadMeshRenderer.transform;
|
|
||||||
quadTransform.position = this.transform.position;
|
|
||||||
quadTransform.rotation = this.transform.rotation;
|
|
||||||
quadTransform.localScale = this.transform.localScale;
|
|
||||||
|
|
||||||
Vector3 v0 = quadTransform.InverseTransformPoint(worldCornerNoDistortion0);
|
|
||||||
Vector3 v1 = quadTransform.InverseTransformPoint(worldCornerNoDistortion1);
|
|
||||||
Vector3 v2 = quadTransform.InverseTransformPoint(worldCornerNoDistortion2);
|
|
||||||
Vector3 v3 = quadTransform.InverseTransformPoint(worldCornerNoDistortion3);
|
|
||||||
Vector3[] vertices = new Vector3[4] { v0, v1, v2, v3 };
|
|
||||||
|
|
||||||
quadMesh.vertices = vertices;
|
|
||||||
|
|
||||||
int[] indices = new int[6] { 0, 2, 1, 2, 3, 1 };
|
|
||||||
quadMesh.triangles = indices;
|
|
||||||
|
|
||||||
Vector3[] normals = new Vector3[4] {
|
|
||||||
-Vector3.forward,
|
|
||||||
-Vector3.forward,
|
|
||||||
-Vector3.forward,
|
|
||||||
-Vector3.forward
|
|
||||||
};
|
|
||||||
quadMesh.normals = normals;
|
|
||||||
|
|
||||||
float maxU = (float)requiredRenderTextureSize.x / (float)allocatedRenderTextureSize.x;
|
|
||||||
float maxV = (float)requiredRenderTextureSize.y / (float)allocatedRenderTextureSize.y;
|
|
||||||
Vector2[] uv = new Vector2[4] {
|
|
||||||
new Vector2(uvCorner0.x * maxU, uvCorner0.y * maxV),
|
|
||||||
new Vector2(uvCorner1.x * maxU, uvCorner1.y * maxV),
|
|
||||||
new Vector2(uvCorner2.x * maxU, uvCorner2.y * maxV),
|
|
||||||
new Vector2(uvCorner3.x * maxU, uvCorner3.y * maxV),
|
|
||||||
};
|
|
||||||
quadMesh.uv = uv;
|
|
||||||
quadMeshFilter.mesh = quadMesh;
|
quadMeshFilter.mesh = quadMesh;
|
||||||
quadMeshRenderer.sharedMaterial.mainTexture = this.renderTexture;
|
quadMeshRenderer.sharedMaterial.mainTexture = this.renderTexture;
|
||||||
quadMeshRenderer.sharedMaterial.color = color;
|
quadMeshRenderer.sharedMaterial.color = color;
|
||||||
|
|||||||
@ -27,31 +27,33 @@
|
|||||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
#if UNITY_2019_3_OR_NEWER
|
using System;
|
||||||
#define HAS_FORCE_RENDER_OFF
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if UNITY_2018_2_OR_NEWER
|
|
||||||
#define HAS_GET_SHARED_MATERIALS
|
|
||||||
#endif
|
|
||||||
|
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.Rendering;
|
using UnityEngine.Rendering;
|
||||||
|
|
||||||
namespace Spine.Unity.Examples {
|
namespace Spine.Unity.Examples {
|
||||||
|
|
||||||
public abstract class SkeletonRenderTextureBase : MonoBehaviour {
|
public abstract class SkeletonRenderTextureBase : MonoBehaviour {
|
||||||
#if HAS_GET_SHARED_MATERIALS
|
|
||||||
public Color color = Color.white;
|
public Color color = Color.white;
|
||||||
public int maxRenderTextureSize = 1024;
|
public int maxRenderTextureSize = 1024;
|
||||||
public GameObject quad;
|
public GameObject quad;
|
||||||
protected Mesh quadMesh;
|
protected Mesh quadMesh;
|
||||||
public RenderTexture renderTexture;
|
public RenderTexture renderTexture;
|
||||||
|
public Camera targetCamera;
|
||||||
|
|
||||||
protected CommandBuffer commandBuffer;
|
protected CommandBuffer commandBuffer;
|
||||||
protected Vector2Int requiredRenderTextureSize;
|
protected Vector2Int requiredRenderTextureSize;
|
||||||
protected Vector2Int allocatedRenderTextureSize;
|
protected Vector2Int allocatedRenderTextureSize;
|
||||||
|
|
||||||
|
protected Vector3 worldCornerNoDistortion0;
|
||||||
|
protected Vector3 worldCornerNoDistortion1;
|
||||||
|
protected Vector3 worldCornerNoDistortion2;
|
||||||
|
protected Vector3 worldCornerNoDistortion3;
|
||||||
|
protected Vector2 uvCorner0;
|
||||||
|
protected Vector2 uvCorner1;
|
||||||
|
protected Vector2 uvCorner2;
|
||||||
|
protected Vector2 uvCorner3;
|
||||||
|
|
||||||
protected virtual void Awake () {
|
protected virtual void Awake () {
|
||||||
commandBuffer = new CommandBuffer();
|
commandBuffer = new CommandBuffer();
|
||||||
}
|
}
|
||||||
@ -61,6 +63,34 @@ namespace Spine.Unity.Examples {
|
|||||||
RenderTexture.ReleaseTemporary(renderTexture);
|
RenderTexture.ReleaseTemporary(renderTexture);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void PrepareTextureMapping (out Vector3 screenSpaceMin, out Vector3 screenSpaceMax,
|
||||||
|
Vector3 screenCorner0, Vector3 screenCorner1, Vector3 screenCorner2, Vector3 screenCorner3) {
|
||||||
|
|
||||||
|
screenSpaceMin =
|
||||||
|
Vector3.Min(screenCorner0, Vector3.Min(screenCorner1,
|
||||||
|
Vector3.Min(screenCorner2, screenCorner3)));
|
||||||
|
screenSpaceMax =
|
||||||
|
Vector3.Max(screenCorner0, Vector3.Max(screenCorner1,
|
||||||
|
Vector3.Max(screenCorner2, screenCorner3)));
|
||||||
|
// ensure we are on whole pixel borders
|
||||||
|
screenSpaceMin.x = Mathf.Floor(screenSpaceMin.x);
|
||||||
|
screenSpaceMin.y = Mathf.Floor(screenSpaceMin.y);
|
||||||
|
screenSpaceMax.x = Mathf.Ceil(screenSpaceMax.x);
|
||||||
|
screenSpaceMax.y = Mathf.Ceil(screenSpaceMax.y);
|
||||||
|
|
||||||
|
// inverse-map screenCornerN to screenSpaceMin/screenSpaceMax area to get UV coordinates
|
||||||
|
uvCorner0 = MathUtilities.InverseLerp(screenSpaceMin, screenSpaceMax, screenCorner0);
|
||||||
|
uvCorner1 = MathUtilities.InverseLerp(screenSpaceMin, screenSpaceMax, screenCorner1);
|
||||||
|
uvCorner2 = MathUtilities.InverseLerp(screenSpaceMin, screenSpaceMax, screenCorner2);
|
||||||
|
uvCorner3 = MathUtilities.InverseLerp(screenSpaceMin, screenSpaceMax, screenCorner3);
|
||||||
|
|
||||||
|
requiredRenderTextureSize = new Vector2Int(
|
||||||
|
Math.Min(maxRenderTextureSize, Math.Abs((int)screenSpaceMax.x - (int)screenSpaceMin.x)),
|
||||||
|
Math.Min(maxRenderTextureSize, Math.Abs((int)screenSpaceMax.y - (int)screenSpaceMin.y)));
|
||||||
|
|
||||||
|
PrepareRenderTexture();
|
||||||
|
}
|
||||||
|
|
||||||
protected void PrepareRenderTexture () {
|
protected void PrepareRenderTexture () {
|
||||||
Vector2Int textureSize = new Vector2Int(
|
Vector2Int textureSize = new Vector2Int(
|
||||||
Mathf.NextPowerOfTwo(requiredRenderTextureSize.x),
|
Mathf.NextPowerOfTwo(requiredRenderTextureSize.x),
|
||||||
@ -74,6 +104,44 @@ namespace Spine.Unity.Examples {
|
|||||||
allocatedRenderTextureSize = textureSize;
|
allocatedRenderTextureSize = textureSize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
protected void AssignAtQuad () {
|
||||||
|
Transform quadTransform = quad.transform;
|
||||||
|
quadTransform.position = this.transform.position;
|
||||||
|
quadTransform.rotation = this.transform.rotation;
|
||||||
|
quadTransform.localScale = this.transform.localScale;
|
||||||
|
|
||||||
|
Vector3 v0 = quadTransform.InverseTransformPoint(worldCornerNoDistortion0);
|
||||||
|
Vector3 v1 = quadTransform.InverseTransformPoint(worldCornerNoDistortion1);
|
||||||
|
Vector3 v2 = quadTransform.InverseTransformPoint(worldCornerNoDistortion2);
|
||||||
|
Vector3 v3 = quadTransform.InverseTransformPoint(worldCornerNoDistortion3);
|
||||||
|
Vector3[] vertices = new Vector3[4] { v0, v1, v2, v3 };
|
||||||
|
|
||||||
|
quadMesh.vertices = vertices;
|
||||||
|
|
||||||
|
int[] indices = new int[6] { 0, 1, 2, 2, 1, 3 };
|
||||||
|
quadMesh.triangles = indices;
|
||||||
|
|
||||||
|
Vector3[] normals = new Vector3[4] {
|
||||||
|
-Vector3.forward,
|
||||||
|
-Vector3.forward,
|
||||||
|
-Vector3.forward,
|
||||||
|
-Vector3.forward
|
||||||
|
};
|
||||||
|
quadMesh.normals = normals;
|
||||||
|
|
||||||
|
float maxU = (float)requiredRenderTextureSize.x / (float)allocatedRenderTextureSize.x;
|
||||||
|
float maxV = (float)requiredRenderTextureSize.y / (float)allocatedRenderTextureSize.y;
|
||||||
|
Vector2[] uv = new Vector2[4] {
|
||||||
|
new Vector2(uvCorner0.x * maxU, uvCorner0.y * maxV),
|
||||||
|
new Vector2(uvCorner1.x * maxU, uvCorner1.y * maxV),
|
||||||
|
new Vector2(uvCorner2.x * maxU, uvCorner2.y * maxV),
|
||||||
|
new Vector2(uvCorner3.x * maxU, uvCorner3.y * maxV),
|
||||||
|
};
|
||||||
|
quadMesh.uv = uv;
|
||||||
|
AssignMeshAtRenderer();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract void AssignMeshAtRenderer ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: ccf9b5e5034b0ea45962f9cf32168dd9
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@ -183,6 +183,59 @@ namespace Spine.Unity {
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Overrides
|
#region Overrides
|
||||||
|
// API for taking over rendering.
|
||||||
|
/// <summary>When true, no meshes and materials are assigned at CanvasRenderers if the used override
|
||||||
|
/// AssignMeshOverrideSingleRenderer or AssignMeshOverrideMultipleRenderers is non-null.</summary>
|
||||||
|
public bool disableMeshAssignmentOnOverride = true;
|
||||||
|
/// <summary>Delegate type for overriding mesh and material assignment,
|
||||||
|
/// used when <c>allowMultipleCanvasRenderers</c> is false.</summary>
|
||||||
|
/// <param name="mesh">Mesh normally assigned at the main CanvasRenderer.</param>
|
||||||
|
/// <param name="graphicMaterial">Material normally assigned at the main CanvasRenderer.</param>
|
||||||
|
/// <param name="texture">Texture normally assigned at the main CanvasRenderer.</param>
|
||||||
|
public delegate void MeshAssignmentDelegateSingle (Mesh mesh, Material graphicMaterial, Texture texture);
|
||||||
|
/// <param name="meshCount">Number of meshes. Don't use <c>meshes.Length</c> as this might be higher
|
||||||
|
/// due to pre-allocated entries.</param>
|
||||||
|
/// <param name="meshes">Mesh array where each element is normally assigned to one of the <c>canvasRenderers</c>.</param>
|
||||||
|
/// <param name="graphicMaterials">Material array where each element is normally assigned to one of the <c>canvasRenderers</c>.</param>
|
||||||
|
/// <param name="textures">Texture array where each element is normally assigned to one of the <c>canvasRenderers</c>.</param>
|
||||||
|
public delegate void MeshAssignmentDelegateMultiple (int meshCount, Mesh[] meshes, Material[] graphicMaterials, Texture[] textures);
|
||||||
|
event MeshAssignmentDelegateSingle assignMeshOverrideSingle;
|
||||||
|
event MeshAssignmentDelegateMultiple assignMeshOverrideMultiple;
|
||||||
|
|
||||||
|
/// <summary>Allows separate code to take over mesh and material assignment for this SkeletonGraphic component.
|
||||||
|
/// Used when <c>allowMultipleCanvasRenderers</c> is false.</summary>
|
||||||
|
public event MeshAssignmentDelegateSingle AssignMeshOverrideSingleRenderer {
|
||||||
|
add {
|
||||||
|
assignMeshOverrideSingle += value;
|
||||||
|
if (disableMeshAssignmentOnOverride && assignMeshOverrideSingle != null) {
|
||||||
|
Initialize(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
remove {
|
||||||
|
assignMeshOverrideSingle -= value;
|
||||||
|
if (disableMeshAssignmentOnOverride && assignMeshOverrideSingle == null) {
|
||||||
|
Initialize(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// <summary>Allows separate code to take over mesh and material assignment for this SkeletonGraphic component.
|
||||||
|
/// Used when <c>allowMultipleCanvasRenderers</c> is true.</summary>
|
||||||
|
public event MeshAssignmentDelegateMultiple AssignMeshOverrideMultipleRenderers {
|
||||||
|
add {
|
||||||
|
assignMeshOverrideMultiple += value;
|
||||||
|
if (disableMeshAssignmentOnOverride && assignMeshOverrideMultiple != null) {
|
||||||
|
Initialize(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
remove {
|
||||||
|
assignMeshOverrideMultiple -= value;
|
||||||
|
if (disableMeshAssignmentOnOverride && assignMeshOverrideMultiple == null) {
|
||||||
|
Initialize(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
[System.NonSerialized] readonly Dictionary<Texture, Texture> customTextureOverride = new Dictionary<Texture, Texture>();
|
[System.NonSerialized] readonly Dictionary<Texture, Texture> customTextureOverride = new Dictionary<Texture, Texture>();
|
||||||
/// <summary>Use this Dictionary to override a Texture with a different Texture.</summary>
|
/// <summary>Use this Dictionary to override a Texture with a different Texture.</summary>
|
||||||
public Dictionary<Texture, Texture> CustomTextureOverride { get { return customTextureOverride; } }
|
public Dictionary<Texture, Texture> CustomTextureOverride { get { return customTextureOverride; } }
|
||||||
@ -334,6 +387,8 @@ namespace Spine.Unity {
|
|||||||
if (updateMode != UpdateMode.FullUpdate) return;
|
if (updateMode != UpdateMode.FullUpdate) return;
|
||||||
|
|
||||||
PrepareInstructionsAndRenderers();
|
PrepareInstructionsAndRenderers();
|
||||||
|
if (OnInstructionsPrepared != null)
|
||||||
|
OnInstructionsPrepared(this.currentInstructions);
|
||||||
SetVerticesDirty(); // triggers Rebuild and avoids potential double-update in a single frame
|
SetVerticesDirty(); // triggers Rebuild and avoids potential double-update in a single frame
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -390,13 +445,21 @@ namespace Spine.Unity {
|
|||||||
public bool IsValid { get { return skeleton != null; } }
|
public bool IsValid { get { return skeleton != null; } }
|
||||||
|
|
||||||
public delegate void SkeletonRendererDelegate (SkeletonGraphic skeletonGraphic);
|
public delegate void SkeletonRendererDelegate (SkeletonGraphic skeletonGraphic);
|
||||||
|
public delegate void InstructionDelegate (SkeletonRendererInstruction instruction);
|
||||||
|
|
||||||
/// <summary>OnRebuild is raised after the Skeleton is successfully initialized.</summary>
|
/// <summary>OnRebuild is raised after the Skeleton is successfully initialized.</summary>
|
||||||
public event SkeletonRendererDelegate OnRebuild;
|
public event SkeletonRendererDelegate OnRebuild;
|
||||||
|
|
||||||
/// <summary>OnMeshAndMaterialsUpdated is at the end of LateUpdate after the Mesh and
|
/// <summary>OnInstructionsPrepared is raised at the end of <c>LateUpdate</c> after render instructions
|
||||||
/// all materials have been updated.</summary>
|
/// are done, target renderers are prepared, and the mesh is ready to be generated.</summary>
|
||||||
|
public event InstructionDelegate OnInstructionsPrepared;
|
||||||
|
|
||||||
|
/// <summary>OnMeshAndMaterialsUpdated is raised at the end of <c>Rebuild</c> after the Mesh and
|
||||||
|
/// all materials have been updated. Note that some Unity API calls are not permitted to be issued from
|
||||||
|
/// <c>Rebuild</c>, so you may want to subscribe to <see cref="OnInstructionsPrepared"/> instead
|
||||||
|
/// from where you can issue such preparation calls.</summary>
|
||||||
public event SkeletonRendererDelegate OnMeshAndMaterialsUpdated;
|
public event SkeletonRendererDelegate OnMeshAndMaterialsUpdated;
|
||||||
|
//FIXXME: perform some final checks on documentation and changes, then finalize these changes and commit. then integrate in 4.0_cleanup project as well.
|
||||||
|
|
||||||
protected Spine.AnimationState state;
|
protected Spine.AnimationState state;
|
||||||
public Spine.AnimationState AnimationState {
|
public Spine.AnimationState AnimationState {
|
||||||
@ -411,6 +474,12 @@ namespace Spine.Unity {
|
|||||||
DoubleBuffered<Spine.Unity.MeshRendererBuffers.SmartMesh> meshBuffers;
|
DoubleBuffered<Spine.Unity.MeshRendererBuffers.SmartMesh> meshBuffers;
|
||||||
SkeletonRendererInstruction currentInstructions = new SkeletonRendererInstruction();
|
SkeletonRendererInstruction currentInstructions = new SkeletonRendererInstruction();
|
||||||
readonly ExposedList<Mesh> meshes = new ExposedList<Mesh>();
|
readonly ExposedList<Mesh> meshes = new ExposedList<Mesh>();
|
||||||
|
readonly ExposedList<Material> usedMaterials = new ExposedList<Material>();
|
||||||
|
readonly ExposedList<Texture> usedTextures = new ExposedList<Texture>();
|
||||||
|
|
||||||
|
public ExposedList<Mesh> MeshesMultipleCanvasRenderers { get { return meshes; } }
|
||||||
|
public ExposedList<Material> MaterialsMultipleCanvasRenderers { get { return usedMaterials; } }
|
||||||
|
public ExposedList<Texture> TexturesMultipleCanvasRenderers { get { return usedTextures; } }
|
||||||
|
|
||||||
public Mesh GetLastMesh () {
|
public Mesh GetLastMesh () {
|
||||||
return meshBuffers.GetCurrent().mesh;
|
return meshBuffers.GetCurrent().mesh;
|
||||||
@ -513,6 +582,8 @@ namespace Spine.Unity {
|
|||||||
for (int i = 0; i < canvasRenderers.Count; ++i)
|
for (int i = 0; i < canvasRenderers.Count; ++i)
|
||||||
canvasRenderers[i].Clear();
|
canvasRenderers[i].Clear();
|
||||||
DestroyMeshes();
|
DestroyMeshes();
|
||||||
|
usedMaterials.Clear();
|
||||||
|
usedTextures.Clear();
|
||||||
DisposeMeshBuffers();
|
DisposeMeshBuffers();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -601,6 +672,7 @@ namespace Spine.Unity {
|
|||||||
int submeshCount = currentInstructions.submeshInstructions.Count;
|
int submeshCount = currentInstructions.submeshInstructions.Count;
|
||||||
EnsureCanvasRendererCount(submeshCount);
|
EnsureCanvasRendererCount(submeshCount);
|
||||||
EnsureMeshesCount(submeshCount);
|
EnsureMeshesCount(submeshCount);
|
||||||
|
EnsureUsedTexturesAndMaterialsCount(submeshCount);
|
||||||
EnsureSeparatorPartCount();
|
EnsureSeparatorPartCount();
|
||||||
PrepareRendererGameObjects(currentInstructions);
|
PrepareRendererGameObjects(currentInstructions);
|
||||||
}
|
}
|
||||||
@ -618,6 +690,7 @@ namespace Spine.Unity {
|
|||||||
if (!this.allowMultipleCanvasRenderers) {
|
if (!this.allowMultipleCanvasRenderers) {
|
||||||
UpdateMeshSingleCanvasRenderer(currentInstructions);
|
UpdateMeshSingleCanvasRenderer(currentInstructions);
|
||||||
} else {
|
} else {
|
||||||
|
UpdateMaterialsMultipleCanvasRenderers(currentInstructions);
|
||||||
UpdateMeshMultipleCanvasRenderers(currentInstructions);
|
UpdateMeshMultipleCanvasRenderers(currentInstructions);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -675,19 +748,67 @@ namespace Spine.Unity {
|
|||||||
if (updateTriangles) meshGenerator.FillTriangles(mesh);
|
if (updateTriangles) meshGenerator.FillTriangles(mesh);
|
||||||
meshGenerator.FillLateVertexData(mesh);
|
meshGenerator.FillLateVertexData(mesh);
|
||||||
|
|
||||||
canvasRenderer.SetMesh(mesh);
|
|
||||||
smartMesh.instructionUsed.Set(currentInstructions);
|
smartMesh.instructionUsed.Set(currentInstructions);
|
||||||
|
if (assignMeshOverrideSingle != null)
|
||||||
|
assignMeshOverrideSingle(mesh, this.canvasRenderer.GetMaterial(), this.mainTexture);
|
||||||
|
|
||||||
|
bool assignAtCanvasRenderer = (assignMeshOverrideSingle == null || !disableMeshAssignmentOnOverride);
|
||||||
|
if (assignAtCanvasRenderer)
|
||||||
|
canvasRenderer.SetMesh(mesh);
|
||||||
|
else
|
||||||
|
canvasRenderer.SetMesh(null);
|
||||||
|
|
||||||
if (currentInstructions.submeshInstructions.Count > 0) {
|
if (currentInstructions.submeshInstructions.Count > 0) {
|
||||||
var material = currentInstructions.submeshInstructions.Items[0].material;
|
var material = currentInstructions.submeshInstructions.Items[0].material;
|
||||||
if (material != null && baseTexture != material.mainTexture) {
|
if (material != null && baseTexture != material.mainTexture) {
|
||||||
baseTexture = material.mainTexture;
|
baseTexture = material.mainTexture;
|
||||||
if (overrideTexture == null)
|
if (overrideTexture == null && assignAtCanvasRenderer)
|
||||||
canvasRenderer.SetTexture(this.mainTexture);
|
canvasRenderer.SetTexture(this.mainTexture);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//this.UpdateMaterial(); // note: This would allocate memory.
|
protected void UpdateMaterialsMultipleCanvasRenderers (SkeletonRendererInstruction currentInstructions) {
|
||||||
|
int submeshCount = currentInstructions.submeshInstructions.Count;
|
||||||
|
bool useOriginalTextureAndMaterial = (customMaterialOverride.Count == 0 && customTextureOverride.Count == 0);
|
||||||
|
|
||||||
|
BlendModeMaterials blendModeMaterials = skeletonDataAsset.blendModeMaterials;
|
||||||
|
bool hasBlendModeMaterials = blendModeMaterials.RequiresBlendModeMaterials;
|
||||||
|
|
||||||
|
bool pmaVertexColors = meshGenerator.settings.pmaVertexColors;
|
||||||
|
Material[] usedMaterialItems = usedMaterials.Items;
|
||||||
|
Texture[] usedTextureItems = usedTextures.Items;
|
||||||
|
for (int i = 0; i < submeshCount; i++) {
|
||||||
|
var submeshInstructionItem = currentInstructions.submeshInstructions.Items[i];
|
||||||
|
var submeshMaterial = submeshInstructionItem.material;
|
||||||
|
if (useOriginalTextureAndMaterial) {
|
||||||
|
usedTextureItems[i] = submeshMaterial.mainTexture;
|
||||||
|
if (!hasBlendModeMaterials) {
|
||||||
|
usedMaterialItems[i] = this.materialForRendering;
|
||||||
|
} else {
|
||||||
|
BlendMode blendMode = blendModeMaterials.BlendModeForMaterial(submeshMaterial);
|
||||||
|
Material usedMaterial = this.materialForRendering;
|
||||||
|
if (blendMode == BlendMode.Additive && !pmaVertexColors && additiveMaterial) {
|
||||||
|
usedMaterial = additiveMaterial;
|
||||||
|
} else if (blendMode == BlendMode.Multiply && multiplyMaterial)
|
||||||
|
usedMaterial = multiplyMaterial;
|
||||||
|
else if (blendMode == BlendMode.Screen && screenMaterial)
|
||||||
|
usedMaterial = screenMaterial;
|
||||||
|
usedMaterialItems[i] = submeshGraphics[i].GetModifiedMaterial(usedMaterial);
|
||||||
|
}
|
||||||
|
} 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;
|
||||||
|
|
||||||
|
usedMaterialItems[i] = submeshGraphics[i].GetModifiedMaterial(usedMaterial);
|
||||||
|
usedTextureItems[i] = usedTexture;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void UpdateMeshMultipleCanvasRenderers (SkeletonRendererInstruction currentInstructions) {
|
protected void UpdateMeshMultipleCanvasRenderers (SkeletonRendererInstruction currentInstructions) {
|
||||||
@ -705,6 +826,9 @@ namespace Spine.Unity {
|
|||||||
bool mainCullTransparentMesh = this.canvasRenderer.cullTransparentMesh;
|
bool mainCullTransparentMesh = this.canvasRenderer.cullTransparentMesh;
|
||||||
#endif
|
#endif
|
||||||
bool pmaVertexColors = meshGenerator.settings.pmaVertexColors;
|
bool pmaVertexColors = meshGenerator.settings.pmaVertexColors;
|
||||||
|
Material[] usedMaterialItems = usedMaterials.Items;
|
||||||
|
Texture[] usedTextureItems = usedTextures.Items;
|
||||||
|
bool assignAtCanvasRenderer = (assignMeshOverrideSingle == null || !disableMeshAssignmentOnOverride);
|
||||||
for (int i = 0; i < submeshCount; i++) {
|
for (int i = 0; i < submeshCount; i++) {
|
||||||
var submeshInstructionItem = currentInstructions.submeshInstructions.Items[i];
|
var submeshInstructionItem = currentInstructions.submeshInstructions.Items[i];
|
||||||
meshGenerator.Begin();
|
meshGenerator.Begin();
|
||||||
@ -717,53 +841,31 @@ namespace Spine.Unity {
|
|||||||
meshGenerator.FillTriangles(targetMesh);
|
meshGenerator.FillTriangles(targetMesh);
|
||||||
meshGenerator.FillLateVertexData(targetMesh);
|
meshGenerator.FillLateVertexData(targetMesh);
|
||||||
|
|
||||||
var submeshMaterial = submeshInstructionItem.material;
|
|
||||||
var canvasRenderer = canvasRenderers[i];
|
var canvasRenderer = canvasRenderers[i];
|
||||||
canvasRenderer.SetMesh(targetMesh);
|
if (assignMeshOverrideSingle == null || !disableMeshAssignmentOnOverride)
|
||||||
canvasRenderer.materialCount = 1;
|
canvasRenderer.SetMesh(targetMesh);
|
||||||
|
else
|
||||||
|
canvasRenderer.SetMesh(null);
|
||||||
|
|
||||||
SkeletonSubmeshGraphic submeshGraphic = submeshGraphics[i];
|
SkeletonSubmeshGraphic submeshGraphic = submeshGraphics[i];
|
||||||
if (useOriginalTextureAndMaterial) {
|
if (useOriginalTextureAndMaterial && hasBlendModeMaterials) {
|
||||||
Texture usedTexture = submeshMaterial.mainTexture;
|
bool allowCullTransparentMesh = true;
|
||||||
if (!hasBlendModeMaterials)
|
BlendMode materialBlendMode = blendModeMaterials.BlendModeForMaterial(usedMaterialItems[i]);
|
||||||
canvasRenderer.SetMaterial(this.materialForRendering, usedTexture);
|
if ((materialBlendMode == BlendMode.Normal && submeshInstructionItem.hasPMAAdditiveSlot) ||
|
||||||
else {
|
(materialBlendMode == BlendMode.Additive && pmaVertexColors)) {
|
||||||
bool allowCullTransparentMesh = true;
|
allowCullTransparentMesh = false;
|
||||||
BlendMode blendMode = blendModeMaterials.BlendModeForMaterial(submeshMaterial);
|
|
||||||
Material usedMaterial = this.materialForRendering;
|
|
||||||
if (blendMode == BlendMode.Normal) {
|
|
||||||
if (submeshInstructionItem.hasPMAAdditiveSlot)
|
|
||||||
allowCullTransparentMesh = false;
|
|
||||||
} else if (blendMode == BlendMode.Additive) {
|
|
||||||
if (pmaVertexColors)
|
|
||||||
allowCullTransparentMesh = false;
|
|
||||||
else if (additiveMaterial)
|
|
||||||
usedMaterial = additiveMaterial;
|
|
||||||
} else if (blendMode == BlendMode.Multiply && multiplyMaterial)
|
|
||||||
usedMaterial = multiplyMaterial;
|
|
||||||
else if (blendMode == BlendMode.Screen && screenMaterial)
|
|
||||||
usedMaterial = screenMaterial;
|
|
||||||
|
|
||||||
usedMaterial = submeshGraphic.GetModifiedMaterial(usedMaterial);
|
|
||||||
canvasRenderer.SetMaterial(usedMaterial, usedTexture);
|
|
||||||
#if HAS_CULL_TRANSPARENT_MESH
|
|
||||||
canvasRenderer.cullTransparentMesh = allowCullTransparentMesh ?
|
|
||||||
mainCullTransparentMesh : false;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
} else {
|
#if HAS_CULL_TRANSPARENT_MESH
|
||||||
var originalTexture = submeshMaterial.mainTexture;
|
canvasRenderer.cullTransparentMesh = allowCullTransparentMesh ?
|
||||||
Material usedMaterial;
|
mainCullTransparentMesh : false;
|
||||||
Texture usedTexture;
|
#endif
|
||||||
if (!customMaterialOverride.TryGetValue(originalTexture, out usedMaterial))
|
|
||||||
usedMaterial = material;
|
|
||||||
if (!customTextureOverride.TryGetValue(originalTexture, out usedTexture))
|
|
||||||
usedTexture = originalTexture;
|
|
||||||
|
|
||||||
usedMaterial = submeshGraphic.GetModifiedMaterial(usedMaterial);
|
|
||||||
canvasRenderer.SetMaterial(usedMaterial, usedTexture);
|
|
||||||
}
|
}
|
||||||
|
canvasRenderer.materialCount = 1;
|
||||||
|
if (assignAtCanvasRenderer)
|
||||||
|
canvasRenderer.SetMaterial(usedMaterialItems[i], usedTextureItems[i]);
|
||||||
}
|
}
|
||||||
|
if (assignMeshOverrideMultiple != null)
|
||||||
|
assignMeshOverrideMultiple(submeshCount, meshesItems, usedMaterialItems, usedTextureItems);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void EnsureCanvasRendererCount (int targetCount) {
|
protected void EnsureCanvasRendererCount (int targetCount) {
|
||||||
@ -856,6 +958,16 @@ namespace Spine.Unity {
|
|||||||
meshes.Add(SpineMesh.NewSkeletonMesh());
|
meshes.Add(SpineMesh.NewSkeletonMesh());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void EnsureUsedTexturesAndMaterialsCount (int targetCount) {
|
||||||
|
int oldCount = usedMaterials.Count;
|
||||||
|
usedMaterials.EnsureCapacity(targetCount);
|
||||||
|
usedTextures.EnsureCapacity(targetCount);
|
||||||
|
for (int i = oldCount; i < targetCount; i++) {
|
||||||
|
usedMaterials.Add(null);
|
||||||
|
usedTextures.Add(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected void DestroyMeshes () {
|
protected void DestroyMeshes () {
|
||||||
foreach (var mesh in meshes) {
|
foreach (var mesh in meshes) {
|
||||||
#if UNITY_EDITOR
|
#if UNITY_EDITOR
|
||||||
|
|||||||
@ -0,0 +1,71 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Spine Runtimes License Agreement
|
||||||
|
* Last updated January 1, 2020. Replaces all prior versions.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013-2022, 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;
|
||||||
|
|
||||||
|
namespace Spine.Unity {
|
||||||
|
public static class MathUtilities {
|
||||||
|
public static float InverseLerp (float a, float b, float value) {
|
||||||
|
return (value - a) / (b - a);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the linear interpolation ratio of <c>a</c> to <c>b</c> that <c>value</c> lies on.
|
||||||
|
/// This is the t value that fulfills <c>value = lerp(a, b, t)</c>.
|
||||||
|
/// </summary>
|
||||||
|
public static Vector2 InverseLerp (Vector2 a, Vector2 b, Vector2 value) {
|
||||||
|
return new Vector2(
|
||||||
|
(value.x - a.x) / (b.x - a.x),
|
||||||
|
(value.y - a.y) / (b.y - a.y));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the linear interpolation ratio of <c>a</c> to <c>b</c> that <c>value</c> lies on.
|
||||||
|
/// This is the t value that fulfills <c>value = lerp(a, b, t)</c>.
|
||||||
|
/// </summary>
|
||||||
|
public static Vector3 InverseLerp (Vector3 a, Vector3 b, Vector3 value) {
|
||||||
|
return new Vector3(
|
||||||
|
(value.x - a.x) / (b.x - a.x),
|
||||||
|
(value.y - a.y) / (b.y - a.y),
|
||||||
|
(value.z - a.z) / (b.z - a.z));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the linear interpolation ratio of <c>a</c> to <c>b</c> that <c>value</c> lies on.
|
||||||
|
/// This is the t value that fulfills <c>value = lerp(a, b, t)</c>.
|
||||||
|
/// </summary>
|
||||||
|
public static Vector4 InverseLerp (Vector4 a, Vector4 b, Vector4 value) {
|
||||||
|
return new Vector4(
|
||||||
|
(value.x - a.x) / (b.x - a.x),
|
||||||
|
(value.y - a.y) / (b.y - a.y),
|
||||||
|
(value.z - a.z) / (b.z - a.z),
|
||||||
|
(value.w - a.w) / (b.w - a.w));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: ef2b5da9383ed474d895b702a9baf79e
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
Loading…
x
Reference in New Issue
Block a user