diff --git a/.gitignore b/.gitignore index 8d074381..6d1a8a60 100644 --- a/.gitignore +++ b/.gitignore @@ -87,3 +87,5 @@ box1/Library/ box1/Temp/Burst/burst-aoty26ykpfz.1k1/lib_burst_generated_part_a6f5259e22ed809ef3937424c4bd686d.gbc box1/Temp/ box1/Logs/ +box1/.idea/ +box1/obj/ diff --git a/box1/Assets/Art.meta b/box1/Assets/Art.meta new file mode 100644 index 00000000..2ef5a866 --- /dev/null +++ b/box1/Assets/Art.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: d751bb349c7984f46b84af7575258297 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Art/Spine.meta b/box1/Assets/Art/Spine.meta new file mode 100644 index 00000000..88195cbe --- /dev/null +++ b/box1/Assets/Art/Spine.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 492569c769c9751438a93daf1b2c4982 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Art/UI.meta b/box1/Assets/Art/UI.meta new file mode 100644 index 00000000..5bcddcdd --- /dev/null +++ b/box1/Assets/Art/UI.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 56a0e90e4e8911043b1397cf0154d079 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Editor.meta b/box1/Assets/Editor.meta new file mode 100644 index 00000000..5b1ff912 --- /dev/null +++ b/box1/Assets/Editor.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: a2a85c0c1c9e1aa4bb50bfee40eea903 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Editor/SpineSettings.asset b/box1/Assets/Editor/SpineSettings.asset new file mode 100644 index 00000000..893a8533 --- /dev/null +++ b/box1/Assets/Editor/SpineSettings.asset @@ -0,0 +1,37 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: b29e98153ec2fbd44b8f7da1b41194e8, type: 3} + m_Name: SpineSettings + m_EditorClassIdentifier: + defaultScale: 0.01 + defaultMix: 0.2 + defaultShader: Spine/Skeleton + defaultZSpacing: 0 + defaultInstantiateLoop: 1 + showHierarchyIcons: 1 + reloadAfterPlayMode: 1 + setTextureImporterSettings: 1 + textureSettingsReference: + fixPrefabOverrideViaMeshFilter: 0 + removePrefabPreviewMeshes: 0 + blendModeMaterialMultiply: {fileID: 0} + blendModeMaterialScreen: {fileID: 0} + blendModeMaterialAdditive: {fileID: 0} + atlasTxtImportWarning: 1 + textureImporterWarning: 1 + componentMaterialWarning: 1 + skeletonDataAssetNoFileError: 1 + autoReloadSceneSkeletons: 1 + handleScale: 1 + mecanimEventIncludeFolderName: 1 + timelineDefaultMixDuration: 0 + timelineUseBlendDuration: 1 diff --git a/box1/Assets/Editor/SpineSettings.asset.meta b/box1/Assets/Editor/SpineSettings.asset.meta new file mode 100644 index 00000000..c61e930f --- /dev/null +++ b/box1/Assets/Editor/SpineSettings.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: a30be1b356f9dd7478efaef8494198bf +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Prefab.meta b/box1/Assets/Prefab.meta new file mode 100644 index 00000000..6146ace2 --- /dev/null +++ b/box1/Assets/Prefab.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 837b121af68baf643b5c0506622876f1 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Prefab/9-Sliced.prefab b/box1/Assets/Prefab/9-Sliced.prefab new file mode 100644 index 00000000..bdae87de --- /dev/null +++ b/box1/Assets/Prefab/9-Sliced.prefab @@ -0,0 +1,145 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &1780511609537152124 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2006744524715583661} + - component: {fileID: 7173914509051702549} + - component: {fileID: 8762182763444239826} + - component: {fileID: 3879485869278254333} + m_Layer: 0 + m_Name: 9-Sliced + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &2006744524715583661 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1780511609537152124} + serializedVersion: 2 + 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_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!212 &7173914509051702549 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1780511609537152124} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!61 &8762182763444239826 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1780511609537152124} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!114 &3879485869278254333 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1780511609537152124} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: diff --git a/box1/Assets/Prefab/9-Sliced.prefab.meta b/box1/Assets/Prefab/9-Sliced.prefab.meta new file mode 100644 index 00000000..4763654f --- /dev/null +++ b/box1/Assets/Prefab/9-Sliced.prefab.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: d4402c8e0df25cc45ab82ebc85e40539 +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Scenes/SampleScene.unity b/box1/Assets/Scenes/SampleScene.unity index 7b420f6e..d06852a3 100644 --- a/box1/Assets/Scenes/SampleScene.unity +++ b/box1/Assets/Scenes/SampleScene.unity @@ -38,7 +38,6 @@ RenderSettings: m_ReflectionIntensity: 1 m_CustomReflection: {fileID: 0} m_Sun: {fileID: 0} - m_IndirectSpecularColor: {r: 0, g: 0, b: 0, a: 1} m_UseRadianceAmbientProbe: 0 --- !u!157 &3 LightmapSettings: @@ -104,7 +103,7 @@ NavMeshSettings: serializedVersion: 2 m_ObjectHideFlags: 0 m_BuildSettings: - serializedVersion: 2 + serializedVersion: 3 agentTypeID: 0 agentRadius: 0.5 agentHeight: 2 @@ -117,12 +116,5339 @@ NavMeshSettings: cellSize: 0.16666667 manualTileSize: 0 tileSize: 256 - accuratePlacement: 0 + buildHeightMesh: 0 maxJobWorkers: 0 preserveTilesOutsideBounds: 0 debug: m_Flags: 0 m_NavMeshData: {fileID: 0} +--- !u!1 &3433539 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 3433543} + - component: {fileID: 3433542} + - component: {fileID: 3433541} + - component: {fileID: 3433540} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &3433540 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3433539} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 9 + gY: 1 + item: {fileID: 0} +--- !u!61 &3433541 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3433539} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &3433542 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3433539} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &3433543 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3433539} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 9, y: 1, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 227227731} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &30918323 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 30918327} + - component: {fileID: 30918326} + - component: {fileID: 30918325} + - component: {fileID: 30918324} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &30918324 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 30918323} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 6 + gY: 0 + item: {fileID: 0} +--- !u!61 &30918325 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 30918323} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &30918326 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 30918323} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &30918327 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 30918323} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 6, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 227227731} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &55411285 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 55411289} + - component: {fileID: 55411288} + - component: {fileID: 55411287} + - component: {fileID: 55411286} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &55411286 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 55411285} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 5 + gY: 1 + item: {fileID: 0} +--- !u!61 &55411287 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 55411285} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &55411288 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 55411285} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &55411289 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 55411285} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 5, y: 1, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &55628959 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 55628963} + - component: {fileID: 55628962} + - component: {fileID: 55628961} + - component: {fileID: 55628960} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &55628960 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 55628959} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 3 + gY: 5 + item: {fileID: 0} +--- !u!61 &55628961 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 55628959} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &55628962 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 55628959} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &55628963 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 55628959} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 3, y: 5, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &57222199 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 57222203} + - component: {fileID: 57222202} + - component: {fileID: 57222201} + - component: {fileID: 57222200} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &57222200 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 57222199} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 6 + gY: 2 + item: {fileID: 0} +--- !u!61 &57222201 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 57222199} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &57222202 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 57222199} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &57222203 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 57222199} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 6, y: 2, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 227227731} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &88449116 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 88449120} + - component: {fileID: 88449119} + - component: {fileID: 88449118} + - component: {fileID: 88449117} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &88449117 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 88449116} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 5 + gY: 0 + item: {fileID: 0} +--- !u!61 &88449118 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 88449116} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &88449119 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 88449116} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &88449120 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 88449116} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 5, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 227227731} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &117781938 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 117781942} + - component: {fileID: 117781941} + - component: {fileID: 117781940} + - component: {fileID: 117781939} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &117781939 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 117781938} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 7 + gY: 8 + item: {fileID: 0} +--- !u!61 &117781940 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 117781938} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &117781941 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 117781938} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &117781942 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 117781938} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 7, y: 8, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &118478190 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 118478194} + - component: {fileID: 118478193} + - component: {fileID: 118478192} + - component: {fileID: 118478191} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &118478191 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 118478190} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 2 + gY: 6 + item: {fileID: 0} +--- !u!61 &118478192 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 118478190} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &118478193 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 118478190} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &118478194 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 118478190} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 2, y: 6, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &135438561 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 135438565} + - component: {fileID: 135438564} + - component: {fileID: 135438563} + - component: {fileID: 135438562} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &135438562 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 135438561} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 1 + gY: 2 + item: {fileID: 0} +--- !u!61 &135438563 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 135438561} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &135438564 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 135438561} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &135438565 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 135438561} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 1, y: 2, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &160666752 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 160666756} + - component: {fileID: 160666755} + - component: {fileID: 160666754} + - component: {fileID: 160666753} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &160666753 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 160666752} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 8 + gY: 1 + item: {fileID: 0} +--- !u!61 &160666754 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 160666752} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &160666755 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 160666752} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &160666756 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 160666752} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 8, y: 1, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &167418908 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 167418912} + - component: {fileID: 167418911} + - component: {fileID: 167418910} + - component: {fileID: 167418909} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &167418909 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 167418908} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 4 + gY: 2 + item: {fileID: 0} +--- !u!61 &167418910 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 167418908} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &167418911 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 167418908} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &167418912 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 167418908} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 4, y: 2, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &171658257 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 171658261} + - component: {fileID: 171658260} + - component: {fileID: 171658259} + - component: {fileID: 171658258} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &171658258 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 171658257} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 7 + gY: 6 + item: {fileID: 0} +--- !u!61 &171658259 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 171658257} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &171658260 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 171658257} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &171658261 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 171658257} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 7, y: 6, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &197506414 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 197506418} + - component: {fileID: 197506417} + - component: {fileID: 197506416} + - component: {fileID: 197506415} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &197506415 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 197506414} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 4 + gY: 0 + item: {fileID: 0} +--- !u!61 &197506416 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 197506414} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &197506417 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 197506414} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &197506418 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 197506414} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 4, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 227227731} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &227227730 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 227227731} + m_Layer: 0 + m_Name: wait + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &227227731 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 227227730} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: -5.56, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 463863508} + - {fileID: 1254055762} + - {fileID: 2066788048} + - {fileID: 418818769} + - {fileID: 1691788222} + - {fileID: 1312809000} + - {fileID: 1106532913} + - {fileID: 1461025080} + - {fileID: 1116539348} + - {fileID: 1010204229} + - {fileID: 558298665} + - {fileID: 707261764} + - {fileID: 468497718} + - {fileID: 1034160433} + - {fileID: 1263010897} + - {fileID: 699603242} + - {fileID: 197506418} + - {fileID: 589997595} + - {fileID: 1503093216} + - {fileID: 2010821069} + - {fileID: 88449120} + - {fileID: 983043046} + - {fileID: 1674163527} + - {fileID: 701195477} + - {fileID: 30918327} + - {fileID: 551496422} + - {fileID: 57222203} + - {fileID: 520549986} + - {fileID: 694229263} + - {fileID: 1200390951} + - {fileID: 732359359} + - {fileID: 1334787030} + - {fileID: 545902924} + - {fileID: 1284770394} + - {fileID: 1864465809} + - {fileID: 1079375776} + - {fileID: 237788083} + - {fileID: 3433543} + - {fileID: 630278470} + - {fileID: 1239476992} + m_Father: {fileID: 2094376466} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &228766927 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 228766931} + - component: {fileID: 228766930} + - component: {fileID: 228766929} + - component: {fileID: 228766928} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &228766928 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 228766927} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 8 + gY: 0 + item: {fileID: 0} +--- !u!61 &228766929 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 228766927} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &228766930 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 228766927} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &228766931 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 228766927} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 8, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &237788079 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 237788083} + - component: {fileID: 237788082} + - component: {fileID: 237788081} + - component: {fileID: 237788080} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &237788080 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 237788079} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 9 + gY: 0 + item: {fileID: 0} +--- !u!61 &237788081 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 237788079} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &237788082 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 237788079} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &237788083 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 237788079} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 9, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 227227731} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &248607775 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 248607779} + - component: {fileID: 248607778} + - component: {fileID: 248607777} + - component: {fileID: 248607776} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &248607776 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 248607775} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 0 + gY: 5 + item: {fileID: 0} +--- !u!61 &248607777 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 248607775} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &248607778 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 248607775} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &248607779 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 248607775} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 5, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &263115405 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 263115409} + - component: {fileID: 263115408} + - component: {fileID: 263115407} + - component: {fileID: 263115406} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &263115406 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 263115405} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 8 + gY: 9 + item: {fileID: 0} +--- !u!61 &263115407 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 263115405} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &263115408 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 263115405} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &263115409 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 263115405} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 8, y: 9, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &268358068 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 268358072} + - component: {fileID: 268358071} + - component: {fileID: 268358070} + - component: {fileID: 268358069} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &268358069 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 268358068} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 4 + gY: 3 + item: {fileID: 0} +--- !u!61 &268358070 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 268358068} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &268358071 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 268358068} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &268358072 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 268358068} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 4, y: 3, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &289223325 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 289223329} + - component: {fileID: 289223328} + - component: {fileID: 289223327} + - component: {fileID: 289223326} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &289223326 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 289223325} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 3 + gY: 3 + item: {fileID: 0} +--- !u!61 &289223327 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 289223325} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &289223328 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 289223325} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &289223329 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 289223325} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 3, y: 3, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &300632456 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 300632460} + - component: {fileID: 300632459} + - component: {fileID: 300632458} + - component: {fileID: 300632457} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &300632457 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 300632456} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 5 + gY: 0 + item: {fileID: 0} +--- !u!61 &300632458 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 300632456} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &300632459 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 300632456} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &300632460 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 300632456} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 5, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &307420393 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 307420397} + - component: {fileID: 307420396} + - component: {fileID: 307420395} + - component: {fileID: 307420394} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &307420394 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 307420393} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 8 + gY: 4 + item: {fileID: 0} +--- !u!61 &307420395 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 307420393} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &307420396 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 307420393} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &307420397 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 307420393} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 8, y: 4, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &312972870 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 312972874} + - component: {fileID: 312972873} + - component: {fileID: 312972872} + - component: {fileID: 312972871} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &312972871 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 312972870} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 7 + gY: 7 + item: {fileID: 0} +--- !u!61 &312972872 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 312972870} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &312972873 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 312972870} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &312972874 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 312972870} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 7, y: 7, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &315710859 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 315710863} + - component: {fileID: 315710862} + - component: {fileID: 315710861} + - component: {fileID: 315710860} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &315710860 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 315710859} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 6 + gY: 6 + item: {fileID: 0} +--- !u!61 &315710861 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 315710859} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &315710862 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 315710859} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &315710863 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 315710859} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 6, y: 6, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &317378689 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 317378693} + - component: {fileID: 317378692} + - component: {fileID: 317378691} + - component: {fileID: 317378690} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &317378690 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 317378689} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 4 + gY: 8 + item: {fileID: 0} +--- !u!61 &317378691 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 317378689} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &317378692 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 317378689} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &317378693 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 317378689} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 4, y: 8, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &344785798 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 344785802} + - component: {fileID: 344785801} + - component: {fileID: 344785800} + - component: {fileID: 344785799} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &344785799 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 344785798} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 5 + gY: 2 + item: {fileID: 0} +--- !u!61 &344785800 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 344785798} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &344785801 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 344785798} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &344785802 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 344785798} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 5, y: 2, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &354415695 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 354415699} + - component: {fileID: 354415698} + - component: {fileID: 354415697} + - component: {fileID: 354415696} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &354415696 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 354415695} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 2 + gY: 9 + item: {fileID: 0} +--- !u!61 &354415697 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 354415695} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &354415698 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 354415695} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &354415699 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 354415695} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 2, y: 9, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &412097167 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 412097171} + - component: {fileID: 412097170} + - component: {fileID: 412097169} + - component: {fileID: 412097168} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &412097168 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 412097167} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 4 + gY: 0 + item: {fileID: 0} +--- !u!61 &412097169 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 412097167} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &412097170 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 412097167} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &412097171 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 412097167} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 4, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &415259103 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 415259107} + - component: {fileID: 415259106} + - component: {fileID: 415259105} + - component: {fileID: 415259104} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &415259104 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 415259103} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 0 + gY: 4 + item: {fileID: 0} +--- !u!61 &415259105 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 415259103} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &415259106 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 415259103} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &415259107 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 415259103} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 4, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &418818765 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 418818769} + - component: {fileID: 418818768} + - component: {fileID: 418818767} + - component: {fileID: 418818766} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &418818766 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 418818765} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 0 + gY: 3 + item: {fileID: 0} +--- !u!61 &418818767 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 418818765} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &418818768 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 418818765} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &418818769 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 418818765} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 3, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 227227731} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &443405375 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 443405379} + - component: {fileID: 443405378} + - component: {fileID: 443405377} + - component: {fileID: 443405376} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &443405376 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 443405375} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 6 + gY: 1 + item: {fileID: 0} +--- !u!61 &443405377 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 443405375} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &443405378 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 443405375} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &443405379 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 443405375} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 6, y: 1, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &455907302 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 455907306} + - component: {fileID: 455907305} + - component: {fileID: 455907304} + - component: {fileID: 455907303} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &455907303 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 455907302} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 5 + gY: 3 + item: {fileID: 0} +--- !u!61 &455907304 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 455907302} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &455907305 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 455907302} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &455907306 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 455907302} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 5, y: 3, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &463863504 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 463863508} + - component: {fileID: 463863507} + - component: {fileID: 463863506} + - component: {fileID: 463863505} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &463863505 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 463863504} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 0 + gY: 0 + item: {fileID: 0} +--- !u!61 &463863506 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 463863504} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &463863507 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 463863504} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &463863508 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 463863504} + serializedVersion: 2 + 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_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 227227731} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &468497714 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 468497718} + - component: {fileID: 468497717} + - component: {fileID: 468497716} + - component: {fileID: 468497715} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &468497715 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 468497714} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 3 + gY: 0 + item: {fileID: 0} +--- !u!61 &468497716 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 468497714} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &468497717 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 468497714} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &468497718 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 468497714} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 3, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 227227731} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &468706807 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 468706811} + - component: {fileID: 468706810} + - component: {fileID: 468706809} + - component: {fileID: 468706808} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &468706808 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 468706807} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 1 + gY: 7 + item: {fileID: 0} +--- !u!61 &468706809 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 468706807} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &468706810 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 468706807} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &468706811 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 468706807} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 1, y: 7, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &504221596 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 504221600} + - component: {fileID: 504221599} + - component: {fileID: 504221598} + - component: {fileID: 504221597} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &504221597 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 504221596} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 2 + gY: 7 + item: {fileID: 0} +--- !u!61 &504221598 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 504221596} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &504221599 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 504221596} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &504221600 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 504221596} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 2, y: 7, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &504794856 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 504794860} + - component: {fileID: 504794859} + - component: {fileID: 504794858} + - component: {fileID: 504794857} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &504794857 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 504794856} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 6 + gY: 9 + item: {fileID: 0} +--- !u!61 &504794858 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 504794856} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &504794859 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 504794856} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &504794860 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 504794856} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 6, y: 9, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!1 &519420028 GameObject: m_ObjectHideFlags: 0 @@ -172,6 +5498,7 @@ MonoBehaviour: serializedVersion: 2 m_Bits: 1 m_VolumeTrigger: {fileID: 0} + m_VolumeFrameworkUpdateModeOption: 2 m_RenderPostProcessing: 0 m_Antialiasing: 0 m_AntialiasingQuality: 2 @@ -179,9 +5506,20 @@ MonoBehaviour: m_Dithering: 0 m_ClearDepth: 1 m_AllowXRRendering: 1 + m_AllowHDROutput: 1 + m_UseScreenCoordOverride: 0 + m_ScreenSizeOverride: {x: 0, y: 0, z: 0, w: 0} + m_ScreenCoordScaleBias: {x: 0, y: 0, z: 0, w: 0} m_RequiresDepthTexture: 0 m_RequiresColorTexture: 0 m_Version: 2 + m_TaaSettings: + m_Quality: 3 + m_FrameInfluence: 0.1 + m_JitterScale: 1 + m_MipBias: 0 + m_VarianceClampScale: 0.9 + m_ContrastAdaptiveSharpening: 0 --- !u!20 &519420031 Camera: m_ObjectHideFlags: 0 @@ -196,9 +5534,17 @@ Camera: m_projectionMatrixMode: 1 m_GateFitMode: 2 m_FOVAxisMode: 0 + m_Iso: 200 + m_ShutterSpeed: 0.005 + m_Aperture: 16 + m_FocusDistance: 10 + m_FocalLength: 50 + m_BladeCount: 5 + m_Curvature: {x: 2, y: 11} + m_BarrelClipping: 0.25 + m_Anamorphism: 0 m_SensorSize: {x: 36, y: 24} m_LensShift: {x: 0, y: 0} - m_FocalLength: 50 m_NormalizedViewPortRect: serializedVersion: 2 x: 0 @@ -209,7 +5555,7 @@ Camera: far clip plane: 1000 field of view: 34 orthographic: 1 - orthographic size: 5 + orthographic size: 12.958887 m_Depth: -1 m_CullingMask: serializedVersion: 2 @@ -232,13 +5578,1327 @@ Transform: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 519420028} + serializedVersion: 2 m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: -10} + m_LocalPosition: {x: 4.38, y: 3.04, z: -10} m_LocalScale: {x: 1, y: 1, z: 1} m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 0} - m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &520549982 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 520549986} + - component: {fileID: 520549985} + - component: {fileID: 520549984} + - component: {fileID: 520549983} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &520549983 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 520549982} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 6 + gY: 3 + item: {fileID: 0} +--- !u!61 &520549984 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 520549982} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &520549985 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 520549982} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &520549986 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 520549982} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 6, y: 3, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 227227731} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &527332041 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 527332045} + - component: {fileID: 527332044} + - component: {fileID: 527332043} + - component: {fileID: 527332042} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &527332042 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 527332041} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 2 + gY: 3 + item: {fileID: 0} +--- !u!61 &527332043 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 527332041} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &527332044 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 527332041} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &527332045 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 527332041} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 2, y: 3, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &545902920 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 545902924} + - component: {fileID: 545902923} + - component: {fileID: 545902922} + - component: {fileID: 545902921} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &545902921 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 545902920} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 8 + gY: 0 + item: {fileID: 0} +--- !u!61 &545902922 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 545902920} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &545902923 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 545902920} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &545902924 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 545902920} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 8, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 227227731} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &551496418 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 551496422} + - component: {fileID: 551496421} + - component: {fileID: 551496420} + - component: {fileID: 551496419} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &551496419 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 551496418} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 6 + gY: 1 + item: {fileID: 0} +--- !u!61 &551496420 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 551496418} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &551496421 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 551496418} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &551496422 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 551496418} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 6, y: 1, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 227227731} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &558298661 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 558298665} + - component: {fileID: 558298664} + - component: {fileID: 558298663} + - component: {fileID: 558298662} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &558298662 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 558298661} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 2 + gY: 2 + item: {fileID: 0} +--- !u!61 &558298663 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 558298661} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &558298664 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 558298661} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &558298665 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 558298661} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 2, y: 2, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 227227731} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &560474322 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 560474326} + - component: {fileID: 560474325} + - component: {fileID: 560474324} + - component: {fileID: 560474323} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &560474323 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 560474322} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 6 + gY: 8 + item: {fileID: 0} +--- !u!61 &560474324 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 560474322} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &560474325 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 560474322} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &560474326 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 560474322} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 6, y: 8, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &576798854 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 576798858} + - component: {fileID: 576798857} + - component: {fileID: 576798856} + - component: {fileID: 576798855} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &576798855 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 576798854} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 0 + gY: 3 + item: {fileID: 0} +--- !u!61 &576798856 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 576798854} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &576798857 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 576798854} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &576798858 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 576798854} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 3, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &589997591 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 589997595} + - component: {fileID: 589997594} + - component: {fileID: 589997593} + - component: {fileID: 589997592} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &589997592 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 589997591} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 4 + gY: 1 + item: {fileID: 0} +--- !u!61 &589997593 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 589997591} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &589997594 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 589997591} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &589997595 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 589997591} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 4, y: 1, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 227227731} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &617284286 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 617284290} + - component: {fileID: 617284289} + - component: {fileID: 617284288} + - component: {fileID: 617284287} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &617284287 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 617284286} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 5 + gY: 7 + item: {fileID: 0} +--- !u!61 &617284288 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 617284286} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &617284289 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 617284286} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &617284290 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 617284286} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 5, y: 7, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!1 &619394800 GameObject: @@ -281,6 +6941,7 @@ MonoBehaviour: m_LightCookieSprite: {fileID: 0} m_DeprecatedPointLightCookieSprite: {fileID: 0} m_LightOrder: 0 + m_AlphaBlendOnOverlap: 0 m_OverlapOperation: 0 m_NormalMapDistance: 3 m_NormalMapQuality: 2 @@ -289,35 +6950,6 @@ MonoBehaviour: m_ShadowIntensity: 0.75 m_ShadowVolumeIntensityEnabled: 0 m_ShadowVolumeIntensity: 0.75 - m_Vertices: - - position: {x: 0.9985302, y: 0.9985302, z: 0} - color: {r: 0.70710677, g: 0.70710677, b: 0, a: 0} - uv: {x: 0, y: 0} - - position: {x: 0.9985302, y: 0.9985302, z: 0} - color: {r: 0, g: 0, b: 0, a: 1} - uv: {x: 0, y: 0} - - position: {x: -0.9985302, y: 0.9985302, z: 0} - color: {r: -0.70710677, g: 0.70710677, b: 0, a: 0} - uv: {x: 0, y: 0} - - position: {x: -0.9985302, y: 0.9985302, z: 0} - color: {r: 0, g: 0, b: 0, a: 1} - uv: {x: 0, y: 0} - - position: {x: -0.99853003, y: -0.9985304, z: 0} - color: {r: -0.70710665, g: -0.7071069, b: 0, a: 0} - uv: {x: 0, y: 0} - - position: {x: -0.99853003, y: -0.9985304, z: 0} - color: {r: 0, g: 0, b: 0, a: 1} - uv: {x: 0, y: 0} - - position: {x: 0.99853003, y: -0.9985304, z: 0} - color: {r: 0.70710665, g: -0.7071069, b: 0, a: 0} - uv: {x: 0, y: 0} - - position: {x: 0.99853003, y: -0.9985304, z: 0} - color: {r: 0, g: 0, b: 0, a: 1} - uv: {x: 0, y: 0} - - position: {x: 0, y: 0, z: 0} - color: {r: 0, g: 0, b: 0, a: 1} - uv: {x: 0, y: 0} - m_Triangles: 030001000800020000000100030002000100050003000800040002000300050004000300070005000800060004000500070006000500010007000800000006000700010000000700 m_LocalBounds: m_Center: {x: 0, y: -0.00000011920929, z: 0} m_Extent: {x: 0.9985302, y: 0.99853027, z: 0} @@ -342,11 +6974,14661 @@ Transform: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 619394800} + serializedVersion: 2 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 0} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &626022339 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 626022343} + - component: {fileID: 626022342} + - component: {fileID: 626022341} + - component: {fileID: 626022340} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &626022340 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 626022339} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 9 + gY: 3 + item: {fileID: 0} +--- !u!61 &626022341 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 626022339} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &626022342 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 626022339} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &626022343 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 626022339} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 9, y: 3, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &630278466 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 630278470} + - component: {fileID: 630278469} + - component: {fileID: 630278468} + - component: {fileID: 630278467} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &630278467 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 630278466} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 9 + gY: 2 + item: {fileID: 0} +--- !u!61 &630278468 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 630278466} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &630278469 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 630278466} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &630278470 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 630278466} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 9, y: 2, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 227227731} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &638819637 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 638819641} + - component: {fileID: 638819640} + - component: {fileID: 638819639} + - component: {fileID: 638819638} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &638819638 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 638819637} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 1 + gY: 3 + item: {fileID: 0} +--- !u!61 &638819639 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 638819637} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &638819640 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 638819637} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &638819641 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 638819637} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 1, y: 3, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &657309863 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 657309867} + - component: {fileID: 657309866} + - component: {fileID: 657309865} + - component: {fileID: 657309864} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &657309864 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 657309863} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 8 + gY: 2 + item: {fileID: 0} +--- !u!61 &657309865 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 657309863} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &657309866 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 657309863} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &657309867 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 657309863} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 8, y: 2, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &665918798 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 665918802} + - component: {fileID: 665918801} + - component: {fileID: 665918800} + - component: {fileID: 665918799} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &665918799 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 665918798} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 4 + gY: 4 + item: {fileID: 0} +--- !u!61 &665918800 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 665918798} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &665918801 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 665918798} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &665918802 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 665918798} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 4, y: 4, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &672190466 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 672190470} + - component: {fileID: 672190469} + - component: {fileID: 672190468} + - component: {fileID: 672190467} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &672190467 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 672190466} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 8 + gY: 5 + item: {fileID: 0} +--- !u!61 &672190468 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 672190466} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &672190469 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 672190466} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &672190470 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 672190466} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 8, y: 5, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &672862053 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 672862057} + - component: {fileID: 672862056} + - component: {fileID: 672862055} + - component: {fileID: 672862054} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &672862054 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 672862053} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 3 + gY: 1 + item: {fileID: 0} +--- !u!61 &672862055 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 672862053} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &672862056 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 672862053} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &672862057 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 672862053} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 3, y: 1, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &675525381 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 675525385} + - component: {fileID: 675525384} + - component: {fileID: 675525383} + - component: {fileID: 675525382} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &675525382 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 675525381} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 6 + gY: 7 + item: {fileID: 0} +--- !u!61 &675525383 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 675525381} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &675525384 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 675525381} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &675525385 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 675525381} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 6, y: 7, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &686257693 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 686257697} + - component: {fileID: 686257696} + - component: {fileID: 686257695} + - component: {fileID: 686257694} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &686257694 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 686257693} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 9 + gY: 0 + item: {fileID: 0} +--- !u!61 &686257695 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 686257693} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &686257696 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 686257693} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &686257697 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 686257693} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 9, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &687334422 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 687334426} + - component: {fileID: 687334425} + - component: {fileID: 687334424} + - component: {fileID: 687334423} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &687334423 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 687334422} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 5 + gY: 5 + item: {fileID: 0} +--- !u!61 &687334424 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 687334422} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &687334425 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 687334422} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &687334426 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 687334422} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 5, y: 5, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &694229259 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 694229263} + - component: {fileID: 694229262} + - component: {fileID: 694229261} + - component: {fileID: 694229260} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &694229260 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 694229259} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 7 + gY: 0 + item: {fileID: 0} +--- !u!61 &694229261 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 694229259} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &694229262 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 694229259} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &694229263 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 694229259} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 7, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 227227731} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &699603238 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 699603242} + - component: {fileID: 699603241} + - component: {fileID: 699603240} + - component: {fileID: 699603239} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &699603239 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 699603238} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 3 + gY: 3 + item: {fileID: 0} +--- !u!61 &699603240 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 699603238} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &699603241 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 699603238} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &699603242 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 699603238} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 3, y: 3, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 227227731} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &701195473 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 701195477} + - component: {fileID: 701195476} + - component: {fileID: 701195475} + - component: {fileID: 701195474} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &701195474 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 701195473} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 5 + gY: 3 + item: {fileID: 0} +--- !u!61 &701195475 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 701195473} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &701195476 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 701195473} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &701195477 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 701195473} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 5, y: 3, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 227227731} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &707261760 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 707261764} + - component: {fileID: 707261763} + - component: {fileID: 707261762} + - component: {fileID: 707261761} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &707261761 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 707261760} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 2 + gY: 3 + item: {fileID: 0} +--- !u!61 &707261762 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 707261760} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &707261763 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 707261760} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &707261764 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 707261760} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 2, y: 3, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 227227731} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &712899306 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 712899310} + - component: {fileID: 712899309} + - component: {fileID: 712899308} + - component: {fileID: 712899307} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &712899307 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 712899306} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 3 + gY: 7 + item: {fileID: 0} +--- !u!61 &712899308 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 712899306} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &712899309 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 712899306} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &712899310 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 712899306} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 3, y: 7, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &732359355 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 732359359} + - component: {fileID: 732359358} + - component: {fileID: 732359357} + - component: {fileID: 732359356} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &732359356 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 732359355} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 7 + gY: 2 + item: {fileID: 0} +--- !u!61 &732359357 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 732359355} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &732359358 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 732359355} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &732359359 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 732359355} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 7, y: 2, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 227227731} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &741706299 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 741706300} + m_Layer: 0 + m_Name: box + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &741706300 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 741706299} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 3.5, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 1557345279} + - {fileID: 1187480673} + - {fileID: 1127444908} + - {fileID: 576798858} + - {fileID: 415259107} + - {fileID: 248607779} + - {fileID: 1074018040} + - {fileID: 839975236} + - {fileID: 1662952245} + - {fileID: 2123764142} + - {fileID: 1146541604} + - {fileID: 1046343798} + - {fileID: 135438565} + - {fileID: 638819641} + - {fileID: 1119295693} + - {fileID: 1367138493} + - {fileID: 1989871252} + - {fileID: 468706811} + - {fileID: 1263211113} + - {fileID: 914503766} + - {fileID: 1511449063} + - {fileID: 1289978613} + - {fileID: 1723035891} + - {fileID: 527332045} + - {fileID: 1877946763} + - {fileID: 1834542160} + - {fileID: 118478194} + - {fileID: 504221600} + - {fileID: 1847432481} + - {fileID: 354415699} + - {fileID: 1833867941} + - {fileID: 672862057} + - {fileID: 770359919} + - {fileID: 289223329} + - {fileID: 1414670427} + - {fileID: 55628963} + - {fileID: 849467724} + - {fileID: 712899310} + - {fileID: 1012752671} + - {fileID: 1629100892} + - {fileID: 412097171} + - {fileID: 929315396} + - {fileID: 167418912} + - {fileID: 268358072} + - {fileID: 665918802} + - {fileID: 1662760824} + - {fileID: 917898909} + - {fileID: 2111485863} + - {fileID: 317378693} + - {fileID: 1845981176} + - {fileID: 300632460} + - {fileID: 55411289} + - {fileID: 344785802} + - {fileID: 455907306} + - {fileID: 1729013583} + - {fileID: 687334426} + - {fileID: 828889408} + - {fileID: 617284290} + - {fileID: 1349777575} + - {fileID: 1570279992} + - {fileID: 1640931057} + - {fileID: 443405379} + - {fileID: 1973362471} + - {fileID: 1840917022} + - {fileID: 1481925010} + - {fileID: 949674235} + - {fileID: 315710863} + - {fileID: 675525385} + - {fileID: 560474326} + - {fileID: 504794860} + - {fileID: 762506057} + - {fileID: 1829541339} + - {fileID: 870421520} + - {fileID: 1667897272} + - {fileID: 1305587186} + - {fileID: 1666690199} + - {fileID: 171658261} + - {fileID: 312972874} + - {fileID: 117781942} + - {fileID: 1315236901} + - {fileID: 228766931} + - {fileID: 160666756} + - {fileID: 657309867} + - {fileID: 1827011610} + - {fileID: 307420397} + - {fileID: 672190470} + - {fileID: 1372805651} + - {fileID: 1117232098} + - {fileID: 1072734476} + - {fileID: 263115409} + - {fileID: 686257697} + - {fileID: 1877106451} + - {fileID: 2072603904} + - {fileID: 626022343} + - {fileID: 1987454604} + - {fileID: 1042635605} + - {fileID: 1283608753} + - {fileID: 2028298787} + - {fileID: 1217401200} + - {fileID: 908631983} + m_Father: {fileID: 2094376466} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &762506053 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 762506057} + - component: {fileID: 762506056} + - component: {fileID: 762506055} + - component: {fileID: 762506054} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &762506054 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 762506053} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 7 + gY: 0 + item: {fileID: 0} +--- !u!61 &762506055 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 762506053} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &762506056 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 762506053} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &762506057 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 762506053} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 7, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &770359915 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 770359919} + - component: {fileID: 770359918} + - component: {fileID: 770359917} + - component: {fileID: 770359916} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &770359916 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 770359915} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 3 + gY: 2 + item: {fileID: 0} +--- !u!61 &770359917 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 770359915} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &770359918 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 770359915} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &770359919 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 770359915} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 3, y: 2, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &828889404 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 828889408} + - component: {fileID: 828889407} + - component: {fileID: 828889406} + - component: {fileID: 828889405} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &828889405 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 828889404} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 5 + gY: 6 + item: {fileID: 0} +--- !u!61 &828889406 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 828889404} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &828889407 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 828889404} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &828889408 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 828889404} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 5, y: 6, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &839975232 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 839975236} + - component: {fileID: 839975235} + - component: {fileID: 839975234} + - component: {fileID: 839975233} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &839975233 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 839975232} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 0 + gY: 7 + item: {fileID: 0} +--- !u!61 &839975234 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 839975232} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &839975235 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 839975232} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &839975236 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 839975232} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 7, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &849467720 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 849467724} + - component: {fileID: 849467723} + - component: {fileID: 849467722} + - component: {fileID: 849467721} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &849467721 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 849467720} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 3 + gY: 6 + item: {fileID: 0} +--- !u!61 &849467722 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 849467720} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &849467723 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 849467720} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &849467724 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 849467720} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 3, y: 6, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &870421516 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 870421520} + - component: {fileID: 870421519} + - component: {fileID: 870421518} + - component: {fileID: 870421517} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &870421517 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 870421516} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 7 + gY: 2 + item: {fileID: 0} +--- !u!61 &870421518 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 870421516} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &870421519 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 870421516} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &870421520 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 870421516} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 7, y: 2, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &908631979 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 908631983} + - component: {fileID: 908631982} + - component: {fileID: 908631981} + - component: {fileID: 908631980} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &908631980 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 908631979} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 9 + gY: 9 + item: {fileID: 0} +--- !u!61 &908631981 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 908631979} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &908631982 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 908631979} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &908631983 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 908631979} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 9, y: 9, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &914503762 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 914503766} + - component: {fileID: 914503765} + - component: {fileID: 914503764} + - component: {fileID: 914503763} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &914503763 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 914503762} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 1 + gY: 9 + item: {fileID: 0} +--- !u!61 &914503764 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 914503762} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &914503765 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 914503762} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &914503766 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 914503762} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 1, y: 9, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &917898905 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 917898909} + - component: {fileID: 917898908} + - component: {fileID: 917898907} + - component: {fileID: 917898906} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &917898906 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 917898905} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 4 + gY: 6 + item: {fileID: 0} +--- !u!61 &917898907 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 917898905} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &917898908 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 917898905} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &917898909 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 917898905} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 4, y: 6, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &929315392 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 929315396} + - component: {fileID: 929315395} + - component: {fileID: 929315394} + - component: {fileID: 929315393} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &929315393 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 929315392} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 4 + gY: 1 + item: {fileID: 0} +--- !u!61 &929315394 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 929315392} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &929315395 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 929315392} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &929315396 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 929315392} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 4, y: 1, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &949674231 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 949674235} + - component: {fileID: 949674234} + - component: {fileID: 949674233} + - component: {fileID: 949674232} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &949674232 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 949674231} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 6 + gY: 5 + item: {fileID: 0} +--- !u!61 &949674233 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 949674231} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &949674234 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 949674231} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &949674235 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 949674231} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 6, y: 5, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &983043042 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 983043046} + - component: {fileID: 983043045} + - component: {fileID: 983043044} + - component: {fileID: 983043043} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &983043043 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 983043042} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 5 + gY: 1 + item: {fileID: 0} +--- !u!61 &983043044 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 983043042} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &983043045 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 983043042} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &983043046 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 983043042} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 5, y: 1, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 227227731} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1010204225 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1010204229} + - component: {fileID: 1010204228} + - component: {fileID: 1010204227} + - component: {fileID: 1010204226} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1010204226 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1010204225} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 2 + gY: 1 + item: {fileID: 0} +--- !u!61 &1010204227 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1010204225} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &1010204228 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1010204225} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &1010204229 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1010204225} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 2, y: 1, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 227227731} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1012752667 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1012752671} + - component: {fileID: 1012752670} + - component: {fileID: 1012752669} + - component: {fileID: 1012752668} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1012752668 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1012752667} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 3 + gY: 8 + item: {fileID: 0} +--- !u!61 &1012752669 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1012752667} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &1012752670 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1012752667} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &1012752671 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1012752667} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 3, y: 8, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1034160429 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1034160433} + - component: {fileID: 1034160432} + - component: {fileID: 1034160431} + - component: {fileID: 1034160430} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1034160430 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1034160429} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 3 + gY: 1 + item: {fileID: 0} +--- !u!61 &1034160431 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1034160429} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &1034160432 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1034160429} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &1034160433 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1034160429} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 3, y: 1, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 227227731} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1042635601 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1042635605} + - component: {fileID: 1042635604} + - component: {fileID: 1042635603} + - component: {fileID: 1042635602} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1042635602 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1042635601} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 9 + gY: 5 + item: {fileID: 0} +--- !u!61 &1042635603 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1042635601} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &1042635604 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1042635601} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &1042635605 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1042635601} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 9, y: 5, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1046343794 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1046343798} + - component: {fileID: 1046343797} + - component: {fileID: 1046343796} + - component: {fileID: 1046343795} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1046343795 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1046343794} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 1 + gY: 1 + item: {fileID: 0} +--- !u!61 &1046343796 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1046343794} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &1046343797 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1046343794} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &1046343798 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1046343794} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 1, y: 1, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1069201188 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1069201192} + - component: {fileID: 1069201191} + - component: {fileID: 1069201190} + - component: {fileID: 1069201189} + m_Layer: 5 + m_Name: Canvas + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1069201189 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1069201188} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: dc42784cf147c0c48a680349fa168899, type: 3} + m_Name: + m_EditorClassIdentifier: + m_IgnoreReversedGraphics: 1 + m_BlockingObjects: 0 + m_BlockingMask: + serializedVersion: 2 + m_Bits: 4294967295 +--- !u!114 &1069201190 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1069201188} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 0cd44c1031e13a943bb63640046fad76, type: 3} + m_Name: + m_EditorClassIdentifier: + m_UiScaleMode: 0 + m_ReferencePixelsPerUnit: 100 + m_ScaleFactor: 1 + m_ReferenceResolution: {x: 800, y: 600} + m_ScreenMatchMode: 0 + m_MatchWidthOrHeight: 0 + m_PhysicalUnit: 3 + m_FallbackScreenDPI: 96 + m_DefaultSpriteDPI: 96 + m_DynamicPixelsPerUnit: 1 + m_PresetInfoIsWorld: 0 +--- !u!223 &1069201191 +Canvas: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1069201188} + m_Enabled: 1 + serializedVersion: 3 + m_RenderMode: 0 + m_Camera: {fileID: 0} + m_PlaneDistance: 100 + m_PixelPerfect: 0 + m_ReceivesEvents: 1 + m_OverrideSorting: 0 + m_OverridePixelPerfect: 0 + m_SortingBucketNormalizedSize: 0 + m_VertexColorAlwaysGammaSpace: 0 + m_AdditionalShaderChannelsFlag: 0 + m_UpdateRectTransformForStandalone: 0 + m_SortingLayerID: 0 + m_SortingOrder: 0 + m_TargetDisplay: 0 +--- !u!224 &1069201192 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1069201188} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 0, y: 0, z: 0} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 1854825446} + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0, y: 0} +--- !u!1 &1072734472 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1072734476} + - component: {fileID: 1072734475} + - component: {fileID: 1072734474} + - component: {fileID: 1072734473} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1072734473 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1072734472} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 8 + gY: 8 + item: {fileID: 0} +--- !u!61 &1072734474 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1072734472} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &1072734475 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1072734472} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &1072734476 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1072734472} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 8, y: 8, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1074018036 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1074018040} + - component: {fileID: 1074018039} + - component: {fileID: 1074018038} + - component: {fileID: 1074018037} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1074018037 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1074018036} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 0 + gY: 6 + item: {fileID: 0} +--- !u!61 &1074018038 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1074018036} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &1074018039 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1074018036} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &1074018040 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1074018036} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 6, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1079375772 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1079375776} + - component: {fileID: 1079375775} + - component: {fileID: 1079375774} + - component: {fileID: 1079375773} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1079375773 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1079375772} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 8 + gY: 3 + item: {fileID: 0} +--- !u!61 &1079375774 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1079375772} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &1079375775 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1079375772} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &1079375776 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1079375772} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 8, y: 3, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 227227731} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1106532909 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1106532913} + - component: {fileID: 1106532912} + - component: {fileID: 1106532911} + - component: {fileID: 1106532910} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1106532910 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1106532909} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 1 + gY: 2 + item: {fileID: 0} +--- !u!61 &1106532911 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1106532909} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &1106532912 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1106532909} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &1106532913 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1106532909} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 1, y: 2, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 227227731} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1116539344 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1116539348} + - component: {fileID: 1116539347} + - component: {fileID: 1116539346} + - component: {fileID: 1116539345} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1116539345 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1116539344} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 2 + gY: 0 + item: {fileID: 0} +--- !u!61 &1116539346 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1116539344} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &1116539347 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1116539344} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &1116539348 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1116539344} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 2, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 227227731} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1117232094 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1117232098} + - component: {fileID: 1117232097} + - component: {fileID: 1117232096} + - component: {fileID: 1117232095} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1117232095 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1117232094} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 8 + gY: 7 + item: {fileID: 0} +--- !u!61 &1117232096 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1117232094} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &1117232097 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1117232094} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &1117232098 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1117232094} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 8, y: 7, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1119295689 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1119295693} + - component: {fileID: 1119295692} + - component: {fileID: 1119295691} + - component: {fileID: 1119295690} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1119295690 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1119295689} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 1 + gY: 4 + item: {fileID: 0} +--- !u!61 &1119295691 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1119295689} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &1119295692 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1119295689} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &1119295693 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1119295689} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 1, y: 4, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1127444904 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1127444908} + - component: {fileID: 1127444907} + - component: {fileID: 1127444906} + - component: {fileID: 1127444905} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1127444905 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1127444904} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 0 + gY: 2 + item: {fileID: 0} +--- !u!61 &1127444906 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1127444904} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &1127444907 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1127444904} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &1127444908 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1127444904} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 2, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1146541600 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1146541604} + - component: {fileID: 1146541603} + - component: {fileID: 1146541602} + - component: {fileID: 1146541601} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1146541601 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1146541600} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 1 + gY: 0 + item: {fileID: 0} +--- !u!61 &1146541602 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1146541600} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &1146541603 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1146541600} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &1146541604 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1146541600} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 1, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1187480669 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1187480673} + - component: {fileID: 1187480672} + - component: {fileID: 1187480671} + - component: {fileID: 1187480670} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1187480670 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1187480669} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 0 + gY: 1 + item: {fileID: 0} +--- !u!61 &1187480671 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1187480669} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &1187480672 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1187480669} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &1187480673 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1187480669} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 1, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1200390947 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1200390951} + - component: {fileID: 1200390950} + - component: {fileID: 1200390949} + - component: {fileID: 1200390948} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1200390948 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1200390947} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 7 + gY: 1 + item: {fileID: 0} +--- !u!61 &1200390949 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1200390947} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &1200390950 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1200390947} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &1200390951 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1200390947} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 7, y: 1, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 227227731} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1217401196 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1217401200} + - component: {fileID: 1217401199} + - component: {fileID: 1217401198} + - component: {fileID: 1217401197} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1217401197 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1217401196} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 9 + gY: 8 + item: {fileID: 0} +--- !u!61 &1217401198 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1217401196} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &1217401199 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1217401196} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &1217401200 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1217401196} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 9, y: 8, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1239476988 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1239476992} + - component: {fileID: 1239476991} + - component: {fileID: 1239476990} + - component: {fileID: 1239476989} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1239476989 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1239476988} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 9 + gY: 3 + item: {fileID: 0} +--- !u!61 &1239476990 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1239476988} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &1239476991 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1239476988} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &1239476992 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1239476988} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 9, y: 3, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 227227731} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1254055758 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1254055762} + - component: {fileID: 1254055761} + - component: {fileID: 1254055760} + - component: {fileID: 1254055759} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1254055759 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1254055758} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 0 + gY: 1 + item: {fileID: 0} +--- !u!61 &1254055760 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1254055758} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &1254055761 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1254055758} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &1254055762 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1254055758} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 1, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 227227731} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1259872545 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1259872547} + - component: {fileID: 1259872546} + m_Layer: 0 + m_Name: GameManager + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1259872546 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1259872545} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 1cf34d8028049784e83a9be2beb1352f, type: 3} + m_Name: + m_EditorClassIdentifier: + itemDatas: + - x: 0 + y: 0 + item: {fileID: 1520619064} + - x: 1 + y: 0 + item: {fileID: 1520619064} +--- !u!4 &1259872547 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1259872545} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 7.599376, y: -0.49398276, z: 0.0150930155} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1263010893 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1263010897} + - component: {fileID: 1263010896} + - component: {fileID: 1263010895} + - component: {fileID: 1263010894} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1263010894 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1263010893} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 3 + gY: 2 + item: {fileID: 0} +--- !u!61 &1263010895 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1263010893} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &1263010896 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1263010893} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &1263010897 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1263010893} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 3, y: 2, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 227227731} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1263211109 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1263211113} + - component: {fileID: 1263211112} + - component: {fileID: 1263211111} + - component: {fileID: 1263211110} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1263211110 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1263211109} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 1 + gY: 8 + item: {fileID: 0} +--- !u!61 &1263211111 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1263211109} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &1263211112 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1263211109} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &1263211113 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1263211109} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 1, y: 8, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1283608749 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1283608753} + - component: {fileID: 1283608752} + - component: {fileID: 1283608751} + - component: {fileID: 1283608750} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1283608750 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1283608749} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 9 + gY: 6 + item: {fileID: 0} +--- !u!61 &1283608751 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1283608749} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &1283608752 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1283608749} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &1283608753 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1283608749} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 9, y: 6, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1284770390 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1284770394} + - component: {fileID: 1284770393} + - component: {fileID: 1284770392} + - component: {fileID: 1284770391} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1284770391 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1284770390} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 8 + gY: 1 + item: {fileID: 0} +--- !u!61 &1284770392 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1284770390} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &1284770393 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1284770390} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &1284770394 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1284770390} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 8, y: 1, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 227227731} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1289978609 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1289978613} + - component: {fileID: 1289978612} + - component: {fileID: 1289978611} + - component: {fileID: 1289978610} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1289978610 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1289978609} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 2 + gY: 1 + item: {fileID: 0} +--- !u!61 &1289978611 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1289978609} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &1289978612 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1289978609} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &1289978613 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1289978609} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 2, y: 1, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1305587182 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1305587186} + - component: {fileID: 1305587185} + - component: {fileID: 1305587184} + - component: {fileID: 1305587183} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1305587183 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1305587182} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 7 + gY: 4 + item: {fileID: 0} +--- !u!61 &1305587184 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1305587182} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &1305587185 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1305587182} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &1305587186 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1305587182} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 7, y: 4, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1312808996 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1312809000} + - component: {fileID: 1312808999} + - component: {fileID: 1312808998} + - component: {fileID: 1312808997} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1312808997 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1312808996} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 1 + gY: 1 + item: {fileID: 0} +--- !u!61 &1312808998 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1312808996} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &1312808999 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1312808996} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &1312809000 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1312808996} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 1, y: 1, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 227227731} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1315236897 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1315236901} + - component: {fileID: 1315236900} + - component: {fileID: 1315236899} + - component: {fileID: 1315236898} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1315236898 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1315236897} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 7 + gY: 9 + item: {fileID: 0} +--- !u!61 &1315236899 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1315236897} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &1315236900 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1315236897} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &1315236901 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1315236897} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 7, y: 9, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1334787026 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1334787030} + - component: {fileID: 1334787029} + - component: {fileID: 1334787028} + - component: {fileID: 1334787027} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1334787027 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1334787026} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 7 + gY: 3 + item: {fileID: 0} +--- !u!61 &1334787028 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1334787026} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &1334787029 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1334787026} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &1334787030 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1334787026} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 7, y: 3, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 227227731} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1335142273 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1335142274} + - component: {fileID: 1335142275} + m_Layer: 0 + m_Name: Item + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &1335142274 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1335142273} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 10.546556, y: 1.4684911, z: -0.031400517} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &1335142275 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1335142273} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 269571902cab4194b99c8d5b28dcc715, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!1 &1349777571 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1349777575} + - component: {fileID: 1349777574} + - component: {fileID: 1349777573} + - component: {fileID: 1349777572} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1349777572 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1349777571} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 5 + gY: 8 + item: {fileID: 0} +--- !u!61 &1349777573 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1349777571} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &1349777574 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1349777571} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &1349777575 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1349777571} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 5, y: 8, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1367138489 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1367138493} + - component: {fileID: 1367138492} + - component: {fileID: 1367138491} + - component: {fileID: 1367138490} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1367138490 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1367138489} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 1 + gY: 5 + item: {fileID: 0} +--- !u!61 &1367138491 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1367138489} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &1367138492 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1367138489} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &1367138493 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1367138489} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 1, y: 5, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1372805647 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1372805651} + - component: {fileID: 1372805650} + - component: {fileID: 1372805649} + - component: {fileID: 1372805648} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1372805648 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1372805647} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 8 + gY: 6 + item: {fileID: 0} +--- !u!61 &1372805649 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1372805647} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &1372805650 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1372805647} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &1372805651 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1372805647} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 8, y: 6, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1414670423 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1414670427} + - component: {fileID: 1414670426} + - component: {fileID: 1414670425} + - component: {fileID: 1414670424} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1414670424 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1414670423} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 3 + gY: 4 + item: {fileID: 0} +--- !u!61 &1414670425 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1414670423} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &1414670426 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1414670423} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &1414670427 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1414670423} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 3, y: 4, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1461025076 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1461025080} + - component: {fileID: 1461025079} + - component: {fileID: 1461025078} + - component: {fileID: 1461025077} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1461025077 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1461025076} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 1 + gY: 3 + item: {fileID: 0} +--- !u!61 &1461025078 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1461025076} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &1461025079 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1461025076} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &1461025080 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1461025076} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 1, y: 3, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 227227731} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1481925006 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1481925010} + - component: {fileID: 1481925009} + - component: {fileID: 1481925008} + - component: {fileID: 1481925007} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1481925007 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1481925006} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 6 + gY: 4 + item: {fileID: 0} +--- !u!61 &1481925008 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1481925006} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &1481925009 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1481925006} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &1481925010 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1481925006} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 6, y: 4, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1503093212 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1503093216} + - component: {fileID: 1503093215} + - component: {fileID: 1503093214} + - component: {fileID: 1503093213} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1503093213 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1503093212} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 4 + gY: 2 + item: {fileID: 0} +--- !u!61 &1503093214 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1503093212} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &1503093215 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1503093212} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &1503093216 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1503093212} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 4, y: 2, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 227227731} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1511449059 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1511449063} + - component: {fileID: 1511449062} + - component: {fileID: 1511449061} + - component: {fileID: 1511449060} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1511449060 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1511449059} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 2 + gY: 0 + item: {fileID: 0} +--- !u!61 &1511449061 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1511449059} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &1511449062 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1511449059} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &1511449063 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1511449059} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 2, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1520619064 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1520619065} + - component: {fileID: 1520619067} + - component: {fileID: 1520619066} + m_Layer: 0 + m_Name: Capsule + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &1520619065 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1520619064} + serializedVersion: 2 + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: -10.28, y: -3.02, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &1520619066 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1520619064} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: d15782fa86faf644f9f08511c76bed3d, type: 3} + m_Name: + m_EditorClassIdentifier: + size: + x: 1 + y: 2 + _grids: [] + dev: {x: 0, y: 0.5, z: 0} +--- !u!212 &1520619067 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1520619064} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 1 + m_Sprite: {fileID: -9095717837082945937, guid: 207ee8102dd4143d288186ef0be518ee, type: 3} + m_Color: {r: 1, g: 0.051886797, b: 0.051886797, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 0 + m_Size: {x: 1, y: 2} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!1 &1557345275 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1557345279} + - component: {fileID: 1557345278} + - component: {fileID: 1557345277} + - component: {fileID: 1557345276} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1557345276 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1557345275} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 0 + gY: 0 + item: {fileID: 0} +--- !u!61 &1557345277 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1557345275} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &1557345278 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1557345275} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &1557345279 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1557345275} + serializedVersion: 2 + 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_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1570279988 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1570279992} + - component: {fileID: 1570279991} + - component: {fileID: 1570279990} + - component: {fileID: 1570279989} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1570279989 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1570279988} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 5 + gY: 9 + item: {fileID: 0} +--- !u!61 &1570279990 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1570279988} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &1570279991 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1570279988} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &1570279992 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1570279988} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 5, y: 9, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1629100888 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1629100892} + - component: {fileID: 1629100891} + - component: {fileID: 1629100890} + - component: {fileID: 1629100889} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1629100889 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1629100888} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 3 + gY: 9 + item: {fileID: 0} +--- !u!61 &1629100890 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1629100888} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &1629100891 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1629100888} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &1629100892 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1629100888} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 3, y: 9, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1640931053 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1640931057} + - component: {fileID: 1640931056} + - component: {fileID: 1640931055} + - component: {fileID: 1640931054} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1640931054 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1640931053} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 6 + gY: 0 + item: {fileID: 0} +--- !u!61 &1640931055 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1640931053} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &1640931056 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1640931053} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &1640931057 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1640931053} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 6, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1662760820 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1662760824} + - component: {fileID: 1662760823} + - component: {fileID: 1662760822} + - component: {fileID: 1662760821} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1662760821 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1662760820} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 4 + gY: 5 + item: {fileID: 0} +--- !u!61 &1662760822 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1662760820} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &1662760823 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1662760820} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &1662760824 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1662760820} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 4, y: 5, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1662952241 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1662952245} + - component: {fileID: 1662952244} + - component: {fileID: 1662952243} + - component: {fileID: 1662952242} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1662952242 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1662952241} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 0 + gY: 8 + item: {fileID: 0} +--- !u!61 &1662952243 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1662952241} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &1662952244 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1662952241} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &1662952245 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1662952241} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 8, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1666690195 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1666690199} + - component: {fileID: 1666690198} + - component: {fileID: 1666690197} + - component: {fileID: 1666690196} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1666690196 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1666690195} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 7 + gY: 5 + item: {fileID: 0} +--- !u!61 &1666690197 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1666690195} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &1666690198 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1666690195} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &1666690199 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1666690195} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 7, y: 5, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1667897268 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1667897272} + - component: {fileID: 1667897271} + - component: {fileID: 1667897270} + - component: {fileID: 1667897269} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1667897269 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1667897268} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 7 + gY: 3 + item: {fileID: 0} +--- !u!61 &1667897270 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1667897268} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &1667897271 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1667897268} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &1667897272 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1667897268} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 7, y: 3, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1674163523 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1674163527} + - component: {fileID: 1674163526} + - component: {fileID: 1674163525} + - component: {fileID: 1674163524} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1674163524 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1674163523} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 5 + gY: 2 + item: {fileID: 0} +--- !u!61 &1674163525 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1674163523} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &1674163526 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1674163523} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &1674163527 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1674163523} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 5, y: 2, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 227227731} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1691788218 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1691788222} + - component: {fileID: 1691788221} + - component: {fileID: 1691788220} + - component: {fileID: 1691788219} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1691788219 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1691788218} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 1 + gY: 0 + item: {fileID: 0} +--- !u!61 &1691788220 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1691788218} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &1691788221 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1691788218} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &1691788222 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1691788218} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 1, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 227227731} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1723035887 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1723035891} + - component: {fileID: 1723035890} + - component: {fileID: 1723035889} + - component: {fileID: 1723035888} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1723035888 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1723035887} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 2 + gY: 2 + item: {fileID: 0} +--- !u!61 &1723035889 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1723035887} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &1723035890 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1723035887} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &1723035891 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1723035887} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 2, y: 2, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1729013579 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1729013583} + - component: {fileID: 1729013582} + - component: {fileID: 1729013581} + - component: {fileID: 1729013580} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1729013580 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1729013579} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 5 + gY: 4 + item: {fileID: 0} +--- !u!61 &1729013581 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1729013579} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &1729013582 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1729013579} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &1729013583 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1729013579} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 5, y: 4, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1827011606 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1827011610} + - component: {fileID: 1827011609} + - component: {fileID: 1827011608} + - component: {fileID: 1827011607} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1827011607 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1827011606} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 8 + gY: 3 + item: {fileID: 0} +--- !u!61 &1827011608 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1827011606} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &1827011609 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1827011606} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &1827011610 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1827011606} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 8, y: 3, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1829541335 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1829541339} + - component: {fileID: 1829541338} + - component: {fileID: 1829541337} + - component: {fileID: 1829541336} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1829541336 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1829541335} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 7 + gY: 1 + item: {fileID: 0} +--- !u!61 &1829541337 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1829541335} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &1829541338 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1829541335} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &1829541339 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1829541335} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 7, y: 1, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1833867937 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1833867941} + - component: {fileID: 1833867940} + - component: {fileID: 1833867939} + - component: {fileID: 1833867938} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1833867938 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1833867937} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 3 + gY: 0 + item: {fileID: 0} +--- !u!61 &1833867939 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1833867937} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &1833867940 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1833867937} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &1833867941 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1833867937} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 3, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1834542156 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1834542160} + - component: {fileID: 1834542159} + - component: {fileID: 1834542158} + - component: {fileID: 1834542157} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1834542157 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1834542156} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 2 + gY: 5 + item: {fileID: 0} +--- !u!61 &1834542158 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1834542156} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &1834542159 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1834542156} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &1834542160 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1834542156} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 2, y: 5, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1840917018 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1840917022} + - component: {fileID: 1840917021} + - component: {fileID: 1840917020} + - component: {fileID: 1840917019} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1840917019 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1840917018} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 6 + gY: 3 + item: {fileID: 0} +--- !u!61 &1840917020 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1840917018} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &1840917021 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1840917018} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &1840917022 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1840917018} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 6, y: 3, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1845981172 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1845981176} + - component: {fileID: 1845981175} + - component: {fileID: 1845981174} + - component: {fileID: 1845981173} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1845981173 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1845981172} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 4 + gY: 9 + item: {fileID: 0} +--- !u!61 &1845981174 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1845981172} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &1845981175 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1845981172} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &1845981176 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1845981172} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 4, y: 9, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1847432477 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1847432481} + - component: {fileID: 1847432480} + - component: {fileID: 1847432479} + - component: {fileID: 1847432478} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1847432478 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1847432477} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 2 + gY: 8 + item: {fileID: 0} +--- !u!61 &1847432479 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1847432477} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &1847432480 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1847432477} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &1847432481 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1847432477} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 2, y: 8, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1854825445 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1854825446} + - component: {fileID: 1854825448} + - component: {fileID: 1854825447} + m_Layer: 5 + m_Name: Panel + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1854825446 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1854825445} + 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_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 1069201192} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1854825447 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1854825445} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 0} + m_RaycastTarget: 0 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10907, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1854825448 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1854825445} + m_CullTransparentMesh: 1 +--- !u!1 &1864465805 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1864465809} + - component: {fileID: 1864465808} + - component: {fileID: 1864465807} + - component: {fileID: 1864465806} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1864465806 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1864465805} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 8 + gY: 2 + item: {fileID: 0} +--- !u!61 &1864465807 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1864465805} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &1864465808 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1864465805} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &1864465809 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1864465805} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 8, y: 2, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 227227731} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1877106447 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1877106451} + - component: {fileID: 1877106450} + - component: {fileID: 1877106449} + - component: {fileID: 1877106448} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1877106448 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1877106447} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 9 + gY: 1 + item: {fileID: 0} +--- !u!61 &1877106449 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1877106447} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &1877106450 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1877106447} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &1877106451 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1877106447} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 9, y: 1, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1877946759 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1877946763} + - component: {fileID: 1877946762} + - component: {fileID: 1877946761} + - component: {fileID: 1877946760} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1877946760 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1877946759} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 2 + gY: 4 + item: {fileID: 0} +--- !u!61 &1877946761 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1877946759} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &1877946762 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1877946759} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &1877946763 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1877946759} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 2, y: 4, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1973362467 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1973362471} + - component: {fileID: 1973362470} + - component: {fileID: 1973362469} + - component: {fileID: 1973362468} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1973362468 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1973362467} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 6 + gY: 2 + item: {fileID: 0} +--- !u!61 &1973362469 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1973362467} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &1973362470 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1973362467} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &1973362471 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1973362467} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 6, y: 2, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1987454600 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1987454604} + - component: {fileID: 1987454603} + - component: {fileID: 1987454602} + - component: {fileID: 1987454601} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1987454601 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1987454600} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 9 + gY: 4 + item: {fileID: 0} +--- !u!61 &1987454602 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1987454600} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &1987454603 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1987454600} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &1987454604 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1987454600} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 9, y: 4, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1989871248 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1989871252} + - component: {fileID: 1989871251} + - component: {fileID: 1989871250} + - component: {fileID: 1989871249} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1989871249 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1989871248} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 1 + gY: 6 + item: {fileID: 0} +--- !u!61 &1989871250 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1989871248} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &1989871251 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1989871248} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &1989871252 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1989871248} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 1, y: 6, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &2010821065 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2010821069} + - component: {fileID: 2010821068} + - component: {fileID: 2010821067} + - component: {fileID: 2010821066} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &2010821066 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2010821065} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 4 + gY: 3 + item: {fileID: 0} +--- !u!61 &2010821067 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2010821065} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &2010821068 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2010821065} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &2010821069 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2010821065} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 4, y: 3, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 227227731} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &2028298783 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2028298787} + - component: {fileID: 2028298786} + - component: {fileID: 2028298785} + - component: {fileID: 2028298784} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &2028298784 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2028298783} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 9 + gY: 7 + item: {fileID: 0} +--- !u!61 &2028298785 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2028298783} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &2028298786 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2028298783} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &2028298787 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2028298783} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 9, y: 7, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &2065864009 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2065864012} + - component: {fileID: 2065864011} + - component: {fileID: 2065864010} + m_Layer: 0 + m_Name: EventSystem + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &2065864010 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2065864009} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4f231c4fb786f3946a6b90b886c48677, type: 3} + m_Name: + m_EditorClassIdentifier: + m_SendPointerHoverToParent: 1 + m_HorizontalAxis: Horizontal + m_VerticalAxis: Vertical + m_SubmitButton: Submit + m_CancelButton: Cancel + m_InputActionsPerSecond: 10 + m_RepeatDelay: 0.5 + m_ForceModuleActive: 0 +--- !u!114 &2065864011 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2065864009} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 76c392e42b5098c458856cdf6ecaaaa1, type: 3} + m_Name: + m_EditorClassIdentifier: + m_FirstSelected: {fileID: 0} + m_sendNavigationEvents: 1 + m_DragThreshold: 10 +--- !u!4 &2065864012 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2065864009} + serializedVersion: 2 + 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_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &2066788044 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2066788048} + - component: {fileID: 2066788047} + - component: {fileID: 2066788046} + - component: {fileID: 2066788045} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &2066788045 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2066788044} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 0 + gY: 2 + item: {fileID: 0} +--- !u!61 &2066788046 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2066788044} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &2066788047 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2066788044} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &2066788048 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2066788044} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 2, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 227227731} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &2072603900 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2072603904} + - component: {fileID: 2072603903} + - component: {fileID: 2072603902} + - component: {fileID: 2072603901} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &2072603901 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2072603900} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 9 + gY: 2 + item: {fileID: 0} +--- !u!61 &2072603902 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2072603900} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &2072603903 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2072603900} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &2072603904 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2072603900} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 9, y: 2, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &2094376464 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2094376466} + - component: {fileID: 2094376465} + m_Layer: 0 + m_Name: Map + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &2094376465 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2094376464} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 259f6700ae19ec24b9c6ff11ffa3e706, type: 3} + m_Name: + m_EditorClassIdentifier: + bx: 10 + by: 10 + gridObj: {fileID: 1780511609537152124, guid: d4402c8e0df25cc45ab82ebc85e40539, type: 3} + boxGridParent: {fileID: 741706300} + _boxGridList: + - {fileID: 1557345276} + - {fileID: 1187480670} + - {fileID: 1127444905} + - {fileID: 576798855} + - {fileID: 415259104} + - {fileID: 248607776} + - {fileID: 1074018037} + - {fileID: 839975233} + - {fileID: 1662952242} + - {fileID: 2123764139} + - {fileID: 1146541601} + - {fileID: 1046343795} + - {fileID: 135438562} + - {fileID: 638819638} + - {fileID: 1119295690} + - {fileID: 1367138490} + - {fileID: 1989871249} + - {fileID: 468706808} + - {fileID: 1263211110} + - {fileID: 914503763} + - {fileID: 1511449060} + - {fileID: 1289978610} + - {fileID: 1723035888} + - {fileID: 527332042} + - {fileID: 1877946760} + - {fileID: 1834542157} + - {fileID: 118478191} + - {fileID: 504221597} + - {fileID: 1847432478} + - {fileID: 354415696} + - {fileID: 1833867938} + - {fileID: 672862054} + - {fileID: 770359916} + - {fileID: 289223326} + - {fileID: 1414670424} + - {fileID: 55628960} + - {fileID: 849467721} + - {fileID: 712899307} + - {fileID: 1012752668} + - {fileID: 1629100889} + - {fileID: 412097168} + - {fileID: 929315393} + - {fileID: 167418909} + - {fileID: 268358069} + - {fileID: 665918799} + - {fileID: 1662760821} + - {fileID: 917898906} + - {fileID: 2111485860} + - {fileID: 317378690} + - {fileID: 1845981173} + - {fileID: 300632457} + - {fileID: 55411286} + - {fileID: 344785799} + - {fileID: 455907303} + - {fileID: 1729013580} + - {fileID: 687334423} + - {fileID: 828889405} + - {fileID: 617284287} + - {fileID: 1349777572} + - {fileID: 1570279989} + - {fileID: 1640931054} + - {fileID: 443405376} + - {fileID: 1973362468} + - {fileID: 1840917019} + - {fileID: 1481925007} + - {fileID: 949674232} + - {fileID: 315710860} + - {fileID: 675525382} + - {fileID: 560474323} + - {fileID: 504794857} + - {fileID: 762506054} + - {fileID: 1829541336} + - {fileID: 870421517} + - {fileID: 1667897269} + - {fileID: 1305587183} + - {fileID: 1666690196} + - {fileID: 171658258} + - {fileID: 312972871} + - {fileID: 117781939} + - {fileID: 1315236898} + - {fileID: 228766928} + - {fileID: 160666753} + - {fileID: 657309864} + - {fileID: 1827011607} + - {fileID: 307420394} + - {fileID: 672190467} + - {fileID: 1372805648} + - {fileID: 1117232095} + - {fileID: 1072734473} + - {fileID: 263115406} + - {fileID: 686257694} + - {fileID: 1877106448} + - {fileID: 2072603901} + - {fileID: 626022340} + - {fileID: 1987454601} + - {fileID: 1042635602} + - {fileID: 1283608750} + - {fileID: 2028298784} + - {fileID: 1217401197} + - {fileID: 908631980} + wx: 10 + wy: 4 + waitGridParent: {fileID: 227227731} + _waitGridList: + - {fileID: 463863505} + - {fileID: 1254055759} + - {fileID: 2066788045} + - {fileID: 418818766} + - {fileID: 1691788219} + - {fileID: 1312808997} + - {fileID: 1106532910} + - {fileID: 1461025077} + - {fileID: 1116539345} + - {fileID: 1010204226} + - {fileID: 558298662} + - {fileID: 707261761} + - {fileID: 468497715} + - {fileID: 1034160430} + - {fileID: 1263010894} + - {fileID: 699603239} + - {fileID: 197506415} + - {fileID: 589997592} + - {fileID: 1503093213} + - {fileID: 2010821066} + - {fileID: 88449117} + - {fileID: 983043043} + - {fileID: 1674163524} + - {fileID: 701195474} + - {fileID: 30918324} + - {fileID: 551496419} + - {fileID: 57222200} + - {fileID: 520549983} + - {fileID: 694229260} + - {fileID: 1200390948} + - {fileID: 732359356} + - {fileID: 1334787027} + - {fileID: 545902921} + - {fileID: 1284770391} + - {fileID: 1864465806} + - {fileID: 1079375773} + - {fileID: 237788080} + - {fileID: 3433540} + - {fileID: 630278467} + - {fileID: 1239476989} +--- !u!4 &2094376466 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2094376464} + serializedVersion: 2 + 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_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 741706300} + - {fileID: 227227731} + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &2111485859 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2111485863} + - component: {fileID: 2111485862} + - component: {fileID: 2111485861} + - component: {fileID: 2111485860} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &2111485860 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2111485859} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 4 + gY: 7 + item: {fileID: 0} +--- !u!61 &2111485861 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2111485859} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &2111485862 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2111485859} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &2111485863 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2111485859} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 4, y: 7, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &2123764138 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2123764142} + - component: {fileID: 2123764141} + - component: {fileID: 2123764140} + - component: {fileID: 2123764139} + m_Layer: 0 + m_Name: 9-Sliced(Clone) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &2123764139 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2123764138} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 997b6bf315937d34f85b8fae99501c7b, type: 3} + m_Name: + m_EditorClassIdentifier: + gX: 0 + gY: 9 + item: {fileID: 0} +--- !u!61 &2123764140 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2123764138} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0.25, y: 0.25, z: 0.25, w: 0.25} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 2 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &2123764141 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2123764138} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -5177388603050735206, guid: 8884154dfe85442a3a3578be807dbcdf, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 2 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &2123764142 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2123764138} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 9, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 741706300} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1660057539 &9223372036854775807 +SceneRoots: + m_ObjectHideFlags: 0 + m_Roots: + - {fileID: 519420032} + - {fileID: 619394802} + - {fileID: 1069201192} + - {fileID: 2065864012} + - {fileID: 2094376466} + - {fileID: 1335142274} + - {fileID: 1259872547} + - {fileID: 1520619065} diff --git a/box1/Assets/Script.meta b/box1/Assets/Script.meta new file mode 100644 index 00000000..f503c9b9 --- /dev/null +++ b/box1/Assets/Script.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 98cdf8b2ae98874458f414dceb5a6875 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Script/GameManager.cs b/box1/Assets/Script/GameManager.cs new file mode 100644 index 00000000..9aee3d37 --- /dev/null +++ b/box1/Assets/Script/GameManager.cs @@ -0,0 +1,62 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +public class GameManager : MonoBehaviour +{ + public static GameManager ins; + public Camera mainCamera; + public List itemDatas; + public ItemObj seletObj; + public Grid stopGrid; + private Vector3 oldvec; + [SerializeField] private float scale=0.2f; + private void Awake() + { + ins = this; + } + + private void Start() + { + ItemSystem.ins.InitItem(itemDatas); + } + + private void Update() + { + if (Input.GetMouseButtonDown(0)) + { + oldvec = Input.mousePosition; + } + if (Input.GetMouseButtonUp(0)) + { + if (seletObj==null) + { + return; + } + if (MapManager.ins.openSave(stopGrid,seletObj)) + { + foreach (var grid in seletObj._grids) + { + grid.item = null; + } + + seletObj.startGrid = stopGrid; + ItemSystem.ins.GetGridsRest(seletObj.startGrid, seletObj); + } + ItemSystem.ins.SetPosition(seletObj, seletObj.startGrid); + stopGrid = null; + seletObj = null; + } + if (Input.GetMouseButton(0) && seletObj!=null) + { + Ray ray = mainCamera.ScreenPointToRay(Input.mousePosition); + RaycastHit hit; + //射线检测,第三个参数可根据需求设置或不设置,具体看api; + Physics.Raycast(ray, out hit, 500000); + Vector3 mousePos = hit.point; + seletObj.transform.position = mousePos; + } + + } +} diff --git a/box1/Assets/Script/GameManager.cs.meta b/box1/Assets/Script/GameManager.cs.meta new file mode 100644 index 00000000..6641607f --- /dev/null +++ b/box1/Assets/Script/GameManager.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1cf34d8028049784e83a9be2beb1352f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Script/Item.meta b/box1/Assets/Script/Item.meta new file mode 100644 index 00000000..d5e59bf7 --- /dev/null +++ b/box1/Assets/Script/Item.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: f0589df71210d11449d857f96944010e +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Script/Item/ItemObj.cs b/box1/Assets/Script/Item/ItemObj.cs new file mode 100644 index 00000000..e7aaa43f --- /dev/null +++ b/box1/Assets/Script/Item/ItemObj.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using Unity.VisualScripting; +using UnityEngine; + +public class ItemObj : MonoBehaviour +{ + public ItemSize itemSize => size; + [SerializeField] private ItemSize size; + + [SerializeField] public List _grids; + public Grid startGrid; + public Vector3 dev; + + public void SetOccGrid(List _list) + { + _grids = _list; + } + // Start is called before the first frame update + void Start() + { + + } + + // Update is called once per frame + void Update() + { + + } +} +[Serializable] +public class ItemSize +{ + public int x = 1; + public int y = 1; +} \ No newline at end of file diff --git a/box1/Assets/Script/Item/ItemObj.cs.meta b/box1/Assets/Script/Item/ItemObj.cs.meta new file mode 100644 index 00000000..45d418cb --- /dev/null +++ b/box1/Assets/Script/Item/ItemObj.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d15782fa86faf644f9f08511c76bed3d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Script/ItemSystem.cs b/box1/Assets/Script/ItemSystem.cs new file mode 100644 index 00000000..b893a256 --- /dev/null +++ b/box1/Assets/Script/ItemSystem.cs @@ -0,0 +1,84 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +public class ItemSystem : MonoBehaviour +{ + public static ItemSystem ins; + + private void Awake() + { + ins = this; + } + + public void InitItem(List itemDatas) + { + foreach (var itemData in itemDatas) + { + var obj = Instantiate(itemData.item, transform); + var item = obj.GetComponent(); + SetPosition(item,MapManager.ins.WaitGrids[itemData.x,itemData.y]); + item.startGrid = MapManager.ins.WaitGrids[itemData.x, itemData.y]; + List grids = new List(); + for (var i = itemData.x; i < itemData.x+item.itemSize.x; i++) + { + for (var j = itemData.y; j < itemData.y + item.itemSize.y; j++) + { + MapManager.ins.WaitGrids[i, j].item = item; + grids.Add(MapManager.ins.WaitGrids[i, j]); + } + } + item.SetOccGrid(grids); + } + } + + public void GetGridsRest(Grid grid,ItemObj item) + { + List grids = new List(); + for (int i = grid.X; i < grid.X+item.itemSize.x; i++) + { + for (int j = grid.Y; j < grid.Y+item.itemSize.y; j++) + { + switch (grid.Type) + { + case GridType.box: + grids.Add(MapManager.ins.boxGrid[i, j]); + MapManager.ins.boxGrid[i, j].item = item; + break; + case GridType.wait: + grids.Add(MapManager.ins.WaitGrids[i, j]); + MapManager.ins.WaitGrids[i, j].item = item; + break; + default: + throw new ArgumentOutOfRangeException(); + } + } + } + item.SetOccGrid(grids); + } + + public void SetPosition(ItemObj itemObj, Grid grid) + { + itemObj.transform.position = grid.transform.position + itemObj.dev; + } + + // Start is called before the first frame update + void Start() + { + + } + + // Update is called once per frame + void Update() + { + + } +} +[Serializable] +public class ItemData +{ + public int x = 0; + public int y = 0; + public GameObject item; +} \ No newline at end of file diff --git a/box1/Assets/Script/ItemSystem.cs.meta b/box1/Assets/Script/ItemSystem.cs.meta new file mode 100644 index 00000000..e8d82fae --- /dev/null +++ b/box1/Assets/Script/ItemSystem.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 269571902cab4194b99c8d5b28dcc715 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Script/Map.meta b/box1/Assets/Script/Map.meta new file mode 100644 index 00000000..106b3abd --- /dev/null +++ b/box1/Assets/Script/Map.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 752015f45b463f94aac53aec3752c652 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Script/Map/Grid.cs b/box1/Assets/Script/Map/Grid.cs new file mode 100644 index 00000000..390066c9 --- /dev/null +++ b/box1/Assets/Script/Map/Grid.cs @@ -0,0 +1,50 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.Serialization; + +/// +/// 格子数据 +/// +public class Grid : MonoBehaviour +{ + public GridType Type; + public int X => gX; + [SerializeField] private int gX; + public int Y => gY; + [SerializeField] private int gY; + public ItemObj item; + + public void SetData(int lx,int ly) + { + gX = lx; + gY = ly; + } + + private void OnMouseEnter() + { + GetComponent().color=Color.red; + GameManager.ins.stopGrid = this; + } + + private void OnMouseExit() + { + GetComponent().color = Color.white; + if (GameManager.ins.stopGrid==this) + { + GameManager.ins.stopGrid = null; + } + } + + private void OnMouseDown() + { + GameManager.ins.seletObj = item; + } +} + +public enum GridType +{ + box, + wait +} \ No newline at end of file diff --git a/box1/Assets/Script/Map/Grid.cs.meta b/box1/Assets/Script/Map/Grid.cs.meta new file mode 100644 index 00000000..06c6d584 --- /dev/null +++ b/box1/Assets/Script/Map/Grid.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 997b6bf315937d34f85b8fae99501c7b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Script/Map/MapManager.cs b/box1/Assets/Script/Map/MapManager.cs new file mode 100644 index 00000000..87d7e47d --- /dev/null +++ b/box1/Assets/Script/Map/MapManager.cs @@ -0,0 +1,119 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +public class MapManager : MonoBehaviour +{ + public static MapManager ins; + [SerializeField] private int bx; + [SerializeField] private int by; + [SerializeField] private GameObject gridObj; + [SerializeField] private Transform boxGridParent; + [SerializeField] private List _boxGridList; + [SerializeField] private int wx; + [SerializeField] private int wy; + [SerializeField] private Transform waitGridParent; + [SerializeField] private List _waitGridList; + public Grid[,] boxGrid; + public Grid[,] WaitGrids; + + [InspectorButton("生成地图")] + private void InsMap() + { + for (var i = 0; i < bx; i++) + { + for (var j = 0; j < by; j++) + { + var obj = Instantiate(gridObj, boxGridParent); + obj.transform.localPosition = new Vector3(i, j, 0); + obj.GetComponent().SetData(i,j); + obj.GetComponent().Type=GridType.box; + _boxGridList.Add(obj.GetComponent()); + } + } + + for (var i = 0; i < wx; i++) + { + for (var j = 0; j < wy; j++) + { + var obj = Instantiate(gridObj, waitGridParent); + obj.transform.localPosition = new Vector3(i, j, 0); + obj.GetComponent().SetData(i,j); + obj.GetComponent().Type=GridType.wait; + _waitGridList.Add(obj.GetComponent()); + } + } + } + + private void Awake() + { + ins = this; + boxGrid = new Grid[bx, by]; + foreach (var grid in _boxGridList) + { + boxGrid[grid.X, grid.Y] = grid; + } + WaitGrids = new Grid[wx, wy]; + foreach (var grid in _waitGridList) + { + WaitGrids[grid.X, grid.Y] = grid; + } + } + + public bool openSave(Grid grid,ItemObj itemObj) + { + switch (grid.Type) + { + case GridType.box: + if (grid.X+itemObj.itemSize.x>bx) + { + return false; + } + if (grid.Y+itemObj.itemSize.y>by) + { + return false; + } + for (var i = grid.X; i < grid.X+itemObj.itemSize.x; i++) + { + for (var j = grid.Y; j < grid.Y+itemObj.itemSize.y; j++) + { + if (boxGrid[i,j].item!=null) + { + return false; + } + } + } + + return true; + break; + case GridType.wait: + if (grid.X+itemObj.itemSize.x>wx) + { + return false; + } + + if (grid.Y+itemObj.itemSize.y>wy) + { + return false; + } + for (int i = grid.X; i < grid.X+itemObj.itemSize.x; i++) + { + for (int j = grid.Y; j < grid.Y+itemObj.itemSize.y; j++) + { + if (WaitGrids[i,j].item!=null) + { + return false; + } + } + } + + return true; + break; + default: + throw new ArgumentOutOfRangeException(); + } + + return false; + } +} diff --git a/box1/Assets/Script/Map/MapManager.cs.meta b/box1/Assets/Script/Map/MapManager.cs.meta new file mode 100644 index 00000000..e63b3e5d --- /dev/null +++ b/box1/Assets/Script/Map/MapManager.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 259f6700ae19ec24b9c6ff11ffa3e706 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Script/Tool.meta b/box1/Assets/Script/Tool.meta new file mode 100644 index 00000000..1c4045d1 --- /dev/null +++ b/box1/Assets/Script/Tool.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: c107ca34f204e1648989227c8b50373c +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Script/Tool/InspectorButton.cs b/box1/Assets/Script/Tool/InspectorButton.cs new file mode 100644 index 00000000..a0674457 --- /dev/null +++ b/box1/Assets/Script/Tool/InspectorButton.cs @@ -0,0 +1,63 @@ +using System; +using System.Collections; +using System.Linq; +using System.Reflection; +using UnityEditor; +using UnityEngine; + +[CustomEditor(typeof(MonoBehaviour), true)] +[CanEditMultipleObjects] +public class InspectorButton : Editor +{ + public override void OnInspectorGUI() + { + base.OnInspectorGUI(); + + var mono = target as MonoBehaviour; + if (mono == null) + return; + + var methods = mono.GetType() + .GetMethods( + BindingFlags.Public | BindingFlags.NonPublic | + BindingFlags.Instance | BindingFlags.Static + ).Where(method => + Attribute.IsDefined(method, typeof(InspectorButtonAttribute)) + ).ToArray(); + + foreach (var method in methods) + { + var attr = method.GetCustomAttribute(); + DrawButton(method, attr.Name); + } + } + + private void DrawButton(MethodInfo methodInfo, string methodName) + { + if (string.IsNullOrEmpty(methodName)) + methodName = methodInfo.Name; + + EditorGUILayout.BeginHorizontal(); + + if (GUILayout.Button( + methodName, + GUILayout.ExpandWidth(true) + )) + { + foreach (var targetObj in targets) + { + var mono = targetObj as MonoBehaviour; + if (mono == null) + continue; + + var val = methodInfo.Invoke(mono, new object[] { }); + if (val is IEnumerator coroutine) + mono.StartCoroutine(coroutine); + else if (val != null) + Debug.Log($"{methodName}调用结果: {val}"); + } + } + + EditorGUILayout.EndHorizontal(); + } +} \ No newline at end of file diff --git a/box1/Assets/Script/Tool/InspectorButton.cs.meta b/box1/Assets/Script/Tool/InspectorButton.cs.meta new file mode 100644 index 00000000..05327c11 --- /dev/null +++ b/box1/Assets/Script/Tool/InspectorButton.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9ebbe62bb83f82141a34aeeef4052a8c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Script/Tool/InspectorButtonAttribute.cs b/box1/Assets/Script/Tool/InspectorButtonAttribute.cs new file mode 100644 index 00000000..9d2578c9 --- /dev/null +++ b/box1/Assets/Script/Tool/InspectorButtonAttribute.cs @@ -0,0 +1,16 @@ +using UnityEngine; + +[System.AttributeUsage(System.AttributeTargets.Method)] +public class InspectorButtonAttribute : PropertyAttribute +{ + public readonly string Name; + + public InspectorButtonAttribute() + { + } + + public InspectorButtonAttribute(string name) + { + Name = name; + } +} \ No newline at end of file diff --git a/box1/Assets/Script/Tool/InspectorButtonAttribute.cs.meta b/box1/Assets/Script/Tool/InspectorButtonAttribute.cs.meta new file mode 100644 index 00000000..7e7ad657 --- /dev/null +++ b/box1/Assets/Script/Tool/InspectorButtonAttribute.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 39d98e97145b3eb42ba141705d3b7ec9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Settings/Renderer2D.asset b/box1/Assets/Settings/Renderer2D.asset index 47cf6bdf..7d96dbb1 100644 --- a/box1/Assets/Settings/Renderer2D.asset +++ b/box1/Assets/Settings/Renderer2D.asset @@ -14,6 +14,7 @@ MonoBehaviour: m_EditorClassIdentifier: debugShaders: debugReplacementPS: {fileID: 4800000, guid: cf852408f2e174538bcd9b7fda1c5ae7, type: 3} + hdrDebugViewPS: {fileID: 4800000, guid: 573620ae32aec764abd4d728906d2587, type: 3} m_RendererFeatures: [] m_RendererFeatureMap: m_UseNativeRenderPass: 0 @@ -45,6 +46,8 @@ MonoBehaviour: m_PointLightShader: {fileID: 4800000, guid: e35a31e1679aeff489e202f5cc4853d5, type: 3} m_PointLightVolumeShader: {fileID: 4800000, guid: c7d04ca57e5449d49ad9cee1c604bc26, type: 3} m_CoreBlitShader: {fileID: 4800000, guid: 93446b5c5339d4f00b85c159e1159b7c, type: 3} + m_BlitHDROverlay: {fileID: 4800000, guid: a89bee29cffa951418fc1e2da94d1959, type: 3} + m_CoreBlitColorAndDepthPS: {fileID: 4800000, guid: d104b2fc1ca6445babb8e90b0758136b, type: 3} m_SamplingShader: {fileID: 4800000, guid: 04c410c9937594faa893a11dceb85f7e, type: 3} m_ProjectedShadowShader: {fileID: 4800000, guid: ce09d4a80b88c5a4eb9768fab4f1ee00, type: 3} m_SpriteShadowShader: {fileID: 4800000, guid: 44fc62292b65ab04eabcf310e799ccf6, type: 3} diff --git a/box1/Assets/Spine.meta b/box1/Assets/Spine.meta new file mode 100644 index 00000000..27f26801 --- /dev/null +++ b/box1/Assets/Spine.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 30918bcaadaaecc42bc215ff52f75b21 +folderAsset: yes +timeCreated: 1488288531 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/CHANGELOG.md b/box1/Assets/Spine/CHANGELOG.md new file mode 100644 index 00000000..b55c4a1d --- /dev/null +++ b/box1/Assets/Spine/CHANGELOG.md @@ -0,0 +1,900 @@ +# 3.8 + +## AS3 +* **Breaking changes** + * Renamed `Slot#getAttachmentVertices()` to `Slot#getDeform()`. + * Changed the `.json` curve format and added more assumptions for omitted values, reducing the average size of JSON exports. + * Renamed `Skin#addAttachment()` to `Skin#setAttachment()`. + * Removed `VertexAttachment#applyDeform()` and replaced it with `VertexAttachment#deformAttachment`. The attachment set on this field is used to decide if a `DeformTimeline` should be applied to the attachment active on the slot to which the timeline is applied. + * Removed `inheritDeform` field, getter, and setter from `MeshAttachment`. + * Changed `.skel` binary format, added a string table. References to strings in the data resolve to this string table, reducing storage size of binary files considerably. + * Changed the `.json` and `.skel` file formats to accomodate the new feature and file size optimiations. Old projects must be exported with Spine 3.8.20+ to be compatible with the 3.8 Spine runtimes. + * Switched projects from FDT to Visual Studio Code. See updated `README.md` files for instructions. + +* **Additions** + * Added `SkeletonBinary` to load binary `.skel` files. See `MixAndMatchExample.as` in `spine-startling-example`. + * Added `x` and `y` coordinates for setup pose AABB in `SkeletonData`. + * Added support for rotated mesh region UVs. + * Added skin-specific bones and constraints which are only updated if the skeleton's current skin contains them. + * Improved Skin API to make it easier to handle mix-and-match use cases. + * Added `Skin#getAttachments()`. Returns all attachments in the skin. + * Added `Skin#getAttachments(int slotIndex)`. Returns all attachements in the skin for the given slot index. + * Added `Skin#addSkin(Skin skin)`. Adds all attachments, bones, and skins from the specified skin to this skin. + * Added `Skin#copySkin(Skin skin)`. Adds all attachments, bones, and skins from the specified skin to this skin. `VertexAttachment` are shallowly copied and will retain any parent mesh relationship. All other attachment types are deep copied. + * Added `Attachment#copy()` to all attachment type implementations. This lets you deep copy an attachment to modify it independently from the original, i.e. when programmatically changing texture coordinates or mesh vertices. + * Added `MeshAttachment#newLinkedMesh()`, creates a linked mesh linkted to either the original mesh, or the parent of the original mesh. + * Added IK softness. + +### Starling +* Added `MixAndMatchExample.as` to demonstrate the new Skin API additions and how to load binary `.skel` files. +* Switched projects from FDT to Visual Studio Code. See updated `README.md` files for instructions. + +## C +* **Breaking changes** + * Renamed `spSlot#attachmentVertices` to `spSlot#deform`. + * Changed the `.json` curve format and added more assumptions for omitted values, reducing the average size of JSON exports. + * Renamed `spSkin_addAttachment()` to `Skin#spSkin_addAttachment()`. + * Removed `spVertexAttachment_applyDeform()` and replaced it with `VertexAttachment#deformAttachment`. The attachment set on this field is used to decide if a `spDeformTimeline` should be applied to the attachment active on the slot to which the timeline is applied. + * Removed `inheritDeform` field, getter, and setter from `spMeshAttachment`. + * Changed `.skel` binary format, added a string table. References to strings in the data resolve to this string table, reducing storage size of binary files considerably. + * Changed the `.json` and `.skel` file formats to accomodate the new feature and file size optimiations. Old projects must be exported with Spine 3.8.20+ to be compatible with the 3.8 Spine runtimes. + +* **Additions** + * Added `x` and `y` coordinates for setup pose AABB in `spSkeletonData`. + * Added support for rotated mesh region UVs. + * Added skin-specific bones and constraints which are only updated if the skeleton's current skin contains them. + * Improved Skin API to make it easier to handle mix-and-match use cases. + * Added `spSkin_getAttachments()`. Returns all attachments in the skin. + * Added `spSkin_getAttachments(int slotIndex)`. Returns all attachements in the skin for the given slot index. + * Added `spSkin_addSkin(spSkin* skin)`. Adds all attachments, bones, and skins from the specified skin to this skin. + * Added `spSkin_copySkin(spSkin* skin)`. Adds all attachments, bones, and skins from the specified skin to this skin. `spVertexAttachment` are shallowly copied and will retain any parent mesh relationship. All other attachment types are deep copied. + * All attachments inserted into skins are reference counted. When the last skin referencing an attachment is disposed, the attachment will also be disposed. + * Added `spAttachment_copy()` to all attachment type implementations. This lets you deep copy an attachment to modify it independently from the original, i.e. when programmatically changing texture coordinates or mesh vertices. + * Added `spMeshAttachment_newLinkedMesh()`, creates a linked mesh linkted to either the original mesh, or the parent of the original mesh. + * Added IK softness. + +### Cocos2d-Objc +* Added mix-and-match example to demonstrate the new Skin API. +* Added `IKExample`. +* Added `SkeletonAnimation preUpdateWorldTransformsListener` and `SkeletonAnimation postUpdateWorldTransformsListener`. When set, these callbacks will be invokved before and after the skeleton's `updateWorldTransforms()` method is called. See the `IKExample` how it can be used. + +### SFML +* Added mix-and-match example to demonstrate the new Skin API. +* Added `IKExample`. + +## C++ +* **Breaking Changes** + * Renamed `Slot::getAttachmentVertices()` to `Slot::getDeform()`. + * Changed the `.json` curve format and added more assumptions for omitted values, reducing the average size of JSON exports. + * Renamed `Skin::addAttachment()` to `Skin::setAttachment()`. + * Removed `VertexAttachment::applyDeform()` and replaced it with `VertexAttachment::getDeformAttachment()`. The attachment set on this field is used to decide if a `DeformTimeline` should be applied to the attachment active on the slot to which the timeline is applied. + * Removed `_inheritDeform` field, getter, and setter from `MeshAttachment`. + * Changed `.skel` binary format, added a string table. References to strings in the data resolve to this string table, reducing storage size of binary files considerably. + * Changed the `.json` and `.skel` file formats to accomodate the new feature and file size optimiations. Old projects must be exported with Spine 3.8.20+ to be compatible with the 3.8 Spine runtimes. + +* **Additions** + * `AnimationState` and `TrackEntry` now also accept a subclass of `AnimationStateListenerObject` as a listener for animation events in the overloaded `setListener()` method. + * `SkeletonBinary` and `SkeletonJson` now parse and set all non-essential data like audio path. + * Added `x` and `y` coordinates for setup pose AABB in `SkeletonData`. + * Added support for rotated mesh region UVs. + * Added skin-specific bones and constraints which are only updated if the skeleton's current skin contains them. + * Improved Skin API to make it easier to handle mix-and-match use cases. + * Added `Skin#getAttachments()`. Returns all attachments in the skin. + * Added `Skin#getAttachments(int slotIndex)`. Returns all attachements in the skin for the given slot index. + * Added `Skin#addSkin(Skin &skin)`. Adds all attachments, bones, and skins from the specified skin to this skin. + * Added `Skin#copySkin(Skin &skin)`. Adds all attachments, bones, and skins from the specified skin to this skin. `VertexAttachment` are shallowly copied and will retain any parent mesh relationship. All other attachment types are deep copied. + * All attachments inserted into skins are reference counted. When the last skin referencing an attachment is disposed, the attachment will also be disposed. + * Added `Attachment#copy()` to all attachment type implementations. This lets you deep copy an attachment to modify it independently from the original, i.e. when programmatically changing texture coordinates or mesh vertices. + * Added `MeshAttachment#newLinkedMesh()`, creates a linked mesh linkted to either the original mesh, or the parent of the original mesh. + * Added IK softness. + * Exposed `x` and `y` on `SkeletonData` through getters and setters. + +### Cocos2d-x +* Updated to cocos2d-x 3.17.1 +* Added mix-and-match example to demonstrate the new Skin API. +* Exmaple project requires Visual Studio 2019 on Windows +* Added `IKExample`. +* Added `SkeletonAnimation::setPreUpdateWorldTransformsListener()` and `SkeletonAnimation::setPreUpdateWorldTransformsListener()`. When set, these callbacks will be invokved before and after the skeleton's `updateWorldTransforms()` method is called. See the `IKExample` how it can be used. + +### SFML +* Added mix-and-match example to demonstrate the new Skin API. + +### UE4 +* Added `bAutoPlaying` flag to `USpineSkeletonAnimationComponent`. When `false`, the component will not update the internal animation state and skeleton. +* Updated example project to UE 4.22. +* (Re-)Importing Spine assets will perform a version compatibility check and alert users about mismatches in editor mode. +* `USpineSkeletonRendererComponent` allows passing a `USpineSkeletonComponent` to update it. This way, the renderer component can be used without a skeleton component on the same actor. +* Added blueprint-callable methods to `SpineSkeletonComponent` and `SpineSkeletonAnimationComponent` to query and set skins, and enumerate bones, slots, and animations. +* Extended skeleton data editor preview. The preview now shows bones, slots, animations, and skins found in the skeleton data. See this [blog post](http://esotericsoftware.com/blog/Unreal-Engine-4-quality-of-life-improvements). +* Added preview animation and skin fields, allowing you to preview animations and skins right in the editor. See this [blog post](http://esotericsoftware.com/blog/Unreal-Engine-4-quality-of-life-improvements). +* Removed dependency on `RHI`, `RenderCore`, and `ShaderCore`. +* Re-importing atlases and their textures now works consistently in all situations. +* Added mix-and-match example to demonstrate the new Skin API. +* Materials on `SkeletonRendererComponent` are now blueprint read and writeable. This allows setting dynamic material instances at runtime + +## C# ## +* **Breaking changes** + * **Changed `IkConstraintData.Bones` type from `List` to `ExposedList`** for unification reasons. *Note: this modification will most likely not affect user code.* + * Renamed `Slot.AttachmentVertices` to `Slot.Deform`. + * Changed the `.json` curve format and added more assumptions for omitted values, reducing the average size of JSON exports. + * Renamed `Skin.AddAttachment()` to `Skin.SetAttachment()`. + * Removed `FindAttachmentsForSlot(int slotIndex, List attachments)` and `FindNamesForSlot (int slotIndex, List names)` and replaced it with `Skin.GetAttachments(int slotIndex, List attachments)` which returns the combined `SkinEntry` object holding both name and attachment. + * Removed `VertexAttachment.ApplyDeform()` and replaced it with `VertexAttachment.DeformAttachment`. The attachment set on this field is used to decide if a `DeformTimeline` should be applied to the attachment active on the slot to which the timeline is applied. + * Removed `inheritDeform` field, getter, and setter from `MeshAttachment`. + * Changed `.skel` binary format, added a string table. References to strings in the data resolve to this string table, reducing storage size of binary files considerably. + * Changed the `.json` and `.skel` file formats to accomodate the new feature and file size optimiations. Old projects must be exported with Spine 3.8.20+ to be compatible with the 3.8 Spine runtimes. + +* **Additions** + * Added `x` and `y` coordinates for setup pose AABB in `SkeletonData`. + * Added support for rotated mesh region UVs. + * Added skin-specific bones and constraints which are only updated if the skeleton's current skin contains them. + * Improved Skin API to make it easier to handle mix-and-match use cases. + * Added `Skin.GetAttachments()`. Returns all attachments in the skin. + * Added `Skin.GetAttachments(int slotIndex, List attachments)`. Returns all attachements in the skin for the given slot index. This method replaces `FindAttachmentsForSlot` and `FindNamesForSlot`. + * Added `Skin.AddSkin(Skin skin)`. Adds all attachments, bones, and skins from the specified skin to this skin. + * Added `Skin.CopySkin(Skin skin)`. Adds all attachments, bones, and skins from the specified skin to this skin. `VertexAttachment` are shallowly copied and will retain any parent mesh relationship. All other attachment types are deep copied. + * Added `Attachment.Copy()` to all attachment type implementations. This lets you deep copy an attachment to modify it independently from the original, i.e. when programmatically changing texture coordinates or mesh vertices. + * Added `MeshAttachment.NewLinkedMesh()`, creates a linked mesh linkted to either the original mesh, or the parent of the original mesh. + * Added IK softness. + +### Unity + +* **Breaking changes** + * **Officially supported Unity versions are 2017.1-2019.4**. + * **Spine `.asmdef` files are again active by default**. They have previously been deactivated to `.txt` extension which is now no longer necessary. + * **Removed PoseSkeleton() and PoseWithAnimation()** extension methods to prevent issues where animations are not mixed out. Problem was that these methods did not set AnimationState, leaving incorrect state at e.g. attachments enabled at slots when starting subsequent animations. As a replacement you can use `AnimationState.ClearTrack(0);` followed by `var entry = AnimationState.SetAnimation(0, animation, loop); entry.TrackTime = time` to achieve similar behaviour. + * **The `Shadow alpha cutoff` shader parameter is now respecting slot-color alpha** values at all Spine shaders. A fragment's texture color alpha is multiplied with slot-color alpha before the result is tested against the `Shadow alpha cutoff` threshold. + * **Removed redundant `Attachment.GetClone()` and `MeshAttachment.GetLinkedClone()` extension methods**. Use methods `Attachment.Copy` and `MeshAttachment.NewLinkedMesh()` instead. + * **Renamed extension method `Attachment.GetClone(bool cloneMeshesAsLinked)` to `Attachment.GetCopy(bool cloneMeshesAsLinked)`** to follow the naming scheme of the Spine API. + * `SkeletonDataAsset.atlasAssets` is now an array of the base class `AtlasAssetBase` instead of `SpineAtlasAsset`, which provides `IEnumerable<> Materials` instead of `List<> materials`. Replace any access via `atlasAsset.materials[0]` with `atlasAsset.Materials.First()` and add a `using System.Linq;` statement. + * **Changed `MeshAttachment.GetLinkedMesh()` method signatures:** removed optional parameters `bool inheritDeform = true, bool copyOriginalProperties = false`. + * Changed namespace `Spine.Unity.Modules` to `Spine.Unity` and `Spine.Unity.Examples` after restructuring (see section below) in respective classes: + * When receiving namespace related errors, replace using statements of `using Spine.Unity.Modules.AttachmentTools;` with `using Spine.Unity.AttachmentTools;`. You can remove `using Spine.Unity.Modules;` statements when a `using Spine.Unity` statement is already present in the file. + * `AttachmentTools`, `SkeletonPartsRenderer`, `SkeletonRenderSeparator`, `SkeletonRendererCustomMaterials` changed to namespace `Spine.Unity`. + * `SkeletonGhost`, `SkeletonGhostRenderer`, `AtlasRegionAttacher`, `SkeletonGraphicMirror`, `SkeletonRagdoll`, `SkeletonRagdoll2D`, `SkeletonUtilityEyeConstraint`, `SkeletonUtilityGroundConstraint`, `SkeletonUtilityKinematicShadow` changed to namespace `Spine.Unity.Examples`. + * Split `Editor/Utility/SpineEditorUtilities` class into multiple files with partial class qualifier. + * Nested classes `SpineEditorUtilities.AssetUtility` and `SpineEditorUtilities.EditorInstantiation` are now no longer nested. If you receive namespace related errors, replace any occurrance of + * `SpineEditorUtilities.AssetUtility` with `AssetUtility` and + * `SpineEditorUtilities.EditorInstantiation` with `EditorInstantiation`. + * **Timeline Support has been moved to a separate UPM Package** Previously the Spine Timeline integration was located in the `Modules/Timeline` directory and was deactivated by default, making it necessary to activate it via the Spine Preferences. Now the Timeline integration has been moved to an additional UPM package which can be found under `Modules/com.esotericsoftware.spine.timeline`. + * **Installation:** You can download the Unity Package Manager (UPM) package via the [download page](http://esotericsoftware.com/spine-unity-download) or find it in the [spine-runtimes/spine-unity/Modules](https://github.com/EsotericSoftware/spine-runtimes/tree/3.8-beta/spine-unity/Modules) subdirectory on the git repository. You can then either unzip (copy if using git) the package to + a) the `Packages` directory in your project where it will automatically be loaded, or + b) to an arbitrary directory outside the Assets directory and then open Package Manager in Unity, select the `+` icon, choose `Add package from disk..` and point it to the package.json file. + The Project panel should now show an entry `Spine Timeline Extensions` under `Packages`. If the directory is not yet listed, you will need to close and re-open Unity to have it display the directory and its contents. + * `SkeletonMecanim`'s `Layer Mix Mode` enum name `MixMode.SpineStyle` has been renamed to `MixMode.Hard`. This is most likely not set via code and thus unlikely to be a problem. Serialized scenes and prefabs are unaffected. + +* **Additions** + * **Spine Preferences stored in Assets/Editor/SpineSettings.asset** Now Spine uses the new `SettingsProvider` API, storing settings in a SpineSettings.asset file which can be shared with team members. Your old preferences are automatically migrated to the new system. + * Added support for Unity's SpriteMask to `SkeletonAnimation` and `SkeletonMecanim`. All mask interaction modes are supported. See this [blog post](http://esotericsoftware.com/blog/Unity-SpriteMask-and-RectMask2D-support). + * Added support for Unity's RectMask2D to SkeletonGraphics. See this [blog post](http://esotericsoftware.com/blog/Unity-SpriteMask-and-RectMask2D-support). + * Added `Create 2D Hinge Chain` button at `SkeletonUtilityBone` inspector, previously only `Create 3D Hinge Chain` was available. + * **Now supporting Lightweight Render Pipeline (LWRP) through an additional UPM package.** + * **Installation:** You can download the Unity Package Manager (UPM) package via the [download page](http://esotericsoftware.com/spine-unity-download) or find it in the [spine-runtimes/spine-unity/Modules](https://github.com/EsotericSoftware/spine-runtimes/tree/3.8-beta/spine-unity/Modules) subdirectory on the git repository. You can then either unzip (copy if using git) the package to + * a) the `Packages` directory in your project where it will automatically be loaded, or + * b) to an arbitrary directory outside the Assets directory and then open Package Manager in Unity, select the `+` icon, choose `Add package from disk..` and point it to the package.json file. + + > If you are using git and Unity 2019.2 or newer versions and receive an error that dependencies could not be resolved by the package manager (only higher versions of Unity's `Lightweight RP` package are available, e.g. `6.9.0` and up), please copy the prepared package-UNITYVERSION.json file for your Unity version (e.g. `package-2019.2.json`) over the existing package.json file to change the dependency accordingly. Unfortunately Unity's Package Manager does not provide a way to specify a version range for a dependency like "5.7.2 - 6.9.0" yet, so this manual step is necessary for git users. + + The Project panel should now show an entry `Spine Lightweight RP Shaders` under `Packages`. If the directory is not yet listed, you will need to close and re-open Unity to have it display the directory and its contents. + * **Usage:** The package provides two shaders specifically built for the lightweight render pipeline: + * `Lightweight Render Pipeline/Spine/Skeleton`, as a lightweight variant of the `Spine/Skeleton` shader, + * `Lightweight Render Pipeline/Spine/Skeleton Lit`, as a lightweight variant of the `Spine/Skeleton Lit` shader and + * `Lightweight Render Pipeline/Spine/Sprite`, as a lightweight variant of the `Spine/Sprite/Vertex Lit` and `Pixel Lit` shaders, which were not functioning in the lightweight render pipeline. The shaders can be assigned to materials as usual and will respect your settings of the assigned `LightweightRenderPipelineAsset` under `Project Settings - Graphics`. + * **Restrictions** As all Spine shaders, the LWRP shaders **do not support `Premultiply alpha` (PMA) atlas textures in Linear color space**. Please export your atlas textures as `straight alpha` textures with disabled `Premultiply alpha` setting when using Linear color space. You can check the current color space via `Project Settings - Player - Other Settings - Color Space.`. + * **Example:** You can find an example scene in the package under `com.esotericsoftware.spine.lwrp-shaders-3.8/Examples/LWRP Shaders.unity` that demonstrates usage of the LWRP shaders. + * Added `Spine/Skeleton Lit ZWrite` shader. This variant of the `Spine/Skeleton Lit` shader writes to the depth buffer with configurable depth alpha threshold. Apart from that it is identical to `Spine/Skeleton Lit`. + * Additional yield instructions to wait for animation track events `End`, `Complete` and `Interrupt`. + * `WaitForSpineAnimationComplete` now proves an additional `bool includeEndEvent` parameter, defaults to `false` (previous behaviour). + * Added a new `WaitForSpineAnimationEnd` yield instruction. + * Added a new generic `WaitForSpineAnimation` yield instruction which can be configured to wait for any combination of animation track events. It is now used as base class for `WaitForSpineAnimationComplete` and `WaitForSpineAnimationEnd`. + * Additional **Fix Draw Order** parameter at SkeletonRenderer, defaults to `disabled` (previous behaviour). + Applies only when 3+ submeshes are used (2+ materials with alternating order, e.g. "A B A"). + If true, MaterialPropertyBlocks are assigned at each material to prevent aggressive batching of submeshes + by e.g. the LWRP renderer, leading to incorrect draw order (e.g. "A1 B A2" changed to "A1A2 B"). + You can leave this parameter disabled when everything is drawn correctly to save the additional performance cost. + * **Additional Timeline features.** SpineAnimationStateClip now provides a `Speed Multiplier`, a start time offset parameter `Clip In`, support for blending successive animations by overlapping tracks. An additional `Use Blend Duration` parameter *(defaults to true)* allows for automatic synchronisation of MixDuration with the current overlap blend duration. An additional Spine preferences parameter `Use Blend Duration` has been added which can be disabled to default to the previous behaviour before this update. + * Additional `SpriteMask and RectMask2D` example scene added for demonstration of mask setup and interaction. + * `Real physics hinge chains` for both 2D and 3D physics. The [SkeletonUtilityBone](http://esotericsoftware.com/spine-unity#SkeletonUtilityBone) Inspector provides an interface to create 2D and 3D hinge chains. Previously created chains have only been respecting gravity, but not momentum of the skeleton or parent bones. The new physics rig created when pressing `Create 3D Hinge Chain` and `Create 2D Hinge Chain` creates a more complex setup that also works when flipping the skeleton. Note that the chain root node is no longer parented to bones of the skeleton. This is a requirement in Unity to have momentum applied properly - do not reparent the chain root to bones of your skeleton, or you will loose any momentum applied by the skeleton's movement. + * `Outline rendering functionality for all shaders.` Every shader now provides an additional set of `Outline` parameters to enable custom outline rendering. When outline rendering is enabled via the `Material` inspector, it automatically switches the shader to the respective `Spine/Outline` shader variant. Outlines are generated by sampling neighbour pixels, so be sure to add enough transparent padding when exporting your atlas textures to fit the desired outline width. In order to enable outline rendering at a skeleton, it is recommended to first prepare an additional outline material copy and then switch the material of the target skeleton to this material. This prevents unnecessary additional runtime material copies and drawcalls. Material switching can be prepared via a [SkeletonRendererCustomMaterials](http://esotericsoftware.com/spine-unity#SkeletonRendererCustomMaterials) component and then enabled or disabled at runtime. Alternatively, you can also directly modify the `SkeletonRenderer.CustomMaterialOverride` property. + Outline rendering is fully supported on `SkeletonGraphic` shaders as well. + * Added `SkeletonRenderer.EditorSkipSkinSync` scripting API property to be able to set custom skins in editor scripts. Enable this property when overwriting the Skeleton's skin from an editor script. Without setting this parameter, changes will be overwritten by the next inspector update. Only affects Inspector synchronisation of skin with `initialSkinName`, not startup initialization. + * All `Spine/SkeletonGraphic` shaders now provide a parameter `CanvasGroup Compatible` which can be enabled to support `CanvasGroup` alpha blending. For correct results, you should then disable `Pma Vertex Colors` in the `SkeletonGraphic` Inspector, in section `Advanced` (otherwise Slot alpha will be applied twice). + * **Now supporting Universal Render Pipeline (URP), including the 2D Renderer pipeline, through an additional UPM package.** + * **Installation:** You can download the Unity Package Manager (UPM) package via the [download page](http://esotericsoftware.com/spine-unity-download) or find it in the [spine-runtimes/spine-unity/Modules](https://github.com/EsotericSoftware/spine-runtimes/tree/3.8-beta/spine-unity/Modules) subdirectory on the git repository. You can then either unzip (copy if using git) the package to + * a) the `Packages` directory in your project where it will automatically be loaded, or + * b) to an arbitrary directory outside the Assets directory and then open Package Manager in Unity, select the `+` icon, choose `Add package from disk..` and point it to the package.json file. + + The Project panel should now show an entry `Spine Universal RP Shaders` under `Packages`. If the directory is not yet listed, you will need to close and re-open Unity to have it display the directory and its contents. + * **Usage:** The package provides two shaders specifically built for the universal render pipeline: + * `Universal Render Pipeline/Spine/Skeleton`, as a universal variant of the `Spine/Skeleton` shader, + * `Universal Render Pipeline/Spine/Skeleton Lit`, as a universal variant of the `Spine/Skeleton Lit` shader, + * `Universal Render Pipeline/Spine/Sprite`, as a universal variant of the `Spine/Sprite/Vertex Lit` and `Pixel Lit` shaders, which were not functioning in the universal render pipeline, + * `Universal Render Pipeline/2D/Spine/Skeleton Lit`, as a universal 2D Renderer variant of the `Spine/Skeleton Lit` shader, and + * `Universal Render Pipeline/2D/Spine/Sprite`, as a universal 2D Renderer variant of the `Spine/Sprite/Vertex Lit` and `Pixel Lit` shaders. + The shaders can be assigned to materials as usual and will respect your settings of the assigned `UniversalRenderPipelineAsset` under `Project Settings - Graphics`. + * **Restrictions** As all Spine shaders, the URP shaders **do not support `Premultiply alpha` (PMA) atlas textures in Linear color space**. Please export your atlas textures as `straight alpha` textures with disabled `Premultiply alpha` setting when using Linear color space. You can check the current color space via `Project Settings - Player - Other Settings - Color Space.`. + * **Example:** You can find an example scene in the package under `com.esotericsoftware.spine.urp-shaders-3.8/Examples/URP Shaders.unity` that demonstrates usage of the URP shaders. + * Spine Preferences now provide an **`Atlas Texture Settings`** parameter for applying customizable texture import settings at all newly imported Spine atlas textures. + When exporting atlas textures from Spine with `Premultiply alpha` enabled (the default), you can leave it at `PMATexturePreset`. If you have disabled `Premultiply alpha`, set it to the included `StraightAlphaTexturePreset` asset. You can also create your own `TextureImporter` `Preset` asset and assign it here (include `PMA` or `Straight` in the name). In Unity versions before 2018.3 you can use `Texture2D` template assets instead of the newer `Preset` assets. Materials created for imported textures will also have the `Straight Alpha Texture` parameter configured accordingly. + * All `Sprite` shaders (including URP and LWRP extension packages) now provide an additional `Fixed Normal Space` option `World-Space`. PReviously options were limited to `View-Space` and `Model-Space`. + * `SkeletonGraphic` now fully supports [`SkeletonUtility`](http://esotericsoftware.com/spine-unity#SkeletonUtility) for generating a hierarchy of [`SkeletonUtilityBones`](http://esotericsoftware.com/spine-unity#SkeletonUtilityBone) in both modes `Follow` and `Override`. This also enables creating hinge chain physics rigs and using `SkeletonUtilityConstraints` such as `SkeletonUtilityGroundConstraint` and `SkeletonUtilityEyeConstraint` on `SkeletonGraphic`. + * Added `OnMeshAndMaterialsUpdated` callback event to `SkeletonRenderer` and `SkeletonGraphic`. It is issued at the end of `LateUpdate`, before rendering. + * Added `Skeleton-OutlineOnly` single pass shader to LWRP and URP extension modules. It can be assigned to materials as `Universal Render Pipeline/Spine/Outline/Skeleton-OutlineOnly`. This allows for separate outline child *GameObjects* that reference the existing Mesh of their parent, and re-draw the mesh using this outline shader. + * Added example component `RenderExistingMesh` to render a mesh again with different materials, as required by the new `Skeleton-OutlineOnly` shaders. + In URP the outline has to be rendered via a separate GameObject as URP does not allow multiple render passes. To add an outline to your SkeletenRenderer: + 1) Add a child GameObject and move it a bit back (e.g. position Z = 0.01). + 2) Add a `RenderExistingMesh` component, provided in the `Spine Examples/Scripts/Sample Components` directory. + 3) Copy the original material, add *_Outline* to its name and set the shader to `Universal Render Pipeline/Spine/Outline/Skeleton-OutlineOnly`. + 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. + * Added **Root Motion support** for `SkeletonAnimation`, `SkeletonMecanim` and `SkeletonGraphic` via new components `SkeletonRootMotion` and `SkeletonMecanimRootMotion`. The `SkeletonAnimation` and `SkeletonGraphic` component Inspector now provides a line `Root Motion` with `Add Component` and `Remove Component` buttons to add/remove the new `SkeletonRootMotion` component to your GameObject. The `SkeletonMecanim` Inspector detects whether root motion is enabled at the `Animator` component and adds a `SkeletonMecanimRootMotion` component automatically. + * `SkeletonMecanim` now provides an additional `Custom MixMode` parameter under `Mecanim Translator`. It is enabled by default in version 3.8 to maintain current behaviour, using the set `Mix Mode` for each Mecanim layer. When disabled, `SkeletonMecanim` will use the recommended `MixMode` according to the layer blend mode. Additional information can be found in the [Mecanim Translator section](http://esotericsoftware.com/spine-unity#Parameters-for-animation-blending-control) on the spine-unity documentation pages. + * Added **SkeletonGraphic Timeline support**. Added supprot for multi-track Timeline preview in the Editor outside of play mode (multi-track scrubbing). See the [Timeline-Extension-UPM-Package](http://esotericsoftware.com/spine-unity#Timeline-Extension-UPM-Package) section of the spine-unity documentation for more information. + * Added support for double-sided lighting at all `SkeletonLit` shaders (including URP and LWRP packages). + * Added frustum culling update mode parameters `Update When Invisible` (Inspector parameter) and `UpdateMode` (available via code) to all Skeleton components. This provides a simple way to disable certain updates when the `Renderer` is no longer visible (outside all cameras, culled in frustum culling). The new `UpdateMode` property allows disabling updates at a finer granularity level than disabling the whole component. Available modes are: `Nothing`, `OnlyAnimationStatus`, `EverythingExceptMesh` and `FullUpdate`. + * Added a new `Spine/Outline/OutlineOnly-ZWrite` shader to provide correct outline-only rendering. Note: the shader requires two render passes and is therefore not compatible with URP. The `Spine Examples/Other Examples/Outline Shaders` example scene has been updated to demonstrate the new shader. + * Added `OnMeshAndMaterialsUpdated` callback event to `SkeletonRenderSeparator` and `SkeletonPartsRenderer`. It is issued at the end of `LateUpdate`, before rendering. + * Added `Root Motion Scale X/Y` parameters to `SkeletonRootMotionBase` subclasses (`SkeletonRootMotion` and `SkeletonMecanimRootMotion`). Also providing `AdjustRootMotionToDistance()` and other methods to allow for easy delta compensation. Delta compensation can be used to e.g. stretch a jump to a given distance. Root motion can be adjusted at the start of an animation or every frame via `skeletonRootMotion.AdjustRootMotionToDistance(targetPosition - transform.position, trackIndex);`. + * Now providing a `Canvas Group Tint Black` parameter a `SkeletonGraphic` Inspector in the `Advanced` section. Enable when using Additive blend mode at SkeletonGraphic under a CanvasGroup. Be sure to also have the parameter `CanvasGroup Compatible` enabled at the shader. + +* **Changes of default values** + * `SkeletonMecanim`'s `Layer Mix Mode` now defaults to `MixMode.MixNext` instead of `MixMode.MixAlways`. + * `BlendModeMaterialAsset` and it's instance `Default BlendModeMaterials.asset` now have `Apply Additive Material` set to `true` by default in order to apply all blend modes by default. + +* **Deprecated** + * Deprecated `Modules/SlotBlendModes/SlotBlendModes` component. Changed namespace from `Spine.Unity.Modules` to `Spine.Unity.Deprecated`. Moved to `Deprecated/SlotBlendModes`. + +* **Restructuring (Non-Breaking)** + + Note: The following changes will most likely not affect users of the Spine-Unity runtime as the API remains unchanged and no references are invalidated. + * Removed duplicates of `.cginc` files in `Modules/Shaders/Sprite` that were also present in the `Modules/Shaders/Sprite/CGIncludes` directory. + * Moved shaders from `Modules/Shaders` to `Shaders` directory. + * Moved shaders from `Modules/SkeletonGraphic/Shaders` to `Shaders/SkeletonGraphic`. + * Renamed shader `Shaders/Spine-SkeletonLit.shader` to `Shaders/Spine-Skeleton-Lit.shader`. + * Moved components from `SkeletonGraphic` to `Components` and `Components/Following` except for `SkeletonGraphicMirror` which was moved to `Spine Examples/Scripts/Sample Components`. + * Moved `BoneFollower`, `BoneFollowerGraphic` and `PointFollower` from `Components` directory to `Components/Following`. + * Moved `BoundingBoxFollower` component from `Modules/BoundingBoxFollower` to `Components/Following`. + * Moved `Modules/SkeletonRenderSeparator` directory to `Components/SkeletonRenderSeparator`. + * Moved `Modules/CustomMaterials` directory to `Components/SkeletonRendererCustomMaterials`. + * Moved `Asset Types/BlendModeMaterialsAsset.cs` class, `Shaders/BlendModes/Default BlendModeMaterials.asset` and materials from `Shaders/BlendModes` to `SkeletonDataModifierAssets/BlendModeMaterials` directory. + * Moved `Modules/Ghost` directory to `Spine Examples/Scripts/Sample Components/Ghost`. + * Moved `Modules/SkeletonUtility Modules` directory to `Spine Examples/Scripts/Sample Components/SkeletonUtility Modules`. + * Moved `Modules/AnimationMatchModifier` directory to `Spine Examples/Scripts/MecanimAnimationMatchModifier`. + * Moved `SkeletonRagdoll` and `SkeletonRagdoll2D` components from `Modules/Ragdoll` directory to `Spine Examples/Scripts/Sample Components/SkeletonUtility Modules`. + * Moved `AttachmentTools.cs` to `Utility` directory. + * Split the file `AttachmentTools` into 5 separate files for each contained class. No namespace or other API changes performed. + * Split the file `Mesh Generation/SpineMesh` into 4 separate files for each contained class. No namespace or other API changes performed. + * Moved `SkeletonExtensions.cs` to `Utility` directory. + * Moved `Modules/YieldInstructions` directory to `Utility/YieldInstructions`. + * Moved corresponding editor scripts of the above components to restructured directories as well. + * Renamed inspector editor class `PointFollowerEditor` to `PointFollowerInspector` for consistency reasons. + +### XNA/MonoGame +* Updated to latest MonoGame version 3.7.1 +* Rewrote example project to be cleaner and better demonstrate basic Spine features. +* Added mix-and-match example to demonstrate the new Skin API. +* Added normalmap support via `SpineEffectNormalmap` and support for loading multiple texture layers following a suffix-pattern. Please see the example code on how to use them. + +## Java +* **Breaking changes** + * Renamed `Slot#getAttachmentVertices()` to `Slot#getDeform()`. + * Changed the `.json` curve format and added more assumptions for omitted values, reducing the average size of JSON exports. + * Renamed `Skin#addAttachment()` to `Skin#setAttachment()`. + * Removed `VertexAttachment#applyDeform()` and replaced it with `VertexAttachment#deformAttachment`. The attachment set on this field is used to decide if a `DeformTimeline` should be applied to the attachment active on the slot to which the timeline is applied. + * Removed `inheritDeform` field, getter, and setter from `MeshAttachment`. + * Changed `.skel` binary format, added a string table. References to strings in the data resolve to this string table, reducing storage size of binary files considerably. + * `JsonRollback` tool now converts from 3.8 JSON to 3.7. + * Changed the `.json` and `.skel` file formats to accomodate the new feature and file size optimiations. Old projects must be exported with Spine 3.8.20+ to be compatible with the 3.8 Spine runtimes. + +* **Additions** + * Added `x` and `y` coordinates for setup pose AABB in `SkeletonData`. + * Added support for rotated mesh region UVs. + * Added skin-specific bones and constraints which are only updated if the skeleton's current skin contains them. + * Improved Skin API to make it easier to handle mix-and-match use cases. + * Added `Skin#getAttachments()`. Returns all attachments in the skin. + * Added `Skin#getAttachments(int slotIndex)`. Returns all attachements in the skin for the given slot index. + * Added `Skin#addSkin(Skin skin)`. Adds all attachments, bones, and skins from the specified skin to this skin. + * Added `Skin#copySkin(Skin skin)`. Adds all attachments, bones, and skins from the specified skin to this skin. `VertexAttachment` are shallowly copied and will retain any parent mesh relationship. All other attachment types are deep copied. + * Added `Attachment#copy()` to all attachment type implementations. This lets you deep copy an attachment to modify it independently from the original, i.e. when programmatically changing texture coordinates or mesh vertices. + * Added `MeshAttachment#newLinkedMesh()`, creates a linked mesh linkted to either the original mesh, or the parent of the original mesh. + * Added IK softness. + +### libGDX +* `SkeletonViewer` can load a skeleton by specifying it as the first argument on the command line. +* Added mix-and-match example to demonstrate the new Skin API. + +## Lua +* **Breaking changes** + * Renamed `Slot:getAttachmentVertices()` to `Slot#deform`. + * Changed the `.json` curve format and added more assumptions for omitted values, reducing the average size of JSON exports. + * Renamed `Skin:addAttachment()` to `Skin#setAttachment()`. + * Removed `VertexAttachment:applyDeform()` and replaced it with `VertexAttachment#deformAttachment`. The attachment set on this field is used to decide if a `DeformTimeline` should be applied to the attachment active on the slot to which the timeline is applied. + * Removed `inheritDeform` field, getter, and setter from `MeshAttachment`. + * Changed the `.json` file format to accomodate the new feature and file size optimiations. Old projects must be exported with Spine 3.8.20+ to be compatible with the 3.8 Spine runtimes. + +* **Additions** + * Added `x` and `y` coordinates for setup pose AABB in `SkeletonData`. + * Added support for rotated mesh region UVs. + * Added skin-specific bones and constraints which are only updated if the skeleton's current skin contains them. + * Improved Skin API to make it easier to handle mix-and-match use cases. + * Added `Skin:getAttachments()`. Returns all attachments in the skin. + * Added `Skin:getAttachments(slotIndex)`. Returns all attachements in the skin for the given slot index. + * Added `Skin:addSkin(Skin skin)`. Adds all attachments, bones, and skins from the specified skin to this skin. + * Added `Skin:copySkin(Skin skin)`. Adds all attachments, bones, and skins from the specified skin to this skin. `VertexAttachment` are shallowly copied and will retain any parent mesh relationship. All other attachment types are deep copied. + * Added `Attachment:copy()` to all attachment type implementations. This lets you deep copy an attachment to modify it independently from the original, i.e. when programmatically changing texture coordinates or mesh vertices. + * Added `MeshAttachment:newLinkedMesh()`, creates a linked mesh linkted to either the original mesh, or the parent of the original mesh. + * Added IK softness. + +### Love2D +* Added support for 0-1 RGBA color component range change in Löve 0.11+. Older Löve versions using the 0-255 range are still supported! +* Added mix-and-match example to demonstrate the new Skin API. + +### Corona +* Added mix-and-match example to demonstrate the new Skin API. + +## Typescript/Javascript +* **Breaking changes** + * Renamed `MixDirection.in/out` to `MixDirection.mixIn/mixOut` as it was crashing a JS compressor. + * Renamed `Slot#getAttachmentVertices()` to `Slot#getDeform()`. + * Changed the `.json` curve format and added more assumptions for omitted values, reducing the average size of JSON exports. + * Renamed `Skin#addAttachment()` to `Skin#setAttachment()`. + * Removed `VertexAttachment#applyDeform()` and replaced it with `VertexAttachment#deformAttachment`. The attachment set on this field is used to decide if a `DeformTimeline` should be applied to the attachment active on the slot to which the timeline is applied. + * Removed `inheritDeform` field, getter, and setter from `MeshAttachment`. + * Changed `.skel` binary format, added a string table. References to strings in the data resolve to this string table, reducing storage size of binary files considerably. + * Changed the `.json` and `.skel` file formats to accomodate the new feature and file size optimiations. Old projects must be exported with Spine 3.8.20+ to be compatible with the 3.8 Spine runtimes. + * Updated runtime to be compatible with TypeScript 3.6.3. + +* **Additions** + * Added support for loading binary data via `AssetManager#loadBinary()`. `AssetManager#get()` will return a `Uint8Array` for such assets. + * Added support for loading binaries via new `SkeletonBinary`. Parses a `Uint8Array`. + * Added `x` and `y` coordinates for setup pose AABB in `SkeletonData`. + * Added support for rotated mesh region UVs. + * Added skin-specific bones and constraints which are only updated if the skeleton's current skin contains them. + * Improved Skin API to make it easier to handle mix-and-match use cases. + * Added `Skin#getAttachments()`. Returns all attachments in the skin. + * Added `Skin#getAttachments(slotIndex: number)`. Returns all attachements in the skin for the given slot index. + * Added `Skin#addSkin(skin: Skin)`. Adds all attachments, bones, and skins from the specified skin to this skin. + * Added `Skin#copySkin(skin: Skin)`. Adds all attachments, bones, and skins from the specified skin to this skin. `VertexAttachment` are shallowly copied and will retain any parent mesh relationship. All other attachment types are deep copied. + * Added `Attachment#copy()` to all attachment type implementations. This lets you deep copy an attachment to modify it independently from the original, i.e. when programmatically changing texture coordinates or mesh vertices. + * Added `MeshAttachment#newLinkedMesh()`, creates a linked mesh linkted to either the original mesh, or the parent of the original mesh. + * Added IK softness. + * Added `AssetManager.setRawDataURI(path, data)`. Allows to embed data URIs for skeletons, atlases and atlas page images directly in the HTML/JS without needing to load it from a separate file. + +### WebGL backend +* `Input` can now take a partially defined implementation of `InputListener`. +* Added mix-and-match example to demonstrate the new Skin API. + +### Canvas backend + +### Three.js backend +* `SkeletonMesh` now takes an optional `SkeletonMeshMaterialParametersCustomizer` function that allows you to modify the `ShaderMaterialParameters` before the material is finalized. Use it to modify things like THREEJS' `Material.depthTest` etc. See #1590. + +### Player +* `SpinePlayer#setAnimation()` can now be called directly to set the animation being displayed. +* The player supports loading `.skel` binary skeleton files by setting the `SpinePlayerConfig#skelUrl` field instead of `SpinePlayerConfig#jsonUrl`. +* Added `SpinePlayerConfig#rawDataURIs`. Allows to embed data URIs for skeletons, atlases and atlas page images directly in the HTML/JS without needing to load it from a separate file. See the example for a demonstration. + +# 3.7 + +## AS3 +* **Breaking changes** + * The completion event will fire for looped 0 duration animations every frame. + * `MixPose` is now called `MixBlend` + * Skeleton `flipX/flipY` has been replaced with `scaleX/scaleY`. This cleans up applying transforms and is more powerful. Allows scaling a whole skeleton which has bones that disallow scale inheritance + * Mix time is no longer affected by `TrackEntry#timeScale`. See https://github.com/EsotericSoftware/spine-runtimes/issues/1194 +* **Additions** + * Added additive animation blending. When playing back multiple animations on different tracks, where each animation modifies the same skeleton property, the results of tracks with lower indices are discarded, and only the result from the track with the highest index is used. With animation blending, the results of all tracks are mixed together. This allows effects like mixing multiple facial expressions (angry, happy, sad) with percentage mixes. By default the old behaviour is retained (results from lower tracks are discarded). To enable additive blending across animation tracks, call `TrackEntry#setMixBlend(MixBlend.add)` on each track. To specify the blend percentage, set `TrackEntry#alpha`. See http://esotericsoftware.com/forum/morph-target-track-animation-mix-mode-9459 for a discussion. + * Support for stretchy IK + * Support for audio events, see `audioPath`, `volume` and `balance` fields on event (data). + * `TrackEntry` has an additional field called `holdPrevious`. It can be used to counter act a limitation of `AnimationState` resulting in "dipping" of parts of the animation. For a full discussion of the problem and the solution we've implemented, see this [forum thread](http://esotericsoftware.com/forum/Probably-Easy-Animation-mixing-with-multiple-tracks-10682?p=48130&hilit=holdprevious#p48130). + +### Starling +* Added support for vertex effects. See `RaptorExample.as` +* Added 'getTexture()' method to 'StarlingTextureAtlasAttachmentLoader' +* Breaking change: if a skeleton requires two color tinting, you have to enable it via `SkeletonSprite.twoColorTint = true`. In this case the skeleton will use the `TwoColorMeshStyle`, which internally uses a different vertex layout and shader. This means that skeletons with two color tinting enabled will break batching and hence increase the number of draw calls in your app. +* Added `VertexEffect` and implementations `JitterEffect` and `SwirlEffect`. Allows you to modify vertices before they are submitted for drawing. See Starling changes. +* Fix issues with StarlingAtlasAttachmentLoader, see https://github.com/EsotericSoftware/spine-runtimes/issues/939 +* Fix issues with region trimming support, see https://github.com/EsotericSoftware/spine-runtimes/commit/262bc26c64d4111002d80e201cb1a3345e6727df +* Added support for overriding `StarlingAtlasAttachmentLoader#getTexture()`, see https://github.com/EsotericSoftware/spine-runtimes/commit/ea7dbecb98edc74e439aa9ef90dcf6eed865f718 +* Texture atlas operations are no longer handled in `Starling#newRegionAttachment` and `Starling#newMeshAttachment` but delegated to the atlas. +* Added sample for additive animation blending, see https://github.com/EsotericSoftware/spine-runtimes/blob/6a556de01429878df47bb276a97959a8bdbbe32f/spine-starling/spine-starling-example/src/spine/examples/OwlExample.as +* Added sample on how to use bounding box attachment vertices https://github.com/EsotericSoftware/spine-runtimes/commit/e20428b02699226164fa73ba4b12f7d029ae6f4d +* Fully transparent meshes are not submitted for rendering. +* No hit-tests are performed when a skeleton is invisible. + +## C +* **Breaking changes** + * Listeners on `spAnimationState` and `spTrackEntry` will now also be called if a track entry gets disposed as part of disposing an animation state. + * The completion event will fire for looped 0 duration animations every frame. + * The spine-cocos2dx and spine-ue4 runtimes are now based on spine-cpp. See below for changes. + * Skeleton `flipX/flipY` has been replaced with `scaleX/scaleY`. This cleans up applying transforms and is more powerful. Allows scaling a whole skeleton which has bones that disallow scale inheritance + * Mix time is no longer affected by `TrackEntry#timeScale`. See https://github.com/EsotericSoftware/spine-runtimes/issues/1194 + * `spMeshAttachment` has two new fields `regionTextureWith` and `regionTextureHeight`. These must be set in custom attachment loader. See `AtlasAttachmentLoader`. +* **Additions** + * Added support for local and relative transform constraint calculation, including additional fields in `spTransformConstraintData`. + * `Animation#apply` and `Timeline#apply`` now take enums `MixPose` and `MixDirection` instead of booleans + * Added `spVertexEffect` and corresponding implementations `spJitterVertexEffect` and `spSwirlVertexEffect`. Create/dispose through the corresponding `spXXXVertexEffect_create()/dispose()` functions. Set on framework/engine specific renderer. + * Functions in `extension.h` are not prefixed with `_sp` instead of just `_` to avoid interference with other libraries. + * Introduced `SP_API` macro. Every spine-c function is prefixed with this macro. By default, it is an empty string. Can be used to markup spine-c functions with e.g. ``__declspec` when compiling to a dll or linking to that dll. + * Added `void *userData` to `spAnimationState`to be consumed in callbacks. + * Added additive animation blending. When playing back multiple animations on different tracks, where each animation modifies the same skeleton property, the results of tracks with lower indices are discarded, and only the result from the track with the highest index is used. With animation blending, the results of all tracks are mixed together. This allows effects like mixing multiple facial expressions (angry, happy, sad) with percentage mixes. By default the old behaviour is retained (results from lower tracks are discarded). To enable additive blending across animation tracks, call `spTrackEntry->mixBlend = SP_MIXBLEND_ADD)` on each track. To specify the blend percentage, set `spTrackEntry->alpha`. See http://esotericsoftware.com/forum/morph-target-track-animation-mix-mode-9459 for a discussion. + * Optimized attachment lookup to give a 40x speed-up. See https://github.com/EsotericSoftware/spine-runtimes/commit/cab81276263890b65d07fa2329ace16db1e365ff + * Support for stretchy IK + * Support for audio events, see `audioPath`, `volume` and `balance` fields on event (data). + * `spTrackEntry` has an additional field called `holdPrevious`. It can be used to counter act a limitation of `AnimationState` resulting in "dipping" of parts of the animation. For a full discussion of the problem and the solution we've implemented, see this [forum thread](http://esotericsoftware.com/forum/Probably-Easy-Animation-mixing-with-multiple-tracks-10682?p=48130&hilit=holdprevious#p48130). + +### Cocos2d-Objc +* Added vertex effect support to modify vertices of skeletons on the CPU. See `RaptorExample.m`. +* Explanation how to handle ARC, see https://github.com/EsotericSoftware/spine-runtimes/commit/a4f122b08c5e2a51d6aad6fc5a947f7ec31f2eb8 +* The super class `::update()` method of `SkeletonRenderer` is now called, see https://github.com/EsotericSoftware/spine-runtimes/commit/f7bb98185236a6d8f35bfefc70afe4f31e9ec9d2 +* Added improved tint-black shader. + +### SFML +* `spine-sfml.h` no longer defines `SPINE_SHORT_NAMES` to avoid collisions with other APIs. See #1058. +* Added support for vertex effects. See raptor example. +* Added premultiplied alpha support to `SkeletonDrawable`. Use `SkeletonDrawable::setUsePremultipliedAlpha()`, see https://github.com/EsotericSoftware/spine-runtimes/commit/34086c1f41415309b2ecce86055f6656fcba2950 +* Added additive animation blending sample, see https://github.com/EsotericSoftware/spine-runtimes/blob/b7e712d3ca1d6be3ebcfe3254dc2cea9c44dda71/spine-sfml/example/main.cpp#L369 + +## C++ +* ** Additions ** + * Added C++ Spine runtime. See the [spine-cpp Runtime Guide](https://esotericsoftware.com/spine-cpp) for more information on spine-cpp. + * Added parsing of non-essential data (fps, images path, audio path) to for `.json`/`.skel` parsers. + +### Cocos2d-x +* Added ETC1 alpha support, thanks @halx99! Does not work when two color tint is enabled. +* Added `spAtlasPage_setCustomTextureLoader()` which let's you do texture loading manually. Thanks @jareguo. +* Added `SkeletonRenderer:setSlotsRange()` and `SkeletonRenderer::createWithSkeleton()`. This allows you to split rendering of a skeleton up into multiple parts, and render other nodes in between. See `SkeletonRendererSeparatorExample.cpp` for an example. +* Fully transparent attachments will not be rendered, improving rendering performance. +* Added improved tint-black shader. +* Updated to cocos2d-x 3.16 +* The skeleton setup pose and world transform are now calculated on initialization to avoid flickering on start-up. +* Updated to cocos2d-x 3.17.1 +* **Breaking change**: Switched from [spine-c](spine-c) to [spine-cpp](spine-cpp) as the underlying Spine runtime. See the [spine-cpp Runtime Guide](https://esotericsoftware.com/spine-cpp) for more information on spine-cpp. + * Added `Cocos2dAttachmentLoader` to be used when constructing an `Atlas`. Used by default by `SkeletonAnimation` and `SkeletonRenderer` when creating instances via the `createXXX` methods. + * All C structs and enums `spXXX` have been replaced with their C++ equivalents `spine::XXX` in all public interfaces. + * All instantiations via `new` of C++ classes from spine-cpp should contain `(__FILE__, __LINE__)`. This allows the tracking of instantations and detection of memory leaks via the `spine::DebugExtension`. + +### SFML +* Create a second SFML backend using [spine-cpp](spine-cpp/). See the [spine-cpp Runtime Guide](https://esotericsoftware.com/spine-cpp) for more information on spine-cpp. +* Added support for vertex effects. See raptor example. +* Added premultiplied alpha support to `SkeletonDrawable`. Use `SkeletonDrawable::setUsePremultipliedAlpha()`, see https://github.com/EsotericSoftware/spine-runtimes/commit/34086c1f41415309b2ecce86055f6656fcba2950 +* Added additive animation blending sample, see https://github.com/EsotericSoftware/spine-runtimes/blob/b7e712d3ca1d6be3ebcfe3254dc2cea9c44dda71/spine-sfml/example/main.cpp#L369 + +### UE4 + * spine-c is now exposed from the plugin shared library on Windows via __declspec. + * Updated to Unreal Engine 4.18 + * Added C++ example, see https://github.com/EsotericSoftware/spine-runtimes/commit/15011e81b7061495dba45e28b4d3f4efb10d7f40 + * `SkeletonRendererComponent` generates collision meshes by default. + * Disabled generation of collision meshes by `SkeletonRendererComponent`. Both `ProceduralMeshComponent` and `RuntimeMeshComponent` have a bug that generates a new PhysiX file every frame per component. Users are advised to add a separate collision shape to the root scene component of an actor instead. + * Using UE4 `FMemory` allocator by default. This should fix issues on some consoles. + * **Breaking change** moved away from `RuntimeMeshComponent`, as its maintainance has seized, back to `ProceduralMeshComponent`. Existing projects should just work. However, if you run into issues, you may have to remove the old `SpineSkeletonRendererComponent` and add a new one to your existing actors. + * **Breaking change** due to the removal of `RuntimeMeshComponent` and reversal to `ProceduralMeshComponent`, two color tinting is currently not supported. `ProceduralMeshComponent` does not support enough vertex attributes for us to encode the second color in the vertex stream. You can remove the `RuntimeMeshComponent/` directory from your plugins directory and remove the component from any `build.cs` files that may reference it. + * **Breaking change**: Switched from [spine-c](spine-c) to [spine-cpp](spine-cpp) as the underlying Spine runtime. See the [spine-cpp Runtime Guide](https://esotericsoftware.com/spine-cpp) for more information on spine-cpp. + * All C structs and enums `spXXX` have been replaced with their C++ equivalents `spine::XXX` in all public interfaces. + * All instantiations via `new` of C++ classes from spine-cpp should contain `(__FILE__, __LINE__)`. This allows the tracking of instantations and detection of memory leaks via the `spine::DebugExtension`. +* Updated to Unreal Engine 4.20 (samples require 4.17+), see the `spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/SpinePlugin.build.cs` file on how to compile in 4.20 with the latest UBT API changes. +* Updated to Unreal Engine 4.21 (samples require 4.21). +* **Breaking change**: `UBoneDriverComponent` and `UBoneFollowerComponent` are now `USceneComponent` instead of `UActorComponent`. They either update only themselves, or also the owning `UActor`, depending on whether the new flag `UseComponentTransform` is set. See https://github.com/EsotericSoftware/spine-runtimes/pull/1175 +* Added query methods for slots, bones, skins and animations to `SpineSkeletonComponent` and `UTrackEntry`. These allow you to query these objects by name in both C++ and blueprints. +* Added `Preview Animation` and `Preview Skin` properties to `SpineSkeletonAnimationComponent`. Enter an animation or skin name to live-preview it in the editor. Enter an empty string to reset the animation or skin. + +## C# ## +* **Breaking changes** + * The completion event will fire for looped 0 duration animations every frame. + * Skeleton `flipX/flipY` has been replaced with `scaleX/scaleY`. This cleans up applying transforms and is more powerful. Allows scaling a whole skeleton which has bones that disallow scale inheritance + * Mix time is no longer affected by `TrackEntry#timeScale`. See https://github.com/EsotericSoftware/spine-runtimes/issues/1194 +* **Additions** + * Added additive animation blending. When playing back multiple animations on different tracks, where each animation modifies the same skeleton property, the results of tracks with lower indices are discarded, and only the result from the track with the highest index is used. With animation blending, the results of all tracks are mixed together. This allows effects like mixing multiple facial expressions (angry, happy, sad) with percentage mixes. By default the old behaviour is retained (results from lower tracks are discarded). To enable additive blending across animation tracks, call `TrackEntry#MixBlend = MixBlend.add` on each track. To specify the blend percentage, set `TrackEntry#Alpha`. See http://esotericsoftware.com/forum/morph-target-track-animation-mix-mode-9459 for a discussion. + * Support for stretchy IK + * Support for audio events, see `audioPath`, `volume` and `balance` fields on event (data). + * `TrackEntry` has an additional field called `holdPrevious`. It can be used to counter act a limitation of `AnimationState` resulting in "dipping" of parts of the animation. For a full discussion of the problem and the solution we've implemented, see this [forum thread](http://esotericsoftware.com/forum/Probably-Easy-Animation-mixing-with-multiple-tracks-10682?p=48130&hilit=holdprevious#p48130). + +### Unity +* **Runtime and Editor, and Assembly Definition** Files and folders have been reorganized into "Runtime" and "Editor". Each of these have an `.asmdef` file that defines these separately as their own assembly in Unity *(Note: Spine `.asmdef` files are currently deactivated to `.txt` extension, see below)*. For projects not using assembly definition, you may delete the `.asmdef` files. These assembly definitions will be ignored by older versions of Unity that don't support it. + * In this scheme, the entirety of the base spine-csharp runtime is inside the "Runtime" folder, to be compiled in the same assembly as spine-unity so they can continue to share internal members. +* **Spine `.asmdef` files are now deactivated (using `.txt` extension) by default** This prevents problems when updating Spine through unitypackages, overwriting the Timeline reference entry in `spine-unity.asmdef` (added automatically when enabling Unity 2019 Timeline support, see `Timeline Support for Unity 2019`), causing compile errors. In case you want to enable the `.asmdef` files, rename the files: + `Spine/Runtime/spine-unity.txt` to `Spine/Runtime/spine-unity.asmdef` and + `Spine/Editor/spine-unity-editor.txt` to `Spine/Editor/spine-unity-editor.asmdef`. +* **SkeletonAnimator is now SkeletonMecanim** The Spine-Unity Mecanim-driven component `SkeletonAnimator` has been renamed `SkeletonMecanim` to make it more autocomplete-friendly and more obvious at human-glance. The .meta files and guids should remain intact so existing projects and prefabs should not break. However, user code needs to be updated to use `SkeletonMecanim`. +* **SpineAtlasAsset** The existing `AtlasAsset` type has been renamed to `SpineAtlasAsset` to signify that it specifically uses a Spine/libGDX atlas as its source. Serialization should be intact but user code will need to be updated to refer to existing atlases as `SpineAtlasAsset`. + * **AtlasAssetBase** `SpineAtlasAsset` now has an abstract base class called `SpineAtlasAsset`. This is the base class to derive when using alternate atlas sources. Existing SkeletonDataAsset field "atlasAssets" now have the "AtlasAssetBase" type. Serialization should be intact, but user code will need to be updated to refer to the atlas assets accordingly. + * This change is in preparation for alternate atlas options such as Unity's SpriteAtlas. +* **Optional Straight Alpha for shaders** Spine-Unity's included Unity shaders now have a `_STRAIGHT_ALPHA_INPUT` shader_feature, toggled as a checkbox in the Material's inspector. This allows the Material to use a non-premultiplied alpha/straight alpha input texture. + * The following shaders now have the "Straight Alpha Texture" checkbox when used on a material: + * `Spine/Skeleton` + * `Spine/Skeleton Tint Black` + * `Spine/Skeleton Lit` + * `Spine/Skeleton Tint` + * `Spine/Skeleton Fill` + * `Spine/SkeletonGraphic (Premultiply Alpha)` was renamed to `Spine/SkeletonGraphic` + * `Spine/SkeletonGraphic Tint Black (Premultiply Alpha)` was renamed to `Spine/SkeletonGraphic Tint Black` + * `Spine/Skeleton PMA Multiply` + * `Spine/Skeleton PMA Screen` + * Dedicated straight alpha shaders were removed from the runtime. + * `Spine/Straight Alpha/Skeleton Fill` + * `Spine/Straight Alpha/Skeleton Tint` +* **Detection of Incorrect Texture Settings** Especially when atlas textures are exported with setting `Premultiply alpha` enabled, it is important to configure Unity's texture import settings correctly. By default, you will now receive warnings where texture settings are expected to cause incorrect rendering. + * The following rules apply: + * `sRGB (Color Texture)` shall be disabled when `Generate Mip Maps` is enabled, otherwise you will receive white border outlines. + * `Alpha Is Transparency` shall be disabled on `Premultiply alpha` textures, otherwise you will receive light ghosting artifacts in transparent areas. + * These warnings can be disabled in `Edit - Preferences - Spine`. +* **Sprite Mask Support for all Included Shaders** The `Skeleton Animation` and `Skeleton Mecanim` components now provide an additional `Mask Interaction` field in the Inspector, covering identical functionality as Unity's built in `Sprite Renderer` component: + * `Mask Interaction` modes: + * `None` - The sprite will not interact with the masking system. Default behavior. + * `Visible Inside Mask` - The sprite will be visible only in areas where a mask is present. + * `Visible Outside Mask` - The sprite will be visible only in areas where no mask is present. + * `Automatically Generated Materials` When switching `Mask Interaction` modes in the Inspector outside of Play mode, the required additional material assets are generated for the respective `Stencil Compare` parameters - with file suffixes `'_InsideMask'` and `'_OutsideMask'`, placed in the same folder as the original materials. By default all generated materials are kept as references by the `Skeleton Animation` component for switching at runtime. + These materials can be managed and optimized via the `SkeletonAnimation`'s `Advanced` section: + * Using the `Clear` button you can clear the reference to unneeded materials, + * Using the `Delete` button the respective assets are deleted as well as references cleared. Note that other `Skeleton Animation` GameObjects might still reference the materials, so use with caution! + * With the `Set` button you can again assign a link to the respective materials to prepare them for runtime use. If the materials were not present or have been deleted, they are generated again based on the default materials. + * When switching `Mask Interaction` mode at runtime, the previously prepared materials are switched active automatically. When the respective materials have not been prepared, material copies of the default materials are created on the fly. Note that these materials are not shared between similar `Skeleton Animation` GameObjects, so it is recommended to use the generated material assets where possible. + * **Every shader now exposes the `Stencil Compare` parameter** for further customization. This way you have maximum flexibility to use custom mechanisms to switch materials at runtime if you should ever need more than the three materials generated by `Skeleton Animation`'s `Mask Interaction` parameter. Reference `Stencil Compare` values are: + * `CompareFunction.Disabled` for `Mask Interaction - None` + * `CompareFunction.LessEqual` for `Mask Interaction - Visible Inside Mask` + * `CompareFunction.Greater` for `Mask Interaction - Visible Outside Mask` +* **RectMask2D Support for SkeletonGraphic** Both `SkeletonGraphic` shaders '`Spine/SkeletonGraphic`' and '`Spine/SkeletonGraphic Tint Black`' now respect masking areas defined via Unity's `RectMask2D` component. +* **Timeline Support for Unity 2019** using the existing Timeline components. By default, all Spine Timeline components are deactivated in Unity 2019 and **can be activated via the Spine Preferences menu**. This step became necessary because in Unity 2019, Timeline has been moved to a separate Package and is no longer included in the Unity core. Please visit `Edit - Preferences - Spine` and at `Timeline Package Support` hit `Enable` to automatically perform all necessary steps to activate the Timeline components. +This will automatically: + 1. download the Unity Timeline package + 2. activate the Spine Timeline components by setting the compile definition `SPINE_TIMELINE_PACKAGE_DOWNLOADED` for all platforms + 3. modify the `spine-unity.asmdef` file by adding the reference to the Unity Timeline library. +* Added `Create 2D Hinge Chain` functionality at `SkeletonUtilityBone` inspector, previously only `Create 3D Hinge Chain` was available. + +### XNA/MonoGame +* Added support for any `Effect` to be used by `SkeletonRenderer` +* Added support for `IVertexEffect` to modify vertices of skeletons on the CPU. `IVertexEffect` instances can be set on the `SkeletonRenderer`. See example project. +* Added `SkeletonDebugRenderer` +* Made `MeshBatcher` of SkeletonRenderer accessible via a getter. Allows user to batch their own geometry together with skeleton meshes for maximum batching instead of using XNA SpriteBatcher. + +## Java +* **Breaking changes** + * Skeleton attachments: Moved update of attached skeleton out of libGDX `SkeletonRenderer`, added overloaded method `Skeleton#updateWorldTransform(Bone)`, used for `SkeletonAttachment`. You now MUST call this new method with the bone of the parent skeleton to which the child skeleton is attached. See `SkeletonAttachmentTest` for and example. + * The completion event will fire for looped 0 duration animations every frame. + * `MixPose` is now called `MixBlend`. + * Skeleton `flipX/flipY` has been replaced with `scaleX/scaleY`. This cleans up applying transforms and is more powerful. Allows scaling a whole skeleton which has bones that disallow scale inheritance + * Mix time is no longer affected by `TrackEntry#timeScale`. See https://github.com/EsotericSoftware/spine-runtimes/issues/1194 +* **Additions** + * Added `EventData#audioPath` field. This field contains the file name of the audio file used for the event. + * Added convenience method to add all attachments from one skin to another, see https://github.com/EsotericSoftware/spine-runtimes/commit/a0b7bb6c445efdfac12b0cdee2057afa3eff3ead + * Added additive animation blending. When playing back multiple animations on different tracks, where each animation modifies the same skeleton property, the results of tracks with lower indices are discarded, and only the result from the track with the highest index is used. With animation blending, the results of all tracks are mixed together. This allows effects like mixing multiple facial expressions (angry, happy, sad) with percentage mixes. By default the old behaviour is retained (results from lower tracks are discarded). To enable additive blending across animation tracks, call `TrackEntry#setMixBlend(MixBlend.add)` on each track. To specify the blend percentage, set `TrackEntry#alpha`. See http://esotericsoftware.com/forum/morph-target-track-animation-mix-mode-9459 for a discussion. + * Support for stretchy IK + * Support for audio events, see `audioPath`, `volume` and `balance` fields on event (data). + * `TrackEntry` has an additional field called `holdPrevious`. It can be used to counter act a limitation of `AnimationState` resulting in "dipping" of parts of the animation. For a full discussion of the problem and the solution we've implemented, see this [forum thread](http://esotericsoftware.com/forum/Probably-Easy-Animation-mixing-with-multiple-tracks-10682?p=48130&hilit=holdprevious#p48130). + +### libGDX +* Added `VertexEffect` interface, instances of which can be set on `SkeletonRenderer`. Allows to modify vertices before submitting them to GPU. See `SwirlEffect`, `JitterEffect` and `VertexEffectTest`. +* Added improved tint-black shader. +* Improved performance by avoiding batch flush when not switching between normal and additive rendering with PMA +* Improvements to skeleton viewer. +* `TwoColorPolygonBatch` implements the `Batch` interface, allowing to the be used with other libGDX classes that require a batcher for drawing, potentially improving performance. See https://github.com/EsotericSoftware/spine-runtimes/commit/a46b3d1d0c135d51f9bef9ca17a5f8e5dda69927 +* Added `SkeletonDrawable` to render skeletons in scene2d UI https://github.com/EsotericSoftware/spine-runtimes/commit/b93686c185e2c9d5466969a8e07eee573ebe4b97 + +## Lua +* **Breaking changes** + * The completion event will fire for looped 0 duration animations every frame. + * Skeleton `flipX/flipY` has been replaced with `scaleX/scaleY`. This cleans up applying transforms and is more powerful. Allows scaling a whole skeleton which has bones that disallow scale inheritance + * Mix time is no longer affected by `TrackEntry#timeScale`. See https://github.com/EsotericSoftware/spine-runtimes/issues/1194 +* **Additions** + * Added `JitterEffect` and `SwirlEffect` and support for vertex effects in Corona and Love + * Added additive animation blending. When playing back multiple animations on different tracks, where each animation modifies the same skeleton property, the results of tracks with lower indices are discarded, and only the result from the track with the highest index is used. With animation blending, the results of all tracks are mixed together. This allows effects like mixing multiple facial expressions (angry, happy, sad) with percentage mixes. By default the old behaviour is retained (results from lower tracks are discarded). To enable additive blending across animation tracks, call `TrackEntry:setMixBlend(MixBlend.add)` on each track. To specify the blend percentage, set `TrackEntry.alpha`. See http://esotericsoftware.com/forum/morph-target-track-animation-mix-mode-9459 for a discussion. + * Support for stretchy IK + * Support for audio events, see `audioPath`, `volume` and `balance` fields on event (data). + * `TrackEntry` has an additional field called `holdPrevious`. It can be used to counter act a limitation of `AnimationState` resulting in "dipping" of parts of the animation. For a full discussion of the problem and the solution we've implemented, see this [forum thread](http://esotericsoftware.com/forum/Probably-Easy-Animation-mixing-with-multiple-tracks-10682?p=48130&hilit=holdprevious#p48130). + +### Love2D +* Added support for vertex effects. Set an implementation like "JitterEffect" on `Skeleton.vertexEffect`. See `main.lua` for an example. + +### Corona +* Added support for vertex effects. Set an implementation like "JitterEffect" on `SkeletonRenderer.vertexEffect`. See `main.lua` for an example + +## Typescript/Javascript +* **Breaking changes** + * The completion event will fire for looped 0 duration animations every frame. + * Skeleton `flipX/flipY` has been replaced with `scaleX/scaleY`. This cleans up applying transforms and is more powerful. Allows scaling a whole skeleton which has bones that disallow scale inheritance + * Mix time is no longer affected by `TrackEntry#timeScale`. See https://github.com/EsotericSoftware/spine-runtimes/issues/1194 +* **Additions** + * Added `AssetManager.loadTextureAtlas`. Instead of loading the `.atlas` and corresponding image files manually, you can simply specify the location of the `.atlas` file and AssetManager will load the atlas and all its images automatically. `AssetManager.get("atlasname.atlas")` will then return an instance of `spine.TextureAtlas`. + * Added additive animation blending. When playing back multiple animations on different tracks, where each animation modifies the same skeleton property, the results of tracks with lower indices are discarded, and only the result from the track with the highest index is used. With animation blending, the results of all tracks are mixed together. This allows effects like mixing multiple facial expressions (angry, happy, sad) with percentage mixes. By default the old behaviour is retained (results from lower tracks are discarded). To enable additive blending across animation tracks, call `TrackEntry#setMixBlend(MixBlend.add)` on each track. To specify the blend percentage, set `TrackEntry#alpha`. See http://esotericsoftware.com/forum/morph-target-track-animation-mix-mode-9459 for a discussion. See https://github.com/EsotericSoftware/spine-runtimes/blob/f045d221836fa56191ccda73dd42ae884d4731b8/spine-ts/webgl/tests/test-additive-animation-blending.html for an example. + * Added work-around for iOS WebKit JIT bug, see https://github.com/EsotericSoftware/spine-runtimes/commit/c28bbebf804980f55cdd773fed9ff145e0e7e76c + * Support for stretchy IK + * Support for audio events, see `audioPath`, `volume` and `balance` fields on event (data). + * `TrackEntry` has an additional field called `holdPrevious`. It can be used to counter act a limitation of `AnimationState` resulting in "dipping" of parts of the animation. For a full discussion of the problem and the solution we've implemented, see this [forum thread](http://esotericsoftware.com/forum/Probably-Easy-Animation-mixing-with-multiple-tracks-10682?p=48130&hilit=holdprevious#p48130). + * Added `AssetManager#setRawDataURI(path, data)`. Allows to set raw data URIs for a specific path, which in turn enables embedding assets into JavaScript/HTML. + +### WebGL backend +* Added `VertexEffect` interface, instances of which can be set on `SkeletonRenderer`. Allows to modify vertices before submitting them to GPU. See `SwirlEffect`, `JitterEffect`, and the example which allows to set effects. +* Added `slotRangeStart` and `slotRangeEnd` parameters to `SkeletonRenderer#draw` and `SceneRenderer#drawSkeleton`. This allows you to render only a range of slots in the draw order. See `spine-ts/webgl/tests/test-slot-range.html` for an example. +* Added improved tint-black shader. +* Added `SceneRenderer#drawTextureUV()`, allowing to draw a texture with manually specified texture coordinates. +* Exposed all renderers in `SceneRenderer`. + +### Canvas backend +* Added support for shearing and non-uniform scaling inherited from parent bones. +* Added support for alpha tinting. + +### Three.js backend +* Added `VertexEffect` interface, instances of which can be set on `SkeletonMesh`. Allows to modify vertices before submitting them to GPU. See `SwirlEffect`, `JitterEffect`. +* Added support for multi-page atlases + +### Widget backend + * Added fields `atlasContent`, `atlasPagesContent`, and `jsonContent` to `WidgetConfiguration` allowing you to directly pass the contents of the `.atlas`, atlas page `.png` files, and the `.json` file without having to do a request. See `README.md` and the example for details. + * `SpineWidget.setAnimation()` now takes an additional optional parameter for callbacks when animations are completed/interrupted/etc. + +# 3.6 + +## AS3 +* **Breaking changes** + * Removed `Bone.worldToLocalRotationX` and `Bone.worldToLocalRotationY`. Replaced by `Bone.worldToLocalRotation` (rotation given relative to x-axis, counter-clockwise, in degrees). + * Made `Bone` fields `_a`, `_b`, `_c`, `_d`, `_worldX` and `_worldY` public, removed underscore prefix. + * Removed `VertexAttachment.computeWorldVertices` overload, changed `VertexAttachment.computeWorldVertices2` to `VertexAttachment.computeWorldVertices`, added `stride` parameter. + * Removed `RegionAttachment.vertices` field. The vertices array is provided to `RegionAttachment.computeWorldVertices` by the API user now. + * Removed `RegionAttachment.updateWorldVertices`, added `RegionAttachment.computeWorldVertices`. The new method now computes the x/y positions of the 4 vertices of the corner and places them in the provided `worldVertices` array, starting at `offset`, then moving by `stride` array elements when advancing to the next vertex. This allows to directly compose the vertex buffer and avoids a copy. The computation of the full vertices, including vertex colors and texture coordinates, is now done by the backend's respective renderer. + * Replaced `r`, `g`, `b`, `a` fields with instances of new `Color` class in `RegionAttachment`, `MeshAttachment`, `Skeleton`, `SkeletonData`, `Slot` and `SlotData`. + * The completion event will fire for looped 0 duration animations every frame. + +* **Additions** + * Added `Skeleton.getBounds` from reference implementation. + * Added support for local and relative transform constraint calculation, including additional fields in `TransformConstraintData` + * Added `Bone.localToWorldRotation`(rotation given relative to x-axis, counter-clockwise, in degrees). + * Added two color tinting support, including `TwoColorTimeline` and additional fields on `Slot` and `SlotData`. + * Added `PointAttachment`, additional method `newPointAttachment` in `AttachmentLoader` interface. + * Added `ClippingAttachment`, additional method `newClippingAttachment` in `AttachmentLoader` interface. + * `AnimationState#apply` returns boolean indicating if any timeline was applied or not. + * `Animation#apply` and `Timeline#apply`` now take enums `MixPose` and `MixDirection` instead of booleans + * Added `VertexEffect` and implementations `JitterEffect` and `SwirlEffect`. Allows you to modify vertices before they are submitted for drawing. See Starling changes. + +### Starling + * Fixed renderer to work with 3.6 changes. + * Added support for two color tinting. + * Added support for clipping. + * Added support for rotated regions in texture atlas loaded via StarlingAtlasAttachmentLoader. + * Added support for vertex effects. See `RaptorExample.as` + * Added 'getTexture()' method to 'StarlingTextureAtlasAttachmentLoader' + * Breaking change: if a skeleton requires two color tinting, you have to enable it via `SkeletonSprite.twoColorTint = true`. In this case the skeleton will use the `TwoColorMeshStyle`, which internally uses a different vertex layout and shader. This means that skeletons with two color tinting enabled will break batching and hence increase the number of draw calls in your app. + +## C +* **Breaking changes** + * `spVertexAttachment_computeWorldVertices` and `spRegionAttachment_computeWorldVerticeS` now take new parameters to make it possible to directly output the calculated vertex positions to a vertex buffer. Removes the need for additional copies in the backends' respective renderers. + * Removed `spBoundingBoxAttachment_computeWorldVertices`, superseded by `spVertexAttachment_computeWorldVertices`. + * Removed `spPathAttachment_computeWorldVertices` and `spPathAttachment_computeWorldVertices1`, superseded by `spVertexAttachment_computeWorldVertices`. + * Removed `sp_MeshAttachment_computeWorldVertices`, superseded by `spVertexAttachment_computeWorldVertices`. + * Removed `spBone_worldToLocalRotationX` and `spBone_worldToLocalRotationY`. Replaced by `spBone_worldToLocalRotation` (rotation given relative to x-axis, counter-clockwise, in degrees). + * Replaced `r`, `g`, `b`, `a` fields with instances of new `spColor` struct in `spRegionAttachment`, `spMeshAttachment`, `spSkeleton`, `spSkeletonData`, `spSlot` and `spSlotData`. + * Removed `spVertexIndex`from public API. + * Listeners on `spAnimationState` or `spTrackEntry` will now be also called in case a track entry is disposed as part of dispoing the `spAnimationState`. + * The completion event will fire for looped 0 duration animations every frame. +* **Additions** + * Added support for local and relative transform constraint calculation, including additional fields in `spTransformConstraintData`. + * Added `spPointAttachment`, additional method `spAtlasAttachmentLoadeR_newPointAttachment`. + * Added support for local and relative transform constraint calculation, including additional fields in `TransformConstraintData` + * Added `spBone_localToWorldRotation`(rotation given relative to x-axis, counter-clockwise, in degrees). + * Added two color tinting support, including `spTwoColorTimeline` and additional fields on `spSlot` and `spSlotData`. + * Added `userData` field to `spTrackEntry`, so users can expose data in `spAnimationState` callbacks. + * Modified kvec.h used by SkeletonBinary.c to use Spine's MALLOC/FREE macros. That way there's only one place to inject custom allocators ([extension.h](https://github.com/EsotericSoftware/spine-runtimes/blob/master/spine-c/spine-c/include/spine/extension.h)) [commit](https://github.com/EsotericSoftware/spine-runtimes/commit/c2cfbc6cb8709daa082726222d558188d75a004f) + * Added macros to define typed dynamic arrays, see `Array.h/.c` + * Added `spClippingAttachment` and respective enum. + * Added `spSkeletonClipper` and `spTriangulator`, used to implement software clipping of attachments. + * `AnimationState#apply` returns boolean indicating if any timeline was applied or not. + * `Animation#apply` and `Timeline#apply`` now take enums `MixPose` and `MixDirection` instead of booleans + * Added `spVertexEffect` and corresponding implementations `spJitterVertexEffect` and `spSwirlVertexEffect`. Create/dispose through the corresponding `spXXXVertexEffect_create()/dispose()` functions. Set on framework/engine specific renderer. See changes for spine-c based frameworks/engines below. + * Functions in `extension.h` are not prefixed with `_sp` instead of just `_` to avoid interference with other libraries. + * Introduced `SP_API` macro. Every spine-c function is prefixed with this macro. By default, it is an empty string. Can be used to markup spine-c functions with e.g. ``__declspec` when compiling to a dll or linking to that dll. + +### Cocos2d-X + * Fixed renderer to work with 3.6 changes + * Optimized rendering by removing all per-frame allocation in `SkeletonRenderer`, resulting in 15% performance increase for large numbers of skeletons being rendered per frame. + * Added support for two color tinting. Tinting is enabled/disabled per `SkeletonRenderer`/`SkeletonAnimation` instance. Use `SkeletonRenderer::setTwoColorTint()`. Note that two color tinting requires the use of a non-standard shader and vertex format. This means that skeletons rendered with two color tinting will break batching. However, skeletons with two color tinting enabled and rendered after each other will be batched. + * Updated example to use Cocos2d-x 3.14.1. + * Added mesh debug rendering. Enable/Disable via `SkeletonRenderer::setDebugMeshesEnabled()`. + * Added support for clipping. + * SkeletonRenderer now combines the displayed color of the Node (cascaded from all parents) with the skeleton color for tinting. + * Added support for vertex effects. See `RaptorExample.cpp`. + * Added ETC1 alpha support, thanks @halx99! Does not work when two color tint is enabled. + * Added `spAtlasPage_setCustomTextureLoader()` which let's you do texture loading manually. Thanks @jareguo. + * Added `SkeletonRenderer:setSlotsRange()` and `SkeletonRenderer::createWithSkeleton()`. This allows you to split rendering of a skeleton up into multiple parts, and render other nodes in between. See `SkeletonRendererSeparatorExample.cpp` for an example. + +### Cocos2d-Objc + * Fixed renderer to work with 3.6 changes + * Added support for two color tinting. Tinting is enabled/disabled per `SkeletonRenderer/SkeletonAnimation.twoColorTint = true`. Note that two color tinted skeletons do not batch with other nodes. + * Added support for clipping. + +### SFML + * Fixed renderer to work with 3.6 changes. Sadly, two color tinting does not work, as the vertex format in SFML is fixed. + * Added support for clipping. + * Added support for vertex effects. See raptor example. + * Added premultiplied alpha support to `SkeletonDrawable`. + +### Unreal Engine 4 + * Fixed renderer to work with 3.6 changes + * Added new UPROPERTY to SpineSkeletonRendererComponent called `Color`. This allows to set the tint color of the skeleton in the editor, C++ and Blueprints. Under the hood, the `spSkeleton->color` will be set on every tick of the renderer component. + * Added support for clipping. + * Switched from built-in ProceduralMeshComponent to RuntimeMeshComponent by Koderz (https://github.com/Koderz/UE4RuntimeMeshComponent, MIT). Needed for more flexibility regarding vertex format, should not have an impact on existing code/assets. You need to copy the RuntimeMeshComponentPlugin from our repository in `spine-ue4\Plugins\` to your project as well! + * Added support for two color tinting. All base materials, e.g. SpineUnlitNormalMaterial, now do proper two color tinting. No material parameters have changed. + * Updated to Unreal Engine 4.16.1. Note that 4.16 has a regression which will make it impossible to compile plain .c files! + * spine-c is now exposed from the plugin shared library on Windows via __declspec. + +## C# +* **Breaking changes** + * `MeshAttachment.parentMesh` is now a private field to enforce using the `.ParentMesh` setter property in external code. The `MeshAttachment.ParentMesh` property is an appropriate replacement wherever `.parentMesh` was used. + * `Skeleton.GetBounds` takes a scratch array as input so it doesn't have to allocate a new array on each invocation itself. Reduces GC activity. + * Removed `Bone.WorldToLocalRotationX` and `Bone.WorldToLocalRotationY`. Replaced by `Bone.WorldToLocalRotation` (rotation given relative to x-axis, counter-clockwise, in degrees). + * Added `stride` parameter to `VertexAttachment.ComputeWorldVertices`. + * Removed `RegionAttachment.Vertices` field. The vertices array is provided to `RegionAttachment.ComputeWorldVertices` by the API user now. + * Removed `RegionAttachment.UpdateWorldVertices`, added `RegionAttachment.ComputeWorldVertices`. The new method now computes the x/y positions of the 4 vertices of the corner and places them in the provided `worldVertices` array, starting at `offset`, then moving by `stride` array elements when advancing to the next vertex. This allows to directly compose the vertex buffer and avoids a copy. The computation of the full vertices, including vertex colors and texture coordinates, is now done by the backend's respective renderer. + * The completion event will fire for looped 0 duration animations every frame. + + * **Additions** + * Added support for local and relative transform constraint calculation, including additional fields in `TransformConstraintData` + * Added `Bone.localToWorldRotation`(rotation given relative to x-axis, counter-clockwise, in degrees). + * Added two color tinting support, including `TwoColorTimeline` and additional fields on `Slot` and `SlotData`. + * Added `PointAttachment`, additional method `NewPointAttachment` in `AttachmentLoader` interface. + * Added `ClippingAttachment`, additional method `NewClippingAttachment` in `AttachmentLoader` interface. + * Added `SkeletonClipper` and `Triangulator`, used to implement software clipping of attachments. + * `AnimationState.Apply` returns a bool indicating if any timeline was applied or not. + * `Animation.Apply` and `Timeline.Apply`` now take enums `MixPose` and `MixDirection` instead of bools. + +### Unity + * Refactored renderer to work with new 3.6 features. + * **Two color tinting** is currently supported via extra UV2 and UV3 mesh vertex streams. To use Two color tinting, you need to: + * switch on "Tint Black" under "Advanced...", + * use the new `Spine/Skeleton Tint Black` shader, or your own shader that treats the UV2 and UV3 streams similarly. + * Additionally, for SkeletonGraphic, you can use `Spine/SkeletonGraphic Tint Black` (or the bundled SkeletonGraphicTintBlack material) or your own shader that uses UV2 and UV3 streams similarly. **Additional Shader Channels** TexCoord1 and TexCoord2 will need to be enabled from the Canvas component's inspector. These correspond to UV2 and UV3. + * **Clipping** is now supported. Caution: The SkeletonAnimation switches to slightly slower mesh generation code when clipping so limit your use of `ClippingAttachment`s when using on large numbers of skeletons. + * **SkeletonRenderer.initialFlip** Spine components such as SkeletonRenderer, SkeletonAnimation, SkeletonAnimator now has `initialFlipX` and `initialFlipY` fields which are also visible in the inspector under "Advanced...". It will allow you to set and preview a starting flip value for your skeleton component. This is applied immediately when the internal skeleton object is instantiated. + * **[SpineAttribute] Improvements** + * **Icons have been added to SpineAttributeDrawers**. This should make your default inspectors easier to understand at a glance. + * **Added Constraint Attributes** You can now use `[SpineIkConstraint]` `[SpineTransformConstraint]` `[SpinePathConstraint]` + * **SpineAttribute dataField** parameter can also now detect sibling fields within arrays and serializable structs/classes. + * **[SpineAttribute(includeNone:false)]** SpineAttributes now have an `includeNone` optional parameter to specify if you want to include or exclude a none ("") value option in the dropdown menu. Default is `includeNone:true`. + * **[SpineAttachment(skinField:"mySkin")]** The SpineAttachment attribute now has a skinField optional parameter to limit the dropdown items to attachments in a specific skin instead of the just default skin or all the skins in SkeletonData. + * **SkeletonDebugWindow**. Debugging tools have been moved from the SkeletonAnimation and SkeletonUtility component inspectors into its own utility window. You can access "Skeleton Debug" under the `Advanced...` foldout in the SkeletonAnimation inspector, or in SkeletonAnimation's right-click/context menu. + * **Skeleton Baking Window** The old Skeleton Baking feature is also now accessible through the SkeletonDataAsset's right-click/context menu. + * **AttachmentTools source material**. `AttachmentTools` methods can now accept a `sourceMaterial` argument to copy material properties from. + * **AttachmentTools Skin Extensions**. Using AttachmentTools, you can now add entries by slot name by also providing a skeleton argument. Also `Append(Skin)`, `RemoveAttachment` and `Clear` have been added. + * **BoneFollower and SkeletonUtilityBone Add RigidBody Button**. The BoneFollower and SkeletonUtilityBone component inspectors will now offer to add a `Rigidbody` or `Rigidbody2D` if it detects a collider of the appropriate type. Having a rigidbody on a moving transform with a collider fits better with the Unity physics systems and prevents excess calculations. It will not detect colliders on child objects so you have to add Rigidbody components manually accordingly. + * **SkeletonRenderer.OnPostProcessVertices** is a new callback that gives you a reference to the MeshGenerator after it has generated a mesh from the current skeleton pose. You can access `meshGenerator.VertexBuffer` or `meshGenerator.ColorBuffer` to modify these before they get pushed into the UnityEngine.Mesh for rendering. This can be useful for non-shader vertex effects. + * **Examples** + * **Examples now use properties**. The code in the example scripts have been switched over to using properties instead of fields to encourage their use for consistency. This is in anticipation of both users who want to move the Spine folders to the Unity Plugins folder (compiled as a different assembly), and of Unity 2017's ability to manually define different assemblies for shorter compilation times. + * **Mix And Match**. The mix-and-match example scene, code and data have been updated to reflect the current recommended setup for animation-compatible custom equip systems The underlying API has changed since 3.5 and the new API calls in MixAndMatch.cs is recommended. Documentation is in progress. + * **Sample Components**. `AtasRegionAttacher` and `SpriteAttacher` are now part of `Sample Components`, to reflect that they are meant to be used as sample code rather than production. A few other sample components have also been added. New imports of the unitypackage Examples folder will see a "Legacy" folder comprised of old sample components that no longer contain the most up-to-date and recommended workflows, but are kept in case old setups used them for production. + * **Spine folder**. In the unitypackage, the "spine-csharp" and "spine-unity" folders are now inside a "Spine" folder. This change will only affect fresh imports. Importing the unitypackage to update Spine-Unity in your existing project will update the appropriate files however you chose to arrange them, as long as the meta files are intact. + * **Breaking changes** + * The Sprite shaders module was updated to the latest version from the [source](https://github.com/traggett/UnitySpriteShaders/commits/master). Some changes were made to the underlying keyword structure. You may need to review the settings of your lit materials. Particularly, your Fixed Normals settings. + * The `Spine/Skeleton Lit` shader was switched over to non-fixed-function code. It now no longer requires mesh normals and has fixed normals at the shader level. + * The old MeshGenerator classes, interfaces and code in `Spine.Unity.MeshGeneration` are now deprecated. All mesh-generating components now share the class `Spine.Unity.MeshGenerator` defined in `SpineMesh.cs`. MeshGenerator is a serializable class. + * The `SkeletonRenderer.renderMeshes` optimization is currently non-functional. + * Old triangle-winding code has been removed from `SkeletonRenderer`. Please use shaders that have backface culling off. + * Render settings in `SkeletonGraphic` can now be accessed under `SkeletonGraphic.MeshGenerator.settings`. This is visible in the SkeletonGraphic inspector as `Advanced...` + * We will continue to bundle the unitypackage with the empty .cs files of deprecated classes until Spine 3.7 to ensure the upgrade process does not break. + * The [SpineAttachment(slotField:)] optional parameter found property value now acts as a Find(slotName) argument rather than Contains(slotName). + * `SkeletonAnimator` now uses a `SkeletonAnimator.MecanimTranslator` class to translate an Animator's Mecanim State Machine into skeleton poses. This makes code reuse possible for a Mecanim version of SkeletonGraphic. + * `SkeletonAnimator` `autoreset` and the `mixModes` array are now a part of SkeletonAnimator's MecanimTranslator `.Translator`. `autoReset` is set to true by default. Old prefabs and scene objects with Skeleton Animator may no longer have correct values set. + * Warnings and conditionals checking for specific Unity 5.2-and-below incompatibility have been removed. + +## XNA/MonoGame + * Added support for clipping + * Removed `RegionBatcher` and `SkeletonRegionRenderer`, renamed `SkeletonMeshRenderer` to `SkeletonRenderer` + * Added support for two color tint. For it to work, you need to add the `SpineEffect.fx` file to your content project, then load it via `var effect = Content.Load("SpineEffect");`, and set it on the `SkeletonRenderer`. See the example project for code. + * Added support for any `Effect` to be used by `SkeletonRenderer` + * Added support for `IVertexEffect` to modify vertices of skeletons on the CPU. `IVertexEffect` instances can be set on the `SkeletonRenderer`. See example project. + * Added `SkeletonDebugRenderer` + * Made `MeshBatcher` of SkeletonRenderer accessible via a getter. Allows user to batch their own geometry together with skeleton meshes for maximum batching instead of using XNA SpriteBatcher. + +## Java +* **Breaking changes** + * `Skeleton.getBounds` takes a scratch array as input so it doesn't have to allocate a new array on each invocation itself. Reduces GC activity. + * Removed `Bone.worldToLocalRotationX` and `Bone.worldToLocalRotationY`. Replaced by `Bone.worldToLocalRotation` (rotation given relative to x-axis, counter-clockwise, in degrees). + * Added `stride` parameter to `VertexAttachment.computeWorldVertices`. + * Removed `RegionAttachment.vertices` field. The vertices array is provided to `RegionAttachment.computeWorldVertices` by the API user now. + * Removed `RegionAttachment.updateWorldVertices`, added `RegionAttachment.computeWorldVertices`. The new method now computes the x/y positions of the 4 vertices of the corner and places them in the provided `worldVertices` array, starting at `offset`, then moving by `stride` array elements when advancing to the next vertex. This allows to directly compose the vertex buffer and avoids a copy. The computation of the full vertices, including vertex colors and texture coordinates, is now done by the backend's respective renderer. + * Skeleton attachments: Moved update of attached skeleton out of libGDX `SkeletonRenderer`, added overloaded method `Skeleton#updateWorldTransform(Bone), used for `SkeletonAttachment`. You now MUST call this new method + with the bone of the parent skeleton to which the child skeleton is attached. See `SkeletonAttachmentTest` for and example. + * The completion event will fire for looped 0 duration animations every frame. + +* **Additions** + * Added support for local and relative transform constraint calculation, including additional fields in `TransformConstraintData` + * Added `Bone.localToWorldRotation`(rotation given relative to x-axis, counter-clockwise, in degrees). + * Added two color tinting support, including `TwoColorTimeline` and additional fields on `Slot` and `SlotData`. + * Added `PointAttachment`, additional method `newPointAttachment` in `AttachmentLoader` interface. + * Added `ClippingAttachment`, additional method `newClippingAttachment` in `AttachmentLoader` interface. + * Added `SkeletonClipper` and `Triangulator`, used to implement software clipping of attachments. + * `AnimationState#apply` returns boolean indicating if any timeline was applied or not. + * `Animation#apply` and `Timeline#apply`` now take enums `MixPose` and `MixDirection` instead of booleans + +### libGDX + * Fixed renderer to work with 3.6 changes + * Added support for two color tinting. Use the new `TwoColorPolygonBatch` together with `SkeletonRenderer` + * Added support for clipping. See `SkeletonClipper`. Used automatically by `SkeletonRenderer`. Does not work when using a `SpriteBatch` with `SkeletonRenderer`. Use `PolygonSpriteBatch` or `TwoColorPolygonBatch` instead. + * Added `VertexEffect` interface, instances of which can be set on `SkeletonRenderer`. Allows to modify vertices before submitting them to GPU. See `SwirlEffect`, `JitterEffect` and `VertexEffectTest`. + +## Lua +* **Breaking changes** + * Removed `Bone:worldToLocalRotationX` and `Bone:worldToLocalRotationY`. Replaced by `Bone:worldToLocalRotation` (rotation given relative to x-axis, counter-clockwise, in degrees). + * `VertexAttachment:computeWorldVertices` now takes offsets and stride to allow compositing vertices directly in a vertex buffer to be send to the GPU. The compositing is now performed in the backends' respective renderers. This also affects the subclasses `MeshAttachment`, `BoundingBoxAttachment` and `PathAttachment`. + * Removed `RegionAttachment:updateWorldVertices`, added `RegionAttachment:computeWorldVertices`, which takes offsets and stride to allow compositing vertices directly in a vertex buffer to be send to the GPU. The compositing is now performed in the backends' respective renderers. + * Removed `MeshAttachment.worldVertices` field. Computation is now performed in each backends' respective renderer. The `uv` coordinates are now stored in `MeshAttachment.uvs`. + * Removed `RegionAttachment.vertices` field. Computation is now performed in each backends respective renderer. The `uv` coordinates for each vertex are now stored in the `RegionAttachment.uvs` field. + * The completion event will fire for looped 0 duration animations every frame. + * **Additions** + * Added `Bone:localToWorldRotation`(rotation given relative to x-axis, counter-clockwise, in degrees). + * Added two color tinting support, including `TwoColorTimeline` and additional fields on `Slot` and `SlotData`. + * Added `PointAttachment`, additional method `newPointAttachment` in `AttachmentLoader` interface. + * Added support for local and relative transform constraint calculation, including additional fields in `TransformConstraintData` + * Added `ClippingAttachment`, additional method `newClippingAttachment` in `AttachmentLoader` interface. + * Added `SkeletonClipper` and `Triangulator`, used to implement software clipping of attachments. + * `AnimationState#apply` returns boolean indicating if any timeline was applied or not. + * `Animation#apply` and `Timeline#apply`` now take enums `MixPose` and `MixDirection` instead of booleans + * Added `JitterEffect` and `SwirlEffect` and support for vertex effects in Corona and Love + +### Love2D + * Fixed renderer to work with 3.6 changes + * Added support for two color tinting. Enable it via `SkeletonRenderer.new(true)`. + * Added clipping support. + * Added support for vertex effects. Set an implementation like "JitterEffect" on `Skeleton.vertexEffect`. See `main.lua` for an example. + +### Corona + * Fixed renderer to work with 3.6 changes. Sadly, two color tinting is not supported, as Corona doesn't let us change the vertex format needed and its doesn't allow to modify shaders in the way needed for two color tinting + * Added clipping support. + * Added support for vertex effects. Set an implementation like "JitterEffect" on `SkeletonRenderer.vertexEffect`. See `main.lua` for an example + +## Typescript/Javascript +* **Breaking changes** + * `Skeleton.getBounds` takes a scratch array as input so it doesn't have to allocate a new array on each invocation itself. Reduces GC activity. + * Removed `Bone.worldToLocalRotationX` and `Bone.worldToLocalRotationY`. Replaced by `Bone.worldToLocalRotation` (rotation given relative to x-axis, counter-clockwise, in degrees). + * Removed `VertexAttachment.computeWorldVertices` overload, changed `VertexAttachment.computeWorldVerticesWith` to `VertexAttachment.computeWorldVertices`, added `stride` parameter. + * Removed `RegionAttachment.vertices` field. The vertices array is provided to `RegionAttachment.computeWorldVertices` by the API user now. + * Removed `RegionAttachment.updateWorldVertices`, added `RegionAttachment.computeWorldVertices`. The new method now computes the x/y positions of the 4 vertices of the corner and places them in the provided `worldVertices` array, starting at `offset`, then moving by `stride` array elements when advancing to the next vertex. This allows to directly compose the vertex buffer and avoids a copy. The computation of the full vertices, including vertex colors and texture coordinates, is now done by the backend's respective renderer. + * The completion event will fire for looped 0 duration animations every frame. + * Removed the Spine Widget in favor of [Spine Web Player](https://esotericsoftware.com/spine-player). + +* **Additions** + * Added support for local and relative transform constraint calculation, including additional fields in `TransformConstraintData` + * Added `Bone.localToWorldRotation`(rotation given relative to x-axis, counter-clockwise, in degrees). + * Added two color tinting support, including `TwoColorTimeline` and additional fields on `Slot` and `SlotData`. + * Added `PointAttachment`, additional method `newPointAttachment` in `AttachmentLoader` interface. + * Added `ClippingAttachment`, additional method `newClippingAttachment` in `AttachmentLoader` interface. + * Added `SkeletonClipper` and `Triangulator`, used to implement software clipping of attachments. + * `AnimationState#apply` returns boolean indicating if any timeline was applied or not. + * `Animation#apply` and `Timeline#apply`` now take enums `MixPose` and `MixDirection` instead of booleans + * Added `AssetManager.loadTextureAtlas`. Instead of loading the `.atlas` and corresponding image files manually, you can simply specify the location of the `.atlas` file and AssetManager will load the atlas and all its images automatically. `AssetManager.get("atlasname.atlas")` will then return an instance of `spine.TextureAtlas`. + * Added the [Spine Web Player](https://esotericsoftware.com/spine-player) + + +### WebGL backend + * Fixed WebGL context loss + * Added `Restorable` interface, implemented by any WebGL resource that needs restoration after a context loss. All WebGL resource classes (`Shader`, `Mesh`, `GLTexture`) implement this interface. + * Added `ManagedWebGLRenderingContext`. Handles setup of a `WebGLRenderingContext` given a canvas element and restoration of WebGL resources (`Shader`, `Mesh`, `GLTexture`) on WebGL context loss. WebGL resources register themselves with the `ManagedWebGLRenderingContext`. If the context is informed of a context loss and restoration, the registered WebGL resources' `restore()` method is called. The `restore()` method implementation on each resource type will recreate the GPU side objects. + * All classes that previously took a `WebGLRenderingContext` in the constructor now also allow a `ManagedWebGLRenderingContext`. This ensures existing applications do not break. + * To use automatic context restauration: + 1. Create or fetch a canvas element from the DOM + 2. Instantiate a `ManagedWebGLRenderingContext`, passing the canvas to the constructor. This will setup a `WebGLRenderingContext` internally and manage context loss/restoration. + 3. Pass the `ManagedWebGLRenderingContext` to the constructors of classes that you previously passed a `WebGLRenderingContext` to (`AssetManager`, `GLTexture`, `Mesh`, `Shader`, `PolygonBatcher`, `SceneRenderer`, `ShapeRenderer`, `SkeletonRenderer`, `SkeletonDebugRenderer`). + * Fixed renderer to work with 3.6 changes. + * Added support for two color tinting. + * Improved performance by using `DYNAMIC_DRAW` for vertex buffer objects and fixing bug that copied to much data to the GPU each frame in `PolygonBatcher`/`Mesh`. + * Added two color tinting support, enabled by default. You can disable it via the constructors of `SceneRenderer`, `SkeletonRenderer`and `PolygonBatcher`. Note that you will need to use a shader created via `Shader.newTwoColoredTexturedShader` shader with `SkeletonRenderer` and `PolygonBatcher` if two color tinting is enabled. + * Added clipping support + * Added `VertexEffect` interface, instances of which can be set on `SkeletonRenderer`. Allows to modify vertices before submitting them to GPU. See `SwirlEffect`, `JitterEffect`, and the example which allows to set effects. + * Added `slotRangeStart` and `slotRangeEnd` parameters to `SkeletonRenderer#draw` and `SceneRenderer#drawSkeleton`. This allows you to render only a range of slots in the draw order. See `spine-ts/webgl/tests/test-slot-range.html` for an example. + +### Canvas backend + * Fixed renderer to work for 3.6 changes. Sadly, we can't support two color tinting via the Canvas API. + * Added support for shearing and non-uniform scaling inherited from parent bones. + * Added support for alpha tinting. + +### Three.js backend + * Fixed renderer to work with 3.6 changes. Two color tinting is not supported. + * Added clipping support + * Added `VertexEffect` interface, instances of which can be set on `SkeletonMesh`. Allows to modify vertices before submitting them to GPU. See `SwirlEffect`, `JitterEffect`. + * Added support for multi-page atlases + +### Widget backend + * Fixed WebGL context loss (see WebGL backend changes). Enabled automatically. + * Fixed renderer to work for 3.6 changes. Supports two color tinting & clipping (see WebGL backend changes for details). + * Added fields `atlasContent`, `atlasPagesContent`, and `jsonContent` to `WidgetConfiguration` allowing you to directly pass the contents of the `.atlas`, atlas page `.png` files, and the `.json` file without having to do a request. See `README.md` and the example for details. + * `SpineWidget.setAnimation()` now takes an additional optional parameter for callbacks when animations are completed/interrupted/etc. diff --git a/box1/Assets/Spine/CHANGELOG.md.meta b/box1/Assets/Spine/CHANGELOG.md.meta new file mode 100644 index 00000000..cd081805 --- /dev/null +++ b/box1/Assets/Spine/CHANGELOG.md.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 3a206f1c4d5fd9e49a16634698666cfe +timeCreated: 1599849712 +licenseType: Pro +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Editor.meta b/box1/Assets/Spine/Editor.meta new file mode 100644 index 00000000..973e2aaf --- /dev/null +++ b/box1/Assets/Spine/Editor.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: ad14d5a4cd7a0444286d315541ee0495 +folderAsset: yes +timeCreated: 1527569319 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Editor/spine-unity-editor.asmdef b/box1/Assets/Spine/Editor/spine-unity-editor.asmdef new file mode 100644 index 00000000..a11acd0e --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity-editor.asmdef @@ -0,0 +1,12 @@ +{ + "name": "spine-unity-editor", + "references": [ + "spine-unity" + ], + "optionalUnityReferences": [], + "includePlatforms": [ + "Editor" + ], + "excludePlatforms": [], + "allowUnsafeCode": false +} \ No newline at end of file diff --git a/box1/Assets/Spine/Editor/spine-unity-editor.asmdef.meta b/box1/Assets/Spine/Editor/spine-unity-editor.asmdef.meta new file mode 100644 index 00000000..ebee9eb6 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity-editor.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 173464ddf4cdb6640a4dfa8a9281ad69 +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Editor/spine-unity.meta b/box1/Assets/Spine/Editor/spine-unity.meta new file mode 100644 index 00000000..c83b8381 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 83fbec88df35fe34bab43a5dde6788af +folderAsset: yes +timeCreated: 1527569675 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor.meta b/box1/Assets/Spine/Editor/spine-unity/Editor.meta new file mode 100644 index 00000000..3db0fd13 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor.meta @@ -0,0 +1,5 @@ +fileFormatVersion: 2 +guid: f0e95036e72b08544a9d295dd4366f40 +folderAsset: yes +DefaultImporter: + userData: diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/Asset Types.meta b/box1/Assets/Spine/Editor/spine-unity/Editor/Asset Types.meta new file mode 100644 index 00000000..5ce846be --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/Asset Types.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: eb646ac6e394e534b80d5cac61478488 +folderAsset: yes +timeCreated: 1563305058 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/Asset Types/AnimationReferenceAssetEditor.cs b/box1/Assets/Spine/Editor/spine-unity/Editor/Asset Types/AnimationReferenceAssetEditor.cs new file mode 100644 index 00000000..7c714b9a --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/Asset Types/AnimationReferenceAssetEditor.cs @@ -0,0 +1,171 @@ +/****************************************************************************** + * 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.Collections; +using System.Collections.Generic; +using UnityEngine; +using UnityEditor; + +using System.Reflection; + +namespace Spine.Unity.Editor { + using Editor = UnityEditor.Editor; + + [CustomEditor(typeof(AnimationReferenceAsset))] + public class AnimationReferenceAssetEditor : Editor { + + const string InspectorHelpText = "This is a Spine-Unity Animation Reference Asset. It serializes a reference to a SkeletonDataAsset and an animationName. It does not contain actual animation data. At runtime, it stores a reference to a Spine.Animation.\n\n" + + "You can use this in your AnimationState calls instead of a string animation name or a Spine.Animation reference. Use its implicit conversion into Spine.Animation or its .Animation property.\n\n" + + "Use AnimationReferenceAssets as an alternative to storing strings or finding animations and caching per component. This only does the lookup by string once, and allows you to store and manage animations via asset references."; + + readonly SkeletonInspectorPreview preview = new SkeletonInspectorPreview(); + FieldInfo skeletonDataAssetField = typeof(AnimationReferenceAsset).GetField("skeletonDataAsset", BindingFlags.NonPublic | BindingFlags.Instance); + FieldInfo nameField = typeof(AnimationReferenceAsset).GetField("animationName", BindingFlags.NonPublic | BindingFlags.Instance); + + AnimationReferenceAsset ThisAnimationReferenceAsset { get { return target as AnimationReferenceAsset; } } + SkeletonDataAsset ThisSkeletonDataAsset { get { return skeletonDataAssetField.GetValue(ThisAnimationReferenceAsset) as SkeletonDataAsset; } } + string ThisAnimationName { get { return nameField.GetValue(ThisAnimationReferenceAsset) as string; } } + + bool changeNextFrame = false; + SerializedProperty animationNameProperty; + SkeletonDataAsset lastSkeletonDataAsset; + SkeletonData lastSkeletonData; + + void OnEnable () { HandleOnEnablePreview(); } + void OnDestroy () { HandleOnDestroyPreview(); } + + public override void OnInspectorGUI () { + animationNameProperty = animationNameProperty ?? serializedObject.FindProperty("animationName"); + string animationName = animationNameProperty.stringValue; + + Animation animation = null; + if (ThisSkeletonDataAsset != null) { + var skeletonData = ThisSkeletonDataAsset.GetSkeletonData(true); + if (skeletonData != null) { + animation = skeletonData.FindAnimation(animationName); + } + } + bool animationNotFound = (animation == null); + + if (changeNextFrame) { + changeNextFrame = false; + + if (ThisSkeletonDataAsset != lastSkeletonDataAsset || ThisSkeletonDataAsset.GetSkeletonData(true) != lastSkeletonData) { + preview.Clear(); + preview.Initialize(Repaint, ThisSkeletonDataAsset, LastSkinName); + + if (animationNotFound) { + animationNameProperty.stringValue = ""; + preview.ClearAnimationSetupPose(); + } + } + + preview.ClearAnimationSetupPose(); + + if (!string.IsNullOrEmpty(animationNameProperty.stringValue)) + preview.PlayPauseAnimation(animationNameProperty.stringValue, true); + } + + lastSkeletonDataAsset = ThisSkeletonDataAsset; + lastSkeletonData = ThisSkeletonDataAsset.GetSkeletonData(true); + + //EditorGUILayout.HelpBox(AnimationReferenceAssetEditor.InspectorHelpText, MessageType.Info, true); + EditorGUILayout.Space(); + EditorGUI.BeginChangeCheck(); + DrawDefaultInspector(); + if (EditorGUI.EndChangeCheck()) { + changeNextFrame = true; + } + + // Draw extra info below default inspector. + EditorGUILayout.Space(); + if (ThisSkeletonDataAsset == null) { + EditorGUILayout.HelpBox("SkeletonDataAsset is missing.", MessageType.Error); + } else if (string.IsNullOrEmpty(animationName)) { + EditorGUILayout.HelpBox("No animation selected.", MessageType.Warning); + } else if (animationNotFound) { + EditorGUILayout.HelpBox(string.Format("Animation named {0} was not found for this Skeleton.", animationNameProperty.stringValue), MessageType.Warning); + } else { + using (new SpineInspectorUtility.BoxScope()) { + if (!string.Equals(AssetUtility.GetPathSafeName(animationName), ThisAnimationReferenceAsset.name, System.StringComparison.OrdinalIgnoreCase)) + EditorGUILayout.HelpBox("Animation name value does not match this asset's name. Inspectors using this asset may be misleading.", MessageType.None); + + EditorGUILayout.LabelField(SpineInspectorUtility.TempContent(animationName, SpineEditorUtilities.Icons.animation)); + if (animation != null) { + EditorGUILayout.LabelField(string.Format("Timelines: {0}", animation.Timelines.Count)); + EditorGUILayout.LabelField(string.Format("Duration: {0} sec", animation.Duration)); + } + } + } + } + + #region Preview Handlers + string TargetAssetGUID { get { return AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(ThisSkeletonDataAsset)); } } + string LastSkinKey { get { return TargetAssetGUID + "_lastSkin"; } } + string LastSkinName { get { return EditorPrefs.GetString(LastSkinKey, ""); } } + + void HandleOnEnablePreview () { + if (ThisSkeletonDataAsset != null && ThisSkeletonDataAsset.skeletonJSON == null) + return; + + preview.Initialize(this.Repaint, ThisSkeletonDataAsset, LastSkinName); + preview.PlayPauseAnimation(ThisAnimationName, true); + preview.OnSkinChanged -= HandleOnSkinChanged; + preview.OnSkinChanged += HandleOnSkinChanged; + EditorApplication.update -= preview.HandleEditorUpdate; + EditorApplication.update += preview.HandleEditorUpdate; + } + + private void HandleOnSkinChanged (string skinName) { + EditorPrefs.SetString(LastSkinKey, skinName); + preview.PlayPauseAnimation(ThisAnimationName, true); + } + + void HandleOnDestroyPreview () { + EditorApplication.update -= preview.HandleEditorUpdate; + preview.OnDestroy(); + } + + override public bool HasPreviewGUI () { + if (serializedObject.isEditingMultipleObjects) return false; + return ThisSkeletonDataAsset != null && ThisSkeletonDataAsset.GetSkeletonData(true) != null; + } + + override public void OnInteractivePreviewGUI (Rect r, GUIStyle background) { + preview.Initialize(this.Repaint, ThisSkeletonDataAsset); + preview.HandleInteractivePreviewGUI(r, background); + } + + public override GUIContent GetPreviewTitle () { return SpineInspectorUtility.TempContent("Preview"); } + public override void OnPreviewSettings () { preview.HandleDrawSettings(); } + public override Texture2D RenderStaticPreview (string assetPath, UnityEngine.Object[] subAssets, int width, int height) { return preview.GetStaticPreview(width, height); } + #endregion + } + +} diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/Asset Types/AnimationReferenceAssetEditor.cs.meta b/box1/Assets/Spine/Editor/spine-unity/Editor/Asset Types/AnimationReferenceAssetEditor.cs.meta new file mode 100644 index 00000000..58c7aaac --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/Asset Types/AnimationReferenceAssetEditor.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 9511532e80feed24881a5863f5485446 +timeCreated: 1523316585 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/Asset Types/SkeletonDataAssetInspector.cs b/box1/Assets/Spine/Editor/spine-unity/Editor/Asset Types/SkeletonDataAssetInspector.cs new file mode 100644 index 00000000..0d28252d --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/Asset Types/SkeletonDataAssetInspector.cs @@ -0,0 +1,1213 @@ +/****************************************************************************** + * 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. + *****************************************************************************/ + +#define SPINE_SKELETON_MECANIM + + #if (UNITY_2017_4 || UNITY_2018_1_OR_NEWER ) + #define SPINE_UNITY_2018_PREVIEW_API + #endif + + +using System; +using System.Reflection; +using System.Collections.Generic; +using UnityEditor; +using UnityEngine; + +using CompatibilityProblemInfo = Spine.Unity.SkeletonDataCompatibility.CompatibilityProblemInfo; + +namespace Spine.Unity.Editor { + using Event = UnityEngine.Event; + using Icons = SpineEditorUtilities.Icons; + using Animation = Spine.Animation; + + [CustomEditor(typeof(SkeletonDataAsset)), CanEditMultipleObjects] + public class SkeletonDataAssetInspector : UnityEditor.Editor { + internal static bool showAnimationStateData = true; + internal static bool showAnimationList = true; + internal static bool showSlotList = false; + internal static bool showAttachments = false; + + SerializedProperty atlasAssets, skeletonJSON, scale, fromAnimation, toAnimation, duration, defaultMix; + SerializedProperty skeletonDataModifiers; + #if SPINE_TK2D + SerializedProperty spriteCollection; + #endif + + #if SPINE_SKELETON_MECANIM + static bool isMecanimExpanded = false; + SerializedProperty controller; + #endif + + SkeletonDataAsset targetSkeletonDataAsset; + SkeletonData targetSkeletonData; + + readonly List warnings = new List(); + CompatibilityProblemInfo compatibilityProblemInfo = null; + readonly SkeletonInspectorPreview preview = new SkeletonInspectorPreview(); + + GUIStyle activePlayButtonStyle, idlePlayButtonStyle; + readonly GUIContent DefaultMixLabel = new GUIContent("Default Mix Duration", "Sets 'SkeletonDataAsset.defaultMix' in the asset and 'AnimationState.data.defaultMix' at runtime load time."); + + string TargetAssetGUID { get { return AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(targetSkeletonDataAsset)); } } + string LastSkinKey { get { return TargetAssetGUID + "_lastSkin"; } } + string LastSkinName { get { return EditorPrefs.GetString(LastSkinKey, ""); } } + + void OnEnable () { + InitializeEditor(); + } + + void OnDestroy () { + HandleOnDestroyPreview(); + AppDomain.CurrentDomain.DomainUnload -= OnDomainUnload; + EditorApplication.update -= preview.HandleEditorUpdate; + } + + private void OnDomainUnload (object sender, EventArgs e) { + OnDestroy(); + } + + public void UpdateSkeletonData () { + preview.Clear(); + InitializeEditor(); + EditorUtility.SetDirty(targetSkeletonDataAsset); + } + + void InitializeEditor () { + SpineEditorUtilities.ConfirmInitialization(); + targetSkeletonDataAsset = (SkeletonDataAsset)target; + + bool newAtlasAssets = atlasAssets == null; + if (newAtlasAssets) atlasAssets = serializedObject.FindProperty("atlasAssets"); + skeletonJSON = serializedObject.FindProperty("skeletonJSON"); + scale = serializedObject.FindProperty("scale"); + fromAnimation = serializedObject.FindProperty("fromAnimation"); + toAnimation = serializedObject.FindProperty("toAnimation"); + duration = serializedObject.FindProperty("duration"); + defaultMix = serializedObject.FindProperty("defaultMix"); + + skeletonDataModifiers = serializedObject.FindProperty("skeletonDataModifiers"); + + #if SPINE_SKELETON_MECANIM + controller = serializedObject.FindProperty("controller"); + #endif + + #if SPINE_TK2D + if (newAtlasAssets) atlasAssets.isExpanded = false; + spriteCollection = serializedObject.FindProperty("spriteCollection"); + #else + // Analysis disable once ConvertIfToOrExpression + if (newAtlasAssets) atlasAssets.isExpanded = true; +#endif + + // This handles the case where the managed editor assembly is unloaded before recompilation when code changes. + AppDomain.CurrentDomain.DomainUnload -= OnDomainUnload; + AppDomain.CurrentDomain.DomainUnload += OnDomainUnload; + + EditorApplication.update -= preview.HandleEditorUpdate; + EditorApplication.update += preview.HandleEditorUpdate; + preview.OnSkinChanged -= HandlePreviewSkinChanged; + preview.OnSkinChanged += HandlePreviewSkinChanged; + + PopulateWarnings(); + if (targetSkeletonDataAsset.skeletonJSON == null) { + targetSkeletonData = null; + return; + } + + targetSkeletonData = NoProblems() ? targetSkeletonDataAsset.GetSkeletonData(false) : null; + + if (targetSkeletonData != null && NoProblems()) { + preview.Initialize(this.Repaint, targetSkeletonDataAsset, this.LastSkinName); + } + + } + + void Clear () { + preview.Clear(); + targetSkeletonDataAsset.Clear(); + targetSkeletonData = null; + } + + override public void OnInspectorGUI () { + // Multi-Editing + if (serializedObject.isEditingMultipleObjects) { + OnInspectorGUIMulti(); + return; + } + + { // Lazy initialization because accessing EditorStyles values in OnEnable during a recompile causes UnityEditor to throw null exceptions. (Unity 5.3.5) + idlePlayButtonStyle = idlePlayButtonStyle ?? new GUIStyle(EditorStyles.miniButton); + if (activePlayButtonStyle == null) { + activePlayButtonStyle = new GUIStyle(idlePlayButtonStyle); + activePlayButtonStyle.normal.textColor = Color.red; + } + } + + serializedObject.Update(); + + // Header + EditorGUILayout.LabelField(SpineInspectorUtility.TempContent(target.name + " (SkeletonDataAsset)", Icons.spine), EditorStyles.whiteLargeLabel); + if (targetSkeletonData != null) EditorGUILayout.LabelField("(Drag and Drop to instantiate.)", EditorStyles.miniLabel); + + // Main Serialized Fields + using (var changeCheck = new EditorGUI.ChangeCheckScope()) { + using (new SpineInspectorUtility.BoxScope()) + DrawSkeletonDataFields(); + + if (compatibilityProblemInfo != null) + return; + + using (new SpineInspectorUtility.BoxScope()) { + DrawAtlasAssetsFields(); + HandleAtlasAssetsNulls(); + } + + if (changeCheck.changed) { + if (serializedObject.ApplyModifiedProperties()) { + this.Clear(); + this.InitializeEditor(); + + if (SpineEditorUtilities.Preferences.autoReloadSceneSkeletons) + SpineEditorUtilities.DataReloadHandler.ReloadSceneSkeletonComponents(targetSkeletonDataAsset); + + return; + } + } + } + + // Unity Quirk: Some code depends on valid preview. If preview is initialized elsewhere, this can cause contents to change between Layout and Repaint events, causing GUILayout control count errors. + if (NoProblems()) + preview.Initialize(this.Repaint, targetSkeletonDataAsset, this.LastSkinName); + + if (targetSkeletonData != null) { + GUILayout.Space(20f); + + using (new SpineInspectorUtility.BoxScope(false)) { + EditorGUILayout.LabelField(SpineInspectorUtility.TempContent("Mix Settings", Icons.animationRoot), EditorStyles.boldLabel); + DrawAnimationStateInfo(); + EditorGUILayout.Space(); + } + + EditorGUILayout.LabelField("Preview", EditorStyles.boldLabel); + DrawAnimationList(); + if (targetSkeletonData.Animations.Count > 0) { + const string AnimationReferenceButtonText = "Create Animation Reference Assets"; + const string AnimationReferenceTooltipText = "AnimationReferenceAsset acts as Unity asset for a reference to a Spine.Animation. This can be used in inspectors.\n\nIt serializes a reference to a SkeletonDataAsset and an animationName.\n\nAt runtime, a reference to its Spine.Animation is loaded and cached into the object to be used as needed. This skips the need to find and cache animation references in individual MonoBehaviours."; + if (GUILayout.Button(SpineInspectorUtility.TempContent(AnimationReferenceButtonText, Icons.animationRoot, AnimationReferenceTooltipText), GUILayout.Width(250), GUILayout.Height(26))) { + CreateAnimationReferenceAssets(); + } + } + EditorGUILayout.Space(); + DrawSlotList(); + EditorGUILayout.Space(); + + DrawUnityTools(); + + } else { + #if !SPINE_TK2D + // Draw Reimport Button + using (new EditorGUI.DisabledGroupScope(skeletonJSON.objectReferenceValue == null)) { + if (GUILayout.Button(SpineInspectorUtility.TempContent("Attempt Reimport", Icons.warning))) + DoReimport(); + } + #else + EditorGUILayout.HelpBox("Couldn't load SkeletonData.", MessageType.Error); + #endif + + DrawWarningList(); + } + + if (!Application.isPlaying) + serializedObject.ApplyModifiedProperties(); + } + + void CreateAnimationReferenceAssets () { + const string AssetFolderName = "ReferenceAssets"; + string parentFolder = System.IO.Path.GetDirectoryName(AssetDatabase.GetAssetPath(targetSkeletonDataAsset)); + string dataPath = parentFolder + "/" + AssetFolderName; + if (!AssetDatabase.IsValidFolder(dataPath)) { + AssetDatabase.CreateFolder(parentFolder, AssetFolderName); + } + + FieldInfo nameField = typeof(AnimationReferenceAsset).GetField("animationName", BindingFlags.NonPublic | BindingFlags.Instance); + FieldInfo skeletonDataAssetField = typeof(AnimationReferenceAsset).GetField("skeletonDataAsset", BindingFlags.NonPublic | BindingFlags.Instance); + foreach (var animation in targetSkeletonData.Animations) { + string assetPath = string.Format("{0}/{1}.asset", dataPath, AssetUtility.GetPathSafeName(animation.Name)); + AnimationReferenceAsset existingAsset = AssetDatabase.LoadAssetAtPath(assetPath); + if (existingAsset == null) { + AnimationReferenceAsset newAsset = ScriptableObject.CreateInstance(); + skeletonDataAssetField.SetValue(newAsset, targetSkeletonDataAsset); + nameField.SetValue(newAsset, animation.Name); + AssetDatabase.CreateAsset(newAsset, assetPath); + } + } + + var folderObject = AssetDatabase.LoadAssetAtPath(dataPath, typeof(UnityEngine.Object)); + if (folderObject != null) { + Selection.activeObject = folderObject; + EditorGUIUtility.PingObject(folderObject); + } + } + + void OnInspectorGUIMulti () { + + // Skeleton data file field. + using (new SpineInspectorUtility.BoxScope()) { + EditorGUILayout.LabelField("SkeletonData", EditorStyles.boldLabel); + EditorGUILayout.PropertyField(skeletonJSON, SpineInspectorUtility.TempContent(skeletonJSON.displayName, Icons.spine)); + EditorGUILayout.DelayedFloatField(scale); //EditorGUILayout.PropertyField(scale); + EditorGUILayout.Space(); + EditorGUILayout.PropertyField(skeletonDataModifiers, true); + } + + // Texture source field. + using (new SpineInspectorUtility.BoxScope()) { + EditorGUILayout.LabelField("Atlas", EditorStyles.boldLabel); + #if !SPINE_TK2D + EditorGUILayout.PropertyField(atlasAssets, true); + #else + using (new EditorGUI.DisabledGroupScope(spriteCollection.objectReferenceValue != null)) { + EditorGUILayout.PropertyField(atlasAssets, true); + } + EditorGUILayout.LabelField("spine-tk2d", EditorStyles.boldLabel); + EditorGUILayout.PropertyField(spriteCollection, true); + #endif + } + + // Mix settings. + using (new SpineInspectorUtility.BoxScope()) { + EditorGUILayout.LabelField("Mix Settings", EditorStyles.boldLabel); + SpineInspectorUtility.PropertyFieldWideLabel(defaultMix, DefaultMixLabel, 160); + EditorGUILayout.Space(); + } + + } + + void DrawSkeletonDataFields () { + using (new EditorGUILayout.HorizontalScope()) { + EditorGUILayout.LabelField("SkeletonData", EditorStyles.boldLabel); + if (targetSkeletonData != null) { + var sd = targetSkeletonData; + string m = string.Format("{8} - {0} {1}\nBones: {2}\nConstraints: \n {5} IK \n {6} Path \n {7} Transform\n\nSlots: {3}\nSkins: {4}\n\nAnimations: {9}", + sd.Version, string.IsNullOrEmpty(sd.Version) ? "" : "export ", sd.Bones.Count, sd.Slots.Count, sd.Skins.Count, sd.IkConstraints.Count, sd.PathConstraints.Count, sd.TransformConstraints.Count, skeletonJSON.objectReferenceValue.name, sd.Animations.Count); + EditorGUILayout.LabelField(GUIContent.none, new GUIContent(Icons.info, m), GUILayout.Width(30f)); + } + } + EditorGUILayout.PropertyField(skeletonJSON, SpineInspectorUtility.TempContent(skeletonJSON.displayName, Icons.spine)); + + if (compatibilityProblemInfo != null) { + EditorGUILayout.LabelField(SpineInspectorUtility.TempContent(compatibilityProblemInfo.DescriptionString(), Icons.warning), GUILayout.Height(52)); + return; + } + + EditorGUILayout.DelayedFloatField(scale); //EditorGUILayout.PropertyField(scale); + EditorGUILayout.Space(); + EditorGUILayout.PropertyField(skeletonDataModifiers, true); + } + + void DrawAtlasAssetsFields () { + EditorGUILayout.LabelField("Atlas", EditorStyles.boldLabel); + #if !SPINE_TK2D + EditorGUILayout.PropertyField(atlasAssets, true); + #else + using (new EditorGUI.DisabledGroupScope(spriteCollection.objectReferenceValue != null)) { + EditorGUILayout.PropertyField(atlasAssets, true); + } + EditorGUILayout.LabelField("spine-tk2d", EditorStyles.boldLabel); + EditorGUILayout.PropertyField(spriteCollection, true); + #endif + + if (atlasAssets.arraySize == 0) + EditorGUILayout.HelpBox("AtlasAssets array is empty. Skeleton's attachments will load without being mapped to images.", MessageType.Info); + } + + void HandleAtlasAssetsNulls () { + bool hasNulls = false; + foreach (var a in targetSkeletonDataAsset.atlasAssets) { + if (a == null) { + hasNulls = true; + break; + } + } + if (hasNulls) { + if (targetSkeletonDataAsset.atlasAssets.Length == 1) { + EditorGUILayout.HelpBox("Atlas array cannot have null entries!", MessageType.None); + } + else { + EditorGUILayout.HelpBox("Atlas array should not have null entries!", MessageType.Error); + if (SpineInspectorUtility.CenteredButton(SpineInspectorUtility.TempContent("Remove null entries"))) { + var trimmedAtlasAssets = new List(); + foreach (var a in targetSkeletonDataAsset.atlasAssets) { + if (a != null) + trimmedAtlasAssets.Add(a); + } + targetSkeletonDataAsset.atlasAssets = trimmedAtlasAssets.ToArray(); + serializedObject.Update(); + } + } + } + } + + void DrawAnimationStateInfo () { + using (new SpineInspectorUtility.IndentScope()) + showAnimationStateData = EditorGUILayout.Foldout(showAnimationStateData, "Animation State Data"); + + if (!showAnimationStateData) + return; + + using (var cc = new EditorGUI.ChangeCheckScope()) { + using (new SpineInspectorUtility.IndentScope()) + SpineInspectorUtility.PropertyFieldWideLabel(defaultMix, DefaultMixLabel, 160); + + + if (fromAnimation.arraySize > 0) { + using (new SpineInspectorUtility.IndentScope()) { + EditorGUILayout.LabelField("Custom Mix Durations", EditorStyles.boldLabel); + } + + for (int i = 0; i < fromAnimation.arraySize; i++) { + SerializedProperty from = fromAnimation.GetArrayElementAtIndex(i); + SerializedProperty to = toAnimation.GetArrayElementAtIndex(i); + SerializedProperty durationProp = duration.GetArrayElementAtIndex(i); + using (new EditorGUILayout.HorizontalScope()) { + GUILayout.Space(16f); // Space instead of EditorGUIUtility.indentLevel. indentLevel will add the space on every field. + EditorGUILayout.PropertyField(from, GUIContent.none); + //EditorGUILayout.LabelField(">", EditorStyles.miniLabel, GUILayout.Width(9f)); + EditorGUILayout.PropertyField(to, GUIContent.none); + //GUILayout.Space(5f); + durationProp.floatValue = EditorGUILayout.FloatField(durationProp.floatValue, GUILayout.MinWidth(25f), GUILayout.MaxWidth(60f)); + if (GUILayout.Button("Delete", EditorStyles.miniButton)) { + duration.DeleteArrayElementAtIndex(i); + toAnimation.DeleteArrayElementAtIndex(i); + fromAnimation.DeleteArrayElementAtIndex(i); + } + } + } + } + + using (new EditorGUILayout.HorizontalScope()) { + EditorGUILayout.Space(); + if (GUILayout.Button("Add Custom Mix")) { + duration.arraySize++; + toAnimation.arraySize++; + fromAnimation.arraySize++; + } + EditorGUILayout.Space(); + } + + if (cc.changed) { + targetSkeletonDataAsset.FillStateData(); + EditorUtility.SetDirty(targetSkeletonDataAsset); + serializedObject.ApplyModifiedProperties(); + } + } + } + + void DrawAnimationList () { + showAnimationList = EditorGUILayout.Foldout(showAnimationList, SpineInspectorUtility.TempContent(string.Format("Animations [{0}]", targetSkeletonData.Animations.Count), Icons.animationRoot)); + if (!showAnimationList) + return; + + bool isPreviewWindowOpen = preview.IsValid; + + if (isPreviewWindowOpen) { + if (GUILayout.Button(SpineInspectorUtility.TempContent("Setup Pose", Icons.skeleton), GUILayout.Width(105), GUILayout.Height(18))) { + preview.ClearAnimationSetupPose(); + preview.RefreshOnNextUpdate(); + } + } else { + EditorGUILayout.HelpBox("Animations can be previewed if you expand the Preview window below.", MessageType.Info); + } + + EditorGUILayout.LabelField("Name", " Duration"); + //bool nonessential = targetSkeletonData.ImagesPath != null; // Currently the only way to determine if skeleton data has nonessential data. (Spine 3.6) + //float fps = targetSkeletonData.Fps; + //if (nonessential && fps == 0) fps = 30; + + var activeTrack = preview.ActiveTrack; + foreach (Animation animation in targetSkeletonData.Animations) { + using (new GUILayout.HorizontalScope()) { + if (isPreviewWindowOpen) { + bool active = activeTrack != null && activeTrack.Animation == animation; + //bool sameAndPlaying = active && activeTrack.TimeScale > 0f; + if (GUILayout.Button("\u25BA", active ? activePlayButtonStyle : idlePlayButtonStyle, GUILayout.Width(24))) { + preview.PlayPauseAnimation(animation.Name, true); + activeTrack = preview.ActiveTrack; + } + } else { + GUILayout.Label("-", GUILayout.Width(24)); + } + //string frameCountString = (fps > 0) ? ("(" + (Mathf.RoundToInt(animation.Duration * fps)) + ")").PadLeft(12, ' ') : string.Empty; + //EditorGUILayout.LabelField(new GUIContent(animation.Name, Icons.animation), SpineInspectorUtility.TempContent(animation.Duration.ToString("f3") + "s" + frameCountString)); + string durationString = animation.Duration.ToString("f3"); + EditorGUILayout.LabelField(new GUIContent(animation.Name, Icons.animation), SpineInspectorUtility.TempContent(durationString + "s", tooltip: string.Format("{0} seconds\n{1} timelines", durationString, animation.Timelines.Count))); + } + } + } + + void DrawSlotList () { + showSlotList = EditorGUILayout.Foldout(showSlotList, SpineInspectorUtility.TempContent("Slots", Icons.slotRoot)); + + if (!showSlotList) return; + if (!preview.IsValid) return; + + var defaultSkin = targetSkeletonData.DefaultSkin; + Skin skin = preview.Skeleton.Skin ?? defaultSkin; + + using (new SpineInspectorUtility.IndentScope()) { + + using (new EditorGUILayout.HorizontalScope()) { + showAttachments = EditorGUILayout.ToggleLeft("Show Attachments", showAttachments, GUILayout.MaxWidth(150f)); + if (showAttachments) { + if (skin != null) { + int attachmentCount = skin.Attachments.Count; + EditorGUILayout.LabelField(SpineInspectorUtility.TempContent(string.Format("{0} ({1} attachment{2})", skin.Name, attachmentCount, SpineInspectorUtility.PluralThenS(attachmentCount)), Icons.skin)); + } + + } + } + + var slotAttachments = new List(); + var defaultSkinAttachments = new List(); + var slotsItems = preview.Skeleton.Slots.Items; + for (int i = preview.Skeleton.Slots.Count - 1; i >= 0; i--) { + Slot slot = slotsItems[i]; + EditorGUILayout.LabelField(SpineInspectorUtility.TempContent(slot.Data.Name, Icons.slot)); + if (showAttachments) { + slotAttachments.Clear(); + defaultSkinAttachments.Clear(); + + using (new SpineInspectorUtility.IndentScope()) { + { + skin.GetAttachments(i, slotAttachments); + if (defaultSkin != null) { + if (skin != defaultSkin) { + defaultSkin.GetAttachments(i, slotAttachments); + defaultSkin.GetAttachments(i, defaultSkinAttachments); + } + else { + defaultSkin.GetAttachments(i, defaultSkinAttachments); + } + } + } + + for (int a = 0; a < slotAttachments.Count; a++) { + var skinEntry = slotAttachments[a]; + Attachment attachment = skinEntry.Attachment; + string attachmentName = skinEntry.Name; + bool attachmentIsFromSkin = !defaultSkinAttachments.Contains(skinEntry); + + Texture2D attachmentTypeIcon = Icons.GetAttachmentIcon(attachment); + bool initialState = slot.Attachment == attachment; + + Texture2D iconToUse = attachmentIsFromSkin ? Icons.skinPlaceholder : attachmentTypeIcon; + bool toggled = EditorGUILayout.ToggleLeft(SpineInspectorUtility.TempContent(attachmentName, iconToUse), slot.Attachment == attachment, GUILayout.MinWidth(150f)); + + if (attachmentIsFromSkin) { + Rect extraIconRect = GUILayoutUtility.GetLastRect(); + extraIconRect.x += extraIconRect.width - (attachmentTypeIcon.width * 2f); + extraIconRect.width = attachmentTypeIcon.width; + extraIconRect.height = attachmentTypeIcon.height; + GUI.DrawTexture(extraIconRect, attachmentTypeIcon); + } + + if (toggled != initialState) { + slot.Attachment = toggled ? attachment : null; + preview.RefreshOnNextUpdate(); + } + } + } + + } + } + } + + } + + void DrawUnityTools () { + #if SPINE_SKELETON_MECANIM + using (new SpineInspectorUtility.BoxScope()) { + isMecanimExpanded = EditorGUILayout.Foldout(isMecanimExpanded, SpineInspectorUtility.TempContent("SkeletonMecanim", SpineInspectorUtility.UnityIcon())); + if (isMecanimExpanded) { + using (new SpineInspectorUtility.IndentScope()) { + EditorGUILayout.PropertyField(controller, SpineInspectorUtility.TempContent("Controller", SpineInspectorUtility.UnityIcon())); + if (controller.objectReferenceValue == null) { + + // Generate Mecanim Controller Button + using (new GUILayout.HorizontalScope()) { + GUILayout.Space(EditorGUIUtility.labelWidth); + if (GUILayout.Button(SpineInspectorUtility.TempContent("Generate Mecanim Controller"), GUILayout.Height(20))) + SkeletonBaker.GenerateMecanimAnimationClips(targetSkeletonDataAsset); + } + EditorGUILayout.HelpBox("SkeletonMecanim is the Mecanim alternative to SkeletonAnimation.\nIt is not required.", MessageType.Info); + + } else { + + // Update AnimationClips button. + using (new GUILayout.HorizontalScope()) { + GUILayout.Space(EditorGUIUtility.labelWidth); + if (GUILayout.Button(SpineInspectorUtility.TempContent("Force Update AnimationClips"), GUILayout.Height(20))) + SkeletonBaker.GenerateMecanimAnimationClips(targetSkeletonDataAsset); + } + + } + } + } + } + #endif + } + + void DrawWarningList () { + foreach (string line in warnings) + EditorGUILayout.LabelField(SpineInspectorUtility.TempContent(line, Icons.warning)); + } + + void PopulateWarnings () { + warnings.Clear(); + compatibilityProblemInfo = null; + + if (skeletonJSON.objectReferenceValue == null) { + warnings.Add("Missing Skeleton JSON"); + } else { + var fieldValue = (TextAsset)skeletonJSON.objectReferenceValue; + + if (!AssetUtility.IsSpineData(fieldValue, out compatibilityProblemInfo)) { + warnings.Add("Skeleton data file is not a valid Spine JSON or binary file."); + } else { + #if SPINE_TK2D + bool searchForSpineAtlasAssets = true; + bool isSpriteCollectionNull = spriteCollection.objectReferenceValue == null; + if (!isSpriteCollectionNull) searchForSpineAtlasAssets = false; + #else + // Analysis disable once ConvertToConstant.Local + bool searchForSpineAtlasAssets = true; + #endif + + if (searchForSpineAtlasAssets) { + bool detectedNullAtlasEntry = false; + var atlasList = new List(); + var actualAtlasAssets = targetSkeletonDataAsset.atlasAssets; + + for (int i = 0; i < actualAtlasAssets.Length; i++) { + if (targetSkeletonDataAsset.atlasAssets[i] == null) { + detectedNullAtlasEntry = true; + break; + } else { + atlasList.Add(actualAtlasAssets[i].GetAtlas()); + } + } + + if (detectedNullAtlasEntry) { + warnings.Add("AtlasAsset elements should not be null."); + } else { + List missingPaths = null; + if (atlasAssets.arraySize > 0) { + missingPaths = AssetUtility.GetRequiredAtlasRegions(AssetDatabase.GetAssetPath(skeletonJSON.objectReferenceValue)); + + foreach (var atlas in atlasList) { + for (int i = 0; i < missingPaths.Count; i++) { + if (atlas.FindRegion(missingPaths[i]) != null) { + missingPaths.RemoveAt(i); + i--; + } + } + } + + #if SPINE_TK2D + if (missingPaths.Count > 0) + warnings.Add("Missing regions. SkeletonDataAsset requires tk2DSpriteCollectionData or Spine AtlasAssets."); + #endif + } + + if (missingPaths != null) { + foreach (string missingRegion in missingPaths) + warnings.Add(string.Format("Missing Region: '{0}'", missingRegion)); + } + + } + } + + } + } + } + + void DoReimport () { + AssetUtility.ImportSpineContent(new [] { AssetDatabase.GetAssetPath(skeletonJSON.objectReferenceValue) }, null, true); + preview.Clear(); + InitializeEditor(); + EditorUtility.SetDirty(targetSkeletonDataAsset); + } + + void HandlePreviewSkinChanged (string skinName) { + EditorPrefs.SetString(LastSkinKey, skinName); + } + + bool NoProblems() { + return warnings.Count == 0 && compatibilityProblemInfo == null; + } + + #region Preview Handlers + void HandleOnDestroyPreview () { + EditorApplication.update -= preview.HandleEditorUpdate; + preview.OnDestroy(); + } + + override public bool HasPreviewGUI () { + if (serializedObject.isEditingMultipleObjects) + return false; + + for (int i = 0; i < atlasAssets.arraySize; i++) { + var prop = atlasAssets.GetArrayElementAtIndex(i); + if (prop.objectReferenceValue == null) + return false; + } + + return skeletonJSON.objectReferenceValue != null; + } + + override public void OnInteractivePreviewGUI (Rect r, GUIStyle background) { + if (NoProblems()) { + preview.Initialize(this.Repaint, targetSkeletonDataAsset, this.LastSkinName); + preview.HandleInteractivePreviewGUI(r, background); + } + } + + override public GUIContent GetPreviewTitle () { return SpineInspectorUtility.TempContent("Preview"); } + public override void OnPreviewSettings () { preview.HandleDrawSettings(); } + public override Texture2D RenderStaticPreview (string assetPath, UnityEngine.Object[] subAssets, int width, int height) { return preview.GetStaticPreview(width, height); } + #endregion + } + + internal class SkeletonInspectorPreview { + Color OriginColor = new Color(0.3f, 0.3f, 0.3f, 1); + static readonly int SliderHash = "Slider".GetHashCode(); + + SkeletonDataAsset skeletonDataAsset; + SkeletonData skeletonData; + + SkeletonAnimation skeletonAnimation; + GameObject previewGameObject; + internal bool requiresRefresh; + float animationLastTime; + + static float CurrentTime { get { return (float)EditorApplication.timeSinceStartup; } } + + Action Repaint; + public event Action OnSkinChanged; + + Texture previewTexture; + PreviewRenderUtility previewRenderUtility; + Camera PreviewUtilityCamera { + get { + if (previewRenderUtility == null) return null; + #if UNITY_2017_1_OR_NEWER + return previewRenderUtility.camera; + #else + return previewRenderUtility.m_Camera; + #endif + } + } + + static Vector3 lastCameraPositionGoal; + static float lastCameraOrthoGoal; + float cameraOrthoGoal = 1; + Vector3 cameraPositionGoal = new Vector3(0, 0, -10); + double cameraAdjustEndFrame = 0; + + List currentAnimationEvents = new List(); + List currentAnimationEventTimes = new List(); + List currentAnimationEventTooltips = new List(); + + public bool IsValid { get { return skeletonAnimation != null && skeletonAnimation.valid; } } + + public Skeleton Skeleton { get { return IsValid ? skeletonAnimation.Skeleton : null; } } + + public float TimeScale { + get { return IsValid ? skeletonAnimation.timeScale : 1f; } + set { if (IsValid) skeletonAnimation.timeScale = value; } + } + + public bool IsPlayingAnimation { get { + if (!IsValid) return false; + var currentTrack = skeletonAnimation.AnimationState.GetCurrent(0); + return currentTrack != null && currentTrack.TimeScale > 0; + } + } + + public TrackEntry ActiveTrack { get { return IsValid ? skeletonAnimation.AnimationState.GetCurrent(0) : null; } } + + public Vector3 PreviewCameraPosition { + get { return PreviewUtilityCamera.transform.position; } + set { PreviewUtilityCamera.transform.position = value; } + } + + public void HandleDrawSettings () { + const float SliderWidth = 150; + const float SliderSnap = 0.25f; + const float SliderMin = 0f; + const float SliderMax = 2f; + + if (IsValid) { + float timeScale = GUILayout.HorizontalSlider(TimeScale, SliderMin, SliderMax, GUILayout.MaxWidth(SliderWidth)); + timeScale = Mathf.RoundToInt(timeScale / SliderSnap) * SliderSnap; + TimeScale = timeScale; + } + } + + public void HandleEditorUpdate () { + AdjustCamera(); + if (IsPlayingAnimation) { + RefreshOnNextUpdate(); + Repaint(); + } else if (requiresRefresh) { + Repaint(); + } + } + + public void Initialize (Action repaintCallback, SkeletonDataAsset skeletonDataAsset, string skinName = "") { + if (skeletonDataAsset == null) return; + if (skeletonDataAsset.GetSkeletonData(false) == null) { + DestroyPreviewGameObject(); + return; + } + + this.Repaint = repaintCallback; + this.skeletonDataAsset = skeletonDataAsset; + this.skeletonData = skeletonDataAsset.GetSkeletonData(false); + + if (skeletonData == null) { + DestroyPreviewGameObject(); + return; + } + + const int PreviewLayer = 30; + const int PreviewCameraCullingMask = 1 << PreviewLayer; + + if (previewRenderUtility == null) { + previewRenderUtility = new PreviewRenderUtility(true); + animationLastTime = CurrentTime; + + { + var c = this.PreviewUtilityCamera; + c.orthographic = true; + c.cullingMask = PreviewCameraCullingMask; + c.nearClipPlane = 0.01f; + c.farClipPlane = 1000f; + c.orthographicSize = lastCameraOrthoGoal; + c.transform.position = lastCameraPositionGoal; + } + + DestroyPreviewGameObject(); + } + + if (previewGameObject == null) { + try { + previewGameObject = EditorInstantiation.InstantiateSkeletonAnimation(skeletonDataAsset, skinName, useObjectFactory:false).gameObject; + + if (previewGameObject != null) { + previewGameObject.hideFlags = HideFlags.HideAndDontSave; + previewGameObject.layer = PreviewLayer; + skeletonAnimation = previewGameObject.GetComponent(); + skeletonAnimation.initialSkinName = skinName; + skeletonAnimation.LateUpdate(); + previewGameObject.GetComponent().enabled = false; + + #if SPINE_UNITY_2018_PREVIEW_API + previewRenderUtility.AddSingleGO(previewGameObject); + #endif + } + + if (this.ActiveTrack != null) cameraAdjustEndFrame = EditorApplication.timeSinceStartup + skeletonAnimation.AnimationState.GetCurrent(0).Alpha; + AdjustCameraGoals(); + } catch { + DestroyPreviewGameObject(); + } + + RefreshOnNextUpdate(); + } + } + + public void HandleInteractivePreviewGUI (Rect r, GUIStyle background) { + if (Event.current.type == EventType.Repaint) { + if (requiresRefresh) { + previewRenderUtility.BeginPreview(r, background); + DoRenderPreview(true); + previewTexture = previewRenderUtility.EndPreview(); + requiresRefresh = false; + } + if (previewTexture != null) + GUI.DrawTexture(r, previewTexture, ScaleMode.StretchToFill, false); + } + + DrawSkinToolbar(r); + //DrawSetupPoseButton(r); + DrawTimeBar(r); + HandleMouseScroll(r); + } + + public Texture2D GetStaticPreview (int width, int height) { + var c = this.PreviewUtilityCamera; + if (c == null) + return null; + + RefreshOnNextUpdate(); + AdjustCameraGoals(); + c.orthographicSize = cameraOrthoGoal / 2; + c.transform.position = cameraPositionGoal; + previewRenderUtility.BeginStaticPreview(new Rect(0, 0, width, height)); + DoRenderPreview(false); + var tex = previewRenderUtility.EndStaticPreview(); + + return tex; + } + + public void DoRenderPreview (bool drawHandles) { + if (this.PreviewUtilityCamera.activeTexture == null || this.PreviewUtilityCamera.targetTexture == null) + return; + + GameObject go = previewGameObject; + if (requiresRefresh && go != null) { + var renderer = go.GetComponent(); + renderer.enabled = true; + + + if (!EditorApplication.isPlaying) { + float current = CurrentTime; + float deltaTime = (current - animationLastTime); + skeletonAnimation.Update(deltaTime); + animationLastTime = current; + skeletonAnimation.LateUpdate(); + } + + var thisPreviewUtilityCamera = this.PreviewUtilityCamera; + + if (drawHandles) { + Handles.SetCamera(thisPreviewUtilityCamera); + Handles.color = OriginColor; + + // Draw Cross + float scale = skeletonDataAsset.scale; + float cl = 1000 * scale; + Handles.DrawLine(new Vector3(-cl, 0), new Vector3(cl, 0)); + Handles.DrawLine(new Vector3(0, cl), new Vector3(0, -cl)); + } + + thisPreviewUtilityCamera.Render(); + + if (drawHandles) { + Handles.SetCamera(thisPreviewUtilityCamera); + SpineHandles.DrawBoundingBoxes(skeletonAnimation.transform, skeletonAnimation.skeleton); + if (SkeletonDataAssetInspector.showAttachments) + SpineHandles.DrawPaths(skeletonAnimation.transform, skeletonAnimation.skeleton); + } + + renderer.enabled = false; + } + } + + public void AdjustCamera () { + if (previewRenderUtility == null) + return; + + if (CurrentTime < cameraAdjustEndFrame) + AdjustCameraGoals(); + + lastCameraPositionGoal = cameraPositionGoal; + lastCameraOrthoGoal = cameraOrthoGoal; + + var c = this.PreviewUtilityCamera; + float orthoSet = Mathf.Lerp(c.orthographicSize, cameraOrthoGoal, 0.1f); + + c.orthographicSize = orthoSet; + + float dist = Vector3.Distance(c.transform.position, cameraPositionGoal); + if (dist > 0f) { + Vector3 pos = Vector3.Lerp(c.transform.position, cameraPositionGoal, 0.1f); + pos.x = 0; + c.transform.position = pos; + c.transform.rotation = Quaternion.identity; + RefreshOnNextUpdate(); + } + } + + void AdjustCameraGoals () { + if (previewGameObject == null) return; + + Bounds bounds = previewGameObject.GetComponent().bounds; + cameraOrthoGoal = bounds.size.y; + cameraPositionGoal = bounds.center + new Vector3(0, 0, -10f); + } + + void HandleMouseScroll (Rect position) { + Event current = Event.current; + int controlID = GUIUtility.GetControlID(SliderHash, FocusType.Passive); + switch (current.GetTypeForControl(controlID)) { + case EventType.ScrollWheel: + if (position.Contains(current.mousePosition)) { + cameraOrthoGoal += current.delta.y * 0.06f; + cameraOrthoGoal = Mathf.Max(0.01f, cameraOrthoGoal); + GUIUtility.hotControl = controlID; + current.Use(); + } + break; + } + } + + public void RefreshOnNextUpdate () { + requiresRefresh = true; + } + + public void ClearAnimationSetupPose () { + if (skeletonAnimation == null) { + Debug.LogWarning("Animation was stopped but preview doesn't exist. It's possible that the Preview Panel is closed."); + } + + skeletonAnimation.AnimationState.ClearTracks(); + skeletonAnimation.Skeleton.SetToSetupPose(); + } + + public void PlayPauseAnimation (string animationName, bool loop) { + if (skeletonData == null) return; + + if (skeletonAnimation == null) { + //Debug.LogWarning("Animation was stopped but preview doesn't exist. It's possible that the Preview Panel is closed."); + return; + } + + if (!skeletonAnimation.valid) return; + + if (string.IsNullOrEmpty(animationName)) { + skeletonAnimation.Skeleton.SetToSetupPose(); + skeletonAnimation.AnimationState.ClearTracks(); + return; + } + + var targetAnimation = skeletonData.FindAnimation(animationName); + if (targetAnimation != null) { + var currentTrack = this.ActiveTrack; + bool isEmpty = (currentTrack == null); + bool isNewAnimation = isEmpty || currentTrack.Animation != targetAnimation; + + var skeleton = skeletonAnimation.Skeleton; + var animationState = skeletonAnimation.AnimationState; + + if (isEmpty) { + skeleton.SetToSetupPose(); + animationState.SetAnimation(0, targetAnimation, loop); + } else { + bool sameAnimation = (currentTrack.Animation == targetAnimation); + if (sameAnimation) { + currentTrack.TimeScale = (currentTrack.TimeScale == 0) ? 1f : 0f; // pause/play + } else { + currentTrack.TimeScale = 1f; + animationState.SetAnimation(0, targetAnimation, loop); + } + } + + if (isNewAnimation) { + currentAnimationEvents.Clear(); + currentAnimationEventTimes.Clear(); + foreach (Timeline timeline in targetAnimation.Timelines) { + var eventTimeline = timeline as EventTimeline; + if (eventTimeline != null) { + for (int i = 0; i < eventTimeline.Events.Length; i++) { + currentAnimationEvents.Add(eventTimeline.Events[i]); + currentAnimationEventTimes.Add(eventTimeline.Frames[i]); + } + } + } + } + } else { + Debug.LogFormat("The Spine.Animation named '{0}' was not found for this Skeleton.", animationName); + } + + } + + void DrawSkinToolbar (Rect r) { + if (!this.IsValid) return; + + var skeleton = this.Skeleton; + string label = (skeleton.Skin != null) ? skeleton.Skin.Name : "default"; + + Rect popRect = new Rect(r); + popRect.y += 32; + popRect.x += 4; + popRect.height = 24; + popRect.width = 40; + EditorGUI.DropShadowLabel(popRect, SpineInspectorUtility.TempContent("Skin")); + + popRect.y += 11; + popRect.width = 150; + popRect.x += 44; + + if (GUI.Button(popRect, SpineInspectorUtility.TempContent(label, Icons.skin), EditorStyles.popup)) { + DrawSkinDropdown(); + } + } + + void DrawSetupPoseButton (Rect r) { + if (!this.IsValid) + return; + + var skeleton = this.Skeleton; + + Rect popRect = new Rect(r); + popRect.y += 64; + popRect.x += 4; + popRect.height = 24; + popRect.width = 40; + + //popRect.y += 11; + popRect.width = 150; + //popRect.x += 44; + + if (GUI.Button(popRect, SpineInspectorUtility.TempContent("Reset to SetupPose", Icons.skeleton))) { + ClearAnimationSetupPose(); + RefreshOnNextUpdate(); + } + } + + void DrawSkinDropdown () { + var menu = new GenericMenu(); + foreach (Skin s in skeletonData.Skins) + menu.AddItem(new GUIContent(s.Name, Icons.skin), skeletonAnimation.skeleton.Skin == s, HandleSkinDropdownSelection, s); + + menu.ShowAsContext(); + } + + void HandleSkinDropdownSelection (object o) { + Skin skin = (Skin)o; + skeletonAnimation.initialSkinName = skin.Name; + skeletonAnimation.Initialize(true); + RefreshOnNextUpdate(); + if (OnSkinChanged != null) OnSkinChanged(skin.Name); + } + + void DrawTimeBar (Rect r) { + if (skeletonAnimation == null) + return; + + Rect barRect = new Rect(r); + barRect.height = 32; + barRect.x += 4; + barRect.width -= 4; + + GUI.Box(barRect, ""); + + Rect lineRect = new Rect(barRect); + float lineRectWidth = lineRect.width; + TrackEntry t = skeletonAnimation.AnimationState.GetCurrent(0); + + if (t != null) { + int loopCount = (int)(t.TrackTime / t.TrackEnd); + float currentTime = t.TrackTime - (t.TrackEnd * loopCount); + float normalizedTime = currentTime / t.Animation.Duration; + float wrappedTime = normalizedTime % 1f; + + lineRect.x = barRect.x + (lineRectWidth * wrappedTime) - 0.5f; + lineRect.width = 2; + + GUI.color = Color.red; + GUI.DrawTexture(lineRect, EditorGUIUtility.whiteTexture); + GUI.color = Color.white; + + currentAnimationEventTooltips = currentAnimationEventTooltips ?? new List(); + currentAnimationEventTooltips.Clear(); + for (int i = 0; i < currentAnimationEvents.Count; i++) { + float eventTime = currentAnimationEventTimes[i]; + var userEventIcon = Icons.userEvent; + var evRect = new Rect(barRect) { + x = Mathf.Max(((eventTime / t.Animation.Duration) * lineRectWidth) - (userEventIcon.width / 2), barRect.x), + y = barRect.y + userEventIcon.height, + width = userEventIcon.width, + height = userEventIcon.height + }; + GUI.DrawTexture(evRect, userEventIcon); + + Event ev = Event.current; + if (ev.type == EventType.Repaint) { + if (evRect.Contains(ev.mousePosition)) { + string eventName = currentAnimationEvents[i].Data.Name; + Rect tooltipRect = new Rect(evRect) { + width = EditorStyles.helpBox.CalcSize(new GUIContent(eventName)).x + }; + tooltipRect.y -= 4; + tooltipRect.y -= tooltipRect.height * currentAnimationEventTooltips.Count; // Avoid several overlapping tooltips. + tooltipRect.x += 4; + + // Handle tooltip overflowing to the right. + float rightEdgeOverflow = (tooltipRect.x + tooltipRect.width) - (barRect.x + barRect.width); + if (rightEdgeOverflow > 0) + tooltipRect.x -= rightEdgeOverflow; + + currentAnimationEventTooltips.Add(new SpineEventTooltip { rect = tooltipRect, text = eventName }); + } + } + } + + // Draw tooltips. + for (int i = 0; i < currentAnimationEventTooltips.Count; i++) { + GUI.Label(currentAnimationEventTooltips[i].rect, currentAnimationEventTooltips[i].text, EditorStyles.helpBox); + GUI.tooltip = currentAnimationEventTooltips[i].text; + } + } + } + + public void OnDestroy () { + DisposePreviewRenderUtility(); + DestroyPreviewGameObject(); + } + + public void Clear () { + DisposePreviewRenderUtility(); + DestroyPreviewGameObject(); + } + + void DisposePreviewRenderUtility () { + if (previewRenderUtility != null) { + previewRenderUtility.Cleanup(); + previewRenderUtility = null; + } + } + + void DestroyPreviewGameObject () { + if (previewGameObject != null) { + GameObject.DestroyImmediate(previewGameObject); + previewGameObject = null; + } + } + + internal struct SpineEventTooltip { + public Rect rect; + public string text; + } + } + +} diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/Asset Types/SkeletonDataAssetInspector.cs.meta b/box1/Assets/Spine/Editor/spine-unity/Editor/Asset Types/SkeletonDataAssetInspector.cs.meta new file mode 100644 index 00000000..fba64b6e --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/Asset Types/SkeletonDataAssetInspector.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 01cbef8f24d105f4bafa9668d669e040 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/Asset Types/SpineAtlasAssetInspector.cs b/box1/Assets/Spine/Editor/spine-unity/Editor/Asset Types/SpineAtlasAssetInspector.cs new file mode 100644 index 00000000..f1c70256 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/Asset Types/SpineAtlasAssetInspector.cs @@ -0,0 +1,380 @@ +/****************************************************************************** + * 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. + *****************************************************************************/ + +//#define BAKE_ALL_BUTTON +//#define REGION_BAKING_MESH + +using System; +using System.Collections.Generic; +using System.Reflection; +using UnityEditor; +using UnityEngine; +using Spine; + +namespace Spine.Unity.Editor { + using Event = UnityEngine.Event; + + [CustomEditor(typeof(SpineAtlasAsset)), CanEditMultipleObjects] + public class SpineAtlasAssetInspector : UnityEditor.Editor { + SerializedProperty atlasFile, materials; + SpineAtlasAsset atlasAsset; + + GUIContent spriteSlicesLabel; + GUIContent SpriteSlicesLabel { + get { + if (spriteSlicesLabel == null) { + spriteSlicesLabel = new GUIContent( + "Apply Regions as Texture Sprite Slices", + SpineEditorUtilities.Icons.unity, + "Adds Sprite slices to atlas texture(s). " + + "Updates existing slices if ones with matching names exist. \n\n" + + "If your atlas was exported with Premultiply Alpha, " + + "your SpriteRenderer should use the generated Spine _Material asset (or any Material with a PMA shader) instead of Sprites-Default."); + } + return spriteSlicesLabel; + } + } + + static List GetRegions (Atlas atlas) { + FieldInfo regionsField = SpineInspectorUtility.GetNonPublicField(typeof(Atlas), "regions"); + return (List)regionsField.GetValue(atlas); + } + + void OnEnable () { + SpineEditorUtilities.ConfirmInitialization(); + atlasFile = serializedObject.FindProperty("atlasFile"); + materials = serializedObject.FindProperty("materials"); + materials.isExpanded = true; + atlasAsset = (SpineAtlasAsset)target; + #if REGION_BAKING_MESH + UpdateBakedList(); + #endif + } + + #if REGION_BAKING_MESH + private List baked; + private List bakedObjects; + + void UpdateBakedList () { + AtlasAsset asset = (AtlasAsset)target; + baked = new List(); + bakedObjects = new List(); + if (atlasFile.objectReferenceValue != null) { + List regions = this.Regions; + string atlasAssetPath = AssetDatabase.GetAssetPath(atlasAsset); + string atlasAssetDirPath = Path.GetDirectoryName(atlasAssetPath); + string bakedDirPath = Path.Combine(atlasAssetDirPath, atlasAsset.name); + for (int i = 0; i < regions.Count; i++) { + AtlasRegion region = regions[i]; + string bakedPrefabPath = Path.Combine(bakedDirPath, AssetUtility.GetPathSafeRegionName(region) + ".prefab").Replace("\\", "/"); + GameObject prefab = (GameObject)AssetDatabase.LoadAssetAtPath(bakedPrefabPath, typeof(GameObject)); + baked.Add(prefab != null); + bakedObjects.Add(prefab); + } + } + } + #endif + + override public void OnInspectorGUI () { + if (serializedObject.isEditingMultipleObjects) { + DrawDefaultInspector(); + return; + } + + serializedObject.Update(); + atlasAsset = atlasAsset ?? (SpineAtlasAsset)target; + EditorGUI.BeginChangeCheck(); + EditorGUILayout.PropertyField(atlasFile); + EditorGUILayout.PropertyField(materials, true); + if (EditorGUI.EndChangeCheck()) { + serializedObject.ApplyModifiedProperties(); + atlasAsset.Clear(); + atlasAsset.GetAtlas(); + } + + if (materials.arraySize == 0) { + EditorGUILayout.HelpBox("No materials", MessageType.Error); + return; + } + + for (int i = 0; i < materials.arraySize; i++) { + SerializedProperty prop = materials.GetArrayElementAtIndex(i); + var material = (Material)prop.objectReferenceValue; + if (material == null) { + EditorGUILayout.HelpBox("Materials cannot be null.", MessageType.Error); + return; + } + } + + EditorGUILayout.Space(); + if (SpineInspectorUtility.LargeCenteredButton(SpineInspectorUtility.TempContent("Set Mipmap Bias to " + SpinePreferences.DEFAULT_MIPMAPBIAS, tooltip: "This may help textures with mipmaps be less blurry when used for 2D sprites."))) { + foreach (var m in atlasAsset.materials) { + var texture = m.mainTexture; + texture.mipMapBias = SpinePreferences.DEFAULT_MIPMAPBIAS; + } + Debug.Log("Texture mipmap bias set to " + SpinePreferences.DEFAULT_MIPMAPBIAS); + } + + EditorGUILayout.Space(); + if (atlasFile.objectReferenceValue != null) { + if (SpineInspectorUtility.LargeCenteredButton(SpriteSlicesLabel)) { + var atlas = atlasAsset.GetAtlas(); + foreach (var m in atlasAsset.materials) + UpdateSpriteSlices(m.mainTexture, atlas); + } + } + + EditorGUILayout.Space(); + + #if REGION_BAKING_MESH + if (atlasFile.objectReferenceValue != null) { + Atlas atlas = asset.GetAtlas(); + FieldInfo field = typeof(Atlas).GetField("regions", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.NonPublic); + List regions = (List)field.GetValue(atlas); + EditorGUILayout.LabelField(new GUIContent("Region Baking", SpineEditorUtilities.Icons.unityIcon)); + EditorGUI.indentLevel++; + AtlasPage lastPage = null; + for (int i = 0; i < regions.Count; i++) { + if (lastPage != regions[i].page) { + if (lastPage != null) { + EditorGUILayout.Separator(); + EditorGUILayout.Separator(); + } + lastPage = regions[i].page; + Material mat = ((Material)lastPage.rendererObject); + if (mat != null) { + GUILayout.BeginHorizontal(); + { + EditorGUI.BeginDisabledGroup(true); + EditorGUILayout.ObjectField(mat, typeof(Material), false, GUILayout.Width(250)); + EditorGUI.EndDisabledGroup(); + } + GUILayout.EndHorizontal(); + + } else { + EditorGUILayout.LabelField(new GUIContent("Page missing material!", SpineEditorUtilities.Icons.warning)); + } + } + GUILayout.BeginHorizontal(); + { + //EditorGUILayout.ToggleLeft(baked[i] ? "" : regions[i].name, baked[i]); + bool result = baked[i] ? EditorGUILayout.ToggleLeft("", baked[i], GUILayout.Width(24)) : EditorGUILayout.ToggleLeft(" " + regions[i].name, baked[i]); + if(baked[i]){ + EditorGUILayout.ObjectField(bakedObjects[i], typeof(GameObject), false, GUILayout.Width(250)); + } + if (result && !baked[i]) { + //bake + baked[i] = true; + bakedObjects[i] = SpineEditorUtilities.BakeRegion(atlasAsset, regions[i]); + EditorGUIUtility.PingObject(bakedObjects[i]); + } else if (!result && baked[i]) { + //unbake + bool unbakeResult = EditorUtility.DisplayDialog("Delete Baked Region", "Do you want to delete the prefab for " + regions[i].name, "Yes", "Cancel"); + switch (unbakeResult) { + case true: + //delete + string atlasAssetPath = AssetDatabase.GetAssetPath(atlasAsset); + string atlasAssetDirPath = Path.GetDirectoryName(atlasAssetPath); + string bakedDirPath = Path.Combine(atlasAssetDirPath, atlasAsset.name); + string bakedPrefabPath = Path.Combine(bakedDirPath, SpineEditorUtilities.GetPathSafeRegionName(regions[i]) + ".prefab").Replace("\\", "/"); + AssetDatabase.DeleteAsset(bakedPrefabPath); + baked[i] = false; + break; + case false: + //do nothing + break; + } + } + } + GUILayout.EndHorizontal(); + } + EditorGUI.indentLevel--; + + #if BAKE_ALL_BUTTON + // Check state + bool allBaked = true; + bool allUnbaked = true; + for (int i = 0; i < regions.Count; i++) { + allBaked &= baked[i]; + allUnbaked &= !baked[i]; + } + + if (!allBaked && GUILayout.Button("Bake All")) { + for (int i = 0; i < regions.Count; i++) { + if (!baked[i]) { + baked[i] = true; + bakedObjects[i] = SpineEditorUtilities.BakeRegion(atlasAsset, regions[i]); + } + } + + } else if (!allUnbaked && GUILayout.Button("Unbake All")) { + bool unbakeResult = EditorUtility.DisplayDialog("Delete All Baked Regions", "Are you sure you want to unbake all region prefabs? This cannot be undone.", "Yes", "Cancel"); + switch (unbakeResult) { + case true: + //delete + for (int i = 0; i < regions.Count; i++) { + if (baked[i]) { + string atlasAssetPath = AssetDatabase.GetAssetPath(atlasAsset); + string atlasAssetDirPath = Path.GetDirectoryName(atlasAssetPath); + string bakedDirPath = Path.Combine(atlasAssetDirPath, atlasAsset.name); + string bakedPrefabPath = Path.Combine(bakedDirPath, SpineEditorUtilities.GetPathSafeRegionName(regions[i]) + ".prefab").Replace("\\", "/"); + AssetDatabase.DeleteAsset(bakedPrefabPath); + baked[i] = false; + } + } + break; + case false: + //do nothing + break; + } + + } + #endif + + } + #else + if (atlasFile.objectReferenceValue != null) { + + + int baseIndent = EditorGUI.indentLevel; + + var regions = SpineAtlasAssetInspector.GetRegions(atlasAsset.GetAtlas()); + int regionsCount = regions.Count; + using (new EditorGUILayout.HorizontalScope()) { + EditorGUILayout.LabelField("Atlas Regions", EditorStyles.boldLabel); + EditorGUILayout.LabelField(string.Format("{0} regions total", regionsCount)); + } + AtlasPage lastPage = null; + for (int i = 0; i < regionsCount; i++) { + if (lastPage != regions[i].page) { + if (lastPage != null) { + EditorGUILayout.Separator(); + EditorGUILayout.Separator(); + } + lastPage = regions[i].page; + Material mat = ((Material)lastPage.rendererObject); + if (mat != null) { + EditorGUI.indentLevel = baseIndent; + using (new GUILayout.HorizontalScope()) + using (new EditorGUI.DisabledGroupScope(true)) + EditorGUILayout.ObjectField(mat, typeof(Material), false, GUILayout.Width(250)); + EditorGUI.indentLevel = baseIndent + 1; + } else { + EditorGUILayout.HelpBox("Page missing material!", MessageType.Warning); + } + } + + string regionName = regions[i].name; + Texture2D icon = SpineEditorUtilities.Icons.image; + if (regionName.EndsWith(" ")) { + regionName = string.Format("'{0}'", regions[i].name); + icon = SpineEditorUtilities.Icons.warning; + EditorGUILayout.LabelField(SpineInspectorUtility.TempContent(regionName, icon, "Region name ends with whitespace. This may cause errors. Please check your source image filenames.")); + } else { + EditorGUILayout.LabelField(SpineInspectorUtility.TempContent(regionName, icon)); + } + + } + EditorGUI.indentLevel = baseIndent; + } + #endif + + if (serializedObject.ApplyModifiedProperties() || SpineInspectorUtility.UndoRedoPerformed(Event.current)) + atlasAsset.Clear(); + } + + static public void UpdateSpriteSlices (Texture texture, Atlas atlas) { + string texturePath = AssetDatabase.GetAssetPath(texture.GetInstanceID()); + var t = (TextureImporter)TextureImporter.GetAtPath(texturePath); + t.spriteImportMode = SpriteImportMode.Multiple; + var spriteSheet = t.spritesheet; + var sprites = new List(spriteSheet); + + var regions = SpineAtlasAssetInspector.GetRegions(atlas); + char[] FilenameDelimiter = {'.'}; + int updatedCount = 0; + int addedCount = 0; + + foreach (var r in regions) { + string pageName = r.page.name.Split(FilenameDelimiter, StringSplitOptions.RemoveEmptyEntries)[0]; + string textureName = texture.name; + bool pageMatch = string.Equals(pageName, textureName, StringComparison.Ordinal); + +// if (pageMatch) { +// int pw = r.page.width; +// int ph = r.page.height; +// bool mismatchSize = pw != texture.width || pw > t.maxTextureSize || ph != texture.height || ph > t.maxTextureSize; +// if (mismatchSize) +// Debug.LogWarningFormat("Size mismatch found.\nExpected atlas size is {0}x{1}. Texture Import Max Size of texture '{2}'({4}x{5}) is currently set to {3}.", pw, ph, texture.name, t.maxTextureSize, texture.width, texture.height); +// } + + int spriteIndex = pageMatch ? sprites.FindIndex( + (s) => string.Equals(s.name, r.name, StringComparison.Ordinal) + ) : -1; + bool spriteNameMatchExists = spriteIndex >= 0; + + if (pageMatch) { + Rect spriteRect = new Rect(); + + if (r.rotate) { + spriteRect.width = r.height; + spriteRect.height = r.width; + } else { + spriteRect.width = r.width; + spriteRect.height = r.height; + } + spriteRect.x = r.x; + spriteRect.y = r.page.height - spriteRect.height - r.y; + + if (spriteNameMatchExists) { + var s = sprites[spriteIndex]; + s.rect = spriteRect; + sprites[spriteIndex] = s; + updatedCount++; + } else { + sprites.Add(new SpriteMetaData { + name = r.name, + pivot = new Vector2(0.5f, 0.5f), + rect = spriteRect + }); + addedCount++; + } + } + + } + + t.spritesheet = sprites.ToArray(); + EditorUtility.SetDirty(t); + AssetDatabase.ImportAsset(texturePath, ImportAssetOptions.ForceUpdate); + EditorGUIUtility.PingObject(texture); + Debug.Log(string.Format("Applied sprite slices to {2}. {0} added. {1} updated.", addedCount, updatedCount, texture.name)); + } + } + +} diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/Asset Types/SpineAtlasAssetInspector.cs.meta b/box1/Assets/Spine/Editor/spine-unity/Editor/Asset Types/SpineAtlasAssetInspector.cs.meta new file mode 100644 index 00000000..2f5962a1 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/Asset Types/SpineAtlasAssetInspector.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: ca9b3ce36d70a05408e3bdd5e92c7f64 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/Asset Types/SpineSpriteAtlasAssetInspector.cs b/box1/Assets/Spine/Editor/spine-unity/Editor/Asset Types/SpineSpriteAtlasAssetInspector.cs new file mode 100644 index 00000000..14451ee0 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/Asset Types/SpineSpriteAtlasAssetInspector.cs @@ -0,0 +1,153 @@ +/****************************************************************************** + * 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.Reflection; +using UnityEditor; +using UnityEngine; +using Spine; + +namespace Spine.Unity.Editor { + using Event = UnityEngine.Event; + + [CustomEditor(typeof(SpineSpriteAtlasAsset)), CanEditMultipleObjects] + public class SpineSpriteAtlasAssetInspector : UnityEditor.Editor { + SerializedProperty atlasFile, materials; + SpineSpriteAtlasAsset atlasAsset; + + static List GetRegions (Atlas atlas) { + FieldInfo regionsField = SpineInspectorUtility.GetNonPublicField(typeof(Atlas), "regions"); + return (List)regionsField.GetValue(atlas); + } + + void OnEnable () { + SpineEditorUtilities.ConfirmInitialization(); + atlasFile = serializedObject.FindProperty("spriteAtlasFile"); + materials = serializedObject.FindProperty("materials"); + materials.isExpanded = true; + atlasAsset = (SpineSpriteAtlasAsset)target; + + if (!SpineSpriteAtlasAsset.AnySpriteAtlasNeedsRegionsLoaded()) + return; + EditorApplication.update -= SpineSpriteAtlasAsset.UpdateWhenEditorPlayModeStarted; + EditorApplication.update += SpineSpriteAtlasAsset.UpdateWhenEditorPlayModeStarted; + } + + void OnDisable () { + EditorApplication.update -= SpineSpriteAtlasAsset.UpdateWhenEditorPlayModeStarted; + } + + override public void OnInspectorGUI () { + if (serializedObject.isEditingMultipleObjects) { + DrawDefaultInspector(); + return; + } + + serializedObject.Update(); + atlasAsset = atlasAsset ?? (SpineSpriteAtlasAsset)target; + + if (atlasAsset.RegionsNeedLoading) { + if (GUILayout.Button(SpineInspectorUtility.TempContent("Load regions by entering Play mode"), GUILayout.Height(20))) { + EditorApplication.isPlaying = true; + } + } + + EditorGUI.BeginChangeCheck(); + EditorGUILayout.PropertyField(atlasFile); + EditorGUILayout.PropertyField(materials, true); + if (EditorGUI.EndChangeCheck()) { + serializedObject.ApplyModifiedProperties(); + atlasAsset.Clear(); + atlasAsset.GetAtlas(); + atlasAsset.updateRegionsInPlayMode = true; + } + + if (materials.arraySize == 0) { + EditorGUILayout.HelpBox("No materials", MessageType.Error); + return; + } + + for (int i = 0; i < materials.arraySize; i++) { + SerializedProperty prop = materials.GetArrayElementAtIndex(i); + var material = (Material)prop.objectReferenceValue; + if (material == null) { + EditorGUILayout.HelpBox("Materials cannot be null.", MessageType.Error); + return; + } + } + + if (atlasFile.objectReferenceValue != null) { + int baseIndent = EditorGUI.indentLevel; + + var regions = SpineSpriteAtlasAssetInspector.GetRegions(atlasAsset.GetAtlas()); + int regionsCount = regions.Count; + using (new EditorGUILayout.HorizontalScope()) { + EditorGUILayout.LabelField("Atlas Regions", EditorStyles.boldLabel); + EditorGUILayout.LabelField(string.Format("{0} regions total", regionsCount)); + } + AtlasPage lastPage = null; + for (int i = 0; i < regionsCount; i++) { + if (lastPage != regions[i].page) { + if (lastPage != null) { + EditorGUILayout.Separator(); + EditorGUILayout.Separator(); + } + lastPage = regions[i].page; + Material mat = ((Material)lastPage.rendererObject); + if (mat != null) { + EditorGUI.indentLevel = baseIndent; + using (new GUILayout.HorizontalScope()) + using (new EditorGUI.DisabledGroupScope(true)) + EditorGUILayout.ObjectField(mat, typeof(Material), false, GUILayout.Width(250)); + EditorGUI.indentLevel = baseIndent + 1; + } else { + EditorGUILayout.HelpBox("Page missing material!", MessageType.Warning); + } + } + + string regionName = regions[i].name; + Texture2D icon = SpineEditorUtilities.Icons.image; + if (regionName.EndsWith(" ")) { + regionName = string.Format("'{0}'", regions[i].name); + icon = SpineEditorUtilities.Icons.warning; + EditorGUILayout.LabelField(SpineInspectorUtility.TempContent(regionName, icon, "Region name ends with whitespace. This may cause errors. Please check your source image filenames.")); + } else { + EditorGUILayout.LabelField(SpineInspectorUtility.TempContent(regionName, icon)); + } + } + EditorGUI.indentLevel = baseIndent; + } + + if (serializedObject.ApplyModifiedProperties() || SpineInspectorUtility.UndoRedoPerformed(Event.current)) + atlasAsset.Clear(); + } + } + +} diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/Asset Types/SpineSpriteAtlasAssetInspector.cs.meta b/box1/Assets/Spine/Editor/spine-unity/Editor/Asset Types/SpineSpriteAtlasAssetInspector.cs.meta new file mode 100644 index 00000000..238789e9 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/Asset Types/SpineSpriteAtlasAssetInspector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f063dc5ff6881db4a9ee2e059812cba2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/Components.meta b/box1/Assets/Spine/Editor/spine-unity/Editor/Components.meta new file mode 100644 index 00000000..a6574b21 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/Components.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 0134640f881c8d24d812a6f9af9d0761 +folderAsset: yes +timeCreated: 1563304704 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/Components/BoneFollowerGraphicInspector.cs b/box1/Assets/Spine/Editor/spine-unity/Editor/Components/BoneFollowerGraphicInspector.cs new file mode 100644 index 00000000..53570bb0 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/Components/BoneFollowerGraphicInspector.cs @@ -0,0 +1,200 @@ +/****************************************************************************** + * 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 UnityEditor; +using Spine.Unity; + +namespace Spine.Unity.Editor { + + using Editor = UnityEditor.Editor; + using Event = UnityEngine.Event; + + [CustomEditor(typeof(BoneFollowerGraphic)), CanEditMultipleObjects] + public class BoneFollowerGraphicInspector : Editor { + + SerializedProperty boneName, skeletonGraphic, followXYPosition, followZPosition, followBoneRotation, followLocalScale, followSkeletonFlip; + BoneFollowerGraphic targetBoneFollower; + bool needsReset; + + #region Context Menu Item + [MenuItem ("CONTEXT/SkeletonGraphic/Add BoneFollower GameObject")] + static void AddBoneFollowerGameObject (MenuCommand cmd) { + var skeletonGraphic = cmd.context as SkeletonGraphic; + var go = EditorInstantiation.NewGameObject("BoneFollower", true, typeof(RectTransform)); + var t = go.transform; + t.SetParent(skeletonGraphic.transform); + t.localPosition = Vector3.zero; + + var f = go.AddComponent(); + f.skeletonGraphic = skeletonGraphic; + f.SetBone(skeletonGraphic.Skeleton.RootBone.Data.Name); + + EditorGUIUtility.PingObject(t); + + Undo.RegisterCreatedObjectUndo(go, "Add BoneFollowerGraphic"); + } + + // Validate + [MenuItem ("CONTEXT/SkeletonGraphic/Add BoneFollower GameObject", true)] + static bool ValidateAddBoneFollowerGameObject (MenuCommand cmd) { + var skeletonGraphic = cmd.context as SkeletonGraphic; + return skeletonGraphic.IsValid; + } + #endregion + + void OnEnable () { + skeletonGraphic = serializedObject.FindProperty("skeletonGraphic"); + boneName = serializedObject.FindProperty("boneName"); + followBoneRotation = serializedObject.FindProperty("followBoneRotation"); + followXYPosition = serializedObject.FindProperty("followXYPosition"); + followZPosition = serializedObject.FindProperty("followZPosition"); + followLocalScale = serializedObject.FindProperty("followLocalScale"); + followSkeletonFlip = serializedObject.FindProperty("followSkeletonFlip"); + + targetBoneFollower = (BoneFollowerGraphic)target; + if (targetBoneFollower.SkeletonGraphic != null) + targetBoneFollower.SkeletonGraphic.Initialize(false); + + if (!targetBoneFollower.valid || needsReset) { + targetBoneFollower.Initialize(); + targetBoneFollower.LateUpdate(); + needsReset = false; + SceneView.RepaintAll(); + } + } + + public void OnSceneGUI () { + var tbf = target as BoneFollowerGraphic; + var skeletonGraphicComponent = tbf.SkeletonGraphic; + if (skeletonGraphicComponent == null) return; + + var transform = skeletonGraphicComponent.transform; + var skeleton = skeletonGraphicComponent.Skeleton; + var canvas = skeletonGraphicComponent.canvas; + float positionScale = canvas == null ? 1f : skeletonGraphicComponent.canvas.referencePixelsPerUnit; + + if (string.IsNullOrEmpty(boneName.stringValue)) { + SpineHandles.DrawBones(transform, skeleton, positionScale); + SpineHandles.DrawBoneNames(transform, skeleton, positionScale); + Handles.Label(tbf.transform.position, "No bone selected", EditorStyles.helpBox); + } else { + var targetBone = tbf.bone; + if (targetBone == null) return; + + SpineHandles.DrawBoneWireframe(transform, targetBone, SpineHandles.TransformContraintColor, positionScale); + Handles.Label(targetBone.GetWorldPosition(transform, positionScale), targetBone.Data.Name, SpineHandles.BoneNameStyle); + } + } + + override public void OnInspectorGUI () { + if (serializedObject.isEditingMultipleObjects) { + if (needsReset) { + needsReset = false; + foreach (var o in targets) { + var bf = (BoneFollower)o; + bf.Initialize(); + bf.LateUpdate(); + } + SceneView.RepaintAll(); + } + + EditorGUI.BeginChangeCheck(); + DrawDefaultInspector(); + needsReset |= EditorGUI.EndChangeCheck(); + return; + } + + if (needsReset && Event.current.type == EventType.Layout) { + targetBoneFollower.Initialize(); + targetBoneFollower.LateUpdate(); + needsReset = false; + SceneView.RepaintAll(); + } + serializedObject.Update(); + + // Find Renderer + if (skeletonGraphic.objectReferenceValue == null) { + SkeletonGraphic parentRenderer = targetBoneFollower.GetComponentInParent(); + if (parentRenderer != null && parentRenderer.gameObject != targetBoneFollower.gameObject) { + skeletonGraphic.objectReferenceValue = parentRenderer; + Debug.Log("Inspector automatically assigned BoneFollowerGraphic.SkeletonGraphic"); + } + } + + EditorGUILayout.PropertyField(skeletonGraphic); + var skeletonGraphicComponent = skeletonGraphic.objectReferenceValue as SkeletonGraphic; + if (skeletonGraphicComponent != null) { + if (skeletonGraphicComponent.gameObject == targetBoneFollower.gameObject) { + skeletonGraphic.objectReferenceValue = null; + EditorUtility.DisplayDialog("Invalid assignment.", "BoneFollowerGraphic can only follow a skeleton on a separate GameObject.\n\nCreate a new GameObject for your BoneFollower, or choose a SkeletonGraphic from a different GameObject.", "Ok"); + } + } + + if (!targetBoneFollower.valid) { + needsReset = true; + } + + if (targetBoneFollower.valid) { + EditorGUI.BeginChangeCheck(); + EditorGUILayout.PropertyField(boneName); + needsReset |= EditorGUI.EndChangeCheck(); + + EditorGUILayout.PropertyField(followBoneRotation); + EditorGUILayout.PropertyField(followXYPosition); + EditorGUILayout.PropertyField(followZPosition); + EditorGUILayout.PropertyField(followLocalScale); + EditorGUILayout.PropertyField(followSkeletonFlip); + + //BoneFollowerInspector.RecommendRigidbodyButton(targetBoneFollower); + } else { + var boneFollowerSkeletonGraphic = targetBoneFollower.skeletonGraphic; + if (boneFollowerSkeletonGraphic == null) { + EditorGUILayout.HelpBox("SkeletonGraphic is unassigned. Please assign a SkeletonRenderer (SkeletonAnimation or SkeletonMecanim).", MessageType.Warning); + } else { + boneFollowerSkeletonGraphic.Initialize(false); + + if (boneFollowerSkeletonGraphic.skeletonDataAsset == null) + EditorGUILayout.HelpBox("Assigned SkeletonGraphic does not have SkeletonData assigned to it.", MessageType.Warning); + + if (!boneFollowerSkeletonGraphic.IsValid) + EditorGUILayout.HelpBox("Assigned SkeletonGraphic is invalid. Check target SkeletonGraphic, its SkeletonDataAsset or the console for other errors.", MessageType.Warning); + } + } + + var current = Event.current; + bool wasUndo = (current.type == EventType.ValidateCommand && current.commandName == "UndoRedoPerformed"); + if (wasUndo) + targetBoneFollower.Initialize(); + + serializedObject.ApplyModifiedProperties(); + } + + } +} diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/Components/BoneFollowerGraphicInspector.cs.meta b/box1/Assets/Spine/Editor/spine-unity/Editor/Components/BoneFollowerGraphicInspector.cs.meta new file mode 100644 index 00000000..b3d60a49 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/Components/BoneFollowerGraphicInspector.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: da44a8561fd243c43a1f77bda36de0eb +timeCreated: 1499279157 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/Components/BoneFollowerInspector.cs b/box1/Assets/Spine/Editor/spine-unity/Editor/Components/BoneFollowerInspector.cs new file mode 100644 index 00000000..4bdae2e6 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/Components/BoneFollowerInspector.cs @@ -0,0 +1,221 @@ +/****************************************************************************** + * 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 UnityEditor; +using UnityEngine; + +namespace Spine.Unity.Editor { + + using Editor = UnityEditor.Editor; + using Event = UnityEngine.Event; + + [CustomEditor(typeof(BoneFollower)), CanEditMultipleObjects] + public class BoneFollowerInspector : Editor { + SerializedProperty boneName, skeletonRenderer, followXYPosition, followZPosition, followBoneRotation, followLocalScale, followSkeletonFlip; + BoneFollower targetBoneFollower; + bool needsReset; + + #region Context Menu Item + [MenuItem ("CONTEXT/SkeletonRenderer/Add BoneFollower GameObject")] + static void AddBoneFollowerGameObject (MenuCommand cmd) { + var skeletonRenderer = cmd.context as SkeletonRenderer; + var go = EditorInstantiation.NewGameObject("New BoneFollower", true); + var t = go.transform; + t.SetParent(skeletonRenderer.transform); + t.localPosition = Vector3.zero; + + var f = go.AddComponent(); + f.skeletonRenderer = skeletonRenderer; + + EditorGUIUtility.PingObject(t); + + Undo.RegisterCreatedObjectUndo(go, "Add BoneFollower"); + } + + // Validate + [MenuItem ("CONTEXT/SkeletonRenderer/Add BoneFollower GameObject", true)] + static bool ValidateAddBoneFollowerGameObject (MenuCommand cmd) { + var skeletonRenderer = cmd.context as SkeletonRenderer; + return skeletonRenderer.valid; + } + + [MenuItem("CONTEXT/BoneFollower/Rename BoneFollower GameObject")] + static void RenameGameObject (MenuCommand cmd) { + AutonameGameObject(cmd.context as BoneFollower); + } + #endregion + + static void AutonameGameObject (BoneFollower boneFollower) { + if (boneFollower == null) return; + + string boneName = boneFollower.boneName; + boneFollower.gameObject.name = string.IsNullOrEmpty(boneName) ? "BoneFollower" : string.Format("{0} (BoneFollower)", boneName); + } + + void OnEnable () { + skeletonRenderer = serializedObject.FindProperty("skeletonRenderer"); + boneName = serializedObject.FindProperty("boneName"); + followBoneRotation = serializedObject.FindProperty("followBoneRotation"); + followXYPosition = serializedObject.FindProperty("followXYPosition"); + followZPosition = serializedObject.FindProperty("followZPosition"); + followLocalScale = serializedObject.FindProperty("followLocalScale"); + followSkeletonFlip = serializedObject.FindProperty("followSkeletonFlip"); + + targetBoneFollower = (BoneFollower)target; + if (targetBoneFollower.SkeletonRenderer != null) + targetBoneFollower.SkeletonRenderer.Initialize(false); + + if (!targetBoneFollower.valid || needsReset) { + targetBoneFollower.Initialize(); + targetBoneFollower.LateUpdate(); + needsReset = false; + SceneView.RepaintAll(); + } + } + + public void OnSceneGUI () { + var tbf = target as BoneFollower; + var skeletonRendererComponent = tbf.skeletonRenderer; + if (skeletonRendererComponent == null) return; + + var transform = skeletonRendererComponent.transform; + var skeleton = skeletonRendererComponent.skeleton; + + if (string.IsNullOrEmpty(boneName.stringValue)) { + SpineHandles.DrawBones(transform, skeleton); + SpineHandles.DrawBoneNames(transform, skeleton); + Handles.Label(tbf.transform.position, "No bone selected", EditorStyles.helpBox); + } else { + var targetBone = tbf.bone; + if (targetBone == null) return; + SpineHandles.DrawBoneWireframe(transform, targetBone, SpineHandles.TransformContraintColor); + Handles.Label(targetBone.GetWorldPosition(transform), targetBone.Data.Name, SpineHandles.BoneNameStyle); + } + } + + override public void OnInspectorGUI () { + if (serializedObject.isEditingMultipleObjects) { + if (needsReset) { + needsReset = false; + foreach (var o in targets) { + var bf = (BoneFollower)o; + bf.Initialize(); + bf.LateUpdate(); + } + SceneView.RepaintAll(); + } + + EditorGUI.BeginChangeCheck(); + DrawDefaultInspector(); + needsReset |= EditorGUI.EndChangeCheck(); + return; + } + + if (needsReset && Event.current.type == EventType.Layout) { + targetBoneFollower.Initialize(); + targetBoneFollower.LateUpdate(); + needsReset = false; + SceneView.RepaintAll(); + } + serializedObject.Update(); + + // Find Renderer + if (skeletonRenderer.objectReferenceValue == null) { + SkeletonRenderer parentRenderer = targetBoneFollower.GetComponentInParent(); + if (parentRenderer != null && parentRenderer.gameObject != targetBoneFollower.gameObject) { + skeletonRenderer.objectReferenceValue = parentRenderer; + Debug.Log("Inspector automatically assigned BoneFollower.SkeletonRenderer"); + } + } + + EditorGUILayout.PropertyField(skeletonRenderer); + var skeletonRendererReference = skeletonRenderer.objectReferenceValue as SkeletonRenderer; + if (skeletonRendererReference != null) { + if (skeletonRendererReference.gameObject == targetBoneFollower.gameObject) { + skeletonRenderer.objectReferenceValue = null; + EditorUtility.DisplayDialog("Invalid assignment.", "BoneFollower can only follow a skeleton on a separate GameObject.\n\nCreate a new GameObject for your BoneFollower, or choose a SkeletonRenderer from a different GameObject.", "Ok"); + } + } + + if (!targetBoneFollower.valid) { + needsReset = true; + } + + if (targetBoneFollower.valid) { + EditorGUI.BeginChangeCheck(); + EditorGUILayout.PropertyField(boneName); + needsReset |= EditorGUI.EndChangeCheck(); + + EditorGUILayout.PropertyField(followBoneRotation); + EditorGUILayout.PropertyField(followXYPosition); + EditorGUILayout.PropertyField(followZPosition); + EditorGUILayout.PropertyField(followLocalScale); + EditorGUILayout.PropertyField(followSkeletonFlip); + + BoneFollowerInspector.RecommendRigidbodyButton(targetBoneFollower); + } else { + var boneFollowerSkeletonRenderer = targetBoneFollower.skeletonRenderer; + if (boneFollowerSkeletonRenderer == null) { + EditorGUILayout.HelpBox("SkeletonRenderer is unassigned. Please assign a SkeletonRenderer (SkeletonAnimation or SkeletonMecanim).", MessageType.Warning); + } else { + boneFollowerSkeletonRenderer.Initialize(false); + + if (boneFollowerSkeletonRenderer.skeletonDataAsset == null) + EditorGUILayout.HelpBox("Assigned SkeletonRenderer does not have SkeletonData assigned to it.", MessageType.Warning); + + if (!boneFollowerSkeletonRenderer.valid) + EditorGUILayout.HelpBox("Assigned SkeletonRenderer is invalid. Check target SkeletonRenderer, its SkeletonDataAsset or the console for other errors.", MessageType.Warning); + } + } + + var current = Event.current; + bool wasUndo = (current.type == EventType.ValidateCommand && current.commandName == "UndoRedoPerformed"); + if (wasUndo) + targetBoneFollower.Initialize(); + + serializedObject.ApplyModifiedProperties(); + } + + internal static void RecommendRigidbodyButton (Component component) { + bool hasCollider2D = component.GetComponent() != null || component.GetComponent() != null; + bool hasCollider3D = !hasCollider2D && component.GetComponent(); + bool missingRigidBody = (hasCollider2D && component.GetComponent() == null) || (hasCollider3D && component.GetComponent() == null); + if (missingRigidBody) { + using (new SpineInspectorUtility.BoxScope()) { + EditorGUILayout.HelpBox("Collider detected. Unity recommends adding a Rigidbody to the Transforms of any colliders that are intended to be dynamically repositioned and rotated.", MessageType.Warning); + var rbType = hasCollider2D ? typeof(Rigidbody2D) : typeof(Rigidbody); + string rbLabel = string.Format("Add {0}", rbType.Name); + var rbContent = SpineInspectorUtility.TempContent(rbLabel, SpineInspectorUtility.UnityIcon(rbType), "Add a rigidbody to this GameObject to be the Physics body parent of the attached collider."); + if (SpineInspectorUtility.CenteredButton(rbContent)) component.gameObject.AddComponent(rbType); + } + } + } + } + +} diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/Components/BoneFollowerInspector.cs.meta b/box1/Assets/Spine/Editor/spine-unity/Editor/Components/BoneFollowerInspector.cs.meta new file mode 100644 index 00000000..0448ccb6 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/Components/BoneFollowerInspector.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: c71ca35fd6241cb49a0b0756a664fcf7 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/Components/BoundingBoxFollowerInspector.cs b/box1/Assets/Spine/Editor/spine-unity/Editor/Components/BoundingBoxFollowerInspector.cs new file mode 100644 index 00000000..7a0e87cf --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/Components/BoundingBoxFollowerInspector.cs @@ -0,0 +1,225 @@ +/****************************************************************************** + * 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 UnityEngine; +using UnityEditor; + +namespace Spine.Unity.Editor { + using Event = UnityEngine.Event; + using Icons = SpineEditorUtilities.Icons; + + [CustomEditor(typeof(BoundingBoxFollower))] + public class BoundingBoxFollowerInspector : UnityEditor.Editor { + SerializedProperty skeletonRenderer, slotName, isTrigger, clearStateOnDisable; + BoundingBoxFollower follower; + bool rebuildRequired = false; + bool addBoneFollower = false; + bool sceneRepaintRequired = false; + bool debugIsExpanded; + + GUIContent addBoneFollowerLabel; + GUIContent AddBoneFollowerLabel { + get { + if (addBoneFollowerLabel == null) addBoneFollowerLabel = new GUIContent("Add Bone Follower", Icons.bone); + return addBoneFollowerLabel; + } + } + + void InitializeEditor () { + skeletonRenderer = serializedObject.FindProperty("skeletonRenderer"); + slotName = serializedObject.FindProperty("slotName"); + isTrigger = serializedObject.FindProperty("isTrigger"); + clearStateOnDisable = serializedObject.FindProperty("clearStateOnDisable"); + follower = (BoundingBoxFollower)target; + } + + public override void OnInspectorGUI () { + + #if !NEW_PREFAB_SYSTEM + bool isInspectingPrefab = (PrefabUtility.GetPrefabType(target) == PrefabType.Prefab); + #else + bool isInspectingPrefab = false; + #endif + + // Note: when calling InitializeEditor() in OnEnable, it throws exception + // "SerializedObjectNotCreatableException: Object at index 0 is null". + InitializeEditor(); + + // Try to auto-assign SkeletonRenderer field. + if (skeletonRenderer.objectReferenceValue == null) { + var foundSkeletonRenderer = follower.GetComponentInParent(); + if (foundSkeletonRenderer != null) + Debug.Log("BoundingBoxFollower automatically assigned: " + foundSkeletonRenderer.gameObject.name); + else if (Event.current.type == EventType.Repaint) + Debug.Log("No Spine GameObject detected. Make sure to set this GameObject as a child of the Spine GameObject; or set BoundingBoxFollower's 'Skeleton Renderer' field in the inspector."); + + skeletonRenderer.objectReferenceValue = foundSkeletonRenderer; + serializedObject.ApplyModifiedProperties(); + InitializeEditor(); + } + + var skeletonRendererValue = skeletonRenderer.objectReferenceValue as SkeletonRenderer; + if (skeletonRendererValue != null && skeletonRendererValue.gameObject == follower.gameObject) { + using (new EditorGUILayout.VerticalScope(EditorStyles.helpBox)) { + EditorGUILayout.HelpBox("It's ideal to add BoundingBoxFollower to a separate child GameObject of the Spine GameObject.", MessageType.Warning); + + if (GUILayout.Button(new GUIContent("Move BoundingBoxFollower to new GameObject", Icons.boundingBox), GUILayout.Height(30f))) { + AddBoundingBoxFollowerChild(skeletonRendererValue, follower); + DestroyImmediate(follower); + return; + } + } + EditorGUILayout.Space(); + } + + EditorGUI.BeginChangeCheck(); + EditorGUILayout.PropertyField(skeletonRenderer); + EditorGUILayout.PropertyField(slotName, new GUIContent("Slot")); + if (EditorGUI.EndChangeCheck()) { + serializedObject.ApplyModifiedProperties(); + InitializeEditor(); + #if !NEW_PREFAB_SYSTEM + if (!isInspectingPrefab) + rebuildRequired = true; + #endif + } + + using (new SpineInspectorUtility.LabelWidthScope(150f)) { + EditorGUI.BeginChangeCheck(); + EditorGUILayout.PropertyField(isTrigger); + bool triggerChanged = EditorGUI.EndChangeCheck(); + + EditorGUI.BeginChangeCheck(); + EditorGUILayout.PropertyField(clearStateOnDisable, new GUIContent(clearStateOnDisable.displayName, "Enable this if you are pooling your Spine GameObject")); + bool clearStateChanged = EditorGUI.EndChangeCheck(); + + if (clearStateChanged || triggerChanged) { + serializedObject.ApplyModifiedProperties(); + InitializeEditor(); + if (triggerChanged) + foreach (var col in follower.colliderTable.Values) + col.isTrigger = isTrigger.boolValue; + } + } + + if (isInspectingPrefab) { + follower.colliderTable.Clear(); + follower.nameTable.Clear(); + EditorGUILayout.HelpBox("BoundingBoxAttachments cannot be previewed in prefabs.", MessageType.Info); + + // How do you prevent components from being saved into the prefab? No such HideFlag. DontSaveInEditor | DontSaveInBuild does not work. DestroyImmediate does not work. + var collider = follower.GetComponent(); + if (collider != null) Debug.LogWarning("Found BoundingBoxFollower collider components in prefab. These are disposed and regenerated at runtime."); + + } else { + using (new SpineInspectorUtility.BoxScope()) { + if (debugIsExpanded = EditorGUILayout.Foldout(debugIsExpanded, "Debug Colliders")) { + EditorGUI.indentLevel++; + EditorGUILayout.LabelField(string.Format("Attachment Names ({0} PolygonCollider2D)", follower.colliderTable.Count)); + EditorGUI.BeginChangeCheck(); + foreach (var kp in follower.nameTable) { + string attachmentName = kp.Value; + var collider = follower.colliderTable[kp.Key]; + bool isPlaceholder = attachmentName != kp.Key.Name; + collider.enabled = EditorGUILayout.ToggleLeft(new GUIContent(!isPlaceholder ? attachmentName : string.Format("{0} [{1}]", attachmentName, kp.Key.Name), isPlaceholder ? Icons.skinPlaceholder : Icons.boundingBox), collider.enabled); + } + sceneRepaintRequired |= EditorGUI.EndChangeCheck(); + EditorGUI.indentLevel--; + } + } + + } + + if (follower.Slot == null) + follower.Initialize(false); + bool hasBoneFollower = follower.GetComponent() != null; + if (!hasBoneFollower) { + bool buttonDisabled = follower.Slot == null; + using (new EditorGUI.DisabledGroupScope(buttonDisabled)) { + addBoneFollower |= SpineInspectorUtility.LargeCenteredButton(AddBoneFollowerLabel, true); + EditorGUILayout.Space(); + } + } + + + if (Event.current.type == EventType.Repaint) { + if (addBoneFollower) { + var boneFollower = follower.gameObject.AddComponent(); + boneFollower.skeletonRenderer = skeletonRendererValue; + boneFollower.SetBone(follower.Slot.Data.BoneData.Name); + addBoneFollower = false; + } + + if (sceneRepaintRequired) { + SceneView.RepaintAll(); + sceneRepaintRequired = false; + } + + if (rebuildRequired) { + follower.Initialize(); + rebuildRequired = false; + } + } + } + + #region Menus + [MenuItem("CONTEXT/SkeletonRenderer/Add BoundingBoxFollower GameObject")] + static void AddBoundingBoxFollowerChild (MenuCommand command) { + var go = AddBoundingBoxFollowerChild((SkeletonRenderer)command.context); + Undo.RegisterCreatedObjectUndo(go, "Add BoundingBoxFollower"); + } + #endregion + + static GameObject AddBoundingBoxFollowerChild (SkeletonRenderer sr, BoundingBoxFollower original = null) { + var go = EditorInstantiation.NewGameObject("BoundingBoxFollower", true); + go.transform.SetParent(sr.transform, false); + var newFollower = go.AddComponent(); + + if (original != null) { + newFollower.slotName = original.slotName; + newFollower.isTrigger = original.isTrigger; + newFollower.clearStateOnDisable = original.clearStateOnDisable; + } + + newFollower.skeletonRenderer = sr; + newFollower.Initialize(); + + + Selection.activeGameObject = go; + EditorGUIUtility.PingObject(go); + return go; + } + + } + +} diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/Components/BoundingBoxFollowerInspector.cs.meta b/box1/Assets/Spine/Editor/spine-unity/Editor/Components/BoundingBoxFollowerInspector.cs.meta new file mode 100644 index 00000000..e42ba773 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/Components/BoundingBoxFollowerInspector.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 670a3cefa3853bd48b5da53a424fd542 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/Components/PointFollowerInspector.cs b/box1/Assets/Spine/Editor/spine-unity/Editor/Components/PointFollowerInspector.cs new file mode 100644 index 00000000..858a8ecf --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/Components/PointFollowerInspector.cs @@ -0,0 +1,188 @@ +/****************************************************************************** + * 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.Collections; +using UnityEditor; +using UnityEngine; + +namespace Spine.Unity.Editor { + + using Editor = UnityEditor.Editor; + using Event = UnityEngine.Event; + + [CustomEditor(typeof(PointFollower)), CanEditMultipleObjects] + public class PointFollowerInspector : Editor { + SerializedProperty slotName, pointAttachmentName, skeletonRenderer, followZPosition, followBoneRotation, followSkeletonFlip; + PointFollower targetPointFollower; + bool needsReset; + + #region Context Menu Item + [MenuItem("CONTEXT/SkeletonRenderer/Add PointFollower GameObject")] + static void AddBoneFollowerGameObject (MenuCommand cmd) { + var skeletonRenderer = cmd.context as SkeletonRenderer; + var go = EditorInstantiation.NewGameObject("PointFollower", true); + var t = go.transform; + t.SetParent(skeletonRenderer.transform); + t.localPosition = Vector3.zero; + + var f = go.AddComponent(); + f.skeletonRenderer = skeletonRenderer; + + EditorGUIUtility.PingObject(t); + + Undo.RegisterCreatedObjectUndo(go, "Add PointFollower"); + } + + // Validate + [MenuItem("CONTEXT/SkeletonRenderer/Add PointFollower GameObject", true)] + static bool ValidateAddBoneFollowerGameObject (MenuCommand cmd) { + var skeletonRenderer = cmd.context as SkeletonRenderer; + return skeletonRenderer.valid; + } + #endregion + + void OnEnable () { + skeletonRenderer = serializedObject.FindProperty("skeletonRenderer"); + slotName = serializedObject.FindProperty("slotName"); + pointAttachmentName = serializedObject.FindProperty("pointAttachmentName"); + + targetPointFollower = (PointFollower)target; + if (targetPointFollower.skeletonRenderer != null) + targetPointFollower.skeletonRenderer.Initialize(false); + + if (!targetPointFollower.IsValid || needsReset) { + targetPointFollower.Initialize(); + targetPointFollower.LateUpdate(); + needsReset = false; + SceneView.RepaintAll(); + } + } + + public void OnSceneGUI () { + var tbf = target as PointFollower; + var skeletonRendererComponent = tbf.skeletonRenderer; + if (skeletonRendererComponent == null) + return; + + var skeleton = skeletonRendererComponent.skeleton; + var skeletonTransform = skeletonRendererComponent.transform; + + if (string.IsNullOrEmpty(pointAttachmentName.stringValue)) { + // Draw all active PointAttachments in the current skin + var currentSkin = skeleton.Skin; + if (currentSkin != skeleton.Data.DefaultSkin) DrawPointsInSkin(skeleton.Data.DefaultSkin, skeleton, skeletonTransform); + if (currentSkin != null) DrawPointsInSkin(currentSkin, skeleton, skeletonTransform); + } else { + int slotIndex = skeleton.FindSlotIndex(slotName.stringValue); + if (slotIndex >= 0) { + var slot = skeleton.Slots.Items[slotIndex]; + var point = skeleton.GetAttachment(slotIndex, pointAttachmentName.stringValue) as PointAttachment; + if (point != null) { + DrawPointAttachmentWithLabel(point, slot.Bone, skeletonTransform); + } + } + } + } + + static void DrawPointsInSkin (Skin skin, Skeleton skeleton, Transform transform) { + foreach (var skinEntry in skin.Attachments) { + var attachment = skinEntry.Value as PointAttachment; + if (attachment != null) { + var skinKey = (Skin.SkinEntry)skinEntry.Key; + var slot = skeleton.Slots.Items[skinKey.SlotIndex]; + DrawPointAttachmentWithLabel(attachment, slot.Bone, transform); + } + } + } + + static void DrawPointAttachmentWithLabel (PointAttachment point, Bone bone, Transform transform) { + Vector3 labelOffset = new Vector3(0f, -0.2f, 0f); + SpineHandles.DrawPointAttachment(bone, point, transform); + Handles.Label(labelOffset + point.GetWorldPosition(bone, transform), point.Name, SpineHandles.PointNameStyle); + } + + override public void OnInspectorGUI () { + if (serializedObject.isEditingMultipleObjects) { + if (needsReset) { + needsReset = false; + foreach (var o in targets) { + var bf = (BoneFollower)o; + bf.Initialize(); + bf.LateUpdate(); + } + SceneView.RepaintAll(); + } + + EditorGUI.BeginChangeCheck(); + DrawDefaultInspector(); + needsReset |= EditorGUI.EndChangeCheck(); + return; + } + + if (needsReset && Event.current.type == EventType.Layout) { + targetPointFollower.Initialize(); + targetPointFollower.LateUpdate(); + needsReset = false; + SceneView.RepaintAll(); + } + serializedObject.Update(); + + DrawDefaultInspector(); + + // Find Renderer + if (skeletonRenderer.objectReferenceValue == null) { + SkeletonRenderer parentRenderer = targetPointFollower.GetComponentInParent(); + if (parentRenderer != null && parentRenderer.gameObject != targetPointFollower.gameObject) { + skeletonRenderer.objectReferenceValue = parentRenderer; + Debug.Log("Inspector automatically assigned PointFollower.SkeletonRenderer"); + } + } + + var skeletonRendererReference = skeletonRenderer.objectReferenceValue as SkeletonRenderer; + if (skeletonRendererReference != null) { + if (skeletonRendererReference.gameObject == targetPointFollower.gameObject) { + skeletonRenderer.objectReferenceValue = null; + EditorUtility.DisplayDialog("Invalid assignment.", "PointFollower can only follow a skeleton on a separate GameObject.\n\nCreate a new GameObject for your PointFollower, or choose a SkeletonRenderer from a different GameObject.", "Ok"); + } + } + + if (!targetPointFollower.IsValid) { + needsReset = true; + } + + var current = Event.current; + bool wasUndo = (current.type == EventType.ValidateCommand && current.commandName == "UndoRedoPerformed"); + if (wasUndo) + targetPointFollower.Initialize(); + + serializedObject.ApplyModifiedProperties(); + } + } + +} diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/Components/PointFollowerInspector.cs.meta b/box1/Assets/Spine/Editor/spine-unity/Editor/Components/PointFollowerInspector.cs.meta new file mode 100644 index 00000000..21061568 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/Components/PointFollowerInspector.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 7c7e838a8ec295a4e9c53602f690f42f +timeCreated: 1518163038 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonAnimationInspector.cs b/box1/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonAnimationInspector.cs new file mode 100644 index 00000000..c87ee626 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonAnimationInspector.cs @@ -0,0 +1,130 @@ +/****************************************************************************** + * 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 UnityEditor; +using UnityEngine; +using Spine; + +namespace Spine.Unity.Editor { + + [CustomEditor(typeof(SkeletonAnimation))] + [CanEditMultipleObjects] + public class SkeletonAnimationInspector : SkeletonRendererInspector { + protected SerializedProperty animationName, loop, timeScale, autoReset; + protected bool wasAnimationNameChanged; + protected bool requireRepaint; + readonly GUIContent LoopLabel = new GUIContent("Loop", "Whether or not .AnimationName should loop. This only applies to the initial animation specified in the inspector, or any subsequent Animations played through .AnimationName. Animations set through state.SetAnimation are unaffected."); + readonly GUIContent TimeScaleLabel = new GUIContent("Time Scale", "The rate at which animations progress over time. 1 means normal speed. 0.5 means 50% speed."); + + protected override void OnEnable () { + base.OnEnable(); + animationName = serializedObject.FindProperty("_animationName"); + loop = serializedObject.FindProperty("loop"); + timeScale = serializedObject.FindProperty("timeScale"); + } + + protected override void DrawInspectorGUI (bool multi) { + base.DrawInspectorGUI(multi); + if (!TargetIsValid) return; + bool sameData = SpineInspectorUtility.TargetsUseSameData(serializedObject); + + foreach (var o in targets) + TrySetAnimation(o as SkeletonAnimation, multi); + wasAnimationNameChanged = false; + + EditorGUILayout.Space(); + if (!sameData) { + EditorGUILayout.DelayedTextField(animationName); + } else { + EditorGUI.BeginChangeCheck(); + EditorGUILayout.PropertyField(animationName); + wasAnimationNameChanged |= EditorGUI.EndChangeCheck(); // Value used in the next update. + } + EditorGUILayout.PropertyField(loop, LoopLabel); + EditorGUILayout.PropertyField(timeScale, TimeScaleLabel); + foreach (var o in targets) { + var component = o as SkeletonAnimation; + component.timeScale = Mathf.Max(component.timeScale, 0); + } + + EditorGUILayout.Space(); + SkeletonRootMotionParameter(); + + if (!isInspectingPrefab) { + if (requireRepaint) { + SceneView.RepaintAll(); + requireRepaint = false; + } + } + } + + protected void TrySetAnimation (SkeletonAnimation skeletonAnimation, bool multi) { + if (skeletonAnimation == null) return; + if (!skeletonAnimation.valid) + return; + + if (!isInspectingPrefab) { + if (wasAnimationNameChanged) { + var skeleton = skeletonAnimation.Skeleton; + var state = skeletonAnimation.AnimationState; + + if (!Application.isPlaying) { + if (state != null) state.ClearTrack(0); + skeleton.SetToSetupPose(); + } + + Spine.Animation animationToUse = skeleton.Data.FindAnimation(animationName.stringValue); + + if (!Application.isPlaying) { + if (animationToUse != null) { + skeletonAnimation.AnimationState.SetAnimation(0, animationToUse, loop.boolValue); + } + skeleton.UpdateWorldTransform(); + skeletonAnimation.LateUpdate(); + requireRepaint = true; + } else { + if (animationToUse != null) + state.SetAnimation(0, animationToUse, loop.boolValue); + else + state.ClearTrack(0); + } + } + + // Reflect animationName serialized property in the inspector even if SetAnimation API was used. + if (Application.isPlaying) { + TrackEntry current = skeletonAnimation.AnimationState.GetCurrent(0); + if (current != null) { + if (skeletonAnimation.AnimationName != animationName.stringValue) + animationName.stringValue = current.Animation.Name; + } + } + } + } + } +} diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonAnimationInspector.cs.meta b/box1/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonAnimationInspector.cs.meta new file mode 100644 index 00000000..1ca79413 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonAnimationInspector.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 39fbfef61034ca045b5aa80088e1e8a4 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonGraphicCustomMaterialsInspector.cs b/box1/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonGraphicCustomMaterialsInspector.cs new file mode 100644 index 00000000..f9a1c2d7 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonGraphicCustomMaterialsInspector.cs @@ -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 componentCustomMaterialOverrides, _customMaterialOverridesPrev; + List 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(); + 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() == 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; + componentCustomTextureOverrides = cm.GetField("customTextureOverrides", PrivateInstance).GetValue(component) as List; + 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 CopyList (List list) { + return list.GetRange(0, list.Count); + } + } +} diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonGraphicCustomMaterialsInspector.cs.meta b/box1/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonGraphicCustomMaterialsInspector.cs.meta new file mode 100644 index 00000000..4a5d3519 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonGraphicCustomMaterialsInspector.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 349bf125947e3aa4bb78690fec69ea17 +timeCreated: 1588789940 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonGraphicInspector.cs b/box1/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonGraphicInspector.cs new file mode 100644 index 00000000..6af4c690 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonGraphicInspector.cs @@ -0,0 +1,430 @@ +/****************************************************************************** + * 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 UnityEngine; +using UnityEditor; + +namespace Spine.Unity.Editor { + using Icons = SpineEditorUtilities.Icons; + + [CustomEditor(typeof(SkeletonGraphic))] + [CanEditMultipleObjects] + public class SkeletonGraphicInspector : UnityEditor.Editor { + + const string SeparatorSlotNamesFieldName = "separatorSlotNames"; + const string ReloadButtonString = "Reload"; + protected GUIContent SkeletonDataAssetLabel; + static GUILayoutOption reloadButtonWidth; + static GUILayoutOption ReloadButtonWidth { get { return reloadButtonWidth = reloadButtonWidth ?? GUILayout.Width(GUI.skin.label.CalcSize(new GUIContent(ReloadButtonString)).x + 20); } } + static GUIStyle ReloadButtonStyle { get { return EditorStyles.miniButton; } } + + SerializedProperty material, color; + SerializedProperty skeletonDataAsset, initialSkinName; + SerializedProperty startingAnimation, startingLoop, timeScale, freeze, updateWhenInvisible, 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 forceReloadQueued = false; + + protected bool TargetIsValid { + get { + if (serializedObject.isEditingMultipleObjects) { + foreach (var o in targets) { + var component = (SkeletonGraphic)o; + if (!component.IsValid) + return false; + } + return true; + } + else { + var component = (SkeletonGraphic)target; + return component.IsValid; + } + } + } + + void OnEnable () { +#if NEW_PREFAB_SYSTEM + isInspectingPrefab = false; +#else + isInspectingPrefab = (PrefabUtility.GetPrefabType(target) == PrefabType.Prefab); +#endif + SpineEditorUtilities.ConfirmInitialization(); + + // Labels + SkeletonDataAssetLabel = new GUIContent("SkeletonData Asset", Icons.spine); + + var so = this.serializedObject; + thisSkeletonGraphic = target as SkeletonGraphic; + + // MaskableGraphic + material = so.FindProperty("m_Material"); + color = so.FindProperty("m_Color"); + raycastTarget = so.FindProperty("m_RaycastTarget"); + + // SkeletonRenderer + skeletonDataAsset = so.FindProperty("skeletonDataAsset"); + initialSkinName = so.FindProperty("initialSkinName"); + + initialFlipX = so.FindProperty("initialFlipX"); + initialFlipY = so.FindProperty("initialFlipY"); + + // SkeletonAnimation + startingAnimation = so.FindProperty("startingAnimation"); + startingLoop = so.FindProperty("startingLoop"); + timeScale = so.FindProperty("timeScale"); + unscaledTime = so.FindProperty("unscaledTime"); + freeze = so.FindProperty("freeze"); + updateWhenInvisible = so.FindProperty("updateWhenInvisible"); + + 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 () { + + if (UnityEngine.Event.current.type == EventType.Layout) { + if (forceReloadQueued) { + forceReloadQueued = false; + foreach (var c in targets) { + SpineEditorUtilities.ReloadSkeletonDataAssetAndComponent(c as SkeletonGraphic); + } + } + else { + foreach (var c in targets) { + var component = c as SkeletonGraphic; + if (!component.IsValid) { + SpineEditorUtilities.ReinitializeComponent(component); + if (!component.IsValid) continue; + } + } + } + } + + bool wasChanged = false; + EditorGUI.BeginChangeCheck(); + + using (new EditorGUILayout.HorizontalScope(EditorStyles.helpBox)) { + SpineInspectorUtility.PropertyFieldFitLabel(skeletonDataAsset, SkeletonDataAssetLabel); + if (GUILayout.Button(ReloadButtonString, ReloadButtonStyle, ReloadButtonWidth)) + forceReloadQueued = true; + } + + EditorGUILayout.PropertyField(material); + EditorGUILayout.PropertyField(color); + + if (thisSkeletonGraphic.skeletonDataAsset == null) { + EditorGUILayout.HelpBox("You need to assign a SkeletonDataAsset first.", MessageType.Info); + serializedObject.ApplyModifiedProperties(); + 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(); + + EditorGUILayout.PropertyField(updateWhenInvisible); + + // 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(); + EditorGUILayout.PropertyField(initialSkinName); + { + var rect = GUILayoutUtility.GetRect(EditorGUIUtility.currentViewWidth, EditorGUIUtility.singleLineHeight); + EditorGUI.PrefixLabel(rect, SpineInspectorUtility.TempContent("Initial Flip")); + rect.x += EditorGUIUtility.labelWidth; + rect.width = 30f; + SpineInspectorUtility.ToggleLeft(rect, initialFlipX, SpineInspectorUtility.TempContent("X", tooltip: "initialFlipX")); + rect.x += 35f; + SpineInspectorUtility.ToggleLeft(rect, initialFlipY, SpineInspectorUtility.TempContent("Y", tooltip: "initialFlipY")); + } + + EditorGUILayout.Space(); + EditorGUILayout.LabelField("Animation", EditorStyles.boldLabel); + EditorGUILayout.PropertyField(startingAnimation); + EditorGUILayout.PropertyField(startingLoop); + EditorGUILayout.PropertyField(timeScale); + EditorGUILayout.PropertyField(unscaledTime, SpineInspectorUtility.TempContent(unscaledTime.displayName, tooltip: "If checked, this will use Time.unscaledDeltaTime to make this update independent of game Time.timeScale. Instance SkeletonGraphic.timeScale will still be applied.")); + EditorGUILayout.Space(); + EditorGUILayout.PropertyField(freeze); + EditorGUILayout.Space(); + SkeletonRendererInspector.SkeletonRootMotionParameter(targets); + EditorGUILayout.Space(); + EditorGUILayout.LabelField("UI", EditorStyles.boldLabel); + EditorGUILayout.PropertyField(raycastTarget); + + EditorGUILayout.BeginHorizontal(GUILayout.Height(EditorGUIUtility.singleLineHeight + 5)); + EditorGUILayout.PrefixLabel("Match RectTransform with Mesh"); + if (GUILayout.Button("Match", EditorStyles.miniButton, GUILayout.Width(65f))) { + foreach (var skeletonGraphic in targets) { + MatchRectTransformWithBounds((SkeletonGraphic)skeletonGraphic); + } + } + EditorGUILayout.EndHorizontal(); + + if (TargetIsValid && !isInspectingPrefab) { + EditorGUILayout.Space(); + if (SpineInspectorUtility.CenteredButton(new GUIContent("Add Skeleton Utility", Icons.skeletonUtility), 21, true, 200f)) + foreach (var t in targets) { + var component = t as Component; + if (component.GetComponent() == null) { + component.gameObject.AddComponent(); + } + } + } + + wasChanged |= EditorGUI.EndChangeCheck(); + + 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 + [MenuItem("CONTEXT/SkeletonGraphic/Match RectTransform with Mesh Bounds")] + static void MatchRectTransformWithBounds (MenuCommand command) { + var skeletonGraphic = (SkeletonGraphic)command.context; + MatchRectTransformWithBounds(skeletonGraphic); + } + + static void MatchRectTransformWithBounds (SkeletonGraphic skeletonGraphic) { + if (!skeletonGraphic.MatchRectTransformWithBounds()) + Debug.Log("Mesh was not previously generated."); + } + + [MenuItem("GameObject/Spine/SkeletonGraphic (UnityUI)", false, 15)] + static public void SkeletonGraphicCreateMenuItem () { + var parentGameObject = Selection.activeObject as GameObject; + var parentTransform = parentGameObject == null ? null : parentGameObject.GetComponent(); + + if (parentTransform == null) + Debug.LogWarning("Your new SkeletonGraphic will not be visible until it is placed under a Canvas"); + + var gameObject = NewSkeletonGraphicGameObject("New SkeletonGraphic"); + gameObject.transform.SetParent(parentTransform, false); + EditorUtility.FocusProjectWindow(); + Selection.activeObject = gameObject; + EditorGUIUtility.PingObject(Selection.activeObject); + } + + // SpineEditorUtilities.InstantiateDelegate. Used by drag and drop. + public static Component SpawnSkeletonGraphicFromDrop (SkeletonDataAsset data) { + return InstantiateSkeletonGraphic(data); + } + + public static SkeletonGraphic InstantiateSkeletonGraphic (SkeletonDataAsset skeletonDataAsset, string skinName) { + return InstantiateSkeletonGraphic(skeletonDataAsset, skeletonDataAsset.GetSkeletonData(true).FindSkin(skinName)); + } + + public static SkeletonGraphic InstantiateSkeletonGraphic (SkeletonDataAsset skeletonDataAsset, Skin skin = null) { + string spineGameObjectName = string.Format("SkeletonGraphic ({0})", skeletonDataAsset.name.Replace("_SkeletonData", "")); + var go = NewSkeletonGraphicGameObject(spineGameObjectName); + var graphic = go.GetComponent(); + graphic.skeletonDataAsset = skeletonDataAsset; + + SkeletonData data = skeletonDataAsset.GetSkeletonData(true); + + if (data == null) { + for (int i = 0; i < skeletonDataAsset.atlasAssets.Length; i++) { + string reloadAtlasPath = AssetDatabase.GetAssetPath(skeletonDataAsset.atlasAssets[i]); + skeletonDataAsset.atlasAssets[i] = (AtlasAssetBase)AssetDatabase.LoadAssetAtPath(reloadAtlasPath, typeof(AtlasAssetBase)); + } + + data = skeletonDataAsset.GetSkeletonData(true); + } + + skin = skin ?? data.DefaultSkin ?? data.Skins.Items[0]; + graphic.MeshGenerator.settings.zSpacing = SpineEditorUtilities.Preferences.defaultZSpacing; + + graphic.startingLoop = SpineEditorUtilities.Preferences.defaultInstantiateLoop; + graphic.Initialize(false); + if (skin != null) graphic.Skeleton.SetSkin(skin); + graphic.initialSkinName = skin.Name; + graphic.Skeleton.UpdateWorldTransform(); + graphic.UpdateMesh(); + return graphic; + } + + static GameObject NewSkeletonGraphicGameObject (string gameObjectName) { + var go = EditorInstantiation.NewGameObject(gameObjectName, true, typeof(RectTransform), typeof(CanvasRenderer), typeof(SkeletonGraphic)); + var graphic = go.GetComponent(); + graphic.material = SkeletonGraphicInspector.DefaultSkeletonGraphicMaterial; + return go; + } + + public static Material DefaultSkeletonGraphicMaterial { + get { + var guids = AssetDatabase.FindAssets("SkeletonGraphicDefault t:material"); + if (guids.Length <= 0) return null; + + var firstAssetPath = AssetDatabase.GUIDToAssetPath(guids[0]); + if (string.IsNullOrEmpty(firstAssetPath)) return null; + + var firstMaterial = AssetDatabase.LoadAssetAtPath(firstAssetPath); + return firstMaterial; + } + } + + #endregion + } +} diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonGraphicInspector.cs.meta b/box1/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonGraphicInspector.cs.meta new file mode 100644 index 00000000..5fced2e9 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonGraphicInspector.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 0d81cc76b52fcdf499b2db252a317726 +timeCreated: 1455570945 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonMecanimInspector.cs b/box1/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonMecanimInspector.cs new file mode 100644 index 00000000..c322a8ec --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonMecanimInspector.cs @@ -0,0 +1,153 @@ +/****************************************************************************** + * 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. + *****************************************************************************/ + +// Contributed by: Mitch Thompson + +using UnityEditor; +using UnityEngine; + +namespace Spine.Unity.Editor { + [CustomEditor(typeof(SkeletonMecanim))] + [CanEditMultipleObjects] + public class SkeletonMecanimInspector : SkeletonRendererInspector { + public static bool mecanimSettingsFoldout; + + protected SerializedProperty autoReset; + protected SerializedProperty useCustomMixMode; + protected SerializedProperty layerMixModes; + protected SerializedProperty layerBlendModes; + + protected override void OnEnable () { + base.OnEnable(); + SerializedProperty mecanimTranslator = serializedObject.FindProperty("translator"); + autoReset = mecanimTranslator.FindPropertyRelative("autoReset"); + useCustomMixMode = mecanimTranslator.FindPropertyRelative("useCustomMixMode"); + layerMixModes = mecanimTranslator.FindPropertyRelative("layerMixModes"); + layerBlendModes = mecanimTranslator.FindPropertyRelative("layerBlendModes"); + } + + protected override void DrawInspectorGUI (bool multi) { + + AddRootMotionComponentIfEnabled(); + + base.DrawInspectorGUI(multi); + + using (new SpineInspectorUtility.BoxScope()) { + mecanimSettingsFoldout = EditorGUILayout.Foldout(mecanimSettingsFoldout, "Mecanim Translator"); + if (mecanimSettingsFoldout) { + EditorGUILayout.PropertyField(autoReset, new GUIContent("Auto Reset", + "When set to true, the skeleton state is mixed out to setup-" + + "pose when an animation finishes, according to the " + + "animation's keyed items.")); + + EditorGUILayout.PropertyField(useCustomMixMode, new GUIContent("Custom MixMode", + "When disabled, the recommended MixMode is used according to the layer blend mode. Enable to specify a custom MixMode for each Mecanim layer.")); + + if (useCustomMixMode.hasMultipleDifferentValues || useCustomMixMode.boolValue == true) { + DrawLayerSettings(); + EditorGUILayout.Space(); + } + } + } + } + + protected void AddRootMotionComponentIfEnabled () { + foreach (var t in targets) { + var component = t as Component; + var animator = component.GetComponent(); + if (animator != null && animator.applyRootMotion) { + if (component.GetComponent() == null) { + component.gameObject.AddComponent(); + } + } + } + } + + protected void DrawLayerSettings () { + string[] layerNames = GetLayerNames(); + float widthLayerColumn = 140; + float widthMixColumn = 84; + + using (new GUILayout.HorizontalScope()) { + var rect = GUILayoutUtility.GetRect(EditorGUIUtility.currentViewWidth, EditorGUIUtility.singleLineHeight); + rect.width = widthLayerColumn; + EditorGUI.LabelField(rect, SpineInspectorUtility.TempContent("Mecanim Layer"), EditorStyles.boldLabel); + + var savedIndent = EditorGUI.indentLevel; + EditorGUI.indentLevel = 0; + + rect.position += new Vector2(rect.width, 0); + rect.width = widthMixColumn; + EditorGUI.LabelField(rect, SpineInspectorUtility.TempContent("Mix Mode"), EditorStyles.boldLabel); + + EditorGUI.indentLevel = savedIndent; + } + + using (new SpineInspectorUtility.IndentScope()) { + int layerCount = layerMixModes.arraySize; + for (int i = 0; i < layerCount; ++i) { + using (new GUILayout.HorizontalScope()) { + string layerName = i < layerNames.Length ? layerNames[i] : ("Layer " + i); + + var rect = GUILayoutUtility.GetRect(EditorGUIUtility.currentViewWidth, EditorGUIUtility.singleLineHeight); + rect.width = widthLayerColumn; + EditorGUI.PrefixLabel(rect, SpineInspectorUtility.TempContent(layerName)); + + var savedIndent = EditorGUI.indentLevel; + EditorGUI.indentLevel = 0; + + var mixMode = layerMixModes.GetArrayElementAtIndex(i); + rect.position += new Vector2(rect.width, 0); + rect.width = widthMixColumn; + EditorGUI.PropertyField(rect, mixMode, GUIContent.none); + + EditorGUI.indentLevel = savedIndent; + } + } + } + } + + protected string[] GetLayerNames () { + int maxLayerCount = 0; + int maxIndex = 0; + for (int i = 0; i < targets.Length; ++i) { + var skeletonMecanim = ((SkeletonMecanim)targets[i]); + int count = skeletonMecanim.Translator.MecanimLayerCount; + if (count > maxLayerCount) { + maxLayerCount = count; + maxIndex = i; + } + } + if (maxLayerCount == 0) + return new string[0]; + var skeletonMecanimMaxLayers = ((SkeletonMecanim)targets[maxIndex]); + return skeletonMecanimMaxLayers.Translator.MecanimLayerNames; + } + } +} diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonMecanimInspector.cs.meta b/box1/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonMecanimInspector.cs.meta new file mode 100644 index 00000000..9ef306e6 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonMecanimInspector.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 6a9ca5213a3a4614c9a9f2e60909bc33 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonMecanimRootMotionInspector.cs b/box1/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonMecanimRootMotionInspector.cs new file mode 100644 index 00000000..bcdbbaab --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonMecanimRootMotionInspector.cs @@ -0,0 +1,81 @@ +/****************************************************************************** + * 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 UnityEditor; +using UnityEngine; + +namespace Spine.Unity.Editor { + [CustomEditor(typeof(SkeletonMecanimRootMotion))] + [CanEditMultipleObjects] + public class SkeletonMecanimRootMotionInspector : SkeletonRootMotionBaseInspector { + protected SerializedProperty mecanimLayerFlags; + + protected GUIContent mecanimLayersLabel; + + protected override void OnEnable () { + base.OnEnable(); + mecanimLayerFlags = serializedObject.FindProperty("mecanimLayerFlags"); + + mecanimLayersLabel = new UnityEngine.GUIContent("Mecanim Layers", "Mecanim layers to apply root motion at. Defaults to the first Mecanim layer."); + } + + override public void OnInspectorGUI () { + + base.MainPropertyFields(); + MecanimLayerMaskPropertyField(); + + base.OptionalPropertyFields(); + serializedObject.ApplyModifiedProperties(); + } + + protected string[] GetLayerNames () { + int maxLayerCount = 0; + int maxIndex = 0; + for (int i = 0; i < targets.Length; ++i) { + var skeletonMecanim = ((SkeletonMecanimRootMotion)targets[i]).SkeletonMecanim; + int count = skeletonMecanim.Translator.MecanimLayerCount; + if (count > maxLayerCount) { + maxLayerCount = count; + maxIndex = i; + } + } + if (maxLayerCount == 0) + return new string[0]; + var skeletonMecanimMaxLayers = ((SkeletonMecanimRootMotion)targets[maxIndex]).SkeletonMecanim; + return skeletonMecanimMaxLayers.Translator.MecanimLayerNames; + } + + protected void MecanimLayerMaskPropertyField () { + string[] layerNames = GetLayerNames(); + if (layerNames.Length > 0) + mecanimLayerFlags.intValue = EditorGUILayout.MaskField( + mecanimLayersLabel, mecanimLayerFlags.intValue, layerNames); + } + } +} diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonMecanimRootMotionInspector.cs.meta b/box1/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonMecanimRootMotionInspector.cs.meta new file mode 100644 index 00000000..04c6dcfc --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonMecanimRootMotionInspector.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 4613924c50d66cf458f0db803776dd2f +timeCreated: 1593175106 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonRendererCustomMaterialsInspector.cs b/box1/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonRendererCustomMaterialsInspector.cs new file mode 100644 index 00000000..44c9f4a4 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonRendererCustomMaterialsInspector.cs @@ -0,0 +1,165 @@ +/****************************************************************************** + * 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. + *****************************************************************************/ + +#define SPINE_OPTIONAL_MATERIALOVERRIDE + +// Contributed by: Lost Polygon + +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 the readme.txt file in SkeletonRendererCustomMaterials folder to learn more. + [CustomEditor(typeof(SkeletonRendererCustomMaterials))] + public class SkeletonRendererCustomMaterialsInspector : UnityEditor.Editor { + List componentCustomMaterialOverrides, _customMaterialOverridesPrev; + List componentCustomSlotMaterials, _customSlotMaterialsPrev; + SkeletonRendererCustomMaterials component; + + const BindingFlags PrivateInstance = BindingFlags.Instance | BindingFlags.NonPublic; + MethodInfo RemoveCustomMaterialOverrides, RemoveCustomSlotMaterials, SetCustomMaterialOverrides, SetCustomSlotMaterials; + + #region SkeletonRenderer context menu + [MenuItem("CONTEXT/SkeletonRenderer/Add Basic Serialized Custom Materials")] + static void AddSkeletonRendererCustomMaterials (MenuCommand menuCommand) { + var skeletonRenderer = (SkeletonRenderer)menuCommand.context; + var newComponent = skeletonRenderer.gameObject.AddComponent(); + Undo.RegisterCreatedObjectUndo(newComponent, "Add Basic Serialized Custom Materials"); + } + + [MenuItem("CONTEXT/SkeletonRenderer/Add Basic Serialized Custom Materials", true)] + static bool AddSkeletonRendererCustomMaterials_Validate (MenuCommand menuCommand) { + var skeletonRenderer = (SkeletonRenderer)menuCommand.context; + return (skeletonRenderer.GetComponent() == null); + } + #endregion + + void OnEnable () { + Type cm = typeof(SkeletonRendererCustomMaterials); + RemoveCustomMaterialOverrides = cm.GetMethod("RemoveCustomMaterialOverrides", PrivateInstance); + RemoveCustomSlotMaterials = cm.GetMethod("RemoveCustomSlotMaterials", PrivateInstance); + SetCustomMaterialOverrides = cm.GetMethod("SetCustomMaterialOverrides", PrivateInstance); + SetCustomSlotMaterials = cm.GetMethod("SetCustomSlotMaterials", PrivateInstance); + } + + public override void OnInspectorGUI () { + component = (SkeletonRendererCustomMaterials)target; + var skeletonRenderer = component.skeletonRenderer; + + // Draw the default inspector + DrawDefaultInspector(); + + if (serializedObject.isEditingMultipleObjects) + return; + + if (componentCustomMaterialOverrides == null) { + Type cm = typeof(SkeletonRendererCustomMaterials); + componentCustomMaterialOverrides = cm.GetField("customMaterialOverrides", PrivateInstance).GetValue(component) as List; + componentCustomSlotMaterials = cm.GetField("customSlotMaterials", PrivateInstance).GetValue(component) as List; + if (componentCustomMaterialOverrides == null) { + Debug.Log("Reflection failed."); + return; + } + } + + // Fill with current values at start + if (_customMaterialOverridesPrev == null || _customSlotMaterialsPrev == null) { + _customMaterialOverridesPrev = CopyList(componentCustomMaterialOverrides); + _customSlotMaterialsPrev = CopyList(componentCustomSlotMaterials); + } + + // 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 customSlotMaterialsNew = CopyList(componentCustomSlotMaterials); + + // Detect changes + if (!_customMaterialOverridesPrev.SequenceEqual(customMaterialOverridesNew) || + !_customSlotMaterialsPrev.SequenceEqual(customSlotMaterialsNew)) { + // 2. Restore old values + componentCustomMaterialOverrides.Clear(); + componentCustomSlotMaterials.Clear(); + componentCustomMaterialOverrides.AddRange(_customMaterialOverridesPrev); + componentCustomSlotMaterials.AddRange(_customSlotMaterialsPrev); + + // 3. Remove overrides + RemoveCustomMaterials(); + + // 4. Restore new values + componentCustomMaterialOverrides.Clear(); + componentCustomSlotMaterials.Clear(); + componentCustomMaterialOverrides.AddRange(customMaterialOverridesNew); + componentCustomSlotMaterials.AddRange(customSlotMaterialsNew); + + // 5. Restore overrides + SetCustomMaterials(); + + if (skeletonRenderer != null) + skeletonRenderer.LateUpdate(); + } + + _customMaterialOverridesPrev = CopyList(componentCustomMaterialOverrides); + _customSlotMaterialsPrev = CopyList(componentCustomSlotMaterials); + + if (SpineInspectorUtility.LargeCenteredButton(SpineInspectorUtility.TempContent("Clear and Reapply Changes", tooltip: "Removes all non-serialized overrides in the SkeletonRenderer and reapplies the overrides on this component."))) { + if (skeletonRenderer != null) { + #if SPINE_OPTIONAL_MATERIALOVERRIDE + skeletonRenderer.CustomMaterialOverride.Clear(); + #endif + skeletonRenderer.CustomSlotMaterials.Clear(); + RemoveCustomMaterials(); + SetCustomMaterials(); + skeletonRenderer.LateUpdate(); + } + } + } + + void RemoveCustomMaterials () { + RemoveCustomMaterialOverrides.Invoke(component, null); + RemoveCustomSlotMaterials.Invoke(component, null); + } + + void SetCustomMaterials () { + SetCustomMaterialOverrides.Invoke(component, null); + SetCustomSlotMaterials.Invoke(component, null); + } + + static List CopyList (List list) { + return list.GetRange(0, list.Count); + } + } +} diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonRendererCustomMaterialsInspector.cs.meta b/box1/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonRendererCustomMaterialsInspector.cs.meta new file mode 100644 index 00000000..1e37a56a --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonRendererCustomMaterialsInspector.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: e70f7f2a241d6d34aafd6a4a52a368d0 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonRendererInspector.cs b/box1/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonRendererInspector.cs new file mode 100644 index 00000000..1e8a3e50 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonRendererInspector.cs @@ -0,0 +1,592 @@ +/****************************************************************************** + * 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 +#else +#define NO_PREFAB_MESH +#endif + +#if UNITY_2018_1_OR_NEWER +#define PER_MATERIAL_PROPERTY_BLOCKS +#endif + +#if UNITY_2017_1_OR_NEWER +#define BUILT_IN_SPRITE_MASK_COMPONENT +#endif + +using UnityEditor; +using System.Collections.Generic; +using UnityEngine; +using System.Reflection; + +namespace Spine.Unity.Editor { + using Event = UnityEngine.Event; + using Icons = SpineEditorUtilities.Icons; + + [CustomEditor(typeof(SkeletonRenderer))] + [CanEditMultipleObjects] + public class SkeletonRendererInspector : UnityEditor.Editor { + public static bool advancedFoldout; + + const string SeparatorSlotNamesFieldName = "separatorSlotNames"; + + protected SerializedProperty skeletonDataAsset, initialSkinName; + protected SerializedProperty initialFlipX, initialFlipY; + protected SerializedProperty updateWhenInvisible, singleSubmesh, separatorSlotNames, clearStateOnDisable, immutableTriangles, fixDrawOrder; + protected SerializedProperty normals, tangents, zSpacing, pmaVertexColors, tintBlack; // MeshGenerator settings + protected SerializedProperty maskInteraction; + protected SerializedProperty maskMaterialsNone, maskMaterialsInside, maskMaterialsOutside; + protected SpineInspectorUtility.SerializedSortingProperties sortingProperties; + + protected bool isInspectingPrefab; + protected bool forceReloadQueued = false; + protected bool setMaskNoneMaterialsQueued = false; + protected bool setInsideMaskMaterialsQueued = false; + protected bool setOutsideMaskMaterialsQueued = false; + protected bool deleteInsideMaskMaterialsQueued = false; + protected bool deleteOutsideMaskMaterialsQueued = false; + + protected GUIContent SkeletonDataAssetLabel, SkeletonUtilityButtonContent; + protected GUIContent PMAVertexColorsLabel, ClearStateOnDisableLabel, ZSpacingLabel, ImmubleTrianglesLabel, TintBlackLabel, UpdateWhenInvisibleLabel, SingleSubmeshLabel, FixDrawOrderLabel; + protected GUIContent NormalsLabel, TangentsLabel, MaskInteractionLabel; + protected GUIContent MaskMaterialsHeadingLabel, MaskMaterialsNoneLabel, MaskMaterialsInsideLabel, MaskMaterialsOutsideLabel; + protected GUIContent SetMaterialButtonLabel, ClearMaterialButtonLabel, DeleteMaterialButtonLabel; + + const string ReloadButtonString = "Reload"; + static GUILayoutOption reloadButtonWidth; + static GUILayoutOption ReloadButtonWidth { get { return reloadButtonWidth = reloadButtonWidth ?? GUILayout.Width(GUI.skin.label.CalcSize(new GUIContent(ReloadButtonString)).x + 20); } } + static GUIStyle ReloadButtonStyle { get { return EditorStyles.miniButton; } } + + protected bool TargetIsValid { + get { + if (serializedObject.isEditingMultipleObjects) { + foreach (var o in targets) { + var component = (SkeletonRenderer)o; + if (!component.valid) + return false; + } + return true; + } else { + var component = (SkeletonRenderer)target; + return component.valid; + } + } + } + + protected virtual void OnEnable () { +#if NEW_PREFAB_SYSTEM + isInspectingPrefab = false; +#else + isInspectingPrefab = (PrefabUtility.GetPrefabType(target) == PrefabType.Prefab); +#endif + SpineEditorUtilities.ConfirmInitialization(); + + // Labels + SkeletonDataAssetLabel = new GUIContent("SkeletonData Asset", Icons.spine); + SkeletonUtilityButtonContent = new GUIContent("Add Skeleton Utility", Icons.skeletonUtility); + ImmubleTrianglesLabel = new GUIContent("Immutable Triangles", "Enable to optimize rendering for skeletons that never change attachment visbility"); + PMAVertexColorsLabel = new GUIContent("PMA Vertex Colors", "Use this if you are using the default Spine/Skeleton shader or any premultiply-alpha shader."); + ClearStateOnDisableLabel = new GUIContent("Clear State On Disable", "Use this if you are pooling or enabling/disabling your Spine GameObject."); + ZSpacingLabel = new GUIContent("Z Spacing", "A value other than 0 adds a space between each rendered attachment to prevent Z Fighting when using shaders that read or write to the depth buffer. Large values may cause unwanted parallax and spaces depending on camera setup."); + NormalsLabel = new GUIContent("Add Normals", "Use this if your shader requires vertex normals. A more efficient solution for 2D setups is to modify the shader to assume a single normal value for the whole mesh."); + TangentsLabel = new GUIContent("Solve Tangents", "Calculates the tangents per frame. Use this if you are using lit shaders (usually with normal maps) that require vertex tangents."); + TintBlackLabel = new GUIContent("Tint Black (!)", "Adds black tint vertex data to the mesh as UV2 and UV3. Black tinting requires that the shader interpret UV2 and UV3 as black tint colors for this effect to work. You may also use the default [Spine/Skeleton Tint Black] shader.\n\nIf you only need to tint the whole skeleton and not individual parts, the [Spine/Skeleton Tint] shader is recommended for better efficiency and changing/animating the _Black material property via MaterialPropertyBlock."); + SingleSubmeshLabel = new GUIContent("Use Single Submesh", "Simplifies submesh generation by assuming you are only using one Material and need only one submesh. This is will disable multiple materials, render separation, and custom slot materials."); + UpdateWhenInvisibleLabel = new GUIContent("Update When Invisible", "Update mode used when the MeshRenderer becomes invisible. Update mode is automatically reset to UpdateMode.FullUpdate when the mesh becomes visible again."); + FixDrawOrderLabel = new GUIContent("Fix Draw Order", "Applies only when 3+ submeshes are used (2+ materials with alternating order, e.g. \"A B A\"). If true, GPU instancing will be disabled at all materials and MaterialPropertyBlocks are assigned at each material to prevent aggressive batching of submeshes by e.g. the LWRP renderer, leading to incorrect draw order (e.g. \"A1 B A2\" changed to \"A1A2 B\"). You can disable this parameter when everything is drawn correctly to save the additional performance cost. Note: the GPU instancing setting will remain disabled at affected material assets after exiting play mode, you have to enable it manually if you accidentally enabled this parameter."); + MaskInteractionLabel = new GUIContent("Mask Interaction", "SkeletonRenderer's interaction with a Sprite Mask."); + MaskMaterialsHeadingLabel = new GUIContent("Mask Interaction Materials", "Materials used for different interaction with sprite masks."); + MaskMaterialsNoneLabel = new GUIContent("Normal Materials", "Normal materials used when Mask Interaction is set to None."); + MaskMaterialsInsideLabel = new GUIContent("Inside Mask", "Materials used when Mask Interaction is set to Inside Mask."); + MaskMaterialsOutsideLabel = new GUIContent("Outside Mask", "Materials used when Mask Interaction is set to Outside Mask."); + SetMaterialButtonLabel = new GUIContent("Set", "Prepares material references for switching to the corresponding Mask Interaction mode at runtime. Creates the required materials if they do not exist."); + ClearMaterialButtonLabel = new GUIContent("Clear", "Clears unused material references. Note: when switching to the corresponding Mask Interaction mode at runtime, a new material is generated on the fly."); + DeleteMaterialButtonLabel = new GUIContent("Delete", "Clears unused material references and deletes the corresponding assets. Note: when switching to the corresponding Mask Interaction mode at runtime, a new material is generated on the fly."); + + var so = this.serializedObject; + skeletonDataAsset = so.FindProperty("skeletonDataAsset"); + initialSkinName = so.FindProperty("initialSkinName"); + initialFlipX = so.FindProperty("initialFlipX"); + initialFlipY = so.FindProperty("initialFlipY"); + normals = so.FindProperty("addNormals"); + tangents = so.FindProperty("calculateTangents"); + immutableTriangles = so.FindProperty("immutableTriangles"); + pmaVertexColors = so.FindProperty("pmaVertexColors"); + clearStateOnDisable = so.FindProperty("clearStateOnDisable"); + tintBlack = so.FindProperty("tintBlack"); + updateWhenInvisible = so.FindProperty("updateWhenInvisible"); + singleSubmesh = so.FindProperty("singleSubmesh"); + fixDrawOrder = so.FindProperty("fixDrawOrder"); + maskInteraction = so.FindProperty("maskInteraction"); + maskMaterialsNone = so.FindProperty("maskMaterials.materialsMaskDisabled"); + maskMaterialsInside = so.FindProperty("maskMaterials.materialsInsideMask"); + maskMaterialsOutside = so.FindProperty("maskMaterials.materialsOutsideMask"); + + separatorSlotNames = so.FindProperty("separatorSlotNames"); + separatorSlotNames.isExpanded = true; + + zSpacing = so.FindProperty("zSpacing"); + + SerializedObject renderersSerializedObject = SpineInspectorUtility.GetRenderersSerializedObject(serializedObject); // Allows proper multi-edit behavior. + sortingProperties = new SpineInspectorUtility.SerializedSortingProperties(renderersSerializedObject); + } + + public void OnSceneGUI () { + var skeletonRenderer = (SkeletonRenderer)target; + var skeleton = skeletonRenderer.Skeleton; + var transform = skeletonRenderer.transform; + if (skeleton == null) return; + + SpineHandles.DrawBones(transform, skeleton); + } + + override public void OnInspectorGUI () { + bool multi = serializedObject.isEditingMultipleObjects; + DrawInspectorGUI(multi); + HandleSkinChange(); + if (serializedObject.ApplyModifiedProperties() || SpineInspectorUtility.UndoRedoPerformed(Event.current) || + AreAnyMaskMaterialsMissing()) { + if (!Application.isPlaying) { + foreach (var o in targets) + SpineEditorUtilities.ReinitializeComponent((SkeletonRenderer)o); + SceneView.RepaintAll(); + } + } + } + + protected virtual void DrawInspectorGUI (bool multi) { + // Initialize. + if (Event.current.type == EventType.Layout) { + if (forceReloadQueued) { + forceReloadQueued = false; + foreach (var c in targets) { + SpineEditorUtilities.ReloadSkeletonDataAssetAndComponent(c as SkeletonRenderer); + } + } else { + foreach (var c in targets) { + var component = c as SkeletonRenderer; + if (!component.valid) { + SpineEditorUtilities.ReinitializeComponent(component); + if (!component.valid) continue; + } + } + } + + #if BUILT_IN_SPRITE_MASK_COMPONENT + if (setMaskNoneMaterialsQueued) { + setMaskNoneMaterialsQueued = false; + foreach (var c in targets) + EditorSetMaskMaterials(c as SkeletonRenderer, SpriteMaskInteraction.None); + } + if (setInsideMaskMaterialsQueued) { + setInsideMaskMaterialsQueued = false; + foreach (var c in targets) + EditorSetMaskMaterials(c as SkeletonRenderer, SpriteMaskInteraction.VisibleInsideMask); + } + if (setOutsideMaskMaterialsQueued) { + setOutsideMaskMaterialsQueued = false; + foreach (var c in targets) + EditorSetMaskMaterials(c as SkeletonRenderer, SpriteMaskInteraction.VisibleOutsideMask); + } + + if (deleteInsideMaskMaterialsQueued) { + deleteInsideMaskMaterialsQueued = false; + foreach (var c in targets) + EditorDeleteMaskMaterials(c as SkeletonRenderer, SpriteMaskInteraction.VisibleInsideMask); + } + if (deleteOutsideMaskMaterialsQueued) { + deleteOutsideMaskMaterialsQueued = false; + foreach (var c in targets) + EditorDeleteMaskMaterials(c as SkeletonRenderer, SpriteMaskInteraction.VisibleOutsideMask); + } + #endif + +#if NO_PREFAB_MESH + if (isInspectingPrefab) { + foreach (var c in targets) { + var component = (SkeletonRenderer)c; + MeshFilter meshFilter = component.GetComponent(); + if (meshFilter != null && meshFilter.sharedMesh != null) + meshFilter.sharedMesh = null; + } + } +#endif + } + + bool valid = TargetIsValid; + + // Fields. + if (multi) { + using (new EditorGUILayout.HorizontalScope(EditorStyles.helpBox)) { + SpineInspectorUtility.PropertyFieldFitLabel(skeletonDataAsset, SkeletonDataAssetLabel); + if (GUILayout.Button(ReloadButtonString, ReloadButtonStyle, ReloadButtonWidth)) + forceReloadQueued = true; + } + + if (valid) EditorGUILayout.PropertyField(initialSkinName, SpineInspectorUtility.TempContent("Initial Skin")); + + } else { + var component = (SkeletonRenderer)target; + + using (new EditorGUILayout.HorizontalScope(EditorStyles.helpBox)) { + SpineInspectorUtility.PropertyFieldFitLabel(skeletonDataAsset, SkeletonDataAssetLabel); + if (component.valid) { + if (GUILayout.Button(ReloadButtonString, ReloadButtonStyle, ReloadButtonWidth)) + forceReloadQueued = true; + } + } + + if (component.skeletonDataAsset == null) { + EditorGUILayout.HelpBox("Skeleton Data Asset required", MessageType.Warning); + return; + } + + if (!SpineEditorUtilities.SkeletonDataAssetIsValid(component.skeletonDataAsset)) { + EditorGUILayout.HelpBox("Skeleton Data Asset error. Please check Skeleton Data Asset.", MessageType.Error); + return; + } + + if (valid) + EditorGUILayout.PropertyField(initialSkinName, SpineInspectorUtility.TempContent("Initial Skin")); + + } + + EditorGUILayout.Space(); + + // Sorting Layers + SpineInspectorUtility.SortingPropertyFields(sortingProperties, applyModifiedProperties: true); + + if (maskInteraction != null) EditorGUILayout.PropertyField(maskInteraction, MaskInteractionLabel); + + if (!valid) + return; + + string errorMessage = null; + if (MaterialChecks.IsMaterialSetupProblematic((SkeletonRenderer)this.target, ref errorMessage)) { + EditorGUILayout.HelpBox(errorMessage, MessageType.Error, true); + } + + // More Render Options... + using (new SpineInspectorUtility.BoxScope()) { + EditorGUI.BeginChangeCheck(); + + EditorGUILayout.BeginHorizontal(GUILayout.Height(EditorGUIUtility.singleLineHeight + 5)); + advancedFoldout = EditorGUILayout.Foldout(advancedFoldout, "Advanced"); + if (advancedFoldout) { + EditorGUILayout.Space(); + if (GUILayout.Button("Debug", EditorStyles.miniButton, GUILayout.Width(65f))) + SkeletonDebugWindow.Init(); + } else { + EditorGUILayout.Space(); + } + EditorGUILayout.EndHorizontal(); + + if (advancedFoldout) { + + using (new SpineInspectorUtility.IndentScope()) { + using (new EditorGUILayout.HorizontalScope()) { + SpineInspectorUtility.ToggleLeftLayout(initialFlipX); + SpineInspectorUtility.ToggleLeftLayout(initialFlipY); + EditorGUILayout.Space(); + } + + EditorGUILayout.Space(); + EditorGUILayout.LabelField("Renderer Settings", EditorStyles.boldLabel); + using (new SpineInspectorUtility.LabelWidthScope()) { + // Optimization options + if (updateWhenInvisible != null) EditorGUILayout.PropertyField(updateWhenInvisible, UpdateWhenInvisibleLabel); + + if (singleSubmesh != null) EditorGUILayout.PropertyField(singleSubmesh, SingleSubmeshLabel); + #if PER_MATERIAL_PROPERTY_BLOCKS + if (fixDrawOrder != null) EditorGUILayout.PropertyField(fixDrawOrder, FixDrawOrderLabel); + #endif + if (immutableTriangles != null) EditorGUILayout.PropertyField(immutableTriangles, ImmubleTrianglesLabel); + EditorGUILayout.PropertyField(clearStateOnDisable, ClearStateOnDisableLabel); + EditorGUILayout.Space(); + } + + SeparatorsField(separatorSlotNames); + EditorGUILayout.Space(); + + // Render options + const float MinZSpacing = -0.1f; + const float MaxZSpacing = 0f; + EditorGUILayout.Slider(zSpacing, MinZSpacing, MaxZSpacing, ZSpacingLabel); + EditorGUILayout.Space(); + + using (new SpineInspectorUtility.LabelWidthScope()) { + EditorGUILayout.LabelField(SpineInspectorUtility.TempContent("Vertex Data", SpineInspectorUtility.UnityIcon()), EditorStyles.boldLabel); + if (pmaVertexColors != null) EditorGUILayout.PropertyField(pmaVertexColors, PMAVertexColorsLabel); + EditorGUILayout.PropertyField(tintBlack, TintBlackLabel); + + // Optional fields. May be disabled in SkeletonRenderer. + if (normals != null) EditorGUILayout.PropertyField(normals, NormalsLabel); + if (tangents != null) EditorGUILayout.PropertyField(tangents, TangentsLabel); + } + + #if BUILT_IN_SPRITE_MASK_COMPONENT + EditorGUILayout.Space(); + if (maskMaterialsNone.arraySize > 0 || maskMaterialsInside.arraySize > 0 || maskMaterialsOutside.arraySize > 0) { + EditorGUILayout.LabelField(SpineInspectorUtility.TempContent("Mask Interaction Materials", SpineInspectorUtility.UnityIcon()), EditorStyles.boldLabel); + bool differentMaskModesSelected = maskInteraction.hasMultipleDifferentValues; + int activeMaskInteractionValue = differentMaskModesSelected ? -1 : maskInteraction.intValue; + + bool ignoredParam = true; + MaskMaterialsEditingField(ref setMaskNoneMaterialsQueued, ref ignoredParam, maskMaterialsNone, MaskMaterialsNoneLabel, + differentMaskModesSelected, allowDelete : false, isActiveMaterial : activeMaskInteractionValue == (int)SpriteMaskInteraction.None); + MaskMaterialsEditingField(ref setInsideMaskMaterialsQueued, ref deleteInsideMaskMaterialsQueued, maskMaterialsInside, MaskMaterialsInsideLabel, + differentMaskModesSelected, allowDelete: true, isActiveMaterial: activeMaskInteractionValue == (int)SpriteMaskInteraction.VisibleInsideMask); + MaskMaterialsEditingField(ref setOutsideMaskMaterialsQueued, ref deleteOutsideMaskMaterialsQueued, maskMaterialsOutside, MaskMaterialsOutsideLabel, + differentMaskModesSelected, allowDelete : true, isActiveMaterial: activeMaskInteractionValue == (int)SpriteMaskInteraction.VisibleOutsideMask); + } + #endif + + EditorGUILayout.Space(); + + if (valid && !isInspectingPrefab) { + if (multi) { + // Support multi-edit SkeletonUtility button. + // EditorGUILayout.Space(); + // bool addSkeletonUtility = GUILayout.Button(buttonContent, GUILayout.Height(30)); + // foreach (var t in targets) { + // var component = t as Component; + // if (addSkeletonUtility && component.GetComponent() == null) + // component.gameObject.AddComponent(); + // } + } else { + var component = (Component)target; + if (component.GetComponent() == null) { + if (SpineInspectorUtility.CenteredButton(SkeletonUtilityButtonContent, 21, true, 200f)) + component.gameObject.AddComponent(); + } + } + } + + EditorGUILayout.Space(); + } + } + + if (EditorGUI.EndChangeCheck()) + SceneView.RepaintAll(); + } + } + + protected void SkeletonRootMotionParameter() { + SkeletonRootMotionParameter(targets); + } + + public static void SkeletonRootMotionParameter(Object[] targets) { + int rootMotionComponentCount = 0; + foreach (var t in targets) { + var component = t as Component; + if (component.GetComponent() != null) { + ++rootMotionComponentCount; + } + } + bool allHaveRootMotion = rootMotionComponentCount == targets.Length; + bool anyHaveRootMotion = rootMotionComponentCount > 0; + + using (new GUILayout.HorizontalScope()) { + EditorGUILayout.PrefixLabel("Root Motion"); + + if (!allHaveRootMotion) { + if (GUILayout.Button(SpineInspectorUtility.TempContent("Add Component", Icons.constraintTransform), GUILayout.MaxWidth(130), GUILayout.Height(18))) { + foreach (var t in targets) { + var component = t as Component; + if (component.GetComponent() == null) { + component.gameObject.AddComponent(); + } + } + } + } + if (anyHaveRootMotion) { + if (GUILayout.Button(SpineInspectorUtility.TempContent("Remove Component", Icons.constraintTransform), GUILayout.MaxWidth(140), GUILayout.Height(18))) { + foreach (var t in targets) { + var component = t as Component; + var rootMotionComponent = component.GetComponent(); + if (rootMotionComponent != null) { + DestroyImmediate(rootMotionComponent); + } + } + } + } + } + } + + 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) { + 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(); + + EditorGUILayout.Space(); + } else + EditorGUILayout.PropertyField(separatorSlotNames, new GUIContent(separatorSlotNames.displayName + string.Format("{0} [{1}]", terminalSlotWarning, separatorSlotNames.arraySize), SeparatorsDescription), true); + } + } + + public void MaskMaterialsEditingField(ref bool wasSetRequested, ref bool wasDeleteRequested, + SerializedProperty maskMaterials, GUIContent label, + bool differentMaskModesSelected, bool allowDelete, bool isActiveMaterial) { + using (new EditorGUILayout.HorizontalScope()) { + + EditorGUILayout.LabelField(label, isActiveMaterial ? EditorStyles.boldLabel : EditorStyles.label, GUILayout.MinWidth(80f), GUILayout.MaxWidth(140)); + EditorGUILayout.LabelField(maskMaterials.hasMultipleDifferentValues ? "-" : maskMaterials.arraySize.ToString(), EditorStyles.miniLabel, GUILayout.Width(42f)); + + bool enableSetButton = differentMaskModesSelected || maskMaterials.arraySize == 0; + bool enableClearButtons = differentMaskModesSelected || (maskMaterials.arraySize != 0 && !isActiveMaterial); + + EditorGUI.BeginDisabledGroup(!enableSetButton); + if (GUILayout.Button(SetMaterialButtonLabel, EditorStyles.miniButtonLeft, GUILayout.Width(46f))) { + wasSetRequested = true; + } + EditorGUI.EndDisabledGroup(); + + EditorGUI.BeginDisabledGroup(!enableClearButtons); + { + if (GUILayout.Button(ClearMaterialButtonLabel, allowDelete ? EditorStyles.miniButtonMid : EditorStyles.miniButtonRight, GUILayout.Width(46f))) { + maskMaterials.ClearArray(); + } + else if (allowDelete && GUILayout.Button(DeleteMaterialButtonLabel, EditorStyles.miniButtonRight, GUILayout.Width(46f))) { + wasDeleteRequested = true; + } + if (!allowDelete) + GUILayout.Space(46f); + } + EditorGUI.EndDisabledGroup(); + } + } + + void HandleSkinChange() { + if (!Application.isPlaying && Event.current.type == EventType.Layout && !initialSkinName.hasMultipleDifferentValues) { + bool mismatchDetected = false; + string newSkinName = initialSkinName.stringValue; + foreach (var o in targets) { + mismatchDetected |= UpdateIfSkinMismatch((SkeletonRenderer)o, newSkinName); + } + + if (mismatchDetected) { + mismatchDetected = false; + SceneView.RepaintAll(); + } + } + } + + static bool UpdateIfSkinMismatch (SkeletonRenderer skeletonRenderer, string componentSkinName) { + if (!skeletonRenderer.valid || skeletonRenderer.EditorSkipSkinSync) return false; + + var skin = skeletonRenderer.Skeleton.Skin; + string skeletonSkinName = skin != null ? skin.Name : null; + bool defaultCase = skin == null && string.IsNullOrEmpty(componentSkinName); + bool fieldMatchesSkin = defaultCase || string.Equals(componentSkinName, skeletonSkinName, System.StringComparison.Ordinal); + + if (!fieldMatchesSkin) { + Skin skinToSet = string.IsNullOrEmpty(componentSkinName) ? null : skeletonRenderer.Skeleton.Data.FindSkin(componentSkinName); + skeletonRenderer.Skeleton.SetSkin(skinToSet); + skeletonRenderer.Skeleton.SetSlotsToSetupPose(); + + // Note: the UpdateIfSkinMismatch concept shall be replaced with e.g. an OnValidate based + // solution or in a separate commit. The current solution does not repaint the Game view because + // it is first applying values and in the next editor pass is calling this skin-changing method. + if (skeletonRenderer is SkeletonAnimation) + ((SkeletonAnimation) skeletonRenderer).Update(0f); + else if (skeletonRenderer is SkeletonMecanim) + ((SkeletonMecanim) skeletonRenderer).Update(); + + skeletonRenderer.LateUpdate(); + return true; + } + return false; + } + + bool AreAnyMaskMaterialsMissing() { + #if BUILT_IN_SPRITE_MASK_COMPONENT + foreach (var o in targets) { + var component = (SkeletonRenderer)o; + if (!component.valid) + continue; + if (SpineMaskUtilities.AreMaskMaterialsMissing(component)) + return true; + } + #endif + return false; + } + + #if BUILT_IN_SPRITE_MASK_COMPONENT + static void EditorSetMaskMaterials(SkeletonRenderer component, SpriteMaskInteraction maskType) + { + if (component == null) return; + if (!SpineEditorUtilities.SkeletonDataAssetIsValid(component.SkeletonDataAsset)) return; + SpineMaskUtilities.EditorInitMaskMaterials(component, component.maskMaterials, maskType); + } + + static void EditorDeleteMaskMaterials(SkeletonRenderer component, SpriteMaskInteraction maskType) { + if (component == null) return; + if (!SpineEditorUtilities.SkeletonDataAssetIsValid(component.SkeletonDataAsset)) return; + SpineMaskUtilities.EditorDeleteMaskMaterials(component.maskMaterials, maskType); + } + #endif + } +} diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonRendererInspector.cs.meta b/box1/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonRendererInspector.cs.meta new file mode 100644 index 00000000..d7791c68 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonRendererInspector.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: d0fc5db9788bce4418ad3252d43faa8a +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonRootMotionBaseInspector.cs b/box1/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonRootMotionBaseInspector.cs new file mode 100644 index 00000000..4f1af954 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonRootMotionBaseInspector.cs @@ -0,0 +1,103 @@ +/****************************************************************************** + * 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 UnityEditor; +using UnityEngine; + +namespace Spine.Unity.Editor { + [CustomEditor(typeof(SkeletonRootMotionBase))] + [CanEditMultipleObjects] + public class SkeletonRootMotionBaseInspector : UnityEditor.Editor { + protected SerializedProperty rootMotionBoneName; + protected SerializedProperty transformPositionX; + protected SerializedProperty transformPositionY; + protected SerializedProperty rootMotionScaleX; + protected SerializedProperty rootMotionScaleY; + protected SerializedProperty rigidBody2D; + protected SerializedProperty rigidBody; + + protected GUIContent rootMotionBoneNameLabel; + protected GUIContent transformPositionXLabel; + protected GUIContent transformPositionYLabel; + protected GUIContent rootMotionScaleXLabel; + protected GUIContent rootMotionScaleYLabel; + protected GUIContent rigidBody2DLabel; + protected GUIContent rigidBodyLabel; + + protected virtual void OnEnable () { + + rootMotionBoneName = serializedObject.FindProperty("rootMotionBoneName"); + transformPositionX = serializedObject.FindProperty("transformPositionX"); + transformPositionY = serializedObject.FindProperty("transformPositionY"); + rootMotionScaleX = serializedObject.FindProperty("rootMotionScaleX"); + rootMotionScaleY = serializedObject.FindProperty("rootMotionScaleY"); + rigidBody2D = serializedObject.FindProperty("rigidBody2D"); + rigidBody = serializedObject.FindProperty("rigidBody"); + + rootMotionBoneNameLabel = new UnityEngine.GUIContent("Root Motion Bone", "The bone to take the motion from."); + transformPositionXLabel = new UnityEngine.GUIContent("X", "Root transform position (X)"); + transformPositionYLabel = new UnityEngine.GUIContent("Y", "Use the Y-movement of the bone."); + rootMotionScaleXLabel = new UnityEngine.GUIContent("Root Motion Scale (X)", "Scale applied to the horizontal root motion delta. Can be used for delta compensation to e.g. stretch a jump to the desired distance."); + rootMotionScaleYLabel = new UnityEngine.GUIContent("Root Motion Scale (Y)", "Scale applied to the vertical root motion delta. Can be used for delta compensation to e.g. stretch a jump to the desired distance."); + rigidBody2DLabel = new UnityEngine.GUIContent("Rigidbody2D", + "Optional Rigidbody2D: Assign a Rigidbody2D here if you want " + + " to apply the root motion to the rigidbody instead of the Transform." + + "\n\n" + + "Note that animation and physics updates are not always in sync." + + "Some jitter may result at certain framerates."); + rigidBodyLabel = new UnityEngine.GUIContent("Rigidbody", + "Optional Rigidbody: Assign a Rigidbody here if you want " + + " to apply the root motion to the rigidbody instead of the Transform." + + "\n\n" + + "Note that animation and physics updates are not always in sync." + + "Some jitter may result at certain framerates."); + } + + public override void OnInspectorGUI () { + MainPropertyFields(); + OptionalPropertyFields(); + serializedObject.ApplyModifiedProperties(); + } + + protected virtual void MainPropertyFields () { + EditorGUILayout.PropertyField(rootMotionBoneName, rootMotionBoneNameLabel); + EditorGUILayout.PropertyField(transformPositionX, transformPositionXLabel); + EditorGUILayout.PropertyField(transformPositionY, transformPositionYLabel); + + EditorGUILayout.PropertyField(rootMotionScaleX, rootMotionScaleXLabel); + EditorGUILayout.PropertyField(rootMotionScaleY, rootMotionScaleYLabel); + } + + protected virtual void OptionalPropertyFields () { + //EditorGUILayout.LabelField("Optional", EditorStyles.boldLabel); + EditorGUILayout.PropertyField(rigidBody2D, rigidBody2DLabel); + EditorGUILayout.PropertyField(rigidBody, rigidBodyLabel); + } + } +} diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonRootMotionBaseInspector.cs.meta b/box1/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonRootMotionBaseInspector.cs.meta new file mode 100644 index 00000000..03044488 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonRootMotionBaseInspector.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: f2cba83baf6afdf44a996e40017c6325 +timeCreated: 1593175106 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonRootMotionInspector.cs b/box1/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonRootMotionInspector.cs new file mode 100644 index 00000000..2c965065 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonRootMotionInspector.cs @@ -0,0 +1,79 @@ +/****************************************************************************** + * 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 UnityEditor; +using UnityEngine; + +namespace Spine.Unity.Editor { + [CustomEditor(typeof(SkeletonRootMotion))] + [CanEditMultipleObjects] + public class SkeletonRootMotionInspector : SkeletonRootMotionBaseInspector { + protected SerializedProperty animationTrackFlags; + protected GUIContent animationTrackFlagsLabel; + + string[] TrackNames; + + protected override void OnEnable () { + base.OnEnable(); + + animationTrackFlags = serializedObject.FindProperty("animationTrackFlags"); + animationTrackFlagsLabel = new UnityEngine.GUIContent("Animation Tracks", + "Animation tracks to apply root motion at. Defaults to the first" + + " animation track (index 0)."); + } + + override public void OnInspectorGUI () { + + base.MainPropertyFields(); + AnimationTracksPropertyField(); + + base.OptionalPropertyFields(); + serializedObject.ApplyModifiedProperties(); + } + + protected void AnimationTracksPropertyField () { + + if (TrackNames == null) { + InitTrackNames(); + + } + + animationTrackFlags.intValue = EditorGUILayout.MaskField( + animationTrackFlagsLabel, animationTrackFlags.intValue, TrackNames); + } + + protected void InitTrackNames () { + int numEntries = 32; + TrackNames = new string[numEntries]; + for (int i = 0; i < numEntries; ++i) { + TrackNames[i] = string.Format("Track {0}", i); + } + } + } +} diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonRootMotionInspector.cs.meta b/box1/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonRootMotionInspector.cs.meta new file mode 100644 index 00000000..7c357a89 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonRootMotionInspector.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: e4836100aed984c4a9af11d39c63cb6b +timeCreated: 1593183609 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonUtilityBoneInspector.cs b/box1/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonUtilityBoneInspector.cs new file mode 100644 index 00000000..b4e12b68 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonUtilityBoneInspector.cs @@ -0,0 +1,541 @@ +/****************************************************************************** + * 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. + *****************************************************************************/ + +// Contributed by: Mitch Thompson + +#if UNITY_2019_2_OR_NEWER +#define HINGE_JOINT_NEW_BEHAVIOUR +#endif + +using UnityEngine; +using UnityEditor; +using System.Collections.Generic; +using Spine; + +namespace Spine.Unity.Editor { + using Icons = SpineEditorUtilities.Icons; + + [CustomEditor(typeof(SkeletonUtilityBone)), CanEditMultipleObjects] + public class SkeletonUtilityBoneInspector : UnityEditor.Editor { + SerializedProperty mode, boneName, zPosition, position, rotation, scale, overrideAlpha, hierarchy, parentReference; + GUIContent hierarchyLabel; + + //multi selected flags + bool containsFollows, containsOverrides, multiObject; + + //single selected helpers + SkeletonUtilityBone utilityBone; + SkeletonUtility skeletonUtility; + bool canCreateHingeChain = false; + + Dictionary> boundingBoxTable = new Dictionary>(); + + void OnEnable () { + mode = this.serializedObject.FindProperty("mode"); + boneName = this.serializedObject.FindProperty("boneName"); + zPosition = this.serializedObject.FindProperty("zPosition"); + position = this.serializedObject.FindProperty("position"); + rotation = this.serializedObject.FindProperty("rotation"); + scale = this.serializedObject.FindProperty("scale"); + overrideAlpha = this.serializedObject.FindProperty("overrideAlpha"); + hierarchy = this.serializedObject.FindProperty("hierarchy"); + hierarchyLabel = new GUIContent("Skeleton Utility Parent"); + parentReference = this.serializedObject.FindProperty("parentReference"); + + utilityBone = (SkeletonUtilityBone)target; + skeletonUtility = utilityBone.hierarchy; + EvaluateFlags(); + + if (!utilityBone.valid && skeletonUtility != null) { + if (skeletonUtility.skeletonRenderer != null) + skeletonUtility.skeletonRenderer.Initialize(false); + if (skeletonUtility.skeletonGraphic != null) + skeletonUtility.skeletonGraphic.Initialize(false); + } + + canCreateHingeChain = CanCreateHingeChain(); + boundingBoxTable.Clear(); + + if (multiObject) return; + if (utilityBone.bone == null) return; + + var skeleton = utilityBone.bone.Skeleton; + int slotCount = skeleton.Slots.Count; + Skin skin = skeleton.Skin; + if (skeleton.Skin == null) + skin = skeleton.Data.DefaultSkin; + + for(int i = 0; i < slotCount; i++){ + Slot slot = skeletonUtility.Skeleton.Slots.Items[i]; + if (slot.Bone == utilityBone.bone) { + var slotAttachments = new List(); + int slotIndex = skeleton.FindSlotIndex(slot.Data.Name); + skin.GetAttachments(slotIndex, slotAttachments); + + var boundingBoxes = new List(); + foreach (var att in slotAttachments) { + var boundingBoxAttachment = att.Attachment as BoundingBoxAttachment; + if (boundingBoxAttachment != null) + boundingBoxes.Add(boundingBoxAttachment); + } + + if (boundingBoxes.Count > 0) + boundingBoxTable.Add(slot, boundingBoxes); + } + } + } + + void EvaluateFlags () { + if (Selection.objects.Length == 1) { + containsFollows = utilityBone.mode == SkeletonUtilityBone.Mode.Follow; + containsOverrides = utilityBone.mode == SkeletonUtilityBone.Mode.Override; + } else { + int boneCount = 0; + foreach (Object o in Selection.objects) { + var go = o as GameObject; + if (go != null) { + SkeletonUtilityBone sub = go.GetComponent(); + if (sub != null) { + boneCount++; + containsFollows |= (sub.mode == SkeletonUtilityBone.Mode.Follow); + containsOverrides |= (sub.mode == SkeletonUtilityBone.Mode.Override); + } + } + } + + multiObject |= (boneCount > 1); + } + } + + public override void OnInspectorGUI () { + serializedObject.Update(); + + EditorGUI.BeginChangeCheck(); + EditorGUILayout.PropertyField(mode); + if (EditorGUI.EndChangeCheck()) { + containsOverrides = mode.enumValueIndex == 1; + containsFollows = mode.enumValueIndex == 0; + } + + using (new EditorGUI.DisabledGroupScope(multiObject)) { + string str = boneName.stringValue; + if (str == "") + str = ""; + if (multiObject) + str = ""; + + using (new GUILayout.HorizontalScope()) { + EditorGUILayout.PrefixLabel("Bone"); + if (GUILayout.Button(str, EditorStyles.popup)) { + BoneSelectorContextMenu(str, ((SkeletonUtilityBone)target).hierarchy.Skeleton.Bones, "", TargetBoneSelected); + } + } + } + + EditorGUILayout.PropertyField(zPosition); + EditorGUILayout.PropertyField(position); + EditorGUILayout.PropertyField(rotation); + EditorGUILayout.PropertyField(scale); + + using (new EditorGUI.DisabledGroupScope(containsFollows)) { + EditorGUILayout.PropertyField(overrideAlpha); + EditorGUILayout.PropertyField(parentReference); + EditorGUILayout.PropertyField(hierarchy, hierarchyLabel); + } + + EditorGUILayout.Space(); + + using (new GUILayout.HorizontalScope()) { + EditorGUILayout.Space(); + using (new EditorGUI.DisabledGroupScope(multiObject || !utilityBone.valid || utilityBone.bone == null || utilityBone.bone.Children.Count == 0)) { + if (GUILayout.Button(SpineInspectorUtility.TempContent("Add Child Bone", Icons.bone), GUILayout.MinWidth(120), GUILayout.Height(24))) + BoneSelectorContextMenu("", utilityBone.bone.Children, "", SpawnChildBoneSelected); + } + using (new EditorGUI.DisabledGroupScope(multiObject || !utilityBone.valid || utilityBone.bone == null || containsOverrides)) { + if (GUILayout.Button(SpineInspectorUtility.TempContent("Add Override", Icons.poseBones), GUILayout.MinWidth(120), GUILayout.Height(24))) + SpawnOverride(); + } + EditorGUILayout.Space(); + } + EditorGUILayout.Space(); + using (new GUILayout.HorizontalScope()) { + EditorGUILayout.Space(); + using (new EditorGUI.DisabledGroupScope(multiObject || !utilityBone.valid || !canCreateHingeChain)) { + if (GUILayout.Button(SpineInspectorUtility.TempContent("Create 3D Hinge Chain", Icons.hingeChain), GUILayout.MinWidth(120), GUILayout.Height(24))) + CreateHingeChain(); + if (GUILayout.Button(SpineInspectorUtility.TempContent("Create 2D Hinge Chain", Icons.hingeChain), GUILayout.MinWidth(120), GUILayout.Height(24))) + CreateHingeChain2D(); + } + EditorGUILayout.Space(); + } + + using (new EditorGUI.DisabledGroupScope(multiObject || boundingBoxTable.Count == 0)) { + EditorGUILayout.LabelField(SpineInspectorUtility.TempContent("Bounding Boxes", Icons.boundingBox), EditorStyles.boldLabel); + + foreach (var entry in boundingBoxTable){ + Slot slot = entry.Key; + var boundingBoxes = entry.Value; + + EditorGUI.indentLevel++; + EditorGUILayout.LabelField(slot.Data.Name); + EditorGUI.indentLevel++; + { + foreach (var box in boundingBoxes) { + using (new GUILayout.HorizontalScope()) { + GUILayout.Space(30); + string buttonLabel = box.IsWeighted() ? box.Name + " (!)" : box.Name; + if (GUILayout.Button(buttonLabel, GUILayout.Width(200))) { + utilityBone.bone.Skeleton.UpdateWorldTransform(); + var bbTransform = utilityBone.transform.Find("[BoundingBox]" + box.Name); // Use FindChild in older versions of Unity. + if (bbTransform != null) { + var originalCollider = bbTransform.GetComponent(); + if (originalCollider != null) + SkeletonUtility.SetColliderPointsLocal(originalCollider, slot, box); + else + SkeletonUtility.AddBoundingBoxAsComponent(box, slot, bbTransform.gameObject); + } else { + var newPolygonCollider = SkeletonUtility.AddBoundingBoxGameObject(null, box, slot, utilityBone.transform); + bbTransform = newPolygonCollider.transform; + } + EditorGUIUtility.PingObject(bbTransform); + } + } + + } + } + EditorGUI.indentLevel--; + EditorGUI.indentLevel--; + } + } + + BoneFollowerInspector.RecommendRigidbodyButton(utilityBone); + + serializedObject.ApplyModifiedProperties(); + } + + static void BoneSelectorContextMenu (string current, ExposedList bones, string topValue, GenericMenu.MenuFunction2 callback) { + var menu = new GenericMenu(); + + if (topValue != "") + menu.AddItem(new GUIContent(topValue), current == topValue, callback, null); + + for (int i = 0; i < bones.Count; i++) + menu.AddItem(new GUIContent(bones.Items[i].Data.Name), bones.Items[i].Data.Name == current, callback, bones.Items[i]); + + menu.ShowAsContext(); + } + + void TargetBoneSelected (object obj) { + if (obj == null) { + boneName.stringValue = ""; + serializedObject.ApplyModifiedProperties(); + } else { + var bone = (Bone)obj; + boneName.stringValue = bone.Data.Name; + serializedObject.ApplyModifiedProperties(); + utilityBone.Reset(); + } + } + + void SpawnChildBoneSelected (object obj) { + if (obj == null) { + // Add recursively + foreach (var bone in utilityBone.bone.Children) { + GameObject go = skeletonUtility.SpawnBoneRecursively(bone, utilityBone.transform, utilityBone.mode, utilityBone.position, utilityBone.rotation, utilityBone.scale); + SkeletonUtilityBone[] newUtilityBones = go.GetComponentsInChildren(); + foreach (SkeletonUtilityBone utilBone in newUtilityBones) + SkeletonUtilityInspector.AttachIcon(utilBone); + } + } else { + var bone = (Bone)obj; + GameObject go = skeletonUtility.SpawnBone(bone, utilityBone.transform, utilityBone.mode, utilityBone.position, utilityBone.rotation, utilityBone.scale); + SkeletonUtilityInspector.AttachIcon(go.GetComponent()); + Selection.activeGameObject = go; + EditorGUIUtility.PingObject(go); + } + } + + void SpawnOverride () { + GameObject go = skeletonUtility.SpawnBone(utilityBone.bone, utilityBone.transform.parent, SkeletonUtilityBone.Mode.Override, utilityBone.position, utilityBone.rotation, utilityBone.scale); + go.name = go.name + " [Override]"; + SkeletonUtilityInspector.AttachIcon(go.GetComponent()); + Selection.activeGameObject = go; + EditorGUIUtility.PingObject(go); + } + + bool CanCreateHingeChain () { + if (utilityBone == null) + return false; + if (utilityBone.GetComponent() != null || utilityBone.GetComponent() != null) + return false; + if (utilityBone.bone != null && utilityBone.bone.Children.Count == 0) + return false; + + var rigidbodies = utilityBone.GetComponentsInChildren(); + var rigidbodies2D = utilityBone.GetComponentsInChildren(); + return rigidbodies.Length <= 0 && rigidbodies2D.Length <= 0; + } + + void CreateHingeChain2D () { + var kinematicParentUtilityBone = utilityBone.transform.parent.GetComponent(); + if (kinematicParentUtilityBone == null) { + UnityEditor.EditorUtility.DisplayDialog("No parent SkeletonUtilityBone found!", "Please select the first physically moving chain node, having a parent GameObject with a SkeletonUtilityBone component attached.", "OK"); + return; + } + + float mass = 10; + const float rotationLimit = 20.0f; + + SetSkeletonUtilityToFlipByRotation(); + + kinematicParentUtilityBone.mode = SkeletonUtilityBone.Mode.Follow; + kinematicParentUtilityBone.position = kinematicParentUtilityBone.rotation = kinematicParentUtilityBone.scale = kinematicParentUtilityBone.zPosition = true; + + GameObject commonParentObject = new GameObject(skeletonUtility.name + " HingeChain Parent " + utilityBone.name); + var commonParentActivateOnFlip = commonParentObject.AddComponent(); + commonParentActivateOnFlip.skeletonRenderer = skeletonUtility.skeletonRenderer; + commonParentActivateOnFlip.skeletonGraphic = skeletonUtility.skeletonGraphic; + + // HingeChain Parent + // Needs to be on top hierarchy level (not attached to the moving skeleton at least) for physics to apply proper momentum. + GameObject normalChainParentObject = new GameObject("HingeChain"); + normalChainParentObject.transform.SetParent(commonParentObject.transform); + commonParentActivateOnFlip.activeOnNormalX = normalChainParentObject; + + //var followRotationComponent = normalChainParentObject.AddComponent(); + //followRotationComponent.reference = skeletonUtility.boneRoot; + + // Follower Kinematic Rigidbody + GameObject followerKinematicObject = new GameObject(kinematicParentUtilityBone.name + " Follower"); + followerKinematicObject.transform.parent = normalChainParentObject.transform; + var followerRigidbody = followerKinematicObject.AddComponent(); + followerRigidbody.mass = mass; + followerRigidbody.isKinematic = true; + followerKinematicObject.AddComponent().reference = kinematicParentUtilityBone.transform; + followerKinematicObject.transform.position = kinematicParentUtilityBone.transform.position; + followerKinematicObject.transform.rotation = kinematicParentUtilityBone.transform.rotation; + + // Child Bones + var utilityBones = utilityBone.GetComponentsInChildren(); + var childBoneParentReference = followerKinematicObject.transform; + for (int i = 0; i < utilityBones.Length; ++i) { + var childBone = utilityBones[i]; + mass *= 0.75f; + childBone.parentReference = (i == 0) ? kinematicParentUtilityBone.transform : childBoneParentReference; + childBone.transform.SetParent(normalChainParentObject.transform, true); // we need a flat hierarchy of all Joint objects in Unity. + AttachRigidbodyAndCollider2D(childBone); + childBone.mode = SkeletonUtilityBone.Mode.Override; + childBone.scale = childBone.position = childBone.zPosition = false; + + HingeJoint2D joint = childBone.gameObject.AddComponent(); + joint.connectedBody = childBoneParentReference.GetComponent(); + joint.useLimits = true; + ApplyJoint2DAngleLimits(joint, rotationLimit, childBoneParentReference, childBone.transform); + + childBone.GetComponent().mass = mass; + childBoneParentReference = childBone.transform; + } + + Duplicate2DHierarchyForFlippedChains(normalChainParentObject, commonParentActivateOnFlip, skeletonUtility.transform, rotationLimit); + UnityEditor.Selection.activeGameObject = commonParentObject; + } + + void ApplyJoint2DAngleLimits (HingeJoint2D joint, float rotationLimit, Transform parentBone, Transform bone) { + #if HINGE_JOINT_NEW_BEHAVIOUR + float referenceAngle = (parentBone.eulerAngles.z - bone.eulerAngles.z + 360f) % 360f; + float minAngle = referenceAngle - rotationLimit; + float maxAngle = referenceAngle + rotationLimit; + if (maxAngle > 270f) { + minAngle -= 360f; + maxAngle -= 360f; + } + if (minAngle < -90f) { + minAngle += 360f; + maxAngle += 360f; + } +#else + float minAngle = - rotationLimit; + float maxAngle = rotationLimit; +#endif + joint.limits = new JointAngleLimits2D { + min = minAngle, + max = maxAngle + }; + } + + void Duplicate2DHierarchyForFlippedChains (GameObject normalChainParentObject, ActivateBasedOnFlipDirection commonParentActivateOnFlip, + Transform skeletonUtilityRoot, float rotationLimit) { + + GameObject mirroredChain = GameObject.Instantiate(normalChainParentObject, normalChainParentObject.transform.position, + normalChainParentObject.transform.rotation, commonParentActivateOnFlip.transform); + mirroredChain.name = normalChainParentObject.name + " FlippedX"; + + commonParentActivateOnFlip.activeOnFlippedX = mirroredChain; + + var followerKinematicObject = mirroredChain.GetComponentInChildren(); + followerKinematicObject.followFlippedX = true; + FlipBone2DHorizontal(followerKinematicObject.transform, skeletonUtilityRoot); + + var childBoneJoints = mirroredChain.GetComponentsInChildren(); + Transform prevRotatedChild = null; + Transform parentTransformForAngles = followerKinematicObject.transform; + for (int i = 0; i < childBoneJoints.Length; ++i) { + var joint = childBoneJoints[i]; + FlipBone2DHorizontal(joint.transform, skeletonUtilityRoot); + ApplyJoint2DAngleLimits(joint, rotationLimit, parentTransformForAngles, joint.transform); + + GameObject rotatedChild = GameObject.Instantiate(joint.gameObject, joint.transform, true); + rotatedChild.name = joint.name + " rotated"; + var rotationEulerAngles = rotatedChild.transform.localEulerAngles; + rotationEulerAngles.x = 180; + rotatedChild.transform.localEulerAngles = rotationEulerAngles; + DestroyImmediate(rotatedChild.GetComponent()); + DestroyImmediate(rotatedChild.GetComponent()); + DestroyImmediate(rotatedChild.GetComponent()); + + DestroyImmediate(joint.gameObject.GetComponent()); + + if (i > 0) { + var utilityBone = rotatedChild.GetComponent(); + utilityBone.parentReference = prevRotatedChild; + } + prevRotatedChild = rotatedChild.transform; + parentTransformForAngles = joint.transform; + } + + mirroredChain.SetActive(false); + } + + void FlipBone2DHorizontal(Transform bone, Transform mirrorPosition) { + Vector3 position = bone.position; + position.x = 2 * mirrorPosition.position.x - position.x; // = mirrorPosition + (mirrorPosition - bone.position) + bone.position = position; + + Vector3 boneZ = bone.forward; + Vector3 boneX = bone.right; + boneX.x *= -1; + + bone.rotation = Quaternion.LookRotation(boneZ, Vector3.Cross(boneZ, boneX)); + } + + void CreateHingeChain () { + var kinematicParentUtilityBone = utilityBone.transform.parent.GetComponent(); + if (kinematicParentUtilityBone == null) { + UnityEditor.EditorUtility.DisplayDialog("No parent SkeletonUtilityBone found!", "Please select the first physically moving chain node, having a parent GameObject with a SkeletonUtilityBone component attached.", "OK"); + return; + } + + SetSkeletonUtilityToFlipByRotation(); + + kinematicParentUtilityBone.mode = SkeletonUtilityBone.Mode.Follow; + kinematicParentUtilityBone.position = kinematicParentUtilityBone.rotation = kinematicParentUtilityBone.scale = kinematicParentUtilityBone.zPosition = true; + + // HingeChain Parent + // Needs to be on top hierarchy level (not attached to the moving skeleton at least) for physics to apply proper momentum. + GameObject chainParentObject = new GameObject(skeletonUtility.name + " HingeChain Parent " + utilityBone.name); + var followRotationComponent = chainParentObject.AddComponent(); + followRotationComponent.reference = skeletonUtility.boneRoot; + + // Follower Kinematic Rigidbody + GameObject followerKinematicObject = new GameObject(kinematicParentUtilityBone.name + " Follower"); + followerKinematicObject.transform.parent = chainParentObject.transform; + var followerRigidbody = followerKinematicObject.AddComponent(); + followerRigidbody.mass = 10; + followerRigidbody.isKinematic = true; + followerKinematicObject.AddComponent().reference = kinematicParentUtilityBone.transform; + followerKinematicObject.transform.position = kinematicParentUtilityBone.transform.position; + followerKinematicObject.transform.rotation = kinematicParentUtilityBone.transform.rotation; + + // Child Bones + var utilityBones = utilityBone.GetComponentsInChildren(); + var childBoneParentReference = followerKinematicObject.transform; + foreach (var childBone in utilityBones) { + childBone.parentReference = childBoneParentReference; + childBone.transform.SetParent(chainParentObject.transform, true); // we need a flat hierarchy of all Joint objects in Unity. + AttachRigidbodyAndCollider(childBone); + childBone.mode = SkeletonUtilityBone.Mode.Override; + + HingeJoint joint = childBone.gameObject.AddComponent(); + joint.axis = Vector3.forward; + joint.connectedBody = childBoneParentReference.GetComponent(); + joint.useLimits = true; + joint.limits = new JointLimits { + min = -20, + max = 20 + }; + childBone.GetComponent().mass = childBoneParentReference.transform.GetComponent().mass * 0.75f; + + childBoneParentReference = childBone.transform; + } + UnityEditor.Selection.activeGameObject = chainParentObject; + } + + void SetSkeletonUtilityToFlipByRotation () { + if (!skeletonUtility.flipBy180DegreeRotation) { + skeletonUtility.flipBy180DegreeRotation = true; + Debug.Log("Set SkeletonUtility " + skeletonUtility.name + " to flip by rotation instead of negative scale (required).", skeletonUtility); + } + } + + static void AttachRigidbodyAndCollider (SkeletonUtilityBone utilBone, bool enableCollider = false) { + if (utilBone.GetComponent() == null) { + if (utilBone.bone.Data.Length == 0) { + SphereCollider sphere = utilBone.gameObject.AddComponent(); + sphere.radius = 0.1f; + sphere.enabled = enableCollider; + } else { + float length = utilBone.bone.Data.Length; + BoxCollider box = utilBone.gameObject.AddComponent(); + box.size = new Vector3(length, length / 3f, 0.2f); + box.center = new Vector3(length / 2f, 0, 0); + box.enabled = enableCollider; + } + } + utilBone.gameObject.AddComponent(); + } + + static void AttachRigidbodyAndCollider2D(SkeletonUtilityBone utilBone, bool enableCollider = false) { + if (utilBone.GetComponent() == null) { + if (utilBone.bone.Data.Length == 0) { + var sphere = utilBone.gameObject.AddComponent(); + sphere.radius = 0.1f; + sphere.enabled = enableCollider; + } + else { + float length = utilBone.bone.Data.Length; + var box = utilBone.gameObject.AddComponent(); + box.size = new Vector3(length, length / 3f, 0.2f); + box.offset = new Vector3(length / 2f, 0, 0); + box.enabled = enableCollider; + } + } + utilBone.gameObject.AddComponent(); + } + } +} diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonUtilityBoneInspector.cs.meta b/box1/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonUtilityBoneInspector.cs.meta new file mode 100644 index 00000000..81de4d60 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonUtilityBoneInspector.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: b3ae20b4bcc31f645afd6f5b64f82473 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonUtilityInspector.cs b/box1/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonUtilityInspector.cs new file mode 100644 index 00000000..d20f00fb --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonUtilityInspector.cs @@ -0,0 +1,192 @@ +/****************************************************************************** + * 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 UnityEngine; +using UnityEditor; +using UnityEditor.AnimatedValues; +using System.Collections.Generic; +using Spine; +using System.Reflection; + +namespace Spine.Unity.Editor { + using Icons = SpineEditorUtilities.Icons; + + [CustomEditor(typeof(SkeletonUtility))] + public class SkeletonUtilityInspector : UnityEditor.Editor { + + SkeletonUtility skeletonUtility; + Skeleton skeleton; + SkeletonRenderer skeletonRenderer; + SkeletonGraphic skeletonGraphic; + +#if !NEW_PREFAB_SYSTEM + bool isPrefab; + #endif + + readonly GUIContent SpawnHierarchyButtonLabel = new GUIContent("Spawn Hierarchy", Icons.skeleton); + + void OnEnable () { + skeletonUtility = (SkeletonUtility)target; + skeletonRenderer = skeletonUtility.skeletonRenderer; + skeletonGraphic = skeletonUtility.skeletonGraphic; + skeleton = skeletonUtility.Skeleton; + + if (skeleton == null) { + if (skeletonRenderer != null) { + skeletonRenderer.Initialize(false); + skeletonRenderer.LateUpdate(); + } + else if (skeletonGraphic != null) { + skeletonGraphic.Initialize(false); + skeletonGraphic.LateUpdate(); + } + skeleton = skeletonUtility.Skeleton; + } + + if ((skeletonRenderer != null && !skeletonRenderer.valid) || + (skeletonGraphic != null && !skeletonGraphic.IsValid)) return; + + #if !NEW_PREFAB_SYSTEM + isPrefab |= PrefabUtility.GetPrefabType(this.target) == PrefabType.Prefab; + #endif + } + + public override void OnInspectorGUI () { + + #if !NEW_PREFAB_SYSTEM + if (isPrefab) { + GUILayout.Label(new GUIContent("Cannot edit Prefabs", Icons.warning)); + return; + } + #endif + + serializedObject.Update(); + + if ((skeletonRenderer != null && !skeletonRenderer.valid) || + (skeletonGraphic != null && !skeletonGraphic.IsValid)) { + GUILayout.Label(new GUIContent("Spine Component invalid. Check Skeleton Data Asset.", Icons.warning)); + return; + } + + EditorGUILayout.PropertyField(serializedObject.FindProperty("boneRoot"), SpineInspectorUtility.TempContent("Skeleton Root")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("flipBy180DegreeRotation"), SpineInspectorUtility.TempContent("Flip by Rotation", null, + "If true, Skeleton.ScaleX and Skeleton.ScaleY are followed " + + "by 180 degree rotation. If false, negative Transform scale is used. " + + "Note that using negative scale is consistent with previous behaviour (hence the default), " + + "however causes serious problems with rigidbodies and physics. Therefore, it is recommended to " + + "enable this parameter where possible. When creating hinge chains for a chain of skeleton bones " + + "via SkeletonUtilityBone, it is mandatory to have this parameter enabled.")); + + bool hasRootBone = skeletonUtility.boneRoot != null; + + if (!hasRootBone) + EditorGUILayout.HelpBox("No hierarchy found. Use Spawn Hierarchy to generate GameObjects for bones.", MessageType.Info); + + using (new EditorGUI.DisabledGroupScope(hasRootBone)) { + if (SpineInspectorUtility.LargeCenteredButton(SpawnHierarchyButtonLabel)) + SpawnHierarchyContextMenu(); + } + + if (hasRootBone) { + if (SpineInspectorUtility.CenteredButton(new GUIContent("Remove Hierarchy"))) { + Undo.RegisterCompleteObjectUndo(skeletonUtility, "Remove Hierarchy"); + Undo.DestroyObjectImmediate(skeletonUtility.boneRoot.gameObject); + skeletonUtility.boneRoot = null; + } + } + + serializedObject.ApplyModifiedProperties(); + } + + void SpawnHierarchyContextMenu () { + var menu = new GenericMenu(); + + menu.AddItem(new GUIContent("Follow all bones"), false, SpawnFollowHierarchy); + menu.AddItem(new GUIContent("Follow (Root Only)"), false, SpawnFollowHierarchyRootOnly); + menu.AddSeparator(""); + menu.AddItem(new GUIContent("Override all bones"), false, SpawnOverrideHierarchy); + menu.AddItem(new GUIContent("Override (Root Only)"), false, SpawnOverrideHierarchyRootOnly); + + menu.ShowAsContext(); + } + + public static void AttachIcon (SkeletonUtilityBone boneComponent) { + Skeleton skeleton = boneComponent.hierarchy.Skeleton; + Texture2D icon = boneComponent.bone.Data.Length == 0 ? Icons.nullBone : Icons.boneNib; + + foreach (IkConstraint c in skeleton.IkConstraints) + if (c.Target == boneComponent.bone) { + icon = Icons.constraintNib; + break; + } + + typeof(EditorGUIUtility).InvokeMember("SetIconForObject", BindingFlags.InvokeMethod | BindingFlags.Static | BindingFlags.NonPublic, null, null, new object[2] { + boneComponent.gameObject, + icon + }); + } + + static void AttachIconsToChildren (Transform root) { + if (root != null) { + var utilityBones = root.GetComponentsInChildren(); + foreach (var utilBone in utilityBones) + AttachIcon(utilBone); + } + } + + void SpawnFollowHierarchy () { + Undo.RegisterCompleteObjectUndo(skeletonUtility, "Spawn Hierarchy"); + Selection.activeGameObject = skeletonUtility.SpawnHierarchy(SkeletonUtilityBone.Mode.Follow, true, true, true); + AttachIconsToChildren(skeletonUtility.boneRoot); + } + + void SpawnFollowHierarchyRootOnly () { + Undo.RegisterCompleteObjectUndo(skeletonUtility, "Spawn Root"); + Selection.activeGameObject = skeletonUtility.SpawnRoot(SkeletonUtilityBone.Mode.Follow, true, true, true); + AttachIconsToChildren(skeletonUtility.boneRoot); + } + + void SpawnOverrideHierarchy () { + Undo.RegisterCompleteObjectUndo(skeletonUtility, "Spawn Hierarchy"); + Selection.activeGameObject = skeletonUtility.SpawnHierarchy(SkeletonUtilityBone.Mode.Override, true, true, true); + AttachIconsToChildren(skeletonUtility.boneRoot); + } + + void SpawnOverrideHierarchyRootOnly () { + Undo.RegisterCompleteObjectUndo(skeletonUtility, "Spawn Root"); + Selection.activeGameObject = skeletonUtility.SpawnRoot(SkeletonUtilityBone.Mode.Override, true, true, true); + AttachIconsToChildren(skeletonUtility.boneRoot); + } + } + +} diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonUtilityInspector.cs.meta b/box1/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonUtilityInspector.cs.meta new file mode 100644 index 00000000..44e13b14 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonUtilityInspector.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: a5b90df955eb8c2429ac67c8b2de6c5c +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/GUI.meta b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI.meta new file mode 100644 index 00000000..d730a557 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI.meta @@ -0,0 +1,5 @@ +fileFormatVersion: 2 +guid: bfaea6b7e7f52bc46b8d1c3cb5e9eaa1 +folderAsset: yes +DefaultImporter: + userData: diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/AtlasAsset Icon.png b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/AtlasAsset Icon.png new file mode 100644 index 00000000..47921306 Binary files /dev/null and b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/AtlasAsset Icon.png differ diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/AtlasAsset Icon.png.meta b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/AtlasAsset Icon.png.meta new file mode 100644 index 00000000..ef7eb691 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/AtlasAsset Icon.png.meta @@ -0,0 +1,92 @@ +fileFormatVersion: 2 +guid: 3fc714a0dc1cf6b4b959e073fff2844e +timeCreated: 1508165143 +licenseType: Free +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 1 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 1024 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 1024 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Android + maxTextureSize: 1024 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: WebGL + maxTextureSize: 1024 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/SkeletonDataAsset Icon.png b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/SkeletonDataAsset Icon.png new file mode 100644 index 00000000..61c0f18a Binary files /dev/null and b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/SkeletonDataAsset Icon.png differ diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/SkeletonDataAsset Icon.png.meta b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/SkeletonDataAsset Icon.png.meta new file mode 100644 index 00000000..22239ca4 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/SkeletonDataAsset Icon.png.meta @@ -0,0 +1,46 @@ +fileFormatVersion: 2 +guid: 68defdbc95b30a74a9ad396bfc9a2277 +TextureImporter: + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: .25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + seamlessCubemap: 0 + textureFormat: -3 + maxTextureSize: 1024 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: .5, y: .5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 1 + textureType: 2 + buildTargetSettings: [] + spriteSheet: + sprites: [] + spritePackingTag: + userData: diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-animation.png b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-animation.png new file mode 100644 index 00000000..f44d38e9 Binary files /dev/null and b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-animation.png differ diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-animation.png.meta b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-animation.png.meta new file mode 100644 index 00000000..dcf6806e --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-animation.png.meta @@ -0,0 +1,53 @@ +fileFormatVersion: 2 +guid: 52b12ec801461494185a4d3dc66f3d1d +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: .25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 8 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: -3 + maxTextureSize: 1024 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: .5, y: .5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 1 + textureType: 2 + buildTargetSettings: [] + spriteSheet: + sprites: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-animationRoot.png b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-animationRoot.png new file mode 100644 index 00000000..61075468 Binary files /dev/null and b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-animationRoot.png differ diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-animationRoot.png.meta b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-animationRoot.png.meta new file mode 100644 index 00000000..1bbca1c8 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-animationRoot.png.meta @@ -0,0 +1,53 @@ +fileFormatVersion: 2 +guid: 3d1be4ea889f3a14b864352fe49a1bde +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: .25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 8 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: -3 + maxTextureSize: 1024 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: .5, y: .5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 1 + textureType: 2 + buildTargetSettings: [] + spriteSheet: + sprites: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-attachment.png b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-attachment.png new file mode 100644 index 00000000..4e14f989 Binary files /dev/null and b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-attachment.png differ diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-attachment.png.meta b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-attachment.png.meta new file mode 100644 index 00000000..1316c3d3 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-attachment.png.meta @@ -0,0 +1,92 @@ +fileFormatVersion: 2 +guid: 04ae56b3698d3e844844cfcef2f009e7 +timeCreated: 1494928093 +licenseType: Free +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: -1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 1 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Android + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: WebGL + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-bone.png b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-bone.png new file mode 100644 index 00000000..ec66a6a8 Binary files /dev/null and b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-bone.png differ diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-bone.png.meta b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-bone.png.meta new file mode 100644 index 00000000..f0cbaeaa --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-bone.png.meta @@ -0,0 +1,53 @@ +fileFormatVersion: 2 +guid: 8322793223a533a4ca8be6f430256dfc +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: .25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 8 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: -3 + maxTextureSize: 1024 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: .5, y: .5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 1 + textureType: 2 + buildTargetSettings: [] + spriteSheet: + sprites: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-boneNib.png b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-boneNib.png new file mode 100644 index 00000000..87373b8f Binary files /dev/null and b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-boneNib.png differ diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-boneNib.png.meta b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-boneNib.png.meta new file mode 100644 index 00000000..a0b91bee --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-boneNib.png.meta @@ -0,0 +1,53 @@ +fileFormatVersion: 2 +guid: 97a43f11e00735147a9dc3dff6d68191 +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: .25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 8 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: -3 + maxTextureSize: 1024 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: .5, y: .5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 1 + textureType: 2 + buildTargetSettings: [] + spriteSheet: + sprites: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-boundingBox.png b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-boundingBox.png new file mode 100644 index 00000000..82beedfc Binary files /dev/null and b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-boundingBox.png differ diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-boundingBox.png.meta b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-boundingBox.png.meta new file mode 100644 index 00000000..0e5d6284 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-boundingBox.png.meta @@ -0,0 +1,47 @@ +fileFormatVersion: 2 +guid: 955aed20030d0504b8a9c6934a5cb47a +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: .25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + seamlessCubemap: 0 + textureFormat: -3 + maxTextureSize: 1024 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: .5, y: .5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 1 + textureType: 2 + buildTargetSettings: [] + spriteSheet: + sprites: [] + spritePackingTag: + userData: diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-clipping.png b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-clipping.png new file mode 100644 index 00000000..398137c4 Binary files /dev/null and b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-clipping.png differ diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-clipping.png.meta b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-clipping.png.meta new file mode 100644 index 00000000..9cb5d0c0 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-clipping.png.meta @@ -0,0 +1,92 @@ +fileFormatVersion: 2 +guid: f5fff1b5caee03642ab77c9984b4bb6a +timeCreated: 1497479335 +licenseType: Free +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 1 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Android + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: WebGL + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-constraintIK.png b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-constraintIK.png new file mode 100644 index 00000000..1c93d754 Binary files /dev/null and b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-constraintIK.png differ diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-constraintIK.png.meta b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-constraintIK.png.meta new file mode 100644 index 00000000..1e11b1dc --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-constraintIK.png.meta @@ -0,0 +1,92 @@ +fileFormatVersion: 2 +guid: 02822eb69e09dd947b434ab81e3d938f +timeCreated: 1494878353 +licenseType: Free +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: -1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 1 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Android + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: WebGL + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-constraintNib.png b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-constraintNib.png new file mode 100644 index 00000000..175bcb04 Binary files /dev/null and b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-constraintNib.png differ diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-constraintNib.png.meta b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-constraintNib.png.meta new file mode 100644 index 00000000..a6927289 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-constraintNib.png.meta @@ -0,0 +1,53 @@ +fileFormatVersion: 2 +guid: de1a4f5ad4bdf1a4ea072c4d59ba87d8 +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: .25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 8 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: -3 + maxTextureSize: 1024 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: .5, y: .5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 1 + textureType: 2 + buildTargetSettings: [] + spriteSheet: + sprites: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-constraintPath.png b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-constraintPath.png new file mode 100644 index 00000000..9663b859 Binary files /dev/null and b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-constraintPath.png differ diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-constraintPath.png.meta b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-constraintPath.png.meta new file mode 100644 index 00000000..4459669b --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-constraintPath.png.meta @@ -0,0 +1,92 @@ +fileFormatVersion: 2 +guid: c1aae98dd56b14c4b8c25360000b7e9e +timeCreated: 1494878353 +licenseType: Free +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: -1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 1 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Android + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: WebGL + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-constraintTransform.png b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-constraintTransform.png new file mode 100644 index 00000000..2264aaa5 Binary files /dev/null and b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-constraintTransform.png differ diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-constraintTransform.png.meta b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-constraintTransform.png.meta new file mode 100644 index 00000000..181bb922 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-constraintTransform.png.meta @@ -0,0 +1,92 @@ +fileFormatVersion: 2 +guid: 4709175437c21f64bab9b061f98a49fc +timeCreated: 1494878353 +licenseType: Free +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: -1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 1 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Android + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: WebGL + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-constraints.png b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-constraints.png new file mode 100644 index 00000000..9c61ee5e Binary files /dev/null and b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-constraints.png differ diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-constraints.png.meta b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-constraints.png.meta new file mode 100644 index 00000000..306364de --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-constraints.png.meta @@ -0,0 +1,92 @@ +fileFormatVersion: 2 +guid: ed0736a1eb519ef42b4892d1db2426b3 +timeCreated: 1494878353 +licenseType: Free +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: -1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 1 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Android + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: WebGL + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-event.png b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-event.png new file mode 100644 index 00000000..4547f254 Binary files /dev/null and b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-event.png differ diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-event.png.meta b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-event.png.meta new file mode 100644 index 00000000..0bf19dba --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-event.png.meta @@ -0,0 +1,53 @@ +fileFormatVersion: 2 +guid: d226a80acc775714aa78b85e16a00e9b +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: .25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 8 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: -3 + maxTextureSize: 1024 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: .5, y: .5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 1 + textureType: 2 + buildTargetSettings: [] + spriteSheet: + sprites: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-hingeChain.png b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-hingeChain.png new file mode 100644 index 00000000..a27af1c7 Binary files /dev/null and b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-hingeChain.png differ diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-hingeChain.png.meta b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-hingeChain.png.meta new file mode 100644 index 00000000..e61da1e8 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-hingeChain.png.meta @@ -0,0 +1,47 @@ +fileFormatVersion: 2 +guid: 2c2c6d283dcf3654baf40001c982891c +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: .25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + seamlessCubemap: 0 + textureFormat: -3 + maxTextureSize: 1024 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: .5, y: .5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 1 + textureType: 2 + buildTargetSettings: [] + spriteSheet: + sprites: [] + spritePackingTag: + userData: diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-image.png b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-image.png new file mode 100644 index 00000000..663d1135 Binary files /dev/null and b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-image.png differ diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-image.png.meta b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-image.png.meta new file mode 100644 index 00000000..421c654a --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-image.png.meta @@ -0,0 +1,53 @@ +fileFormatVersion: 2 +guid: 2b3a6f35bbaa8414eb51a344743ee641 +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: .25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 8 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: -3 + maxTextureSize: 1024 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: .5, y: .5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 1 + textureType: 2 + buildTargetSettings: [] + spriteSheet: + sprites: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-mesh.png b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-mesh.png new file mode 100644 index 00000000..1035553b Binary files /dev/null and b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-mesh.png differ diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-mesh.png.meta b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-mesh.png.meta new file mode 100644 index 00000000..2b49d8b0 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-mesh.png.meta @@ -0,0 +1,53 @@ +fileFormatVersion: 2 +guid: a309a2e14638a204091b915126910f45 +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: .25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 8 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: -1 + maxTextureSize: 1024 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: .5, y: .5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 1 + textureType: 2 + buildTargetSettings: [] + spriteSheet: + sprites: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-null.png b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-null.png new file mode 100644 index 00000000..9a6d738e Binary files /dev/null and b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-null.png differ diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-null.png.meta b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-null.png.meta new file mode 100644 index 00000000..29da564a --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-null.png.meta @@ -0,0 +1,53 @@ +fileFormatVersion: 2 +guid: d1de1604dfe4cb64c9d31246a8e43c78 +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: .25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 8 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: -3 + maxTextureSize: 1024 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: .5, y: .5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 1 + textureType: 2 + buildTargetSettings: [] + spriteSheet: + sprites: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-path.png b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-path.png new file mode 100644 index 00000000..604ae0d6 Binary files /dev/null and b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-path.png differ diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-path.png.meta b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-path.png.meta new file mode 100644 index 00000000..8aebfb76 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-path.png.meta @@ -0,0 +1,59 @@ +fileFormatVersion: 2 +guid: dbc817a6c9e9c5747b7f6261bf5d1d09 +timeCreated: 1482240904 +licenseType: Free +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 7 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: -3 + maxTextureSize: 1024 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + allowsAlphaSplitting: 0 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + buildTargetSettings: [] + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-point.png b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-point.png new file mode 100644 index 00000000..0e5099f4 Binary files /dev/null and b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-point.png differ diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-point.png.meta b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-point.png.meta new file mode 100644 index 00000000..9df5c2a5 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-point.png.meta @@ -0,0 +1,92 @@ +fileFormatVersion: 2 +guid: d7a76922e4dd9fa429da15c018ff127f +timeCreated: 1524196821 +licenseType: Free +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 1 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 1024 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 1024 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Android + maxTextureSize: 1024 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: WebGL + maxTextureSize: 1024 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-poseBones.png b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-poseBones.png new file mode 100644 index 00000000..102700af Binary files /dev/null and b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-poseBones.png differ diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-poseBones.png.meta b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-poseBones.png.meta new file mode 100644 index 00000000..800466b4 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-poseBones.png.meta @@ -0,0 +1,53 @@ +fileFormatVersion: 2 +guid: da6f6d414e43aac46a57cc5a87208db4 +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: .25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 8 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: -3 + maxTextureSize: 1024 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: .5, y: .5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 1 + textureType: 2 + buildTargetSettings: [] + spriteSheet: + sprites: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-skeleton.png b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-skeleton.png new file mode 100644 index 00000000..b5d5adf2 Binary files /dev/null and b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-skeleton.png differ diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-skeleton.png.meta b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-skeleton.png.meta new file mode 100644 index 00000000..9c2a1a73 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-skeleton.png.meta @@ -0,0 +1,53 @@ +fileFormatVersion: 2 +guid: f2216037084d99d4481810cb521ed96f +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: .25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 8 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: -3 + maxTextureSize: 1024 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: .5, y: .5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 1 + textureType: 2 + buildTargetSettings: [] + spriteSheet: + sprites: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-skeletonUtility.png b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-skeletonUtility.png new file mode 100644 index 00000000..ce4d937b Binary files /dev/null and b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-skeletonUtility.png differ diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-skeletonUtility.png.meta b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-skeletonUtility.png.meta new file mode 100644 index 00000000..3a77fd7f --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-skeletonUtility.png.meta @@ -0,0 +1,53 @@ +fileFormatVersion: 2 +guid: 5bb0631368b462047869d8788673cb48 +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: .25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 8 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: -3 + maxTextureSize: 1024 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: .5, y: .5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 1 + textureType: 2 + buildTargetSettings: [] + spriteSheet: + sprites: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-skin.png b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-skin.png new file mode 100644 index 00000000..4dc8e7fd Binary files /dev/null and b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-skin.png differ diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-skin.png.meta b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-skin.png.meta new file mode 100644 index 00000000..f02b09c5 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-skin.png.meta @@ -0,0 +1,92 @@ +fileFormatVersion: 2 +guid: bfd9f3d2607e9e44c97384d7575a17dc +timeCreated: 1494878353 +licenseType: Free +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 1 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: -3 + maxTextureSize: 1024 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 1024 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 1024 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Android + maxTextureSize: 1024 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: WebGL + maxTextureSize: 1024 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-skinPlaceholder.png b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-skinPlaceholder.png new file mode 100644 index 00000000..17bfef06 Binary files /dev/null and b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-skinPlaceholder.png differ diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-skinPlaceholder.png.meta b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-skinPlaceholder.png.meta new file mode 100644 index 00000000..92955a92 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-skinPlaceholder.png.meta @@ -0,0 +1,53 @@ +fileFormatVersion: 2 +guid: 04c82a4acf7b5244e947f2709ec3a6cf +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: .25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 8 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: -3 + maxTextureSize: 1024 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: .5, y: .5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 1 + textureType: 2 + buildTargetSettings: [] + spriteSheet: + sprites: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-skinsRoot.png b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-skinsRoot.png new file mode 100644 index 00000000..31857cf3 Binary files /dev/null and b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-skinsRoot.png differ diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-skinsRoot.png.meta b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-skinsRoot.png.meta new file mode 100644 index 00000000..b8ce214c --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-skinsRoot.png.meta @@ -0,0 +1,53 @@ +fileFormatVersion: 2 +guid: 8bd14c7643597a74ba2edc10a5e4c4ed +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: .25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 8 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: -3 + maxTextureSize: 1024 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: .5, y: .5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 1 + textureType: 2 + buildTargetSettings: [] + spriteSheet: + sprites: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-slot.png b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-slot.png new file mode 100644 index 00000000..ca938722 Binary files /dev/null and b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-slot.png differ diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-slot.png.meta b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-slot.png.meta new file mode 100644 index 00000000..66d52b05 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-slot.png.meta @@ -0,0 +1,53 @@ +fileFormatVersion: 2 +guid: 0338faf3e7d93e2478fcbc022d13e081 +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: .25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 8 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: -3 + maxTextureSize: 1024 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: .5, y: .5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 1 + textureType: 2 + buildTargetSettings: [] + spriteSheet: + sprites: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-slotRoot.png b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-slotRoot.png new file mode 100644 index 00000000..dfca413a Binary files /dev/null and b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-slotRoot.png differ diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-slotRoot.png.meta b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-slotRoot.png.meta new file mode 100644 index 00000000..3d9fdd73 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-slotRoot.png.meta @@ -0,0 +1,53 @@ +fileFormatVersion: 2 +guid: 4a1646cf39026224c85ecba92d7d6948 +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: .25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 8 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: -1 + maxTextureSize: 1024 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: .5, y: .5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 1 + textureType: 2 + buildTargetSettings: [] + spriteSheet: + sprites: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-spine.png b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-spine.png new file mode 100644 index 00000000..7fd5473c Binary files /dev/null and b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-spine.png differ diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-spine.png.meta b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-spine.png.meta new file mode 100644 index 00000000..811e17a6 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-spine.png.meta @@ -0,0 +1,53 @@ +fileFormatVersion: 2 +guid: 4e7c964fa5e07024c8bf1debecc3b7c8 +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: .25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 8 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: -3 + maxTextureSize: 1024 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: .5, y: .5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 1 + textureType: 2 + buildTargetSettings: [] + spriteSheet: + sprites: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-subMeshRenderer.png b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-subMeshRenderer.png new file mode 100644 index 00000000..ec7c9e64 Binary files /dev/null and b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-subMeshRenderer.png differ diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-subMeshRenderer.png.meta b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-subMeshRenderer.png.meta new file mode 100644 index 00000000..fa379283 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-subMeshRenderer.png.meta @@ -0,0 +1,53 @@ +fileFormatVersion: 2 +guid: f31c0c0d608e8ba4f9a1afb032092287 +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: .25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 8 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: -1 + maxTextureSize: 1024 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: .5, y: .5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 1 + textureType: 2 + buildTargetSettings: [] + spriteSheet: + sprites: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-warning.png b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-warning.png new file mode 100644 index 00000000..05e3f4cd Binary files /dev/null and b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-warning.png differ diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-warning.png.meta b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-warning.png.meta new file mode 100644 index 00000000..87c616fc --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-warning.png.meta @@ -0,0 +1,53 @@ +fileFormatVersion: 2 +guid: 754d724c1bd750048852e8cf3d4a05ee +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: .25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 8 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: -3 + maxTextureSize: 1024 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: .5, y: .5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 1 + textureType: 2 + buildTargetSettings: [] + spriteSheet: + sprites: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-weights.png b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-weights.png new file mode 100644 index 00000000..fa8f1906 Binary files /dev/null and b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-weights.png differ diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-weights.png.meta b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-weights.png.meta new file mode 100644 index 00000000..e25807b0 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-weights.png.meta @@ -0,0 +1,53 @@ +fileFormatVersion: 2 +guid: 0b1bcb09fa228d049ba3c9ea6a57e1ee +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: .25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 8 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: -3 + maxTextureSize: 1024 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: .5, y: .5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 1 + textureType: 2 + buildTargetSettings: [] + spriteSheet: + sprites: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/ImporterPresets.meta b/box1/Assets/Spine/Editor/spine-unity/Editor/ImporterPresets.meta new file mode 100644 index 00000000..39eef80b --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/ImporterPresets.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: a018d561e5df35848bcabbe2809c7549 +folderAsset: yes +timeCreated: 1580402759 +licenseType: Pro +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/ImporterPresets/PMAPresetTemplate.png b/box1/Assets/Spine/Editor/spine-unity/Editor/ImporterPresets/PMAPresetTemplate.png new file mode 100644 index 00000000..b40be5a3 Binary files /dev/null and b/box1/Assets/Spine/Editor/spine-unity/Editor/ImporterPresets/PMAPresetTemplate.png differ diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/ImporterPresets/PMAPresetTemplate.png.meta b/box1/Assets/Spine/Editor/spine-unity/Editor/ImporterPresets/PMAPresetTemplate.png.meta new file mode 100644 index 00000000..8153700c --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/ImporterPresets/PMAPresetTemplate.png.meta @@ -0,0 +1,82 @@ +fileFormatVersion: 2 +guid: 77f055f38c1115f42a2df16b0428c4e6 +timeCreated: 1580402818 +licenseType: Pro +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: -1 + mipBias: -1 + wrapU: -1 + wrapV: -1 + wrapW: -1 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/ImporterPresets/PMATexturePreset.preset b/box1/Assets/Spine/Editor/spine-unity/Editor/ImporterPresets/PMATexturePreset.preset new file mode 100644 index 00000000..f5d5a733 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/ImporterPresets/PMATexturePreset.preset @@ -0,0 +1,390 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!181963792 &2655988077585873504 +Preset: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: PMATexturePreset + m_TargetType: + m_NativeTypeID: 1006 + m_ManagedTypePPtr: {fileID: 0} + m_ManagedTypeFallback: + m_Properties: + - target: {fileID: 0} + propertyPath: m_ExternalObjects.Array.size + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_MipMapMode + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_EnableMipMap + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_sRGBTexture + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_LinearTexture + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_FadeOut + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_BorderMipMap + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_MipMapsPreserveCoverage + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_AlphaTestReferenceValue + value: 0.5 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_MipMapFadeDistanceStart + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_MipMapFadeDistanceEnd + value: 3 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_ConvertToNormalMap + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_ExternalNormalMap + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_HeightScale + value: 0.25 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_NormalMapFilter + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_IsReadable + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_StreamingMipmaps + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_StreamingMipmapsPriority + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_GrayScaleToAlpha + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_GenerateCubemap + value: 6 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_CubemapConvolution + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_SeamlessCubemap + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_TextureFormat + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_MaxTextureSize + value: 2048 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_TextureSettings.m_FilterMode + value: -1 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_TextureSettings.m_Aniso + value: -1 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_TextureSettings.m_MipBias + value: -100 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_TextureSettings.m_WrapU + value: -1 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_TextureSettings.m_WrapV + value: -1 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_TextureSettings.m_WrapW + value: -1 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_NPOTScale + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_Lightmap + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_CompressionQuality + value: 50 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_SpriteMode + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_SpriteExtrude + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_SpriteMeshType + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_Alignment + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_SpritePivot.x + value: 0.5 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_SpritePivot.y + value: 0.5 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_SpritePixelsToUnits + value: 100 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_SpriteBorder.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_SpriteBorder.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_SpriteBorder.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_SpriteBorder.w + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_SpriteGenerateFallbackPhysicsShape + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_AlphaUsage + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_AlphaIsTransparency + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_SpriteTessellationDetail + value: -1 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_TextureType + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_TextureShape + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_SingleChannelComponent + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_MaxTextureSizeSet + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_CompressionQualitySet + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_TextureFormatSet + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_PlatformSettings.Array.size + value: 2 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_PlatformSettings.Array.data[0].m_BuildTarget + value: DefaultTexturePlatform + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_PlatformSettings.Array.data[0].m_MaxTextureSize + value: 2048 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_PlatformSettings.Array.data[0].m_ResizeAlgorithm + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_PlatformSettings.Array.data[0].m_TextureFormat + value: -1 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_PlatformSettings.Array.data[0].m_TextureCompression + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_PlatformSettings.Array.data[0].m_CompressionQuality + value: 50 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_PlatformSettings.Array.data[0].m_CrunchedCompression + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_PlatformSettings.Array.data[0].m_AllowsAlphaSplitting + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_PlatformSettings.Array.data[0].m_Overridden + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_PlatformSettings.Array.data[0].m_AndroidETC2FallbackOverride + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_PlatformSettings.Array.data[0].m_ForceMaximumCompressionQuality_BC6H_BC7 + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_PlatformSettings.Array.data[1].m_BuildTarget + value: Standalone + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_PlatformSettings.Array.data[1].m_MaxTextureSize + value: 2048 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_PlatformSettings.Array.data[1].m_ResizeAlgorithm + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_PlatformSettings.Array.data[1].m_TextureFormat + value: -1 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_PlatformSettings.Array.data[1].m_TextureCompression + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_PlatformSettings.Array.data[1].m_CompressionQuality + value: 50 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_PlatformSettings.Array.data[1].m_CrunchedCompression + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_PlatformSettings.Array.data[1].m_AllowsAlphaSplitting + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_PlatformSettings.Array.data[1].m_Overridden + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_PlatformSettings.Array.data[1].m_AndroidETC2FallbackOverride + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_PlatformSettings.Array.data[1].m_ForceMaximumCompressionQuality_BC6H_BC7 + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_SpriteSheet.m_Sprites.Array.size + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_SpriteSheet.m_Outline.Array.size + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_SpriteSheet.m_PhysicsShape.Array.size + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_SpriteSheet.m_Bones.Array.size + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_SpriteSheet.m_SpriteID + value: + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_SpriteSheet.m_InternalID + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_SpriteSheet.m_Vertices.Array.size + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_SpriteSheet.m_Indices.Array.size + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_SpriteSheet.m_Edges.Array.size + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_SpriteSheet.m_Weights.Array.size + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_SpriteSheet.m_SecondaryTextures.Array.size + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_SpritePackingTag + value: + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_PSDRemoveMatte + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_PSDShowRemoveMatteOption + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_UserData + value: + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_AssetBundleName + value: + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_AssetBundleVariant + value: + objectReference: {fileID: 0} diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/ImporterPresets/PMATexturePreset.preset.meta b/box1/Assets/Spine/Editor/spine-unity/Editor/ImporterPresets/PMATexturePreset.preset.meta new file mode 100644 index 00000000..8c4a8e8e --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/ImporterPresets/PMATexturePreset.preset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 665f49f3e2dc7b645b6577f14455f445 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/ImporterPresets/StraightAlphaPreset.preset b/box1/Assets/Spine/Editor/spine-unity/Editor/ImporterPresets/StraightAlphaPreset.preset new file mode 100644 index 00000000..60212d41 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/ImporterPresets/StraightAlphaPreset.preset @@ -0,0 +1,390 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!181963792 &2655988077585873504 +Preset: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: StraightAlphaPreset + m_TargetType: + m_NativeTypeID: 1006 + m_ManagedTypePPtr: {fileID: 0} + m_ManagedTypeFallback: + m_Properties: + - target: {fileID: 0} + propertyPath: m_ExternalObjects.Array.size + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_MipMapMode + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_EnableMipMap + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_sRGBTexture + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_LinearTexture + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_FadeOut + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_BorderMipMap + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_MipMapsPreserveCoverage + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_AlphaTestReferenceValue + value: 0.5 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_MipMapFadeDistanceStart + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_MipMapFadeDistanceEnd + value: 3 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_ConvertToNormalMap + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_ExternalNormalMap + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_HeightScale + value: 0.25 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_NormalMapFilter + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_IsReadable + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_StreamingMipmaps + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_StreamingMipmapsPriority + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_GrayScaleToAlpha + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_GenerateCubemap + value: 6 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_CubemapConvolution + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_SeamlessCubemap + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_TextureFormat + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_MaxTextureSize + value: 2048 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_TextureSettings.m_FilterMode + value: -1 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_TextureSettings.m_Aniso + value: -1 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_TextureSettings.m_MipBias + value: -100 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_TextureSettings.m_WrapU + value: -1 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_TextureSettings.m_WrapV + value: -1 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_TextureSettings.m_WrapW + value: -1 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_NPOTScale + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_Lightmap + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_CompressionQuality + value: 50 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_SpriteMode + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_SpriteExtrude + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_SpriteMeshType + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_Alignment + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_SpritePivot.x + value: 0.5 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_SpritePivot.y + value: 0.5 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_SpritePixelsToUnits + value: 100 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_SpriteBorder.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_SpriteBorder.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_SpriteBorder.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_SpriteBorder.w + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_SpriteGenerateFallbackPhysicsShape + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_AlphaUsage + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_AlphaIsTransparency + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_SpriteTessellationDetail + value: -1 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_TextureType + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_TextureShape + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_SingleChannelComponent + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_MaxTextureSizeSet + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_CompressionQualitySet + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_TextureFormatSet + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_PlatformSettings.Array.size + value: 2 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_PlatformSettings.Array.data[0].m_BuildTarget + value: DefaultTexturePlatform + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_PlatformSettings.Array.data[0].m_MaxTextureSize + value: 2048 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_PlatformSettings.Array.data[0].m_ResizeAlgorithm + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_PlatformSettings.Array.data[0].m_TextureFormat + value: -1 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_PlatformSettings.Array.data[0].m_TextureCompression + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_PlatformSettings.Array.data[0].m_CompressionQuality + value: 50 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_PlatformSettings.Array.data[0].m_CrunchedCompression + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_PlatformSettings.Array.data[0].m_AllowsAlphaSplitting + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_PlatformSettings.Array.data[0].m_Overridden + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_PlatformSettings.Array.data[0].m_AndroidETC2FallbackOverride + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_PlatformSettings.Array.data[0].m_ForceMaximumCompressionQuality_BC6H_BC7 + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_PlatformSettings.Array.data[1].m_BuildTarget + value: Standalone + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_PlatformSettings.Array.data[1].m_MaxTextureSize + value: 2048 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_PlatformSettings.Array.data[1].m_ResizeAlgorithm + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_PlatformSettings.Array.data[1].m_TextureFormat + value: -1 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_PlatformSettings.Array.data[1].m_TextureCompression + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_PlatformSettings.Array.data[1].m_CompressionQuality + value: 50 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_PlatformSettings.Array.data[1].m_CrunchedCompression + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_PlatformSettings.Array.data[1].m_AllowsAlphaSplitting + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_PlatformSettings.Array.data[1].m_Overridden + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_PlatformSettings.Array.data[1].m_AndroidETC2FallbackOverride + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_PlatformSettings.Array.data[1].m_ForceMaximumCompressionQuality_BC6H_BC7 + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_SpriteSheet.m_Sprites.Array.size + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_SpriteSheet.m_Outline.Array.size + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_SpriteSheet.m_PhysicsShape.Array.size + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_SpriteSheet.m_Bones.Array.size + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_SpriteSheet.m_SpriteID + value: + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_SpriteSheet.m_InternalID + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_SpriteSheet.m_Vertices.Array.size + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_SpriteSheet.m_Indices.Array.size + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_SpriteSheet.m_Edges.Array.size + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_SpriteSheet.m_Weights.Array.size + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_SpriteSheet.m_SecondaryTextures.Array.size + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_SpritePackingTag + value: + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_PSDRemoveMatte + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_PSDShowRemoveMatteOption + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_UserData + value: + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_AssetBundleName + value: + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_AssetBundleVariant + value: + objectReference: {fileID: 0} diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/ImporterPresets/StraightAlphaPreset.preset.meta b/box1/Assets/Spine/Editor/spine-unity/Editor/ImporterPresets/StraightAlphaPreset.preset.meta new file mode 100644 index 00000000..b64d04ef --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/ImporterPresets/StraightAlphaPreset.preset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: b3fe5ce49a7c8c041a9d60e4f7f403de +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/ImporterPresets/StraightAlphaPresetTemplate.png b/box1/Assets/Spine/Editor/spine-unity/Editor/ImporterPresets/StraightAlphaPresetTemplate.png new file mode 100644 index 00000000..4db601f8 Binary files /dev/null and b/box1/Assets/Spine/Editor/spine-unity/Editor/ImporterPresets/StraightAlphaPresetTemplate.png differ diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/ImporterPresets/StraightAlphaPresetTemplate.png.meta b/box1/Assets/Spine/Editor/spine-unity/Editor/ImporterPresets/StraightAlphaPresetTemplate.png.meta new file mode 100644 index 00000000..721d7ca3 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/ImporterPresets/StraightAlphaPresetTemplate.png.meta @@ -0,0 +1,82 @@ +fileFormatVersion: 2 +guid: ade885c25e49d7740b5c00d4e10a6197 +timeCreated: 1580402818 +licenseType: Pro +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: -1 + mipBias: -1 + wrapU: -1 + wrapV: -1 + wrapW: -1 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/Menus.cs b/box1/Assets/Spine/Editor/spine-unity/Editor/Menus.cs new file mode 100644 index 00000000..605a2e39 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/Menus.cs @@ -0,0 +1,47 @@ +/****************************************************************************** + * 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.IO; +using UnityEditor; +using UnityEngine; + +namespace Spine.Unity.Editor { + public static class Menus { + [MenuItem("GameObject/Spine/SkeletonRenderer", false, 10)] + static public void CreateSkeletonRendererGameObject () { + EditorInstantiation.InstantiateEmptySpineGameObject("New SkeletonRenderer", true); + } + + [MenuItem("GameObject/Spine/SkeletonAnimation", false, 10)] + static public void CreateSkeletonAnimationGameObject () { + EditorInstantiation.InstantiateEmptySpineGameObject("New SkeletonAnimation", true); + } + } +} diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/Menus.cs.meta b/box1/Assets/Spine/Editor/spine-unity/Editor/Menus.cs.meta new file mode 100644 index 00000000..d33433fe --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/Menus.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: cf21125cbd8928844a85a3ad9002693b +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/Resources.meta b/box1/Assets/Spine/Editor/spine-unity/Editor/Resources.meta new file mode 100644 index 00000000..8d1a705d --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/Resources.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 24903fdac57ee784b9597fcb751ec22f +folderAsset: yes +timeCreated: 1444565388 +licenseType: Pro +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/Resources/SpineAssetDatabaseMarker.txt b/box1/Assets/Spine/Editor/spine-unity/Editor/Resources/SpineAssetDatabaseMarker.txt new file mode 100644 index 00000000..1a3c1a3e --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/Resources/SpineAssetDatabaseMarker.txt @@ -0,0 +1 @@ +DO NOT MOVE OR DELETE THIS FILE \ No newline at end of file diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/Resources/SpineAssetDatabaseMarker.txt.meta b/box1/Assets/Spine/Editor/spine-unity/Editor/Resources/SpineAssetDatabaseMarker.txt.meta new file mode 100644 index 00000000..7569884b --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/Resources/SpineAssetDatabaseMarker.txt.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 57281c00bdd90ad4392f811f2b9f0da1 +timeCreated: 1444565392 +licenseType: Pro +TextScriptImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/Shaders.meta b/box1/Assets/Spine/Editor/spine-unity/Editor/Shaders.meta new file mode 100644 index 00000000..007cc76e --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/Shaders.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 10e0b626d7ae7394a934ee9f2fb81b5a +folderAsset: yes +timeCreated: 1527569604 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/Shaders/SpineShaderWithOutlineGUI.cs b/box1/Assets/Spine/Editor/spine-unity/Editor/Shaders/SpineShaderWithOutlineGUI.cs new file mode 100644 index 00000000..4b0d5824 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/Shaders/SpineShaderWithOutlineGUI.cs @@ -0,0 +1,226 @@ +/****************************************************************************** + * 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 UnityEditor; +using Spine.Unity; + +using SpineInspectorUtility = Spine.Unity.Editor.SpineInspectorUtility; + +public class SpineShaderWithOutlineGUI : ShaderGUI { + + protected MaterialEditor _materialEditor; + bool _showAdvancedOutlineSettings = false; + bool _showStencilSettings = false; + + MaterialProperty _OutlineWidth = null; + MaterialProperty _OutlineColor = null; + MaterialProperty _OutlineReferenceTexWidth = null; + MaterialProperty _ThresholdEnd = null; + MaterialProperty _OutlineSmoothness = null; + MaterialProperty _Use8Neighbourhood = null; + MaterialProperty _OutlineMipLevel = null; + MaterialProperty _StencilComp = null; + MaterialProperty _StencilRef = null; + + static GUIContent _EnableOutlineText = new GUIContent("Outline", "Enable outline rendering. Draws an outline by sampling 4 or 8 neighbourhood pixels at a given distance specified via 'Outline Width'."); + static GUIContent _OutlineWidthText = new GUIContent("Outline Width", ""); + static GUIContent _OutlineColorText = new GUIContent("Outline Color", ""); + static GUIContent _OutlineReferenceTexWidthText = new GUIContent("Reference Texture Width", ""); + static GUIContent _ThresholdEndText = new GUIContent("Outline Threshold", ""); + static GUIContent _OutlineSmoothnessText = new GUIContent("Outline Smoothness", ""); + static GUIContent _Use8NeighbourhoodText = new GUIContent("Sample 8 Neighbours", ""); + static GUIContent _OutlineMipLevelText = new GUIContent("Outline Mip Level", ""); + static GUIContent _StencilCompText = new GUIContent("Stencil Comparison", ""); + static GUIContent _StencilRefText = new GUIContent("Stencil Reference", ""); + + static GUIContent _OutlineAdvancedText = new GUIContent("Advanced", ""); + static GUIContent _ShowStencilText = new GUIContent("Stencil", "Stencil parameters for mask interaction."); + + protected const string ShaderOutlineNamePrefix = "Spine/Outline/"; + protected const string ShaderNormalNamePrefix = "Spine/"; + protected const string ShaderWithoutStandardVariantSuffix = "OutlineOnly"; + + #region ShaderGUI + + public override void OnGUI (MaterialEditor materialEditor, MaterialProperty[] properties) { + FindProperties(properties); // MaterialProperties can be animated so we do not cache them but fetch them every event to ensure animated values are updated correctly + _materialEditor = materialEditor; + + base.OnGUI(materialEditor, properties); + EditorGUILayout.Space(); + RenderStencilProperties(); + EditorGUILayout.Space(); + RenderOutlineProperties(); + } + + #endregion + + #region Virtual Interface + + protected virtual void FindProperties (MaterialProperty[] props) { + + _OutlineWidth = FindProperty("_OutlineWidth", props, false); + _OutlineReferenceTexWidth = FindProperty("_OutlineReferenceTexWidth", props, false); + _OutlineColor = FindProperty("_OutlineColor", props, false); + _ThresholdEnd = FindProperty("_ThresholdEnd", props, false); + _OutlineSmoothness = FindProperty("_OutlineSmoothness", props, false); + _Use8Neighbourhood = FindProperty("_Use8Neighbourhood", props, false); + _OutlineMipLevel = FindProperty("_OutlineMipLevel", props, false); + + _StencilComp = FindProperty("_StencilComp", props, false); + _StencilRef = FindProperty("_StencilRef", props, false); + if (_StencilRef == null) + _StencilRef = FindProperty("_Stencil", props, false); + } + + protected virtual void RenderStencilProperties () { + if (_StencilComp == null) + return; // not a shader supporting custom stencil operations + + // Use default labelWidth + EditorGUIUtility.labelWidth = 0f; + _showStencilSettings = EditorGUILayout.Foldout(_showStencilSettings, _ShowStencilText); + if (_showStencilSettings) { + using (new SpineInspectorUtility.IndentScope()) { + _materialEditor.ShaderProperty(_StencilComp, _StencilCompText); + _materialEditor.ShaderProperty(_StencilRef, _StencilRefText); + } + } + } + + protected virtual void RenderOutlineProperties () { + + if (_OutlineWidth == null) + return; // not an outline shader + + // Use default labelWidth + EditorGUIUtility.labelWidth = 0f; + + bool mixedValue; + bool hasOutlineVariant = !IsShaderWithoutStandardVariantShader(_materialEditor, out mixedValue); + bool isOutlineEnabled = true; + if (hasOutlineVariant) { + isOutlineEnabled = IsOutlineEnabled(_materialEditor, out mixedValue); + EditorGUI.showMixedValue = mixedValue; + EditorGUI.BeginChangeCheck(); + + var origFontStyle = EditorStyles.label.fontStyle; + EditorStyles.label.fontStyle = FontStyle.Bold; + isOutlineEnabled = EditorGUILayout.Toggle(_EnableOutlineText, isOutlineEnabled); + EditorStyles.label.fontStyle = origFontStyle; + EditorGUI.showMixedValue = false; + if (EditorGUI.EndChangeCheck()) { + foreach (Material material in _materialEditor.targets) { + SwitchShaderToOutlineSettings(material, isOutlineEnabled); + } + } + } + else { + var origFontStyle = EditorStyles.label.fontStyle; + EditorStyles.label.fontStyle = FontStyle.Bold; + EditorGUILayout.LabelField(_EnableOutlineText); + EditorStyles.label.fontStyle = origFontStyle; + } + + if (isOutlineEnabled) { + _materialEditor.ShaderProperty(_OutlineWidth, _OutlineWidthText); + _materialEditor.ShaderProperty(_OutlineColor, _OutlineColorText); + + _showAdvancedOutlineSettings = EditorGUILayout.Foldout(_showAdvancedOutlineSettings, _OutlineAdvancedText); + if (_showAdvancedOutlineSettings) { + using (new SpineInspectorUtility.IndentScope()) { + _materialEditor.ShaderProperty(_OutlineReferenceTexWidth, _OutlineReferenceTexWidthText); + _materialEditor.ShaderProperty(_ThresholdEnd, _ThresholdEndText); + _materialEditor.ShaderProperty(_OutlineSmoothness, _OutlineSmoothnessText); + _materialEditor.ShaderProperty(_Use8Neighbourhood, _Use8NeighbourhoodText); + _materialEditor.ShaderProperty(_OutlineMipLevel, _OutlineMipLevelText); + } + } + } + } + + #endregion + + #region Private Functions + + void SwitchShaderToOutlineSettings (Material material, bool enableOutline) { + + var shaderName = material.shader.name; + bool isSetToOutlineShader = shaderName.Contains(ShaderOutlineNamePrefix); + if (isSetToOutlineShader && !enableOutline) { + shaderName = shaderName.Replace(ShaderOutlineNamePrefix, ShaderNormalNamePrefix); + _materialEditor.SetShader(Shader.Find(shaderName), false); + return; + } + else if (!isSetToOutlineShader && enableOutline) { + shaderName = shaderName.Replace(ShaderNormalNamePrefix, ShaderOutlineNamePrefix); + _materialEditor.SetShader(Shader.Find(shaderName), false); + return; + } + } + + static bool IsOutlineEnabled (MaterialEditor editor, out bool mixedValue) { + mixedValue = false; + bool isAnyEnabled = false; + foreach (Material material in editor.targets) { + if (material.shader.name.Contains(ShaderOutlineNamePrefix)) { + isAnyEnabled = true; + } + else if (isAnyEnabled) { + mixedValue = true; + } + } + return isAnyEnabled; + } + + static bool IsShaderWithoutStandardVariantShader (MaterialEditor editor, out bool mixedValue) { + mixedValue = false; + bool isAnyShaderWithoutVariant = false; + foreach (Material material in editor.targets) { + if (material.shader.name.Contains(ShaderWithoutStandardVariantSuffix)) { + isAnyShaderWithoutVariant = true; + } + else if (isAnyShaderWithoutVariant) { + mixedValue = true; + } + } + return isAnyShaderWithoutVariant; + } + + static bool BoldToggleField (GUIContent label, bool value) { + FontStyle origFontStyle = EditorStyles.label.fontStyle; + EditorStyles.label.fontStyle = FontStyle.Bold; + value = EditorGUILayout.Toggle(label, value, EditorStyles.toggle); + EditorStyles.label.fontStyle = origFontStyle; + return value; + } + + #endregion +} diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/Shaders/SpineShaderWithOutlineGUI.cs.meta b/box1/Assets/Spine/Editor/spine-unity/Editor/Shaders/SpineShaderWithOutlineGUI.cs.meta new file mode 100644 index 00000000..394bd693 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/Shaders/SpineShaderWithOutlineGUI.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: efbbf90926e217c40831926fce374905 +timeCreated: 1573666328 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/Shaders/SpineSpriteShaderGUI.cs b/box1/Assets/Spine/Editor/spine-unity/Editor/Shaders/SpineSpriteShaderGUI.cs new file mode 100644 index 00000000..29839722 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/Shaders/SpineSpriteShaderGUI.cs @@ -0,0 +1,1123 @@ +/****************************************************************************** + * 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 UnityEditor; +using Spine.Unity; + +using SpineInspectorUtility = Spine.Unity.Editor.SpineInspectorUtility; + +public class SpineSpriteShaderGUI : SpineShaderWithOutlineGUI { + static readonly string kShaderVertexLit = "Spine/Sprite/Vertex Lit"; + static readonly string kShaderPixelLit = "Spine/Sprite/Pixel Lit"; + static readonly string kShaderUnlit = "Spine/Sprite/Unlit"; + + static readonly string kShaderVertexLitOutline = "Spine/Outline/Sprite/Vertex Lit"; + static readonly string kShaderPixelLitOutline = "Spine/Outline/Sprite/Pixel Lit"; + static readonly string kShaderUnlitOutline = "Spine/Outline/Sprite/Unlit"; + + static readonly string kShaderLitLW = "Lightweight Render Pipeline/Spine/Sprite"; + static readonly string kShaderLitURP = "Universal Render Pipeline/Spine/Sprite"; + static readonly string kShaderLitURP2D = "Universal Render Pipeline/2D/Spine/Sprite"; + static readonly int kSolidQueue = 2000; + static readonly int kAlphaTestQueue = 2450; + static readonly int kTransparentQueue = 3000; + + private enum eBlendMode { + PreMultipliedAlpha, + StandardAlpha, + Opaque, + Additive, + SoftAdditive, + Multiply, + Multiplyx2, + }; + + private enum eLightMode { + VertexLit, + PixelLit, + Unlit, + LitLightweight, + LitUniversal, + LitUniversal2D + }; + + private enum eCulling { + Off = 0, + Front = 1, + Back = 2, + }; + + private enum eNormalsMode { + MeshNormals = -1, + FixedNormalsViewSpace = 0, + FixedNormalsModelSpace = 1, + FixedNormalsWorldSpace = 2 + }; + + MaterialProperty _mainTexture = null; + MaterialProperty _color = null; + MaterialProperty _maskTexture = null; + + MaterialProperty _pixelSnap = null; + + MaterialProperty _writeToDepth = null; + MaterialProperty _depthAlphaCutoff = null; + MaterialProperty _shadowAlphaCutoff = null; + MaterialProperty _renderQueue = null; + MaterialProperty _culling = null; + MaterialProperty _customRenderQueue = null; + + MaterialProperty _overlayColor = null; + MaterialProperty _hue = null; + MaterialProperty _saturation = null; + MaterialProperty _brightness = null; + + MaterialProperty _rimPower = null; + MaterialProperty _rimColor = null; + + MaterialProperty _bumpMap = null; + MaterialProperty _bumpScale = null; + MaterialProperty _diffuseRamp = null; + MaterialProperty _fixedNormal = null; + + MaterialProperty _blendTexture = null; + MaterialProperty _blendTextureLerp = null; + + MaterialProperty _emissionMap = null; + MaterialProperty _emissionColor = null; + MaterialProperty _emissionPower = null; + + MaterialProperty _metallic = null; + MaterialProperty _metallicGlossMap = null; + MaterialProperty _smoothness = null; + MaterialProperty _smoothnessScale = null; + + static GUIContent _albedoText = new GUIContent("Albedo", "Albedo (RGB) and Transparency (A)"); + static GUIContent _maskText = new GUIContent("Light Mask", "Light mask texture (secondary Sprite texture)"); + static GUIContent _altAlbedoText = new GUIContent("Secondary Albedo", "When a secondary albedo texture is set the albedo will be a blended mix of the two textures based on the blend value."); + static GUIContent _metallicMapText = new GUIContent("Metallic", "Metallic (R) and Smoothness (A)"); + static GUIContent _smoothnessText = new GUIContent("Smoothness", "Smoothness value"); + static GUIContent _smoothnessScaleText = new GUIContent("Smoothness", "Smoothness scale factor"); + static GUIContent _normalMapText = new GUIContent("Normal Map", "Normal Map"); + static GUIContent _emissionText = new GUIContent("Emission", "Emission (RGB)"); + static GUIContent _emissionPowerText = new GUIContent("Emission Power"); + static GUIContent _emissionToggleText = new GUIContent("Emission", "Enable Emission."); + static GUIContent _diffuseRampText = new GUIContent("Diffuse Ramp", "A black and white gradient can be used to create a 'Toon Shading' effect."); + static GUIContent _depthText = new GUIContent("Write to Depth", "Write to Depth Buffer by clipping alpha."); + static GUIContent _depthAlphaCutoffText = new GUIContent("Depth Alpha Cutoff", "Threshold for depth write alpha cutoff"); + static GUIContent _shadowAlphaCutoffText = new GUIContent("Shadow Alpha Cutoff", "Threshold for shadow alpha cutoff"); + static GUIContent _receiveShadowsText = new GUIContent("Receive Shadows", "When enabled, other GameObjects can cast shadows onto this GameObject. 'Write to Depth' has to be enabled in Lightweight RP."); + static GUIContent _fixedNormalText = new GUIContent("Fixed Normals", "If this is ticked instead of requiring mesh normals a Fixed Normal will be used instead (it's quicker and can result in better looking lighting effects on 2d objects)."); + static GUIContent _fixedNormalDirectionText = new GUIContent("Fixed Normal Direction", "Should normally be (0,0,1) if in view-space or (0,0,-1) if in model-space."); + static GUIContent _adjustBackfaceTangentText = new GUIContent("Adjust Back-face Tangents", "Tick only if you are going to rotate the sprite to face away from the camera, the tangents will be flipped when this is the case to make lighting correct."); + static GUIContent _sphericalHarmonicsText = new GUIContent("Light Probes & Ambient", "Enable to use spherical harmonics to aplpy ambient light and/or light probes. In vertex-lit mode this will be approximated from scenes ambient trilight settings."); + static GUIContent _lightingModeText = new GUIContent("Lighting Mode", "Lighting Mode"); + static GUIContent[] _lightingModeOptions = { + new GUIContent("Vertex Lit"), + new GUIContent("Pixel Lit"), + new GUIContent("Unlit"), + new GUIContent("Lit Lightweight"), + new GUIContent("Lit Universal"), + new GUIContent("Lit Universal2D") + }; + static GUIContent _blendModeText = new GUIContent("Blend Mode", "Blend Mode"); + static GUIContent[] _blendModeOptions = { + new GUIContent("Pre-Multiplied Alpha"), + new GUIContent("Standard Alpha"), + new GUIContent("Opaque"), + new GUIContent("Additive"), + new GUIContent("Soft Additive"), + new GUIContent("Multiply"), + new GUIContent("Multiply x2") + }; + static GUIContent _rendererQueueText = new GUIContent("Render Queue Offset"); + static GUIContent _cullingModeText = new GUIContent("Culling Mode"); + static GUIContent[] _cullingModeOptions = { new GUIContent("Off"), new GUIContent("Front"), new GUIContent("Back") }; + static GUIContent _pixelSnapText = new GUIContent("Pixel Snap"); + //static GUIContent _customRenderTypetagsText = new GUIContent("Use Custom RenderType tags"); + static GUIContent _fixedNormalSpaceText = new GUIContent("Fixed Normal Space"); + static GUIContent[] _fixedNormalSpaceOptions = { new GUIContent("View-Space"), new GUIContent("Model-Space"), new GUIContent("World-Space") }; + static GUIContent _rimLightingToggleText = new GUIContent("Rim Lighting", "Enable Rim Lighting."); + static GUIContent _rimColorText = new GUIContent("Rim Color"); + static GUIContent _rimPowerText = new GUIContent("Rim Power"); + static GUIContent _specularToggleText = new GUIContent("Specular", "Enable Specular."); + static GUIContent _colorAdjustmentToggleText = new GUIContent("Color Adjustment", "Enable material color adjustment."); + static GUIContent _colorAdjustmentColorText = new GUIContent("Overlay Color"); + static GUIContent _colorAdjustmentHueText = new GUIContent("Hue"); + static GUIContent _colorAdjustmentSaturationText = new GUIContent("Saturation"); + static GUIContent _colorAdjustmentBrightnessText = new GUIContent("Brightness"); + static GUIContent _fogToggleText = new GUIContent("Fog", "Enable Fog rendering on this renderer."); + static GUIContent _meshRequiresTangentsText = new GUIContent("Note: Material requires a mesh with tangents."); + static GUIContent _meshRequiresNormalsText = new GUIContent("Note: Material requires a mesh with normals."); + static GUIContent _meshRequiresNormalsAndTangentsText = new GUIContent("Note: Material requires a mesh with Normals and Tangents."); + + const string _primaryMapsText = "Main Maps"; + const string _depthLabelText = "Depth"; + const string _shadowsText = "Shadows"; + const string _customRenderType = "Use Custom RenderType"; + + #region ShaderGUI + + public override void OnGUI (MaterialEditor materialEditor, MaterialProperty[] properties) { + FindProperties(properties); // MaterialProperties can be animated so we do not cache them but fetch them every event to ensure animated values are updated correctly + _materialEditor = materialEditor; + ShaderPropertiesGUI(); + } + + public override void AssignNewShaderToMaterial (Material material, Shader oldShader, Shader newShader) { + base.AssignNewShaderToMaterial(material, oldShader, newShader); + + //If not originally a sprite shader set default keywords + if (oldShader.name != kShaderVertexLit && oldShader.name != kShaderPixelLit && oldShader.name != kShaderUnlit && + oldShader.name != kShaderVertexLitOutline && oldShader.name != kShaderPixelLitOutline && oldShader.name != kShaderUnlitOutline && + oldShader.name != kShaderLitLW && + oldShader.name != kShaderLitURP && + oldShader.name != kShaderLitURP2D) { + SetDefaultSpriteKeywords(material, newShader); + } + + SetMaterialKeywords(material); + } + + #endregion + + #region Virtual Interface + + protected override void FindProperties (MaterialProperty[] props) { + base.FindProperties(props); + + _mainTexture = FindProperty("_MainTex", props); + _maskTexture = FindProperty("_MaskTex", props, false); + _color = FindProperty("_Color", props); + + _pixelSnap = FindProperty("PixelSnap", props); + + _writeToDepth = FindProperty("_ZWrite", props, false); + _depthAlphaCutoff = FindProperty("_Cutoff", props); + _shadowAlphaCutoff = FindProperty("_ShadowAlphaCutoff", props); + _renderQueue = FindProperty("_RenderQueue", props); + _culling = FindProperty("_Cull", props); + _customRenderQueue = FindProperty("_CustomRenderQueue", props); + + _bumpMap = FindProperty("_BumpMap", props, false); + _bumpScale = FindProperty("_BumpScale", props, false); + _diffuseRamp = FindProperty("_DiffuseRamp", props, false); + _fixedNormal = FindProperty("_FixedNormal", props, false); + _blendTexture = FindProperty("_BlendTex", props, false); + _blendTextureLerp = FindProperty("_BlendAmount", props, false); + + _overlayColor = FindProperty("_OverlayColor", props, false); + _hue = FindProperty("_Hue", props, false); + _saturation = FindProperty("_Saturation", props, false); + _brightness = FindProperty("_Brightness", props, false); + + _rimPower = FindProperty("_RimPower", props, false); + _rimColor = FindProperty("_RimColor", props, false); + + _emissionMap = FindProperty("_EmissionMap", props, false); + _emissionColor = FindProperty("_EmissionColor", props, false); + _emissionPower = FindProperty("_EmissionPower", props, false); + + _metallic = FindProperty("_Metallic", props, false); + _metallicGlossMap = FindProperty("_MetallicGlossMap", props, false); + _smoothness = FindProperty("_Glossiness", props, false); + _smoothnessScale = FindProperty("_GlossMapScale", props, false); + } + + static bool BoldToggleField (GUIContent label, bool value) { + FontStyle origFontStyle = EditorStyles.label.fontStyle; + EditorStyles.label.fontStyle = FontStyle.Bold; + value = EditorGUILayout.Toggle(label, value, EditorStyles.toggle); + EditorStyles.label.fontStyle = origFontStyle; + return value; + } + + protected virtual void ShaderPropertiesGUI () { + // Use default labelWidth + EditorGUIUtility.labelWidth = 0f; + + RenderMeshInfoBox(); + + // Detect any changes to the material + bool dataChanged = RenderModes(); + + GUILayout.Label(_primaryMapsText, EditorStyles.boldLabel); + { + dataChanged |= RenderTextureProperties(); + } + + GUILayout.Label(_depthLabelText, EditorStyles.boldLabel); + { + dataChanged |= RenderDepthProperties(); + } + + GUILayout.Label(_shadowsText, EditorStyles.boldLabel); + { + dataChanged |= RenderShadowsProperties(); + } + + if (_metallic != null) { + dataChanged |= RenderSpecularProperties(); + } + + if (_emissionMap != null && _emissionColor != null) { + dataChanged |= RenderEmissionProperties(); + } + + if (_fixedNormal != null) { + dataChanged |= RenderNormalsProperties(); + } + + if (_fixedNormal != null) { + dataChanged |= RenderSphericalHarmonicsProperties(); + } + + { + dataChanged |= RenderFogProperties(); + } + + { + dataChanged |= RenderColorProperties(); + } + + if (_rimColor != null) { + dataChanged |= RenderRimLightingProperties(); + } + + { + EditorGUILayout.Space(); + RenderStencilProperties(); + } + + { + EditorGUILayout.Space(); + RenderOutlineProperties(); + } + + if (dataChanged) { + MaterialChanged(_materialEditor); + } + } + + protected virtual bool RenderModes () { + bool dataChanged = false; + + //Lighting Mode + { + EditorGUI.BeginChangeCheck(); + + eLightMode lightMode = GetMaterialLightMode((Material)_materialEditor.target); + EditorGUI.showMixedValue = false; + foreach (Material material in _materialEditor.targets) { + if (lightMode != GetMaterialLightMode(material)) { + EditorGUI.showMixedValue = true; + break; + } + } + + lightMode = (eLightMode)EditorGUILayout.Popup(_lightingModeText, (int)lightMode, _lightingModeOptions); + if (EditorGUI.EndChangeCheck()) { + foreach (Material material in _materialEditor.targets) { + switch (lightMode) { + case eLightMode.VertexLit: + if (material.shader.name != kShaderVertexLit) + _materialEditor.SetShader(Shader.Find(kShaderVertexLit), false); + break; + case eLightMode.PixelLit: + if (material.shader.name != kShaderPixelLit) + _materialEditor.SetShader(Shader.Find(kShaderPixelLit), false); + break; + case eLightMode.Unlit: + if (material.shader.name != kShaderUnlit) + _materialEditor.SetShader(Shader.Find(kShaderUnlit), false); + break; + case eLightMode.LitLightweight: + if (material.shader.name != kShaderLitLW) + _materialEditor.SetShader(Shader.Find(kShaderLitLW), false); + break; + case eLightMode.LitUniversal: + if (material.shader.name != kShaderLitURP) + _materialEditor.SetShader(Shader.Find(kShaderLitURP), false); + break; + case eLightMode.LitUniversal2D: + if (material.shader.name != kShaderLitURP2D) + _materialEditor.SetShader(Shader.Find(kShaderLitURP2D), false); + break; + } + } + + dataChanged = true; + } + } + + //Blend Mode + { + eBlendMode blendMode = GetMaterialBlendMode((Material)_materialEditor.target); + EditorGUI.showMixedValue = false; + foreach (Material material in _materialEditor.targets) { + if (blendMode != GetMaterialBlendMode(material)) { + EditorGUI.showMixedValue = true; + break; + } + } + + EditorGUI.BeginChangeCheck(); + blendMode = (eBlendMode)EditorGUILayout.Popup(_blendModeText, (int)blendMode, _blendModeOptions); + if (EditorGUI.EndChangeCheck()) { + foreach (Material mat in _materialEditor.targets) { + SetBlendMode(mat, blendMode); + } + + dataChanged = true; + } + + if (QualitySettings.activeColorSpace == ColorSpace.Linear && + !EditorGUI.showMixedValue && blendMode == eBlendMode.PreMultipliedAlpha) { + EditorGUILayout.HelpBox(MaterialChecks.kPMANotSupportedLinearMessage, MessageType.Error, true); + } + } + + EditorGUI.BeginDisabledGroup(true); + _materialEditor.RenderQueueField(); + EditorGUI.EndDisabledGroup(); + + EditorGUI.BeginChangeCheck(); + EditorGUI.showMixedValue = _renderQueue.hasMixedValue; + int renderQueue = EditorGUILayout.IntField(_rendererQueueText, (int)_renderQueue.floatValue); + if (EditorGUI.EndChangeCheck()) { + SetInt("_RenderQueue", renderQueue); + dataChanged = true; + } + + EditorGUI.BeginChangeCheck(); + var culling = (eCulling)Mathf.RoundToInt(_culling.floatValue); + EditorGUI.showMixedValue = _culling.hasMixedValue; + culling = (eCulling)EditorGUILayout.Popup(_cullingModeText, (int)culling, _cullingModeOptions); + if (EditorGUI.EndChangeCheck()) { + SetInt("_Cull", (int)culling); + dataChanged = true; + } + + EditorGUI.showMixedValue = false; + + EditorGUI.BeginChangeCheck(); + _materialEditor.ShaderProperty(_pixelSnap, _pixelSnapText); + dataChanged |= EditorGUI.EndChangeCheck(); + + return dataChanged; + } + + protected virtual bool RenderTextureProperties () { + bool dataChanged = false; + + EditorGUI.BeginChangeCheck(); + + _materialEditor.TexturePropertySingleLine(_albedoText, _mainTexture, _color); + + if (_bumpMap != null) + _materialEditor.TexturePropertySingleLine(_normalMapText, _bumpMap, _bumpMap.textureValue != null ? _bumpScale : null); + + if (_maskTexture != null) + _materialEditor.TexturePropertySingleLine(_maskText, _maskTexture); + + if (_diffuseRamp != null) + _materialEditor.TexturePropertySingleLine(_diffuseRampText, _diffuseRamp); + + dataChanged |= EditorGUI.EndChangeCheck(); + + if (_blendTexture != null) { + EditorGUI.BeginChangeCheck(); + _materialEditor.TexturePropertySingleLine(_altAlbedoText, _blendTexture, _blendTextureLerp); + if (EditorGUI.EndChangeCheck()) { + SetKeyword(_materialEditor, "_TEXTURE_BLEND", _blendTexture != null); + dataChanged = true; + } + } + + EditorGUI.BeginChangeCheck(); + _materialEditor.TextureScaleOffsetProperty(_mainTexture); + dataChanged |= EditorGUI.EndChangeCheck(); + + EditorGUI.showMixedValue = false; + + return dataChanged; + } + + protected virtual bool RenderDepthProperties () { + bool dataChanged = false; + + EditorGUI.BeginChangeCheck(); + + bool showDepthAlphaCutoff = true; + // e.g. Pixel Lit shader always has ZWrite enabled + if (_writeToDepth != null) { + bool mixedValue = _writeToDepth.hasMixedValue; + EditorGUI.showMixedValue = mixedValue; + bool writeTodepth = EditorGUILayout.Toggle(_depthText, _writeToDepth.floatValue != 0.0f); + + if (EditorGUI.EndChangeCheck()) { + SetInt("_ZWrite", writeTodepth ? 1 : 0); + _depthAlphaCutoff.floatValue = writeTodepth ? 0.5f : 0.0f; + mixedValue = false; + dataChanged = true; + } + + showDepthAlphaCutoff = writeTodepth && !mixedValue && GetMaterialBlendMode((Material)_materialEditor.target) != eBlendMode.Opaque; + } + if (showDepthAlphaCutoff) { + EditorGUI.BeginChangeCheck(); + _materialEditor.RangeProperty(_depthAlphaCutoff, _depthAlphaCutoffText.text); + dataChanged |= EditorGUI.EndChangeCheck(); + } + + { + bool useCustomRenderType = _customRenderQueue.floatValue > 0.0f; + EditorGUI.BeginChangeCheck(); + EditorGUI.showMixedValue = _customRenderQueue.hasMixedValue; + useCustomRenderType = EditorGUILayout.Toggle(_customRenderType, useCustomRenderType); + if (EditorGUI.EndChangeCheck()) { + dataChanged = true; + + _customRenderQueue.floatValue = useCustomRenderType ? 1.0f : 0.0f; + + foreach (Material material in _materialEditor.targets) { + eBlendMode blendMode = GetMaterialBlendMode(material); + + switch (blendMode) { + case eBlendMode.Opaque: + { + SetRenderType(material, "Opaque", useCustomRenderType); + } + break; + default: + { + bool zWrite = HasZWriteEnabled(material); + SetRenderType(material, zWrite ? "TransparentCutout" : "Transparent", useCustomRenderType); + } + break; + } + } + } + } + + EditorGUI.showMixedValue = false; + + return dataChanged; + } + + protected virtual bool RenderNormalsProperties () { + bool dataChanged = false; + + eNormalsMode normalsMode = GetMaterialNormalsMode((Material)_materialEditor.target); + bool mixedNormalsMode = false; + foreach (Material material in _materialEditor.targets) { + if (normalsMode != GetMaterialNormalsMode(material)) { + mixedNormalsMode = true; + break; + } + } + + EditorGUI.BeginChangeCheck(); + EditorGUI.showMixedValue = mixedNormalsMode; + bool fixedNormals = BoldToggleField(_fixedNormalText, normalsMode != eNormalsMode.MeshNormals); + + if (EditorGUI.EndChangeCheck()) { + normalsMode = fixedNormals ? eNormalsMode.FixedNormalsViewSpace : eNormalsMode.MeshNormals; + SetNormalsMode(_materialEditor, normalsMode, false); + _fixedNormal.vectorValue = new Vector4(0.0f, 0.0f, normalsMode == eNormalsMode.FixedNormalsViewSpace ? 1.0f : -1.0f, 1.0f); + mixedNormalsMode = false; + dataChanged = true; + } + + if (fixedNormals) { + //Show drop down for normals space + EditorGUI.BeginChangeCheck(); + EditorGUI.showMixedValue = mixedNormalsMode; + normalsMode = (eNormalsMode)EditorGUILayout.Popup(_fixedNormalSpaceText, (int)normalsMode, _fixedNormalSpaceOptions); + if (EditorGUI.EndChangeCheck()) { + SetNormalsMode((Material)_materialEditor.target, normalsMode, GetMaterialFixedNormalsBackfaceRenderingOn((Material)_materialEditor.target)); + + foreach (Material material in _materialEditor.targets) { + SetNormalsMode(material, normalsMode, GetMaterialFixedNormalsBackfaceRenderingOn(material)); + } + + //Reset fixed normal to default (Vector3.forward for model-space, -Vector3.forward for view-space). + _fixedNormal.vectorValue = new Vector4(0.0f, 0.0f, normalsMode == eNormalsMode.FixedNormalsViewSpace ? 1.0f : -1.0f, 1.0f); + + mixedNormalsMode = false; + dataChanged = true; + } + + //Show fixed normal + EditorGUI.BeginChangeCheck(); + EditorGUI.showMixedValue = _fixedNormal.hasMixedValue; + Vector3 normal = EditorGUILayout.Vector3Field(_fixedNormalDirectionText, _fixedNormal.vectorValue); + if (EditorGUI.EndChangeCheck()) { + _fixedNormal.vectorValue = new Vector4(normal.x, normal.y, normal.z, 1.0f); + dataChanged = true; + } + + //Show adjust for back face rendering + { + bool fixBackFaceRendering = GetMaterialFixedNormalsBackfaceRenderingOn((Material)_materialEditor.target); + bool mixedBackFaceRendering = false; + foreach (Material material in _materialEditor.targets) { + if (fixBackFaceRendering != GetMaterialFixedNormalsBackfaceRenderingOn(material)) { + mixedBackFaceRendering = true; + break; + } + } + + EditorGUI.BeginChangeCheck(); + EditorGUI.showMixedValue = mixedBackFaceRendering; + bool backRendering = EditorGUILayout.Toggle(_adjustBackfaceTangentText, fixBackFaceRendering); + + if (EditorGUI.EndChangeCheck()) { + SetNormalsMode(_materialEditor, normalsMode, backRendering); + dataChanged = true; + } + } + + } + + EditorGUI.showMixedValue = false; + + return dataChanged; + } + + protected virtual bool RenderShadowsProperties () { + bool dataChanged = false; + + EditorGUI.BeginChangeCheck(); + _materialEditor.RangeProperty(_shadowAlphaCutoff, _shadowAlphaCutoffText.text); + dataChanged = EditorGUI.EndChangeCheck(); + bool areMixedShaders = false; + bool hasReceiveShadowsParameter = IsLWRPShader(_materialEditor, out areMixedShaders) || + IsURP3DShader(_materialEditor, out areMixedShaders); + + if (hasReceiveShadowsParameter) { + bool forceDisableReceiveShadows = !_writeToDepth.hasMixedValue && _writeToDepth.floatValue == 0; + EditorGUI.BeginDisabledGroup(forceDisableReceiveShadows); + + EditorGUI.BeginChangeCheck(); + bool mixedValue; + bool enableReceive = !IsKeywordEnabled(_materialEditor, "_RECEIVE_SHADOWS_OFF", out mixedValue); + EditorGUI.showMixedValue = mixedValue; + enableReceive = EditorGUILayout.Toggle(_receiveShadowsText, enableReceive); + + EditorGUI.showMixedValue = false; + + if (EditorGUI.EndChangeCheck() || forceDisableReceiveShadows) { + SetKeyword(_materialEditor, "_RECEIVE_SHADOWS_OFF", !enableReceive || forceDisableReceiveShadows); + dataChanged = true; + } + EditorGUI.EndDisabledGroup(); // forceDisableReceiveShadows + } + + return dataChanged; + } + + protected virtual bool RenderSphericalHarmonicsProperties () { + + bool areMixedShaders = false; + bool isLWRPShader = IsLWRPShader(_materialEditor, out areMixedShaders); + bool isURP3DShader = IsURP3DShader(_materialEditor, out areMixedShaders); + bool isURP2DShader = IsURP2DShader(_materialEditor, out areMixedShaders); + bool hasSHParameter = !(isLWRPShader || isURP3DShader || isURP2DShader); + if (!hasSHParameter) + return false; + + EditorGUI.BeginChangeCheck(); + bool mixedValue; + bool enabled = IsKeywordEnabled(_materialEditor, "_SPHERICAL_HARMONICS", out mixedValue); + EditorGUI.showMixedValue = mixedValue; + enabled = BoldToggleField(_sphericalHarmonicsText, enabled); + EditorGUI.showMixedValue = false; + + if (EditorGUI.EndChangeCheck()) { + SetKeyword(_materialEditor, "_SPHERICAL_HARMONICS", enabled); + return true; + } + + return false; + } + + protected virtual bool RenderFogProperties () { + + bool areMixedShaders = false; + bool isURP2DShader = IsURP2DShader(_materialEditor, out areMixedShaders); + + if (isURP2DShader && !areMixedShaders) + return false; + + EditorGUI.BeginChangeCheck(); + bool mixedValue; + bool fog = IsKeywordEnabled(_materialEditor, "_FOG", out mixedValue); + EditorGUI.showMixedValue = mixedValue; + fog = BoldToggleField(_fogToggleText, fog); + EditorGUI.showMixedValue = false; + + if (EditorGUI.EndChangeCheck()) { + SetKeyword(_materialEditor, "_FOG", fog); + return true; + } + + return false; + } + + protected virtual bool RenderColorProperties () { + bool dataChanged = false; + + EditorGUI.BeginChangeCheck(); + bool mixedValue; + bool colorAdjust = IsKeywordEnabled(_materialEditor, "_COLOR_ADJUST", out mixedValue); + EditorGUI.showMixedValue = mixedValue; + colorAdjust = BoldToggleField(_colorAdjustmentToggleText, colorAdjust); + EditorGUI.showMixedValue = false; + if (EditorGUI.EndChangeCheck()) { + SetKeyword(_materialEditor, "_COLOR_ADJUST", colorAdjust); + mixedValue = false; + dataChanged = true; + } + + if (colorAdjust && !mixedValue) { + EditorGUI.BeginChangeCheck(); + _materialEditor.ColorProperty(_overlayColor, _colorAdjustmentColorText.text); + _materialEditor.RangeProperty(_hue, _colorAdjustmentHueText.text); + _materialEditor.RangeProperty(_saturation, _colorAdjustmentSaturationText.text); + _materialEditor.RangeProperty(_brightness, _colorAdjustmentBrightnessText.text); + dataChanged |= EditorGUI.EndChangeCheck(); + } + + return dataChanged; + } + + protected virtual bool RenderSpecularProperties () { + bool dataChanged = false; + + bool mixedSpecularValue; + bool specular = IsKeywordEnabled(_materialEditor, "_SPECULAR", out mixedSpecularValue); + bool mixedSpecularGlossMapValue; + bool specularGlossMap = IsKeywordEnabled(_materialEditor, "_SPECULAR_GLOSSMAP", out mixedSpecularGlossMapValue); + bool mixedValue = mixedSpecularValue || mixedSpecularGlossMapValue; + + EditorGUI.BeginChangeCheck(); + EditorGUI.showMixedValue = mixedValue; + bool specularEnabled = BoldToggleField(_specularToggleText, specular || specularGlossMap); + EditorGUI.showMixedValue = false; + if (EditorGUI.EndChangeCheck()) { + foreach (Material material in _materialEditor.targets) { + bool hasGlossMap = material.GetTexture("_MetallicGlossMap") != null; + SetKeyword(material, "_SPECULAR", specularEnabled && !hasGlossMap); + SetKeyword(material, "_SPECULAR_GLOSSMAP", specularEnabled && hasGlossMap); + } + + mixedValue = false; + dataChanged = true; + } + + if (specularEnabled && !mixedValue) { + EditorGUI.BeginChangeCheck(); + bool hasGlossMap = _metallicGlossMap.textureValue != null; + _materialEditor.TexturePropertySingleLine(_metallicMapText, _metallicGlossMap, hasGlossMap ? null : _metallic); + if (EditorGUI.EndChangeCheck()) { + hasGlossMap = _metallicGlossMap.textureValue != null; + SetKeyword(_materialEditor, "_SPECULAR", !hasGlossMap); + SetKeyword(_materialEditor, "_SPECULAR_GLOSSMAP", hasGlossMap); + + dataChanged = true; + } + + const int indentation = 2; + _materialEditor.ShaderProperty(hasGlossMap ? _smoothnessScale : _smoothness, hasGlossMap ? _smoothnessScaleText : _smoothnessText, indentation); + } + + return dataChanged; + } + + protected virtual bool RenderEmissionProperties () { + bool dataChanged = false; + + bool mixedValue; + bool emission = IsKeywordEnabled(_materialEditor, "_EMISSION", out mixedValue); + + EditorGUI.BeginChangeCheck(); + EditorGUI.showMixedValue = mixedValue; + emission = BoldToggleField(_emissionToggleText, emission); + EditorGUI.showMixedValue = false; + if (EditorGUI.EndChangeCheck()) { + SetKeyword(_materialEditor, "_EMISSION", emission); + mixedValue = false; + dataChanged = true; + } + + if (emission && !mixedValue) { + EditorGUI.BeginChangeCheck(); + +#if UNITY_2018_1_OR_NEWER + _materialEditor.TexturePropertyWithHDRColor(_emissionText, _emissionMap, _emissionColor, true); +#else + _materialEditor.TexturePropertyWithHDRColor(_emissionText, _emissionMap, _emissionColor, new ColorPickerHDRConfig(0, 1, 0.01010101f, 3), true); +#endif + _materialEditor.FloatProperty(_emissionPower, _emissionPowerText.text); + dataChanged |= EditorGUI.EndChangeCheck(); + } + + return dataChanged; + } + + protected virtual bool RenderRimLightingProperties () { + bool dataChanged = false; + + bool mixedValue; + bool rimLighting = IsKeywordEnabled(_materialEditor, "_RIM_LIGHTING", out mixedValue); + + EditorGUI.BeginChangeCheck(); + EditorGUI.showMixedValue = mixedValue; + rimLighting = BoldToggleField(_rimLightingToggleText, rimLighting); + EditorGUI.showMixedValue = false; + if (EditorGUI.EndChangeCheck()) { + SetKeyword(_materialEditor, "_RIM_LIGHTING", rimLighting); + mixedValue = false; + dataChanged = true; + } + + if (rimLighting && !mixedValue) { + EditorGUI.BeginChangeCheck(); + _materialEditor.ColorProperty(_rimColor, _rimColorText.text); + _materialEditor.FloatProperty(_rimPower, _rimPowerText.text); + dataChanged |= EditorGUI.EndChangeCheck(); + } + + return dataChanged; + } + + #endregion + + #region Private Functions + + void RenderMeshInfoBox () { + var material = (Material)_materialEditor.target; + bool requiresNormals = _fixedNormal != null && GetMaterialNormalsMode(material) == eNormalsMode.MeshNormals; + bool requiresTangents = material.HasProperty("_BumpMap") && material.GetTexture("_BumpMap") != null; + + if (requiresNormals || requiresTangents) { + GUILayout.Label(requiresNormals && requiresTangents ? _meshRequiresNormalsAndTangentsText : requiresNormals ? _meshRequiresNormalsText : _meshRequiresTangentsText, GUI.skin.GetStyle("helpBox")); + } + } + + void SetInt (string propertyName, int value) { + foreach (Material material in _materialEditor.targets) { + material.SetInt(propertyName, value); + } + } + + void SetDefaultSpriteKeywords (Material material, Shader shader) { + //Disable emission by default (is set on by default in standard shader) + SetKeyword(material, "_EMISSION", false); + //Start with preMultiply alpha by default + SetBlendMode(material, eBlendMode.PreMultipliedAlpha); + //Start with mesh normals by default + SetNormalsMode(material, eNormalsMode.MeshNormals, false); + if (_fixedNormal != null) + _fixedNormal.vectorValue = new Vector4(0.0f, 0.0f, 1.0f, 1.0f); + //Start with spherical harmonics disabled? + SetKeyword(material, "_SPHERICAL_HARMONICS", false); + //Start with specular disabled + SetKeyword(material, "_SPECULAR", false); + SetKeyword(material, "_SPECULAR_GLOSSMAP", false); + //Start with Culling disabled + material.SetInt("_Cull", (int)eCulling.Off); + //Start with Z writing disabled + if (material.HasProperty("_ZWrite")) + material.SetInt("_ZWrite", 0); + } + + //Z write is on then + + static void SetRenderType (Material material, string renderType, bool useCustomRenderQueue) { + //Want a check box to say if should use Sprite render queue (for custom writing depth and normals) + bool zWrite = HasZWriteEnabled(material); + + if (useCustomRenderQueue) { + //If sprite has fixed normals then assign custom render type so we can write its correct normal with soft edges + eNormalsMode normalsMode = GetMaterialNormalsMode(material); + + switch (normalsMode) { + case eNormalsMode.FixedNormalsViewSpace: + renderType = "SpriteViewSpaceFixedNormal"; + break; + case eNormalsMode.FixedNormalsModelSpace: + renderType = "SpriteModelSpaceFixedNormal"; + break; + case eNormalsMode.MeshNormals: + { + //If sprite doesn't write to depth assign custom render type so we can write its depth with soft edges + if (!zWrite) { + renderType = "Sprite"; + } + } + break; + } + } + + //If we don't write to depth set tag so custom shaders can write to depth themselves + material.SetOverrideTag("AlphaDepth", zWrite ? "False" : "True"); + + material.SetOverrideTag("RenderType", renderType); + } + + static void SetMaterialKeywords (Material material) { + eBlendMode blendMode = GetMaterialBlendMode(material); + SetBlendMode(material, blendMode); + + bool zWrite = HasZWriteEnabled(material); + bool clipAlpha = zWrite && blendMode != eBlendMode.Opaque && material.GetFloat("_Cutoff") > 0.0f; + SetKeyword(material, "_ALPHA_CLIP", clipAlpha); + + bool normalMap = material.HasProperty("_BumpMap") && material.GetTexture("_BumpMap") != null; + SetKeyword(material, "_NORMALMAP", normalMap); + + bool diffuseRamp = material.HasProperty("_DiffuseRamp") && material.GetTexture("_DiffuseRamp") != null; + SetKeyword(material, "_DIFFUSE_RAMP", diffuseRamp); + + bool blendTexture = material.HasProperty("_BlendTex") && material.GetTexture("_BlendTex") != null; + SetKeyword(material, "_TEXTURE_BLEND", blendTexture); + } + + static void MaterialChanged (MaterialEditor materialEditor) { + foreach (Material material in materialEditor.targets) + SetMaterialKeywords(material); + } + + static void SetKeyword (MaterialEditor m, string keyword, bool state) { + foreach (Material material in m.targets) { + SetKeyword(material, keyword, state); + } + } + + static void SetKeyword (Material m, string keyword, bool state) { + if (state) + m.EnableKeyword(keyword); + else + m.DisableKeyword(keyword); + } + + static bool IsLWRPShader (MaterialEditor editor, out bool mixedValue) { + return IsShaderType(kShaderLitLW, editor, out mixedValue); + } + + static bool IsURP3DShader (MaterialEditor editor, out bool mixedValue) { + return IsShaderType(kShaderLitURP, editor, out mixedValue); + } + + static bool IsURP2DShader (MaterialEditor editor, out bool mixedValue) { + return IsShaderType(kShaderLitURP2D, editor, out mixedValue); + } + + static bool IsShaderType (string shaderType, MaterialEditor editor, out bool mixedValue) { + + mixedValue = false; + bool isAnyTargetTypeShader = false; + foreach (Material material in editor.targets) { + if (material.shader.name == shaderType) { + isAnyTargetTypeShader = true; + } + else if (isAnyTargetTypeShader) { + mixedValue = true; + } + } + return isAnyTargetTypeShader; + } + + static bool IsKeywordEnabled (MaterialEditor editor, string keyword, out bool mixedValue) { + bool keywordEnabled = ((Material)editor.target).IsKeywordEnabled(keyword); + mixedValue = false; + + foreach (Material material in editor.targets) { + if (material.IsKeywordEnabled(keyword) != keywordEnabled) { + mixedValue = true; + break; + } + } + + return keywordEnabled; + } + + static eLightMode GetMaterialLightMode (Material material) { + if (material.shader.name == kShaderPixelLit || + material.shader.name == kShaderPixelLitOutline) { + return eLightMode.PixelLit; + } + else if (material.shader.name == kShaderUnlit || + material.shader.name == kShaderUnlitOutline) { + return eLightMode.Unlit; + } + else if (material.shader.name == kShaderLitLW) { + return eLightMode.LitLightweight; + } + else if (material.shader.name == kShaderLitURP) { + return eLightMode.LitUniversal; + } + else if (material.shader.name == kShaderLitURP2D) { + return eLightMode.LitUniversal2D; + } + else { // if (material.shader.name == kShaderVertexLit || kShaderVertexLitOutline) + return eLightMode.VertexLit; + } + } + + static eBlendMode GetMaterialBlendMode (Material material) { + if (material.IsKeywordEnabled("_ALPHABLEND_ON")) + return eBlendMode.StandardAlpha; + if (material.IsKeywordEnabled("_ALPHAPREMULTIPLY_ON")) + return eBlendMode.PreMultipliedAlpha; + if (material.IsKeywordEnabled("_MULTIPLYBLEND")) + return eBlendMode.Multiply; + if (material.IsKeywordEnabled("_MULTIPLYBLEND_X2")) + return eBlendMode.Multiplyx2; + if (material.IsKeywordEnabled("_ADDITIVEBLEND")) + return eBlendMode.Additive; + if (material.IsKeywordEnabled("_ADDITIVEBLEND_SOFT")) + return eBlendMode.SoftAdditive; + + return eBlendMode.Opaque; + } + + static void SetBlendMode (Material material, eBlendMode blendMode) { + SetKeyword(material, "_ALPHABLEND_ON", blendMode == eBlendMode.StandardAlpha); + SetKeyword(material, "_ALPHAPREMULTIPLY_ON", blendMode == eBlendMode.PreMultipliedAlpha); + SetKeyword(material, "_MULTIPLYBLEND", blendMode == eBlendMode.Multiply); + SetKeyword(material, "_MULTIPLYBLEND_X2", blendMode == eBlendMode.Multiplyx2); + SetKeyword(material, "_ADDITIVEBLEND", blendMode == eBlendMode.Additive); + SetKeyword(material, "_ADDITIVEBLEND_SOFT", blendMode == eBlendMode.SoftAdditive); + + int renderQueue; + bool useCustomRenderQueue = material.GetFloat("_CustomRenderQueue") > 0.0f; + + switch (blendMode) { + case eBlendMode.Opaque: + { + material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One); + material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero); + SetRenderType(material, "Opaque", useCustomRenderQueue); + renderQueue = kSolidQueue; + } + break; + case eBlendMode.Additive: + { + material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha); + material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.One); + bool zWrite = HasZWriteEnabled(material); + SetRenderType(material, zWrite ? "TransparentCutout" : "Transparent", useCustomRenderQueue); + renderQueue = zWrite ? kAlphaTestQueue : kTransparentQueue; + } + break; + case eBlendMode.SoftAdditive: + { + material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One); + material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcColor); + bool zWrite = HasZWriteEnabled(material); + SetRenderType(material, zWrite ? "TransparentCutout" : "Transparent", useCustomRenderQueue); + renderQueue = zWrite ? kAlphaTestQueue : kTransparentQueue; + } + break; + case eBlendMode.Multiply: + { + material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.Zero); + material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.SrcColor); + bool zWrite = HasZWriteEnabled(material); + SetRenderType(material, zWrite ? "TransparentCutout" : "Transparent", useCustomRenderQueue); + renderQueue = zWrite ? kAlphaTestQueue : kTransparentQueue; + } + break; + case eBlendMode.Multiplyx2: + { + material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.DstColor); + material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.SrcColor); + bool zWrite = HasZWriteEnabled(material); + SetRenderType(material, zWrite ? "TransparentCutout" : "Transparent", useCustomRenderQueue); + renderQueue = zWrite ? kAlphaTestQueue : kTransparentQueue; + } + break; + default: + { + material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One); + material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha); + bool zWrite = HasZWriteEnabled(material); + SetRenderType(material, zWrite ? "TransparentCutout" : "Transparent", useCustomRenderQueue); + renderQueue = zWrite ? kAlphaTestQueue : kTransparentQueue; + } + break; + } + + material.renderQueue = renderQueue + material.GetInt("_RenderQueue"); + material.SetOverrideTag("IgnoreProjector", blendMode == eBlendMode.Opaque ? "False" : "True"); + } + + static eNormalsMode GetMaterialNormalsMode (Material material) { + if (material.IsKeywordEnabled("_FIXED_NORMALS_VIEWSPACE") || material.IsKeywordEnabled("_FIXED_NORMALS_VIEWSPACE_BACKFACE")) + return eNormalsMode.FixedNormalsViewSpace; + if (material.IsKeywordEnabled("_FIXED_NORMALS_WORLDSPACE")) + return eNormalsMode.FixedNormalsWorldSpace; + if (material.IsKeywordEnabled("_FIXED_NORMALS_MODELSPACE") || material.IsKeywordEnabled("_FIXED_NORMALS_MODELSPACE_BACKFACE")) + return eNormalsMode.FixedNormalsModelSpace; + + return eNormalsMode.MeshNormals; + } + + static void SetNormalsMode (MaterialEditor materialEditor, eNormalsMode normalsMode, bool allowBackFaceRendering) { + SetNormalsMode((Material)materialEditor.target, normalsMode, allowBackFaceRendering); + + foreach (Material material in materialEditor.targets) { + SetNormalsMode(material, normalsMode, allowBackFaceRendering); + } + } + + static void SetNormalsMode (Material material, eNormalsMode normalsMode, bool allowBackFaceRendering) { + SetKeyword(material, "_FIXED_NORMALS_VIEWSPACE", normalsMode == eNormalsMode.FixedNormalsViewSpace && !allowBackFaceRendering); + SetKeyword(material, "_FIXED_NORMALS_VIEWSPACE_BACKFACE", normalsMode == eNormalsMode.FixedNormalsViewSpace && allowBackFaceRendering); + SetKeyword(material, "_FIXED_NORMALS_WORLDSPACE", normalsMode == eNormalsMode.FixedNormalsWorldSpace); + SetKeyword(material, "_FIXED_NORMALS_MODELSPACE", normalsMode == eNormalsMode.FixedNormalsModelSpace && !allowBackFaceRendering); + SetKeyword(material, "_FIXED_NORMALS_MODELSPACE_BACKFACE", normalsMode == eNormalsMode.FixedNormalsModelSpace && allowBackFaceRendering); + } + + static bool GetMaterialFixedNormalsBackfaceRenderingOn (Material material) { + return material.IsKeywordEnabled("_FIXED_NORMALS_VIEWSPACE_BACKFACE") || material.IsKeywordEnabled("_FIXED_NORMALS_MODELSPACE_BACKFACE"); + } + + static bool HasZWriteEnabled (Material material) { + if (material.HasProperty("_ZWrite")) { + return material.GetFloat("_ZWrite") > 0.0f; + } + else return true; // Pixel Lit shader always has _ZWrite enabled. + } + #endregion +} diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/Shaders/SpineSpriteShaderGUI.cs.meta b/box1/Assets/Spine/Editor/spine-unity/Editor/Shaders/SpineSpriteShaderGUI.cs.meta new file mode 100644 index 00000000..2215e75e --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/Shaders/SpineSpriteShaderGUI.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: aef90b4c481362e42891bb46de344c1c +timeCreated: 1479458475 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/SpineAttributeDrawers.cs b/box1/Assets/Spine/Editor/spine-unity/Editor/SpineAttributeDrawers.cs new file mode 100644 index 00000000..33a92835 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/SpineAttributeDrawers.cs @@ -0,0 +1,602 @@ +/****************************************************************************** + * 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. + *****************************************************************************/ + +// Contributed by: Mitch Thompson + +using UnityEngine; +using UnityEditor; +using System; +using System.Collections.Generic; +using System.Reflection; +using Spine; +using System.Linq; + +namespace Spine.Unity.Editor { + public struct SpineDrawerValuePair { + public string stringValue; + public SerializedProperty property; + + public SpineDrawerValuePair (string val, SerializedProperty property) { + this.stringValue = val; + this.property = property; + } + } + + public abstract class SpineTreeItemDrawerBase : PropertyDrawer where T:SpineAttributeBase { + protected SkeletonDataAsset skeletonDataAsset; + internal const string NoneStringConstant = ""; + + internal virtual string NoneString { get { return NoneStringConstant; } } + + GUIContent noneLabel; + GUIContent NoneLabel (Texture2D image = null) { + if (noneLabel == null) noneLabel = new GUIContent(NoneString); + noneLabel.image = image; + return noneLabel; + } + + protected T TargetAttribute { get { return (T)attribute; } } + protected SerializedProperty SerializedProperty { get; private set; } + + protected abstract Texture2D Icon { get; } + + public override void OnGUI (Rect position, SerializedProperty property, GUIContent label) { + SerializedProperty = property; + + if (property.propertyType != SerializedPropertyType.String) { + EditorGUI.LabelField(position, "ERROR:", "May only apply to type string"); + return; + } + + // Handle multi-editing when instances don't use the same SkeletonDataAsset. + if (!SpineInspectorUtility.TargetsUseSameData(property.serializedObject)) { + EditorGUI.DelayedTextField(position, property, label); + return; + } + + SerializedProperty dataField = property.FindBaseOrSiblingProperty(TargetAttribute.dataField); + + if (dataField != null) { + var objectReferenceValue = dataField.objectReferenceValue; + if (objectReferenceValue is SkeletonDataAsset) { + skeletonDataAsset = (SkeletonDataAsset)objectReferenceValue; + } else if (objectReferenceValue is IHasSkeletonDataAsset) { + var hasSkeletonDataAsset = (IHasSkeletonDataAsset)objectReferenceValue; + if (hasSkeletonDataAsset != null) + skeletonDataAsset = hasSkeletonDataAsset.SkeletonDataAsset; + } else if (objectReferenceValue != null) { + EditorGUI.LabelField(position, "ERROR:", "Invalid reference type"); + return; + } + + } else { + var targetObject = property.serializedObject.targetObject; + + IHasSkeletonDataAsset hasSkeletonDataAsset = targetObject as IHasSkeletonDataAsset; + if (hasSkeletonDataAsset == null) { + var component = targetObject as Component; + if (component != null) + hasSkeletonDataAsset = component.GetComponentInChildren(typeof(IHasSkeletonDataAsset)) as IHasSkeletonDataAsset; + } + + if (hasSkeletonDataAsset != null) + skeletonDataAsset = hasSkeletonDataAsset.SkeletonDataAsset; + } + + if (skeletonDataAsset == null) { + if (TargetAttribute.fallbackToTextField) { + EditorGUI.PropertyField(position, property); //EditorGUI.TextField(position, label, property.stringValue); + } else { + EditorGUI.LabelField(position, "ERROR:", "Must have reference to a SkeletonDataAsset"); + } + + skeletonDataAsset = property.serializedObject.targetObject as SkeletonDataAsset; + if (skeletonDataAsset == null) return; + } + + position = EditorGUI.PrefixLabel(position, label); + + Texture2D image = Icon; + string propertyStringValue = (property.hasMultipleDifferentValues) ? SpineInspectorUtility.EmDash : property.stringValue; + if (GUI.Button(position, string.IsNullOrEmpty(propertyStringValue) ? NoneLabel(image) : SpineInspectorUtility.TempContent(propertyStringValue, image), EditorStyles.popup)) + Selector(property); + } + + public ISkeletonComponent GetTargetSkeletonComponent (SerializedProperty property) { + var dataField = property.FindBaseOrSiblingProperty(TargetAttribute.dataField); + + if (dataField != null) { + var skeletonComponent = dataField.objectReferenceValue as ISkeletonComponent; + if (dataField.objectReferenceValue != null && skeletonComponent != null) // note the overloaded UnityEngine.Object == null check. Do not simplify. + return skeletonComponent; + } else { + var component = property.serializedObject.targetObject as Component; + if (component != null) + return component.GetComponentInChildren(typeof(ISkeletonComponent)) as ISkeletonComponent; + } + + return null; + } + + protected virtual void Selector (SerializedProperty property) { + SkeletonData data = skeletonDataAsset.GetSkeletonData(true); + if (data == null) return; + + var menu = new GenericMenu(); + PopulateMenu(menu, property, this.TargetAttribute, data); + menu.ShowAsContext(); + } + + protected abstract void PopulateMenu (GenericMenu menu, SerializedProperty property, T targetAttribute, SkeletonData data); + + protected virtual void HandleSelect (object menuItemObject) { + var clickedItem = (SpineDrawerValuePair)menuItemObject; + var serializedProperty = clickedItem.property; + if (serializedProperty.serializedObject.isEditingMultipleObjects) serializedProperty.stringValue = "oaifnoiasf��123526"; // HACK: to trigger change on multi-editing. + serializedProperty.stringValue = clickedItem.stringValue; + serializedProperty.serializedObject.ApplyModifiedProperties(); + } + + public override float GetPropertyHeight (SerializedProperty property, GUIContent label) { + return 18; + } + + } + + [CustomPropertyDrawer(typeof(SpineSlot))] + public class SpineSlotDrawer : SpineTreeItemDrawerBase { + + protected override Texture2D Icon { get { return SpineEditorUtilities.Icons.slot; } } + + protected override void PopulateMenu (GenericMenu menu, SerializedProperty property, SpineSlot targetAttribute, SkeletonData data) { + if (TargetAttribute.includeNone) + menu.AddItem(new GUIContent(NoneString), !property.hasMultipleDifferentValues && string.IsNullOrEmpty(property.stringValue), HandleSelect, new SpineDrawerValuePair(string.Empty, property)); + + IEnumerable orderedSlots = data.Slots.Items.OrderBy(slotData => slotData.Name); + foreach (SlotData slotData in orderedSlots) { + int slotIndex = slotData.Index; + string name = slotData.Name; + if (name.StartsWith(targetAttribute.startsWith, StringComparison.Ordinal)) { + + if (targetAttribute.containsBoundingBoxes) { + var skinEntries = new List(); + foreach (var skin in data.Skins) { + skin.GetAttachments(slotIndex, skinEntries); + } + + bool hasBoundingBox = false; + foreach (var entry in skinEntries) { + var bbAttachment = entry.Attachment as BoundingBoxAttachment; + if (bbAttachment != null) { + string menuLabel = bbAttachment.IsWeighted() ? name + " (!)" : name; + menu.AddItem(new GUIContent(menuLabel), !property.hasMultipleDifferentValues && name == property.stringValue, HandleSelect, new SpineDrawerValuePair(name, property)); + hasBoundingBox = true; + break; + } + } + + if (!hasBoundingBox) + menu.AddDisabledItem(new GUIContent(name)); + + } else { + menu.AddItem(new GUIContent(name), !property.hasMultipleDifferentValues && name == property.stringValue, HandleSelect, new SpineDrawerValuePair(name, property)); + } + + } + + } + } + + } + + [CustomPropertyDrawer(typeof(SpineSkin))] + public class SpineSkinDrawer : SpineTreeItemDrawerBase { + const string DefaultSkinName = "default"; + + protected override Texture2D Icon { get { return SpineEditorUtilities.Icons.skin; } } + + internal override string NoneString { get { return TargetAttribute.defaultAsEmptyString ? DefaultSkinName : NoneStringConstant; } } + + public static void GetSkinMenuItems (SkeletonData data, List outputNames, List outputMenuItems, bool includeNone = true) { + if (data == null) return; + if (outputNames == null) return; + if (outputMenuItems == null) return; + + var skins = data.Skins; + + outputNames.Clear(); + outputMenuItems.Clear(); + + var icon = SpineEditorUtilities.Icons.skin; + + if (includeNone) { + outputNames.Add(""); + outputMenuItems.Add(new GUIContent(NoneStringConstant, icon)); + } + + foreach (var s in skins) { + string skinName = s.Name; + outputNames.Add(skinName); + outputMenuItems.Add(new GUIContent(skinName, icon)); + } + } + + protected override void PopulateMenu (GenericMenu menu, SerializedProperty property, SpineSkin targetAttribute, SkeletonData data) { + menu.AddDisabledItem(new GUIContent(skeletonDataAsset.name)); + menu.AddSeparator(""); + + for (int i = 0; i < data.Skins.Count; i++) { + string name = data.Skins.Items[i].Name; + if (name.StartsWith(targetAttribute.startsWith, StringComparison.Ordinal)) { + bool isDefault = string.Equals(name, DefaultSkinName, StringComparison.Ordinal); + string choiceValue = TargetAttribute.defaultAsEmptyString && isDefault ? string.Empty : name; + menu.AddItem(new GUIContent(name), !property.hasMultipleDifferentValues && choiceValue == property.stringValue, HandleSelect, new SpineDrawerValuePair(choiceValue, property)); + } + + } + } + + } + + [CustomPropertyDrawer(typeof(SpineAnimation))] + public class SpineAnimationDrawer : SpineTreeItemDrawerBase { + + protected override Texture2D Icon { get { return SpineEditorUtilities.Icons.animation; } } + + public static void GetAnimationMenuItems (SkeletonData data, List outputNames, List outputMenuItems, bool includeNone = true) { + if (data == null) return; + if (outputNames == null) return; + if (outputMenuItems == null) return; + + var animations = data.Animations; + + outputNames.Clear(); + outputMenuItems.Clear(); + + if (includeNone) { + outputNames.Add(""); + outputMenuItems.Add(new GUIContent(NoneStringConstant, SpineEditorUtilities.Icons.animation)); + } + + foreach (var a in animations) { + string animationName = a.Name; + outputNames.Add(animationName); + outputMenuItems.Add(new GUIContent(animationName, SpineEditorUtilities.Icons.animation)); + } + } + + protected override void PopulateMenu (GenericMenu menu, SerializedProperty property, SpineAnimation targetAttribute, SkeletonData data) { + var animations = skeletonDataAsset.GetAnimationStateData().SkeletonData.Animations; + + if (TargetAttribute.includeNone) + menu.AddItem(new GUIContent(NoneString), !property.hasMultipleDifferentValues && string.IsNullOrEmpty(property.stringValue), HandleSelect, new SpineDrawerValuePair(string.Empty, property)); + + for (int i = 0; i < animations.Count; i++) { + string name = animations.Items[i].Name; + if (name.StartsWith(targetAttribute.startsWith, StringComparison.Ordinal)) + menu.AddItem(new GUIContent(name), !property.hasMultipleDifferentValues && name == property.stringValue, HandleSelect, new SpineDrawerValuePair(name, property)); + } + } + + } + + [CustomPropertyDrawer(typeof(SpineEvent))] + public class SpineEventNameDrawer : SpineTreeItemDrawerBase { + + protected override Texture2D Icon { get { return SpineEditorUtilities.Icons.userEvent; } } + + public static void GetEventMenuItems (SkeletonData data, List eventNames, List menuItems, bool includeNone = true) { + if (data == null) return; + + var animations = data.Events; + + eventNames.Clear(); + menuItems.Clear(); + + if (includeNone) { + eventNames.Add(""); + menuItems.Add(new GUIContent(NoneStringConstant, SpineEditorUtilities.Icons.userEvent)); + } + + foreach (var a in animations) { + string animationName = a.Name; + eventNames.Add(animationName); + menuItems.Add(new GUIContent(animationName, SpineEditorUtilities.Icons.userEvent)); + } + } + + protected override void PopulateMenu (GenericMenu menu, SerializedProperty property, SpineEvent targetAttribute, SkeletonData data) { + var events = skeletonDataAsset.GetSkeletonData(false).Events; + + if (TargetAttribute.includeNone) + menu.AddItem(new GUIContent(NoneString), !property.hasMultipleDifferentValues && string.IsNullOrEmpty(property.stringValue), HandleSelect, new SpineDrawerValuePair(string.Empty, property)); + + for (int i = 0; i < events.Count; i++) { + var eventObject = events.Items[i]; + string name = eventObject.Name; + if (name.StartsWith(targetAttribute.startsWith, StringComparison.Ordinal)) { + if (!TargetAttribute.audioOnly || !string.IsNullOrEmpty(eventObject.AudioPath)) { + menu.AddItem(new GUIContent(name), !property.hasMultipleDifferentValues && name == property.stringValue, HandleSelect, new SpineDrawerValuePair(name, property)); + } + } + + } + } + + } + + [CustomPropertyDrawer(typeof(SpineIkConstraint))] + public class SpineIkConstraintDrawer : SpineTreeItemDrawerBase { + + protected override Texture2D Icon { get { return SpineEditorUtilities.Icons.constraintIK; } } + + protected override void PopulateMenu (GenericMenu menu, SerializedProperty property, SpineIkConstraint targetAttribute, SkeletonData data) { + var constraints = skeletonDataAsset.GetSkeletonData(false).IkConstraints; + + if (TargetAttribute.includeNone) + menu.AddItem(new GUIContent(NoneString), !property.hasMultipleDifferentValues && string.IsNullOrEmpty(property.stringValue), HandleSelect, new SpineDrawerValuePair(string.Empty, property)); + + for (int i = 0; i < constraints.Count; i++) { + string name = constraints.Items[i].Name; + if (name.StartsWith(targetAttribute.startsWith, StringComparison.Ordinal)) + menu.AddItem(new GUIContent(name), !property.hasMultipleDifferentValues && name == property.stringValue, HandleSelect, new SpineDrawerValuePair(name, property)); + } + } + + } + + [CustomPropertyDrawer(typeof(SpineTransformConstraint))] + public class SpineTransformConstraintDrawer : SpineTreeItemDrawerBase { + + protected override Texture2D Icon { get { return SpineEditorUtilities.Icons.constraintTransform; } } + + protected override void PopulateMenu (GenericMenu menu, SerializedProperty property, SpineTransformConstraint targetAttribute, SkeletonData data) { + var constraints = skeletonDataAsset.GetSkeletonData(false).TransformConstraints; + + if (TargetAttribute.includeNone) + menu.AddItem(new GUIContent(NoneString), !property.hasMultipleDifferentValues && string.IsNullOrEmpty(property.stringValue), HandleSelect, new SpineDrawerValuePair(string.Empty, property)); + + for (int i = 0; i < constraints.Count; i++) { + string name = constraints.Items[i].Name; + if (name.StartsWith(targetAttribute.startsWith, StringComparison.Ordinal)) + menu.AddItem(new GUIContent(name), !property.hasMultipleDifferentValues && name == property.stringValue, HandleSelect, new SpineDrawerValuePair(name, property)); + } + } + } + + [CustomPropertyDrawer(typeof(SpinePathConstraint))] + public class SpinePathConstraintDrawer : SpineTreeItemDrawerBase { + + protected override Texture2D Icon { get { return SpineEditorUtilities.Icons.constraintPath; } } + + protected override void PopulateMenu (GenericMenu menu, SerializedProperty property, SpinePathConstraint targetAttribute, SkeletonData data) { + var constraints = skeletonDataAsset.GetSkeletonData(false).PathConstraints; + + if (TargetAttribute.includeNone) + menu.AddItem(new GUIContent(NoneString), !property.hasMultipleDifferentValues && string.IsNullOrEmpty(property.stringValue), HandleSelect, new SpineDrawerValuePair(string.Empty, property)); + + for (int i = 0; i < constraints.Count; i++) { + string name = constraints.Items[i].Name; + if (name.StartsWith(targetAttribute.startsWith, StringComparison.Ordinal)) + menu.AddItem(new GUIContent(name), !property.hasMultipleDifferentValues && name == property.stringValue, HandleSelect, new SpineDrawerValuePair(name, property)); + } + } + } + + [CustomPropertyDrawer(typeof(SpineAttachment))] + public class SpineAttachmentDrawer : SpineTreeItemDrawerBase { + + protected override Texture2D Icon { get { return SpineEditorUtilities.Icons.genericAttachment; } } + + protected override void PopulateMenu (GenericMenu menu, SerializedProperty property, SpineAttachment targetAttribute, SkeletonData data) { + ISkeletonComponent skeletonComponent = GetTargetSkeletonComponent(property); + var validSkins = new List(); + + if (skeletonComponent != null && targetAttribute.currentSkinOnly) { + Skin currentSkin = null; + + var skinProperty = property.FindBaseOrSiblingProperty(targetAttribute.skinField); + if (skinProperty != null) currentSkin = skeletonComponent.Skeleton.Data.FindSkin(skinProperty.stringValue); + + currentSkin = currentSkin ?? skeletonComponent.Skeleton.Skin; + if (currentSkin != null) + validSkins.Add(currentSkin); + else + validSkins.Add(data.Skins.Items[0]); + + } else { + foreach (Skin skin in data.Skins) + if (skin != null) validSkins.Add(skin); + } + + var attachmentNames = new List(); + var placeholderNames = new List(); + string prefix = ""; + + if (skeletonComponent != null && targetAttribute.currentSkinOnly) + menu.AddDisabledItem(new GUIContent((skeletonComponent as Component).gameObject.name + " (Skeleton)")); + else + menu.AddDisabledItem(new GUIContent(skeletonDataAsset.name)); + + menu.AddSeparator(""); + if (TargetAttribute.includeNone) { + const string NullAttachmentName = ""; + menu.AddItem(new GUIContent("Null"), !property.hasMultipleDifferentValues && property.stringValue == NullAttachmentName, HandleSelect, new SpineDrawerValuePair(NullAttachmentName, property)); + menu.AddSeparator(""); + } + + Skin defaultSkin = data.Skins.Items[0]; + var slotProperty = property.FindBaseOrSiblingProperty(TargetAttribute.slotField); + + string slotMatch = ""; + if (slotProperty != null) { + if (slotProperty.propertyType == SerializedPropertyType.String) + slotMatch = slotProperty.stringValue.ToLower(); + } + + foreach (Skin skin in validSkins) { + string skinPrefix = skin.Name + "/"; + + if (validSkins.Count > 1) + prefix = skinPrefix; + + for (int i = 0; i < data.Slots.Count; i++) { + if (slotMatch.Length > 0 && !(data.Slots.Items[i].Name.Equals(slotMatch, StringComparison.OrdinalIgnoreCase))) + continue; + + attachmentNames.Clear(); + placeholderNames.Clear(); + + var skinEntries = new List(); + skin.GetAttachments(i, skinEntries); + foreach (var entry in skinEntries) { + attachmentNames.Add(entry.Name); + } + + if (skin != defaultSkin) { + foreach (var entry in skinEntries) { + placeholderNames.Add(entry.Name); + } + skinEntries.Clear(); + defaultSkin.GetAttachments(i, skinEntries); + foreach (var entry in skinEntries) { + attachmentNames.Add(entry.Name); + } + } + + for (int a = 0; a < attachmentNames.Count; a++) { + string attachmentPath = attachmentNames[a]; + string menuPath = prefix + data.Slots.Items[i].Name + "/" + attachmentPath; + string name = attachmentNames[a]; + + if (targetAttribute.returnAttachmentPath) + name = skin.Name + "/" + data.Slots.Items[i].Name + "/" + attachmentPath; + + if (targetAttribute.placeholdersOnly && !placeholderNames.Contains(attachmentPath)) { + menu.AddDisabledItem(new GUIContent(menuPath)); + } else { + menu.AddItem(new GUIContent(menuPath), !property.hasMultipleDifferentValues && name == property.stringValue, HandleSelect, new SpineDrawerValuePair(name, property)); + } + } + + } + } + } + + } + + [CustomPropertyDrawer(typeof(SpineBone))] + public class SpineBoneDrawer : SpineTreeItemDrawerBase { + + protected override Texture2D Icon { get { return SpineEditorUtilities.Icons.bone; } } + + protected override void PopulateMenu (GenericMenu menu, SerializedProperty property, SpineBone targetAttribute, SkeletonData data) { + menu.AddDisabledItem(new GUIContent(skeletonDataAsset.name)); + menu.AddSeparator(""); + + if (TargetAttribute.includeNone) + menu.AddItem(new GUIContent(NoneString), !property.hasMultipleDifferentValues && string.IsNullOrEmpty(property.stringValue), HandleSelect, new SpineDrawerValuePair(string.Empty, property)); + + for (int i = 0; i < data.Bones.Count; i++) { + var bone = data.Bones.Items[i]; + string name = bone.Name; + if (name.StartsWith(targetAttribute.startsWith, StringComparison.Ordinal)) { + // jointName = "root/hip/bone" to show a hierarchial tree. + string jointName = name; + var iterator = bone; + while ((iterator = iterator.Parent) != null) + jointName = string.Format("{0}/{1}", iterator.Name, jointName); + + menu.AddItem(new GUIContent(jointName), !property.hasMultipleDifferentValues && name == property.stringValue, HandleSelect, new SpineDrawerValuePair(name, property)); + } + } + } + + } + + [CustomPropertyDrawer(typeof(SpineAtlasRegion))] + public class SpineAtlasRegionDrawer : PropertyDrawer { + SerializedProperty atlasProp; + + protected SpineAtlasRegion TargetAttribute { get { return (SpineAtlasRegion)attribute; } } + + public override void OnGUI (Rect position, SerializedProperty property, GUIContent label) { + if (property.propertyType != SerializedPropertyType.String) { + EditorGUI.LabelField(position, "ERROR:", "May only apply to type string"); + return; + } + + string atlasAssetFieldName = TargetAttribute.atlasAssetField; + if (string.IsNullOrEmpty(atlasAssetFieldName)) + atlasAssetFieldName = "atlasAsset"; + + atlasProp = property.FindBaseOrSiblingProperty(atlasAssetFieldName); + + if (atlasProp == null) { + EditorGUI.LabelField(position, "ERROR:", "Must have AtlasAsset variable!"); + return; + } else if (atlasProp.objectReferenceValue == null) { + EditorGUI.LabelField(position, "ERROR:", "Atlas variable must not be null!"); + return; + } else if (!atlasProp.objectReferenceValue.GetType().IsSubclassOf(typeof(AtlasAssetBase)) && + atlasProp.objectReferenceValue.GetType() != typeof(AtlasAssetBase)) { + EditorGUI.LabelField(position, "ERROR:", "Atlas variable must be of type AtlasAsset!"); + } + + position = EditorGUI.PrefixLabel(position, label); + + if (GUI.Button(position, property.stringValue, EditorStyles.popup)) + Selector(property); + + } + + void Selector (SerializedProperty property) { + GenericMenu menu = new GenericMenu(); + AtlasAssetBase atlasAsset = (AtlasAssetBase)atlasProp.objectReferenceValue; + Atlas atlas = atlasAsset.GetAtlas(); + FieldInfo field = typeof(Atlas).GetField("regions", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); + List regions = (List)field.GetValue(atlas); + + for (int i = 0; i < regions.Count; i++) { + string name = regions[i].name; + menu.AddItem(new GUIContent(name), !property.hasMultipleDifferentValues && name == property.stringValue, HandleSelect, new SpineDrawerValuePair(name, property)); + } + + menu.ShowAsContext(); + } + + static void HandleSelect (object val) { + var pair = (SpineDrawerValuePair)val; + pair.property.stringValue = pair.stringValue; + pair.property.serializedObject.ApplyModifiedProperties(); + } + + } + +} diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/SpineAttributeDrawers.cs.meta b/box1/Assets/Spine/Editor/spine-unity/Editor/SpineAttributeDrawers.cs.meta new file mode 100644 index 00000000..901111a0 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/SpineAttributeDrawers.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: f2de282d583d4a641bf1c349f0a3eef9 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/Utility.meta b/box1/Assets/Spine/Editor/spine-unity/Editor/Utility.meta new file mode 100644 index 00000000..b46de85a --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/Utility.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 33c080d1c093a2c45b6c72c17a557067 +folderAsset: yes +timeCreated: 1563304704 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/Utility/AssetDatabaseAvailabilityDetector.cs b/box1/Assets/Spine/Editor/spine-unity/Editor/Utility/AssetDatabaseAvailabilityDetector.cs new file mode 100644 index 00000000..8c464a83 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/Utility/AssetDatabaseAvailabilityDetector.cs @@ -0,0 +1,50 @@ +/****************************************************************************** + * 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; + +namespace Spine.Unity.Editor { + public static class AssetDatabaseAvailabilityDetector { + const string MarkerResourceName = "SpineAssetDatabaseMarker"; + private static bool isMarkerLoaded; + + public static bool IsAssetDatabaseAvailable (bool forceCheck = false) { + if (!forceCheck && isMarkerLoaded) + return true; + + TextAsset markerTextAsset = Resources.Load(AssetDatabaseAvailabilityDetector.MarkerResourceName); + isMarkerLoaded = markerTextAsset != null; + if (markerTextAsset != null) { + Resources.UnloadAsset(markerTextAsset); + } + + return isMarkerLoaded; + } + } +} diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/Utility/AssetDatabaseAvailabilityDetector.cs.meta b/box1/Assets/Spine/Editor/spine-unity/Editor/Utility/AssetDatabaseAvailabilityDetector.cs.meta new file mode 100644 index 00000000..00b99c13 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/Utility/AssetDatabaseAvailabilityDetector.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 25086cd81e3158b439761b73d7366c47 +timeCreated: 1444587791 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/Utility/AssetUtility.cs b/box1/Assets/Spine/Editor/spine-unity/Editor/Utility/AssetUtility.cs new file mode 100644 index 00000000..54988fdc --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/Utility/AssetUtility.cs @@ -0,0 +1,1279 @@ +/****************************************************************************** + * 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. + *****************************************************************************/ + +#pragma warning disable 0219 + +#define SPINE_SKELETONMECANIM + +#if UNITY_2017_2_OR_NEWER +#define NEWPLAYMODECALLBACKS +#endif + +#if UNITY_2018_3 || UNITY_2019 || UNITY_2018_3_OR_NEWER +#define NEW_PREFAB_SYSTEM +#endif + +#if UNITY_2018_3_OR_NEWER +#define NEW_PREFERENCES_SETTINGS_PROVIDER +#endif + +#if UNITY_2018_2_OR_NEWER +#define EXPOSES_SPRITE_ATLAS_UTILITIES +#endif + +using UnityEngine; +using UnityEditor; +using System.Collections.Generic; +using System.IO; +using System.Text; +using System.Linq; +using System.Reflection; + +using CompatibilityProblemInfo = Spine.Unity.SkeletonDataCompatibility.CompatibilityProblemInfo; + +namespace Spine.Unity.Editor { + using PathAndProblemInfo = System.Collections.Generic.KeyValuePair; + + public static class AssetUtility { + + public const string SkeletonDataSuffix = "_SkeletonData"; + public const string AtlasSuffix = "_Atlas"; + public const string SpriteAtlasSuffix = "_SpriteAtlas"; + + /// HACK: This list keeps the asset reference temporarily during importing. + /// + /// In cases of very large projects/sufficient RAM pressure, when AssetDatabase.SaveAssets is called, + /// Unity can mistakenly unload assets whose references are only on the stack. + /// This leads to MissingReferenceException and other errors. + public static readonly List protectFromStackGarbageCollection = new List(); + public static HashSet assetsImportedInWrongState = new HashSet(); + + public static void HandleOnPostprocessAllAssets (string[] imported, List texturesWithoutMetaFile) { + // In case user used "Assets -> Reimport All", during the import process, + // asset database is not initialized until some point. During that period, + // all attempts to load any assets using API (i.e. AssetDatabase.LoadAssetAtPath) + // will return null, and as result, assets won't be loaded even if they actually exists, + // which may lead to numerous importing errors. + // This situation also happens if Library folder is deleted from the project, which is a pretty + // common case, since when using version control systems, the Library folder must be excluded. + // + // So to avoid this, in case asset database is not available, we delay loading the assets + // until next time. + // + // Unity *always* reimports some internal assets after the process is done, so this method + // is always called once again in a state when asset database is available. + // + // Checking whether AssetDatabase is initialized is done by attempting to load + // a known "marker" asset that should always be available. Failing to load this asset + // means that AssetDatabase is not initialized. + AssetUtility.assetsImportedInWrongState.UnionWith(imported); + if (AssetDatabaseAvailabilityDetector.IsAssetDatabaseAvailable()) { + string[] combinedAssets = AssetUtility.assetsImportedInWrongState.ToArray(); + AssetUtility.assetsImportedInWrongState.Clear(); + AssetUtility.ImportSpineContent(combinedAssets, texturesWithoutMetaFile); + } + } + +#region Match SkeletonData with Atlases + static readonly AttachmentType[] AtlasTypes = { AttachmentType.Region, AttachmentType.Linkedmesh, AttachmentType.Mesh }; + + public static List GetRequiredAtlasRegions (string skeletonDataPath) { + List requiredPaths = new List(); + + if (skeletonDataPath.Contains(".skel")) { + AddRequiredAtlasRegionsFromBinary(skeletonDataPath, requiredPaths); + return requiredPaths; + } + + TextReader reader = null; + TextAsset spineJson = AssetDatabase.LoadAssetAtPath(skeletonDataPath); + Dictionary root = null; + try { + if (spineJson != null) { + reader = new StringReader(spineJson.text); + } + else { + // On a "Reimport All" the order of imports can be wrong, thus LoadAssetAtPath() above could return null. + // as a workaround, we provide a fallback reader. + reader = new StreamReader(skeletonDataPath); + } + root = Json.Deserialize(reader) as Dictionary; + } + finally { + if (reader != null) + reader.Dispose(); + } + + if (root == null || !root.ContainsKey("skins")) + return requiredPaths; + + var skinsList = root["skins"] as List; + if (skinsList == null) + return requiredPaths; + + foreach (Dictionary skinMap in skinsList) { + if (!skinMap.ContainsKey("attachments")) + continue; + foreach (var slot in (Dictionary)skinMap["attachments"]) { + foreach (var attachment in ((Dictionary)slot.Value)) { + var data = ((Dictionary)attachment.Value); + + // Ignore non-atlas-requiring types. + if (data.ContainsKey("type")) { + AttachmentType attachmentType; + string typeString = (string)data["type"]; + try { + attachmentType = (AttachmentType)System.Enum.Parse(typeof(AttachmentType), typeString, true); + } catch (System.ArgumentException e) { + // For more info, visit: http://esotericsoftware.com/forum/Spine-editor-and-runtime-version-management-6534 + Debug.LogWarning(string.Format("Unidentified Attachment type: \"{0}\". Skeleton may have been exported from an incompatible Spine version.", typeString), spineJson); + throw e; + } + + if (!AtlasTypes.Contains(attachmentType)) + continue; + } + + if (data.ContainsKey("path")) + requiredPaths.Add((string)data["path"]); + else if (data.ContainsKey("name")) + requiredPaths.Add((string)data["name"]); + else + requiredPaths.Add(attachment.Key); + } + } + } + + return requiredPaths; + } + + internal static void AddRequiredAtlasRegionsFromBinary (string skeletonDataPath, List requiredPaths) { + SkeletonBinary binary = new SkeletonBinary(new AtlasRequirementLoader(requiredPaths)); + Stream input = null; + TextAsset data = AssetDatabase.LoadAssetAtPath(skeletonDataPath); + try { + if (data != null) { + input = new MemoryStream(data.bytes); + } + else { + // On a "Reimport All" the order of imports can be wrong, thus LoadAssetAtPath() above could return null. + // as a workaround, we provide a fallback reader. + input = File.Open(skeletonDataPath, FileMode.Open, FileAccess.Read); + } + binary.ReadSkeletonData(input); + } + finally { + if (input != null) + input.Dispose(); + } + binary = null; + } + + internal static AtlasAssetBase GetMatchingAtlas (List requiredPaths, List atlasAssets) { + AtlasAssetBase atlasAssetMatch = null; + + foreach (AtlasAssetBase a in atlasAssets) { + Atlas atlas = a.GetAtlas(); + bool failed = false; + foreach (string regionPath in requiredPaths) { + if (atlas.FindRegion(regionPath) == null) { + failed = true; + break; + } + } + + if (!failed) { + atlasAssetMatch = a; + break; + } + } + + return atlasAssetMatch; + } + + public class AtlasRequirementLoader : AttachmentLoader { + List requirementList; + + public AtlasRequirementLoader (List requirementList) { + this.requirementList = requirementList; + } + + public RegionAttachment NewRegionAttachment (Skin skin, string name, string path) { + requirementList.Add(path); + return new RegionAttachment(name); + } + + public MeshAttachment NewMeshAttachment (Skin skin, string name, string path) { + requirementList.Add(path); + return new MeshAttachment(name); + } + + public BoundingBoxAttachment NewBoundingBoxAttachment (Skin skin, string name) { + return new BoundingBoxAttachment(name); + } + + public PathAttachment NewPathAttachment (Skin skin, string name) { + return new PathAttachment(name); + } + + public PointAttachment NewPointAttachment (Skin skin, string name) { + return new PointAttachment(name); + } + + public ClippingAttachment NewClippingAttachment (Skin skin, string name) { + return new ClippingAttachment(name); + } + } +#endregion + + public static void ImportSpineContent (string[] imported, List texturesWithoutMetaFile, + bool reimport = false) { + + var atlasPaths = new List(); + var imagePaths = new List(); + var skeletonPaths = new List(); + CompatibilityProblemInfo compatibilityProblemInfo = null; + + foreach (string str in imported) { + string extension = Path.GetExtension(str).ToLower(); + switch (extension) { + case ".atlas": + if (SpineEditorUtilities.Preferences.atlasTxtImportWarning) { + Debug.LogWarningFormat("`{0}` : If this file is a Spine atlas, please change its extension to `.atlas.txt`. This is to allow Unity to recognize it and avoid filename collisions. You can also set this file extension when exporting from the Spine editor.", str); + } + break; + case ".txt": + if (str.EndsWith(".atlas.txt", System.StringComparison.Ordinal)) + atlasPaths.Add(str); + break; + case ".png": + case ".jpg": + imagePaths.Add(str); + break; + case ".json": + var jsonAsset = AssetDatabase.LoadAssetAtPath(str); + if (jsonAsset != null && IsSpineData(jsonAsset, out compatibilityProblemInfo)) + skeletonPaths.Add(new PathAndProblemInfo(str, compatibilityProblemInfo)); + break; + case ".bytes": + if (str.ToLower().EndsWith(".skel.bytes", System.StringComparison.Ordinal)) { + if (IsSpineData(AssetDatabase.LoadAssetAtPath(str), out compatibilityProblemInfo)) + skeletonPaths.Add(new PathAndProblemInfo(str, compatibilityProblemInfo)); + } + break; + } + } + + // Import atlases first. + var newAtlases = new List(); + foreach (string ap in atlasPaths) { + if (ap.StartsWith("Packages")) + continue; + TextAsset atlasText = AssetDatabase.LoadAssetAtPath(ap); + AtlasAssetBase atlas = IngestSpineAtlas(atlasText, texturesWithoutMetaFile); + newAtlases.Add(atlas); + } + AddDependentSkeletonIfAtlasChanged(skeletonPaths, atlasPaths); + + // Import skeletons and match them with atlases. + bool abortSkeletonImport = false; + foreach (var skeletonPathEntry in skeletonPaths) { + string skeletonPath = skeletonPathEntry.Key; + var compatibilityProblems = skeletonPathEntry.Value; + if (skeletonPath.StartsWith("Packages")) + continue; + if (!reimport && CheckForValidSkeletonData(skeletonPath)) { + ReloadSkeletonData(skeletonPath, compatibilityProblems); + continue; + } + + var loadedAsset = AssetDatabase.LoadAssetAtPath(skeletonPath); + if (compatibilityProblems != null) { + IngestIncompatibleSpineProject(loadedAsset, compatibilityProblems); + continue; + } + + string dir = Path.GetDirectoryName(skeletonPath).Replace('\\', '/'); + +#if SPINE_TK2D + IngestSpineProject(loadedAsset, null); +#else + var atlasesForSkeleton = FindAtlasesAtPath(dir); + atlasesForSkeleton.AddRange(newAtlases); + var requiredPaths = GetRequiredAtlasRegions(skeletonPath); + var atlasMatch = GetMatchingAtlas(requiredPaths, atlasesForSkeleton); + if (atlasMatch != null || requiredPaths.Count == 0) { + IngestSpineProject(loadedAsset, atlasMatch); + } else { + SkeletonImportDialog(skeletonPath, atlasesForSkeleton, requiredPaths, ref abortSkeletonImport); + } + + if (abortSkeletonImport) + break; +#endif + } + + if (atlasPaths.Count > 0 || imagePaths.Count > 0 || skeletonPaths.Count > 0) { + SkeletonDataAssetInspector[] skeletonDataInspectors = Resources.FindObjectsOfTypeAll(); + foreach (var inspector in skeletonDataInspectors) { + inspector.UpdateSkeletonData(); + } + } + + // Any post processing of images + + // Under some circumstances (e.g. on first import) SkeletonGraphic objects + // have their skeletonGraphic.skeletonDataAsset reference corrupted + // by the instance of the ScriptableObject being destroyed but still assigned. + // Here we restore broken skeletonGraphic.skeletonDataAsset references. + var skeletonGraphicObjects = Resources.FindObjectsOfTypeAll(typeof(SkeletonGraphic)) as SkeletonGraphic[]; + foreach (var skeletonGraphic in skeletonGraphicObjects) { + + if (skeletonGraphic.skeletonDataAsset == null) { + var skeletonGraphicID = skeletonGraphic.GetInstanceID(); + if (SpineEditorUtilities.DataReloadHandler.savedSkeletonDataAssetAtSKeletonGraphicID.ContainsKey(skeletonGraphicID)) { + string assetPath = SpineEditorUtilities.DataReloadHandler.savedSkeletonDataAssetAtSKeletonGraphicID[skeletonGraphicID]; + skeletonGraphic.skeletonDataAsset = (SkeletonDataAsset)AssetDatabase.LoadAssetAtPath(assetPath); + } + } + } + } + + static void AddDependentSkeletonIfAtlasChanged(List skeletonPaths, List atlasPaths) { + foreach (var atlasPath in atlasPaths) { + string skeletonPathJson = atlasPath.Replace(".atlas.txt", ".json"); + string skeletonPathBinary = atlasPath.Replace(".atlas.txt", ".skel.bytes"); + string usedSkeletonPath = System.IO.File.Exists(skeletonPathJson) ? skeletonPathJson : + System.IO.File.Exists(skeletonPathBinary) ? skeletonPathBinary : null; + if (usedSkeletonPath == null) + continue; + + if (skeletonPaths.FindIndex(p => { return p.Key == usedSkeletonPath; } ) < 0) { + skeletonPaths.Add(new PathAndProblemInfo(usedSkeletonPath, null)); + } + } + } + + static void ReloadSkeletonData (string skeletonJSONPath, CompatibilityProblemInfo compatibilityProblemInfo) { + string dir = Path.GetDirectoryName(skeletonJSONPath).Replace('\\', '/'); + TextAsset textAsset = AssetDatabase.LoadAssetAtPath(skeletonJSONPath); + DirectoryInfo dirInfo = new DirectoryInfo(dir); + FileInfo[] files = dirInfo.GetFiles("*.asset"); + + foreach (var f in files) { + string localPath = dir + "/" + f.Name; + var obj = AssetDatabase.LoadAssetAtPath(localPath, typeof(Object)); + var skeletonDataAsset = obj as SkeletonDataAsset; + if (skeletonDataAsset != null) { + if (skeletonDataAsset.skeletonJSON == textAsset) { + if (Selection.activeObject == skeletonDataAsset) + Selection.activeObject = null; + + if (compatibilityProblemInfo != null) { + SkeletonDataCompatibility.DisplayCompatibilityProblem(compatibilityProblemInfo.DescriptionString(), textAsset); + return; + } + + Debug.LogFormat("Changes to '{0}' or atlas detected. Clearing SkeletonDataAsset: {1}", skeletonJSONPath, localPath); + skeletonDataAsset.Clear(); + + string guid = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(skeletonDataAsset)); + string lastHash = EditorPrefs.GetString(guid + "_hash"); + + // For some weird reason sometimes Unity loses the internal Object pointer, + // and as a result, all comparisons with null returns true. + // But the C# wrapper is still alive, so we can "restore" the object + // by reloading it from its Instance ID. + AtlasAssetBase[] skeletonDataAtlasAssets = skeletonDataAsset.atlasAssets; + if (skeletonDataAtlasAssets != null) { + for (int i = 0; i < skeletonDataAtlasAssets.Length; i++) { + if (!ReferenceEquals(null, skeletonDataAtlasAssets[i]) && + skeletonDataAtlasAssets[i].Equals(null) && + skeletonDataAtlasAssets[i].GetInstanceID() != 0 + ) { + skeletonDataAtlasAssets[i] = EditorUtility.InstanceIDToObject(skeletonDataAtlasAssets[i].GetInstanceID()) as AtlasAssetBase; + } + } + } + + SkeletonData skeletonData = skeletonDataAsset.GetSkeletonData(true); + string currentHash = skeletonData != null ? skeletonData.Hash : null; + +#if SPINE_SKELETONMECANIM + if (currentHash == null || lastHash != currentHash) + SkeletonBaker.UpdateMecanimClips(skeletonDataAsset); +#endif + + // if (currentHash == null || lastHash != currentHash) + // Do any upkeep on synchronized assets + + if (currentHash != null) + EditorPrefs.SetString(guid + "_hash", currentHash); + } + SpineEditorUtilities.DataReloadHandler.ReloadSceneSkeletonComponents(skeletonDataAsset); + } + } + } + +#region Import Atlases + static List FindAtlasesAtPath (string path) { + List arr = new List(); + DirectoryInfo dir = new DirectoryInfo(path); + FileInfo[] assetInfoArr = dir.GetFiles("*.asset"); + + int subLen = Application.dataPath.Length - 6; + foreach (var f in assetInfoArr) { + string assetRelativePath = f.FullName.Substring(subLen, f.FullName.Length - subLen).Replace("\\", "/"); + Object obj = AssetDatabase.LoadAssetAtPath(assetRelativePath, typeof(AtlasAssetBase)); + if (obj != null) + arr.Add(obj as AtlasAssetBase); + } + + return arr; + } + + static AtlasAssetBase IngestSpineAtlas (TextAsset atlasText, List texturesWithoutMetaFile) { + if (atlasText == null) { + Debug.LogWarning("Atlas source cannot be null!"); + return null; + } + + string primaryName = Path.GetFileNameWithoutExtension(atlasText.name).Replace(".atlas", ""); + string assetPath = Path.GetDirectoryName(AssetDatabase.GetAssetPath(atlasText)).Replace('\\', '/'); + + string atlasPath = assetPath + "/" + primaryName + AtlasSuffix + ".asset"; + + SpineAtlasAsset atlasAsset = (SpineAtlasAsset)AssetDatabase.LoadAssetAtPath(atlasPath, typeof(SpineAtlasAsset)); + + List vestigialMaterials = new List(); + + if (atlasAsset == null) + atlasAsset = SpineAtlasAsset.CreateInstance(); + else { + foreach (Material m in atlasAsset.materials) + vestigialMaterials.Add(m); + } + + protectFromStackGarbageCollection.Add(atlasAsset); + atlasAsset.atlasFile = atlasText; + + //strip CR + string atlasStr = atlasText.text; + atlasStr = atlasStr.Replace("\r", ""); + + string[] atlasLines = atlasStr.Split('\n'); + List pageFiles = new List(); + for (int i = 0; i < atlasLines.Length - 1; i++) { + if (atlasLines[i].Trim().Length == 0) + pageFiles.Add(atlasLines[i + 1].Trim()); + } + + var populatingMaterials = new List(pageFiles.Count);//atlasAsset.materials = new Material[pageFiles.Count]; + + for (int i = 0; i < pageFiles.Count; i++) { + string texturePath = assetPath + "/" + pageFiles[i]; + Texture2D texture = (Texture2D)AssetDatabase.LoadAssetAtPath(texturePath, typeof(Texture2D)); + bool textureIsUninitialized = texturesWithoutMetaFile != null && texturesWithoutMetaFile.Contains(texturePath); + if (SpineEditorUtilities.Preferences.setTextureImporterSettings && textureIsUninitialized) { + if (string.IsNullOrEmpty(SpineEditorUtilities.Preferences.textureSettingsReference)) + SetDefaultTextureSettings(texturePath, atlasAsset); + else + SetReferenceTextureSettings(texturePath, atlasAsset, SpineEditorUtilities.Preferences.textureSettingsReference); + } + + string pageName = Path.GetFileNameWithoutExtension(pageFiles[i]); + + //because this looks silly + if (pageName == primaryName && pageFiles.Count == 1) + pageName = "Material"; + + string materialPath = assetPath + "/" + primaryName + "_" + pageName + ".mat"; + Material mat = (Material)AssetDatabase.LoadAssetAtPath(materialPath, typeof(Material)); + + if (mat == null) { + mat = new Material(Shader.Find(SpineEditorUtilities.Preferences.defaultShader)); + ApplyPMAOrStraightAlphaSettings(mat, SpineEditorUtilities.Preferences.textureSettingsReference); + AssetDatabase.CreateAsset(mat, materialPath); + } else { + vestigialMaterials.Remove(mat); + } + + if (texture != null) + mat.mainTexture = texture; + + EditorUtility.SetDirty(mat); + // note: don't call AssetDatabase.SaveAssets() since this would trigger OnPostprocessAllAssets() every time unnecessarily. + populatingMaterials.Add(mat); //atlasAsset.materials[i] = mat; + } + + atlasAsset.materials = populatingMaterials.ToArray(); + + for (int i = 0; i < vestigialMaterials.Count; i++) + AssetDatabase.DeleteAsset(AssetDatabase.GetAssetPath(vestigialMaterials[i])); + + if (AssetDatabase.GetAssetPath(atlasAsset) == "") + AssetDatabase.CreateAsset(atlasAsset, atlasPath); + else + atlasAsset.Clear(); + + EditorUtility.SetDirty(atlasAsset); + AssetDatabase.SaveAssets(); + + if (pageFiles.Count != atlasAsset.materials.Length) + Debug.LogWarning(string.Format("{0} :: Not all atlas pages were imported. If you rename your image files, please make sure you also edit the filenames specified in the atlas file.", atlasAsset.name), atlasAsset); + else + Debug.Log(string.Format("{0} :: Imported with {1} material", atlasAsset.name, atlasAsset.materials.Length), atlasAsset); + + // Iterate regions and bake marked. + Atlas atlas = atlasAsset.GetAtlas(); + if (atlas != null) { + FieldInfo field = typeof(Atlas).GetField("regions", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.NonPublic); + var regions = (List)field.GetValue(atlas); + string atlasAssetPath = AssetDatabase.GetAssetPath(atlasAsset); + string atlasAssetDirPath = Path.GetDirectoryName(atlasAssetPath).Replace('\\', '/'); + string bakedDirPath = Path.Combine(atlasAssetDirPath, atlasAsset.name); + + bool hasBakedRegions = false; + for (int i = 0; i < regions.Count; i++) { + AtlasRegion region = regions[i]; + string bakedPrefabPath = Path.Combine(bakedDirPath, AssetUtility.GetPathSafeName(region.name) + ".prefab").Replace("\\", "/"); + GameObject prefab = (GameObject)AssetDatabase.LoadAssetAtPath(bakedPrefabPath, typeof(GameObject)); + if (prefab != null) { + SkeletonBaker.BakeRegion(atlasAsset, region, false); + hasBakedRegions = true; + } + } + + if (hasBakedRegions) { + AssetDatabase.SaveAssets(); + AssetDatabase.Refresh(); + } + } + + protectFromStackGarbageCollection.Remove(atlasAsset); + // note: at Asset Pipeline V2 this LoadAssetAtPath of the just created + // asset returns null, regardless of refresh calls. + var loadedAtlas = (AtlasAssetBase)AssetDatabase.LoadAssetAtPath(atlasPath, typeof(AtlasAssetBase)); + return loadedAtlas != null ? loadedAtlas : atlasAsset; + } + + public static bool SpriteAtlasSettingsNeedAdjustment (UnityEngine.U2D.SpriteAtlas spriteAtlas) { + #if EXPOSES_SPRITE_ATLAS_UTILITIES + UnityEditor.U2D.SpriteAtlasPackingSettings packingSettings = UnityEditor.U2D.SpriteAtlasExtensions.GetPackingSettings(spriteAtlas); + UnityEditor.U2D.SpriteAtlasTextureSettings textureSettings = UnityEditor.U2D.SpriteAtlasExtensions.GetTextureSettings(spriteAtlas); + + bool areSettingsAsDesired = + packingSettings.enableRotation == true && + packingSettings.enableTightPacking == false && + textureSettings.readable == true && + textureSettings.generateMipMaps == false; + // note: platformSettings.textureCompression is always providing "Compressed", so we have to skip it. + return !areSettingsAsDesired; + #else + return false; + #endif + } + + public static bool AdjustSpriteAtlasSettings (UnityEngine.U2D.SpriteAtlas spriteAtlas) { + #if EXPOSES_SPRITE_ATLAS_UTILITIES + UnityEditor.U2D.SpriteAtlasPackingSettings packingSettings = UnityEditor.U2D.SpriteAtlasExtensions.GetPackingSettings(spriteAtlas); + UnityEditor.U2D.SpriteAtlasTextureSettings textureSettings = UnityEditor.U2D.SpriteAtlasExtensions.GetTextureSettings(spriteAtlas); + + packingSettings.enableRotation = true; + packingSettings.enableTightPacking = false; + UnityEditor.U2D.SpriteAtlasExtensions.SetPackingSettings(spriteAtlas, packingSettings); + + textureSettings.readable = true; + textureSettings.generateMipMaps = false; + UnityEditor.U2D.SpriteAtlasExtensions.SetTextureSettings(spriteAtlas, textureSettings); + + TextureImporterPlatformSettings platformSettings = new TextureImporterPlatformSettings(); + platformSettings.textureCompression = TextureImporterCompression.Uncompressed; + platformSettings.crunchedCompression = false; + UnityEditor.U2D.SpriteAtlasExtensions.SetPlatformSettings(spriteAtlas, platformSettings); + + string atlasPath = AssetDatabase.GetAssetPath(spriteAtlas); + Debug.Log(string.Format("Adjusted unsuitable SpriteAtlas settings '{0}'", atlasPath), spriteAtlas); + return false; + #else + return true; + #endif + } + + public static bool GeneratePngFromSpriteAtlas (UnityEngine.U2D.SpriteAtlas spriteAtlas, out string texturePath) { + texturePath = System.IO.Path.ChangeExtension(AssetDatabase.GetAssetPath(spriteAtlas), ".png"); + if (spriteAtlas == null) + return false; + + Texture2D tempTexture = SpineSpriteAtlasAsset.AccessPackedTextureEditor(spriteAtlas); + if (tempTexture == null) + return false; + + byte[] bytes = null; + try { + bytes = tempTexture.EncodeToPNG(); + } + catch (System.Exception) { + // handled below + } + if (bytes == null || bytes.Length == 0) { + Debug.LogError("Could not read Compressed SpriteAtlas. Please enable 'Read/Write Enabled' and ensure 'Compression' is set to 'None' in Inspector.", spriteAtlas); + return false; + } + System.IO.File.WriteAllBytes(texturePath, bytes); + AssetDatabase.SaveAssets(); + AssetDatabase.Refresh(); + return System.IO.File.Exists(texturePath); + } + + public static AtlasAssetBase IngestSpriteAtlas (UnityEngine.U2D.SpriteAtlas spriteAtlas, List texturesWithoutMetaFile) { + if (spriteAtlas == null) { + Debug.LogWarning("SpriteAtlas source cannot be null!"); + return null; + } + + if (SpriteAtlasSettingsNeedAdjustment(spriteAtlas)) { + // settings need to be adjusted via the 'Spine SpriteAtlas Import' window if you want to use it as a Spine atlas. + return null; + } + + Texture2D texture = null; + { // only one page file + string texturePath; + GeneratePngFromSpriteAtlas(spriteAtlas, out texturePath); + texture = AssetDatabase.LoadAssetAtPath(texturePath); + if (texture == null && System.IO.File.Exists(texturePath)) { + EditorUtility.SetDirty(spriteAtlas); + return null; // next iteration will load the texture as well. + } + } + + string primaryName = spriteAtlas.name; + string assetPath = Path.GetDirectoryName(AssetDatabase.GetAssetPath(spriteAtlas)).Replace('\\', '/'); + + string atlasPath = assetPath + "/" + primaryName + SpriteAtlasSuffix + ".asset"; + + SpineSpriteAtlasAsset atlasAsset = AssetDatabase.LoadAssetAtPath(atlasPath); + + List vestigialMaterials = new List(); + + if (atlasAsset == null) + atlasAsset = SpineSpriteAtlasAsset.CreateInstance(); + else { + foreach (Material m in atlasAsset.materials) + vestigialMaterials.Add(m); + } + + protectFromStackGarbageCollection.Add(atlasAsset); + atlasAsset.spriteAtlasFile = spriteAtlas; + + int pagesCount = 1; + var populatingMaterials = new List(pagesCount); + + { + string pageName = "SpriteAtlas"; + + string materialPath = assetPath + "/" + primaryName + "_" + pageName + ".mat"; + Material mat = AssetDatabase.LoadAssetAtPath(materialPath); + + if (mat == null) { + mat = new Material(Shader.Find(SpineEditorUtilities.Preferences.defaultShader)); + ApplyPMAOrStraightAlphaSettings(mat, SpineEditorUtilities.Preferences.textureSettingsReference); + AssetDatabase.CreateAsset(mat, materialPath); + } + else { + vestigialMaterials.Remove(mat); + } + + if (texture != null) + mat.mainTexture = texture; + + EditorUtility.SetDirty(mat); + // note: don't call AssetDatabase.SaveAssets() since this would trigger OnPostprocessAllAssets() every time unnecessarily. + populatingMaterials.Add(mat); //atlasAsset.materials[i] = mat; + } + + atlasAsset.materials = populatingMaterials.ToArray(); + + for (int i = 0; i < vestigialMaterials.Count; i++) + AssetDatabase.DeleteAsset(AssetDatabase.GetAssetPath(vestigialMaterials[i])); + + if (AssetDatabase.GetAssetPath(atlasAsset) == "") + AssetDatabase.CreateAsset(atlasAsset, atlasPath); + else + atlasAsset.Clear(); + + atlasAsset.GetAtlas(); + atlasAsset.updateRegionsInPlayMode = true; + + EditorUtility.SetDirty(atlasAsset); + AssetDatabase.SaveAssets(); + + Debug.Log(string.Format("{0} :: Imported with {1} material", atlasAsset.name, atlasAsset.materials.Length), atlasAsset); + + protectFromStackGarbageCollection.Remove(atlasAsset); + return (AtlasAssetBase)AssetDatabase.LoadAssetAtPath(atlasPath, typeof(AtlasAssetBase)); + } + + static bool SetDefaultTextureSettings (string texturePath, SpineAtlasAsset atlasAsset) { + TextureImporter texImporter = (TextureImporter)TextureImporter.GetAtPath(texturePath); + if (texImporter == null) { + Debug.LogWarning(string.Format("{0}: Texture asset \"{1}\" not found. Skipping. Please check your atlas file for renamed files.", atlasAsset.name, texturePath), atlasAsset); + return false; + } + + texImporter.textureCompression = TextureImporterCompression.Uncompressed; + texImporter.alphaSource = TextureImporterAlphaSource.FromInput; + texImporter.mipmapEnabled = false; + texImporter.alphaIsTransparency = false; // Prevent the texture importer from applying bleed to the transparent parts for PMA. + texImporter.spriteImportMode = SpriteImportMode.None; + texImporter.maxTextureSize = 2048; + + EditorUtility.SetDirty(texImporter); + AssetDatabase.ImportAsset(texturePath); + AssetDatabase.SaveAssets(); + return true; + } + +#if NEW_PREFERENCES_SETTINGS_PROVIDER + static bool SetReferenceTextureSettings (string texturePath, SpineAtlasAsset atlasAsset, string referenceAssetPath) { + var texturePreset = AssetDatabase.LoadAssetAtPath(referenceAssetPath); + bool isTexturePreset = texturePreset != null && texturePreset.GetTargetTypeName() == "TextureImporter"; + if (!isTexturePreset) + return SetDefaultTextureSettings(texturePath, atlasAsset); + + TextureImporter texImporter = (TextureImporter)TextureImporter.GetAtPath(texturePath); + if (texImporter == null) { + Debug.LogWarning(string.Format("{0}: Texture asset \"{1}\" not found. Skipping. Please check your atlas file for renamed files.", atlasAsset.name, texturePath), atlasAsset); + return false; + } + + texturePreset.ApplyTo(texImporter); + AssetDatabase.ImportAsset(texturePath); + AssetDatabase.SaveAssets(); + return true; + } +#else + static bool SetReferenceTextureSettings (string texturePath, SpineAtlasAsset atlasAsset, string referenceAssetPath) { + TextureImporter reference = TextureImporter.GetAtPath(referenceAssetPath) as TextureImporter; + if (reference == null) + return SetDefaultTextureSettings(texturePath, atlasAsset); + + TextureImporter texImporter = (TextureImporter)TextureImporter.GetAtPath(texturePath); + if (texImporter == null) { + Debug.LogWarning(string.Format("{0}: Texture asset \"{1}\" not found. Skipping. Please check your atlas file for renamed files.", atlasAsset.name, texturePath), atlasAsset); + return false; + } + + texImporter.sRGBTexture = reference.sRGBTexture; + texImporter.textureCompression = reference.textureCompression; + texImporter.alphaSource = reference.alphaSource; + texImporter.mipmapEnabled = reference.mipmapEnabled; + texImporter.alphaIsTransparency = reference.alphaIsTransparency; + texImporter.spriteImportMode = reference.spriteImportMode; + texImporter.maxTextureSize = reference.maxTextureSize; + texImporter.isReadable = reference.isReadable; + texImporter.filterMode = reference.filterMode; + texImporter.mipmapFilter = reference.mipmapFilter; + texImporter.textureType = reference.textureType; + + EditorUtility.SetDirty(texImporter); + AssetDatabase.ImportAsset(texturePath); + AssetDatabase.SaveAssets(); + return true; + } +#endif + + static void ApplyPMAOrStraightAlphaSettings (Material material, string referenceTextureSettings) { + bool isUsingPMAWorkflow = string.IsNullOrEmpty(referenceTextureSettings) || + (!referenceTextureSettings.ToLower().Contains("straight") && referenceTextureSettings.ToLower().Contains("pma")); + + MaterialChecks.EnablePMAAtMaterial(material, isUsingPMAWorkflow); + } +#endregion + +#region Import SkeletonData (json or binary) + internal static string GetSkeletonDataAssetFilePath(TextAsset spineJson) { + string primaryName = Path.GetFileNameWithoutExtension(spineJson.name); + string assetPath = Path.GetDirectoryName(AssetDatabase.GetAssetPath(spineJson)).Replace('\\', '/'); + return assetPath + "/" + primaryName + SkeletonDataSuffix + ".asset"; + } + + internal static SkeletonDataAsset IngestIncompatibleSpineProject(TextAsset spineJson, + CompatibilityProblemInfo compatibilityProblemInfo) { + + string filePath = GetSkeletonDataAssetFilePath(spineJson); + + if (spineJson == null) + return null; + + SkeletonDataAsset skeletonDataAsset = (SkeletonDataAsset)AssetDatabase.LoadAssetAtPath(filePath, typeof(SkeletonDataAsset)); + if (skeletonDataAsset == null) { + skeletonDataAsset = SkeletonDataAsset.CreateInstance(); + skeletonDataAsset.skeletonJSON = spineJson; + AssetDatabase.CreateAsset(skeletonDataAsset, filePath); + } + EditorUtility.SetDirty(skeletonDataAsset); + + SkeletonDataCompatibility.DisplayCompatibilityProblem(compatibilityProblemInfo.DescriptionString(), spineJson); + return skeletonDataAsset; + } + + internal static SkeletonDataAsset IngestSpineProject (TextAsset spineJson, params AtlasAssetBase[] atlasAssets) { + string filePath = GetSkeletonDataAssetFilePath(spineJson); + +#if SPINE_TK2D + if (spineJson != null) { + SkeletonDataAsset skeletonDataAsset = (SkeletonDataAsset)AssetDatabase.LoadAssetAtPath(filePath, typeof(SkeletonDataAsset)); + if (skeletonDataAsset == null) { + skeletonDataAsset = SkeletonDataAsset.CreateInstance(); + skeletonDataAsset.skeletonJSON = spineJson; + skeletonDataAsset.fromAnimation = new string[0]; + skeletonDataAsset.toAnimation = new string[0]; + skeletonDataAsset.duration = new float[0]; + skeletonDataAsset.defaultMix = SpineEditorUtilities.Preferences.defaultMix; + skeletonDataAsset.scale = SpineEditorUtilities.Preferences.defaultScale; + + AssetDatabase.CreateAsset(skeletonDataAsset, filePath); + AssetDatabase.SaveAssets(); + } else { + skeletonDataAsset.Clear(); + skeletonDataAsset.GetSkeletonData(true); + } + + return skeletonDataAsset; + } else { + EditorUtility.DisplayDialog("Error!", "Tried to ingest null Spine data.", "OK"); + return null; + } + +#else + if (spineJson != null && atlasAssets != null) { + SkeletonDataAsset skeletonDataAsset = (SkeletonDataAsset)AssetDatabase.LoadAssetAtPath(filePath, typeof(SkeletonDataAsset)); + if (skeletonDataAsset == null) { + skeletonDataAsset = ScriptableObject.CreateInstance(); + { + skeletonDataAsset.atlasAssets = atlasAssets; + skeletonDataAsset.skeletonJSON = spineJson; + skeletonDataAsset.defaultMix = SpineEditorUtilities.Preferences.defaultMix; + skeletonDataAsset.scale = SpineEditorUtilities.Preferences.defaultScale; + } + + AssetDatabase.CreateAsset(skeletonDataAsset, filePath); + AssetDatabase.SaveAssets(); + } else { + skeletonDataAsset.atlasAssets = atlasAssets; + skeletonDataAsset.Clear(); + skeletonDataAsset.GetSkeletonData(true); + } + + return skeletonDataAsset; + } else { + EditorUtility.DisplayDialog("Error!", "Must specify both Spine JSON and AtlasAsset array", "OK"); + return null; + } +#endif + } +#endregion + +#region Spine Skeleton Data File Validation + public static bool CheckForValidSkeletonData (string skeletonJSONPath) { + string dir = Path.GetDirectoryName(skeletonJSONPath).Replace('\\', '/'); + TextAsset textAsset = AssetDatabase.LoadAssetAtPath(skeletonJSONPath); + DirectoryInfo dirInfo = new DirectoryInfo(dir); + FileInfo[] files = dirInfo.GetFiles("*.asset"); + + foreach (var path in files) { + string localPath = dir + "/" + path.Name; + var obj = AssetDatabase.LoadAssetAtPath(localPath, typeof(Object)); + var skeletonDataAsset = obj as SkeletonDataAsset; + if (skeletonDataAsset != null && skeletonDataAsset.skeletonJSON == textAsset) + return true; + } + + return false; + } + + public static bool IsSpineData (TextAsset asset, out CompatibilityProblemInfo compatibilityProblemInfo) { + SkeletonDataCompatibility.VersionInfo fileVersion = SkeletonDataCompatibility.GetVersionInfo(asset); + compatibilityProblemInfo = SkeletonDataCompatibility.GetCompatibilityProblemInfo(fileVersion); + return fileVersion != null; + } +#endregion + +#region Dialogs + public static void SkeletonImportDialog (string skeletonPath, List localAtlases, List requiredPaths, ref bool abortSkeletonImport) { + bool resolved = false; + while (!resolved) { + + string filename = Path.GetFileNameWithoutExtension(skeletonPath); + int result = EditorUtility.DisplayDialogComplex( + string.Format("AtlasAsset for \"{0}\"", filename), + string.Format("Could not automatically set the AtlasAsset for \"{0}\".\n\n (You may resolve this manually later.)", filename), + "Resolve atlases...", "Import without atlases", "Stop importing" + ); + + switch (result) { + case -1: + //Debug.Log("Select Atlas"); + AtlasAssetBase selectedAtlas = BrowseAtlasDialog(Path.GetDirectoryName(skeletonPath).Replace('\\', '/')); + if (selectedAtlas != null) { + localAtlases.Clear(); + localAtlases.Add(selectedAtlas); + var atlasMatch = AssetUtility.GetMatchingAtlas(requiredPaths, localAtlases); + if (atlasMatch != null) { + resolved = true; + AssetUtility.IngestSpineProject(AssetDatabase.LoadAssetAtPath(skeletonPath), atlasMatch); + } + } + break; + case 0: // Resolve AtlasAssets... + var atlasList = MultiAtlasDialog(requiredPaths, Path.GetDirectoryName(skeletonPath).Replace('\\', '/'), + Path.GetFileNameWithoutExtension(skeletonPath)); + if (atlasList != null) + AssetUtility.IngestSpineProject(AssetDatabase.LoadAssetAtPath(skeletonPath), atlasList.ToArray()); + + resolved = true; + break; + case 1: // Import without atlas + Debug.LogWarning("Imported with missing atlases. Skeleton will not render: " + Path.GetFileName(skeletonPath)); + AssetUtility.IngestSpineProject(AssetDatabase.LoadAssetAtPath(skeletonPath), new AtlasAssetBase[] { }); + resolved = true; + break; + case 2: // Stop importing all + abortSkeletonImport = true; + resolved = true; + break; + } + } + } + + public static List MultiAtlasDialog (List requiredPaths, string initialDirectory, string filename = "") { + List atlasAssets = new List(); + bool resolved = false; + string lastAtlasPath = initialDirectory; + while (!resolved) { + + // Build dialog box message. + var missingRegions = new List(requiredPaths); + var dialogText = new StringBuilder(); + { + dialogText.AppendLine(string.Format("SkeletonDataAsset for \"{0}\"", filename)); + dialogText.AppendLine("has missing regions."); + dialogText.AppendLine(); + dialogText.AppendLine("Current Atlases:"); + + if (atlasAssets.Count == 0) + dialogText.AppendLine("\t--none--"); + + for (int i = 0; i < atlasAssets.Count; i++) + dialogText.AppendLine("\t" + atlasAssets[i].name); + + dialogText.AppendLine(); + dialogText.AppendLine("Missing Regions:"); + + foreach (var atlasAsset in atlasAssets) { + var atlas = atlasAsset.GetAtlas(); + for (int i = 0; i < missingRegions.Count; i++) { + if (atlas.FindRegion(missingRegions[i]) != null) { + missingRegions.RemoveAt(i); + i--; + } + } + } + + int n = missingRegions.Count; + if (n == 0) + break; + + const int MaxListLength = 15; + for (int i = 0; (i < n && i < MaxListLength); i++) + dialogText.AppendLine(string.Format("\t {0}", missingRegions[i])); + + if (n > MaxListLength) + dialogText.AppendLine(string.Format("\t... {0} more...", n - MaxListLength)); + } + + // Show dialog box. + int result = EditorUtility.DisplayDialogComplex( + "SkeletonDataAsset has missing Atlas.", + dialogText.ToString(), + "Browse Atlas...", "Import anyway", "Cancel import" + ); + + switch (result) { + case 0: // Browse... + AtlasAssetBase selectedAtlasAsset = BrowseAtlasDialog(lastAtlasPath); + if (selectedAtlasAsset != null) { + if (!atlasAssets.Contains(selectedAtlasAsset)) { + var atlas = selectedAtlasAsset.GetAtlas(); + bool hasValidRegion = false; + foreach (string str in missingRegions) { + if (atlas.FindRegion(str) != null) { + hasValidRegion = true; + break; + } + } + atlasAssets.Add(selectedAtlasAsset); + } + } + break; + case 1: // Import anyway + resolved = true; + break; + case 2: // Cancel + atlasAssets = null; + resolved = true; + break; + } + } + + return atlasAssets; + } + + public static AtlasAssetBase BrowseAtlasDialog (string dirPath) { + string path = EditorUtility.OpenFilePanel("Select AtlasAsset...", dirPath, "asset"); + if (path == "") + return null; // Canceled or closed by user. + + int subLen = Application.dataPath.Length - 6; + string assetRelativePath = path.Substring(subLen, path.Length - subLen).Replace("\\", "/"); + + var obj = AssetDatabase.LoadAssetAtPath(assetRelativePath, typeof(AtlasAssetBase)); + if (obj == null || !(obj is AtlasAssetBase)) { + Debug.Log("Chosen asset was not of type AtlasAssetBase"); + return null; + } + + return (AtlasAssetBase)obj; + } +#endregion + + public static string GetPathSafeName (string name) { + foreach (char c in System.IO.Path.GetInvalidFileNameChars()) { // Doesn't handle more obscure file name limitations. + name = name.Replace(c, '_'); + } + return name; + } + } + + public static class EditorInstantiation { + public delegate Component InstantiateDelegate (SkeletonDataAsset skeletonDataAsset); + + public class SkeletonComponentSpawnType { + public string menuLabel; + public InstantiateDelegate instantiateDelegate; + public bool isUI; + } + + internal static readonly List additionalSpawnTypes = new List(); + + public static void TryInitializeSkeletonRendererSettings (SkeletonRenderer skeletonRenderer, Skin skin = null) { + const string PMAShaderQuery = "Spine/Skeleton"; + const string TintBlackShaderQuery = "Tint Black"; + + if (skeletonRenderer == null) return; + var skeletonDataAsset = skeletonRenderer.skeletonDataAsset; + if (skeletonDataAsset == null) return; + + bool pmaVertexColors = false; + bool tintBlack = false; + foreach (AtlasAssetBase atlasAsset in skeletonDataAsset.atlasAssets) { + if (!pmaVertexColors) { + foreach (Material m in atlasAsset.Materials) { + if (m.shader.name.Contains(PMAShaderQuery)) { + pmaVertexColors = true; + break; + } + } + } + + if (!tintBlack) { + foreach (Material m in atlasAsset.Materials) { + if (m.shader.name.Contains(TintBlackShaderQuery)) { + tintBlack = true; + break; + } + } + } + } + + skeletonRenderer.pmaVertexColors = pmaVertexColors; + skeletonRenderer.tintBlack = tintBlack; + skeletonRenderer.zSpacing = SpineEditorUtilities.Preferences.defaultZSpacing; + + var data = skeletonDataAsset.GetSkeletonData(false); + bool noSkins = data.DefaultSkin == null && (data.Skins == null || data.Skins.Count == 0); // Support attachmentless/skinless SkeletonData. + skin = skin ?? data.DefaultSkin ?? (noSkins ? null : data.Skins.Items[0]); + if (skin != null && skin != data.DefaultSkin) { + skeletonRenderer.initialSkinName = skin.Name; + } + } + + public static SkeletonAnimation InstantiateSkeletonAnimation (SkeletonDataAsset skeletonDataAsset, string skinName, + bool destroyInvalid = true, bool useObjectFactory = true) { + + var skeletonData = skeletonDataAsset.GetSkeletonData(true); + var skin = skeletonData != null ? skeletonData.FindSkin(skinName) : null; + return InstantiateSkeletonAnimation(skeletonDataAsset, skin, destroyInvalid, useObjectFactory); + } + + public static SkeletonAnimation InstantiateSkeletonAnimation (SkeletonDataAsset skeletonDataAsset, Skin skin = null, + bool destroyInvalid = true, bool useObjectFactory = true) { + + SkeletonData data = skeletonDataAsset.GetSkeletonData(true); + + if (data == null) { + for (int i = 0; i < skeletonDataAsset.atlasAssets.Length; i++) { + string reloadAtlasPath = AssetDatabase.GetAssetPath(skeletonDataAsset.atlasAssets[i]); + skeletonDataAsset.atlasAssets[i] = (AtlasAssetBase)AssetDatabase.LoadAssetAtPath(reloadAtlasPath, typeof(AtlasAssetBase)); + } + data = skeletonDataAsset.GetSkeletonData(false); + } + + if (data == null) { + Debug.LogWarning("InstantiateSkeletonAnimation tried to instantiate a skeleton from an invalid SkeletonDataAsset.", skeletonDataAsset); + return null; + } + + string spineGameObjectName = string.Format("Spine GameObject ({0})", skeletonDataAsset.name.Replace(AssetUtility.SkeletonDataSuffix, "")); + GameObject go = EditorInstantiation.NewGameObject(spineGameObjectName, useObjectFactory, + typeof(MeshFilter), typeof(MeshRenderer), typeof(SkeletonAnimation)); + SkeletonAnimation newSkeletonAnimation = go.GetComponent(); + newSkeletonAnimation.skeletonDataAsset = skeletonDataAsset; + TryInitializeSkeletonRendererSettings(newSkeletonAnimation, skin); + + // Initialize + try { + newSkeletonAnimation.Initialize(false); + } catch (System.Exception e) { + if (destroyInvalid) { + Debug.LogWarning("Editor-instantiated SkeletonAnimation threw an Exception. Destroying GameObject to prevent orphaned GameObject.\n" + e.Message, skeletonDataAsset); + GameObject.DestroyImmediate(go); + } + throw e; + } + + newSkeletonAnimation.loop = SpineEditorUtilities.Preferences.defaultInstantiateLoop; + newSkeletonAnimation.skeleton.Update(0); + newSkeletonAnimation.state.Update(0); + newSkeletonAnimation.state.Apply(newSkeletonAnimation.skeleton); + newSkeletonAnimation.skeleton.UpdateWorldTransform(); + + return newSkeletonAnimation; + } + + /// Handles creating a new GameObject in the Unity Editor. This uses the new ObjectFactory API where applicable. + public static GameObject NewGameObject (string name, bool useObjectFactory) { +#if NEW_PREFAB_SYSTEM + if (useObjectFactory) + return ObjectFactory.CreateGameObject(name); +#endif + return new GameObject(name); + } + + /// Handles creating a new GameObject in the Unity Editor. This uses the new ObjectFactory API where applicable. + public static GameObject NewGameObject (string name, bool useObjectFactory, params System.Type[] components) { +#if NEW_PREFAB_SYSTEM + if (useObjectFactory) + return ObjectFactory.CreateGameObject(name, components); +#endif + return new GameObject(name, components); + } + + public static void InstantiateEmptySpineGameObject (string name, bool useObjectFactory) where T : MonoBehaviour { + var parentGameObject = Selection.activeObject as GameObject; + var parentTransform = parentGameObject == null ? null : parentGameObject.transform; + + var gameObject = EditorInstantiation.NewGameObject(name, useObjectFactory, typeof(T)); + gameObject.transform.SetParent(parentTransform, false); + EditorUtility.FocusProjectWindow(); + Selection.activeObject = gameObject; + EditorGUIUtility.PingObject(Selection.activeObject); + } + +#region SkeletonMecanim +#if SPINE_SKELETONMECANIM + public static SkeletonMecanim InstantiateSkeletonMecanim (SkeletonDataAsset skeletonDataAsset, string skinName) { + return InstantiateSkeletonMecanim(skeletonDataAsset, skeletonDataAsset.GetSkeletonData(true).FindSkin(skinName)); + } + + public static SkeletonMecanim InstantiateSkeletonMecanim (SkeletonDataAsset skeletonDataAsset, Skin skin = null, + bool destroyInvalid = true, bool useObjectFactory = true) { + SkeletonData data = skeletonDataAsset.GetSkeletonData(true); + + if (data == null) { + for (int i = 0; i < skeletonDataAsset.atlasAssets.Length; i++) { + string reloadAtlasPath = AssetDatabase.GetAssetPath(skeletonDataAsset.atlasAssets[i]); + skeletonDataAsset.atlasAssets[i] = (AtlasAssetBase)AssetDatabase.LoadAssetAtPath(reloadAtlasPath, typeof(AtlasAssetBase)); + } + data = skeletonDataAsset.GetSkeletonData(false); + } + + if (data == null) { + Debug.LogWarning("InstantiateSkeletonMecanim tried to instantiate a skeleton from an invalid SkeletonDataAsset.", skeletonDataAsset); + return null; + } + + string spineGameObjectName = string.Format("Spine Mecanim GameObject ({0})", skeletonDataAsset.name.Replace(AssetUtility.SkeletonDataSuffix, "")); + GameObject go = EditorInstantiation.NewGameObject(spineGameObjectName, useObjectFactory, + typeof(MeshFilter), typeof(MeshRenderer), typeof(Animator), typeof(SkeletonMecanim)); + + if (skeletonDataAsset.controller == null) { + SkeletonBaker.GenerateMecanimAnimationClips(skeletonDataAsset); + Debug.Log(string.Format("Mecanim controller was automatically generated and assigned for {0}", skeletonDataAsset.name), skeletonDataAsset); + } + + go.GetComponent().runtimeAnimatorController = skeletonDataAsset.controller; + + SkeletonMecanim newSkeletonMecanim = go.GetComponent(); + newSkeletonMecanim.skeletonDataAsset = skeletonDataAsset; + TryInitializeSkeletonRendererSettings(newSkeletonMecanim, skin); + + // Initialize + try { + newSkeletonMecanim.Initialize(false); + } catch (System.Exception e) { + if (destroyInvalid) { + Debug.LogWarning("Editor-instantiated SkeletonAnimation threw an Exception. Destroying GameObject to prevent orphaned GameObject.", skeletonDataAsset); + GameObject.DestroyImmediate(go); + } + throw e; + } + + newSkeletonMecanim.skeleton.Update(0); + newSkeletonMecanim.skeleton.UpdateWorldTransform(); + newSkeletonMecanim.LateUpdate(); + + return newSkeletonMecanim; + } +#endif +#endregion + } +} diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/Utility/AssetUtility.cs.meta b/box1/Assets/Spine/Editor/spine-unity/Editor/Utility/AssetUtility.cs.meta new file mode 100644 index 00000000..2f6480e8 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/Utility/AssetUtility.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 49377c72c37e2c149b106c260a241f3c +timeCreated: 1563311043 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/Utility/BuildSettings.cs b/box1/Assets/Spine/Editor/spine-unity/Editor/Utility/BuildSettings.cs new file mode 100644 index 00000000..b3a2156a --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/Utility/BuildSettings.cs @@ -0,0 +1,182 @@ +/****************************************************************************** + * 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. + *****************************************************************************/ + +#pragma warning disable 0219 + +#define SPINE_SKELETONMECANIM + +#if UNITY_2017_2_OR_NEWER +#define NEWPLAYMODECALLBACKS +#endif + +#if UNITY_2018_3 || UNITY_2019 || UNITY_2018_3_OR_NEWER +#define NEW_PREFAB_SYSTEM +#endif + +#if UNITY_2018 || UNITY_2019 || UNITY_2018_3_OR_NEWER +#define NEWHIERARCHYWINDOWCALLBACKS +#endif + +using UnityEngine; +using UnityEditor; +using System.Collections.Generic; +using System.IO; +using System.Text; +using System.Linq; +using System.Reflection; +using System.Globalization; + +namespace Spine.Unity.Editor { + public partial class SpineEditorUtilities { + public static class SpineTK2DEditorUtility { + const string SPINE_TK2D_DEFINE = "SPINE_TK2D"; + + internal static bool IsTK2DInstalled () { + return (Shader.Find("tk2d/SolidVertexColor") != null || + Shader.Find("tk2d/AdditiveVertexColor") != null); + } + + internal static bool IsTK2DAllowed { + get { + return false; // replace with "return true;" to allow TK2D support + } + } + + internal static void EnableTK2D () { + if (!IsTK2DAllowed) + return; + SpineBuildEnvUtility.DisableSpineAsmdefFiles(); + SpineBuildEnvUtility.EnableBuildDefine(SPINE_TK2D_DEFINE); + } + + internal static void DisableTK2D () { + SpineBuildEnvUtility.EnableSpineAsmdefFiles(); + SpineBuildEnvUtility.DisableBuildDefine(SPINE_TK2D_DEFINE); + } + } + } + + public static class SpineBuildEnvUtility + { + static bool IsInvalidGroup (BuildTargetGroup group) { + int gi = (int)group; + return + gi == 15 || gi == 16 + || + group == BuildTargetGroup.Unknown; + } + + public static bool EnableBuildDefine (string define) { + + bool wasDefineAdded = false; + Debug.LogWarning("Please ignore errors \"PlayerSettings Validation: Requested build target group doesn't exist\" below"); + foreach (BuildTargetGroup group in System.Enum.GetValues(typeof(BuildTargetGroup))) { + if (IsInvalidGroup(group)) + continue; + + string defines = PlayerSettings.GetScriptingDefineSymbolsForGroup(group); + if (!defines.Contains(define)) { + wasDefineAdded = true; + if (defines.EndsWith(";", System.StringComparison.Ordinal)) + defines += define; + else + defines += ";" + define; + + PlayerSettings.SetScriptingDefineSymbolsForGroup(group, defines); + } + } + Debug.LogWarning("Please ignore errors \"PlayerSettings Validation: Requested build target group doesn't exist\" above"); + + if (wasDefineAdded) { + Debug.LogWarning("Setting Scripting Define Symbol " + define); + } + else { + Debug.LogWarning("Already Set Scripting Define Symbol " + define); + } + return wasDefineAdded; + } + + public static bool DisableBuildDefine (string define) { + + bool wasDefineRemoved = false; + foreach (BuildTargetGroup group in System.Enum.GetValues(typeof(BuildTargetGroup))) { + if (IsInvalidGroup(group)) + continue; + + string defines = PlayerSettings.GetScriptingDefineSymbolsForGroup(group); + if (defines.Contains(define)) { + wasDefineRemoved = true; + if (defines.Contains(define + ";")) + defines = defines.Replace(define + ";", ""); + else + defines = defines.Replace(define, ""); + + PlayerSettings.SetScriptingDefineSymbolsForGroup(group, defines); + } + } + + if (wasDefineRemoved) { + Debug.LogWarning("Removing Scripting Define Symbol " + define); + } + else { + Debug.LogWarning("Already Removed Scripting Define Symbol " + define); + } + return wasDefineRemoved; + } + + public static void DisableSpineAsmdefFiles () { + SetAsmdefFileActive("spine-unity-editor", false); + SetAsmdefFileActive("spine-unity", false); + } + + public static void EnableSpineAsmdefFiles () { + SetAsmdefFileActive("spine-unity-editor", true); + SetAsmdefFileActive("spine-unity", true); + } + + internal static void SetAsmdefFileActive (string filename, bool setActive) { + + string typeSearchString = setActive ? " t:TextAsset" : " t:AssemblyDefinitionAsset"; + string extensionBeforeChange = setActive ? ".txt" : ".asmdef"; + string[] guids = AssetDatabase.FindAssets(filename + typeSearchString); + foreach (string guid in guids) { + string currentPath = AssetDatabase.GUIDToAssetPath(guid); + if (System.IO.Path.GetExtension(currentPath) != extensionBeforeChange) // asmdef is also found as t:TextAsset, so check + continue; + + string targetPath = System.IO.Path.ChangeExtension(currentPath, setActive ? "asmdef" : "txt"); + if (System.IO.File.Exists(currentPath) && !System.IO.File.Exists(targetPath)) { + System.IO.File.Copy(currentPath, targetPath); + System.IO.File.Copy(currentPath + ".meta", targetPath + ".meta"); + } + AssetDatabase.DeleteAsset(currentPath); + } + } + } +} diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/Utility/BuildSettings.cs.meta b/box1/Assets/Spine/Editor/spine-unity/Editor/Utility/BuildSettings.cs.meta new file mode 100644 index 00000000..87100134 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/Utility/BuildSettings.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 80767dcb23931c645ad70c88670ddeb6 +timeCreated: 1563313275 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/Utility/DataReloadHandler.cs b/box1/Assets/Spine/Editor/spine-unity/Editor/Utility/DataReloadHandler.cs new file mode 100644 index 00000000..59da1974 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/Utility/DataReloadHandler.cs @@ -0,0 +1,133 @@ +/****************************************************************************** + * 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. + *****************************************************************************/ + +#pragma warning disable 0219 + +#define SPINE_SKELETONMECANIM + +#if UNITY_2017_2_OR_NEWER +#define NEWPLAYMODECALLBACKS +#endif + +using UnityEngine; +using UnityEditor; +using System.Collections.Generic; +using System.IO; +using System.Text; +using System.Linq; +using System.Reflection; +using System.Globalization; + +namespace Spine.Unity.Editor { + + public partial class SpineEditorUtilities { + public static class DataReloadHandler { + + internal static Dictionary savedSkeletonDataAssetAtSKeletonGraphicID = new Dictionary(); + + #if NEWPLAYMODECALLBACKS + internal static void OnPlaymodeStateChanged (PlayModeStateChange stateChange) { + #else + internal static void OnPlaymodeStateChanged () { + #endif + ReloadAllActiveSkeletonsEditMode(); + } + + public static void ReloadAllActiveSkeletonsEditMode () { + + if (EditorApplication.isPaused) return; + if (EditorApplication.isPlaying) return; + if (EditorApplication.isCompiling) return; + if (EditorApplication.isPlayingOrWillChangePlaymode) return; + + var skeletonDataAssetsToReload = new HashSet(); + + var activeSkeletonRenderers = GameObject.FindObjectsOfType(); + foreach (var sr in activeSkeletonRenderers) { + var skeletonDataAsset = sr.skeletonDataAsset; + if (skeletonDataAsset != null) skeletonDataAssetsToReload.Add(skeletonDataAsset); + } + + // Under some circumstances (e.g. on first import) SkeletonGraphic objects + // have their skeletonGraphic.skeletonDataAsset reference corrupted + // by the instance of the ScriptableObject being destroyed but still assigned. + // Here we save the skeletonGraphic.skeletonDataAsset asset path in order + // to restore it later. + var activeSkeletonGraphics = GameObject.FindObjectsOfType(); + foreach (var sg in activeSkeletonGraphics) { + var skeletonDataAsset = sg.skeletonDataAsset; + if (skeletonDataAsset != null) { + var assetPath = AssetDatabase.GetAssetPath(skeletonDataAsset); + var sgID = sg.GetInstanceID(); + savedSkeletonDataAssetAtSKeletonGraphicID[sgID] = assetPath; + skeletonDataAssetsToReload.Add(skeletonDataAsset); + } + } + + foreach (var sda in skeletonDataAssetsToReload) { + sda.Clear(); + sda.GetSkeletonData(true); + } + + foreach (var sr in activeSkeletonRenderers) { + var meshRenderer = sr.GetComponent(); + var sharedMaterials = meshRenderer.sharedMaterials; + foreach (var m in sharedMaterials) { + if (m == null) { + sr.Initialize(true); + break; + } + } + } + + foreach (var sg in activeSkeletonGraphics) { + if (sg.mainTexture == null) + sg.Initialize(true); + } + } + + public static void ReloadSceneSkeletonComponents (SkeletonDataAsset skeletonDataAsset) { + if (EditorApplication.isPaused) return; + if (EditorApplication.isPlaying) return; + if (EditorApplication.isCompiling) return; + if (EditorApplication.isPlayingOrWillChangePlaymode) return; + + var activeSkeletonRenderers = GameObject.FindObjectsOfType(); + foreach (var sr in activeSkeletonRenderers) { + if (sr.isActiveAndEnabled && sr.skeletonDataAsset == skeletonDataAsset) sr.Initialize(true); + } + + var activeSkeletonGraphics = GameObject.FindObjectsOfType(); + foreach (var sg in activeSkeletonGraphics) { + if (sg.isActiveAndEnabled && sg.skeletonDataAsset == skeletonDataAsset) sg.Initialize(true); + } + } + } + } +} diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/Utility/DataReloadHandler.cs.meta b/box1/Assets/Spine/Editor/spine-unity/Editor/Utility/DataReloadHandler.cs.meta new file mode 100644 index 00000000..21bfdf21 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/Utility/DataReloadHandler.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: d8a1a76014a68634a8ede50af6db1cae +timeCreated: 1563310382 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/Utility/Icons.cs b/box1/Assets/Spine/Editor/spine-unity/Editor/Utility/Icons.cs new file mode 100644 index 00000000..71e7ce15 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/Utility/Icons.cs @@ -0,0 +1,147 @@ +/****************************************************************************** + * 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. + *****************************************************************************/ + +#pragma warning disable 0219 + +#define SPINE_SKELETONMECANIM + +using UnityEngine; +using UnityEditor; +using System.Collections.Generic; +using System.IO; +using System.Text; +using System.Linq; +using System.Reflection; +using System.Globalization; + +namespace Spine.Unity.Editor { + public partial class SpineEditorUtilities { + public static class Icons { + public static Texture2D skeleton; + public static Texture2D nullBone; + public static Texture2D bone; + public static Texture2D poseBones; + public static Texture2D boneNib; + public static Texture2D slot; + public static Texture2D slotRoot; + public static Texture2D skinPlaceholder; + public static Texture2D image; + public static Texture2D genericAttachment; + public static Texture2D boundingBox; + public static Texture2D point; + public static Texture2D mesh; + public static Texture2D weights; + public static Texture2D path; + public static Texture2D clipping; + public static Texture2D skin; + public static Texture2D skinsRoot; + public static Texture2D animation; + public static Texture2D animationRoot; + public static Texture2D spine; + public static Texture2D userEvent; + public static Texture2D constraintNib; + public static Texture2D constraintRoot; + public static Texture2D constraintTransform; + public static Texture2D constraintPath; + public static Texture2D constraintIK; + public static Texture2D warning; + public static Texture2D skeletonUtility; + public static Texture2D hingeChain; + public static Texture2D subMeshRenderer; + public static Texture2D skeletonDataAssetIcon; + public static Texture2D info; + public static Texture2D unity; + + static Texture2D LoadIcon (string filename) { + return (Texture2D)AssetDatabase.LoadMainAssetAtPath(SpineEditorUtilities.editorGUIPath + "/" + filename); + } + + public static void Initialize () { + skeleton = LoadIcon("icon-skeleton.png"); + nullBone = LoadIcon("icon-null.png"); + bone = LoadIcon("icon-bone.png"); + poseBones = LoadIcon("icon-poseBones.png"); + boneNib = LoadIcon("icon-boneNib.png"); + slot = LoadIcon("icon-slot.png"); + slotRoot = LoadIcon("icon-slotRoot.png"); + skinPlaceholder = LoadIcon("icon-skinPlaceholder.png"); + + genericAttachment = LoadIcon("icon-attachment.png"); + image = LoadIcon("icon-image.png"); + boundingBox = LoadIcon("icon-boundingBox.png"); + point = LoadIcon("icon-point.png"); + mesh = LoadIcon("icon-mesh.png"); + weights = LoadIcon("icon-weights.png"); + path = LoadIcon("icon-path.png"); + clipping = LoadIcon("icon-clipping.png"); + + skin = LoadIcon("icon-skin.png"); + skinsRoot = LoadIcon("icon-skinsRoot.png"); + animation = LoadIcon("icon-animation.png"); + animationRoot = LoadIcon("icon-animationRoot.png"); + spine = LoadIcon("icon-spine.png"); + userEvent = LoadIcon("icon-event.png"); + constraintNib = LoadIcon("icon-constraintNib.png"); + + constraintRoot = LoadIcon("icon-constraints.png"); + constraintTransform = LoadIcon("icon-constraintTransform.png"); + constraintPath = LoadIcon("icon-constraintPath.png"); + constraintIK = LoadIcon("icon-constraintIK.png"); + + warning = LoadIcon("icon-warning.png"); + skeletonUtility = LoadIcon("icon-skeletonUtility.png"); + hingeChain = LoadIcon("icon-hingeChain.png"); + subMeshRenderer = LoadIcon("icon-subMeshRenderer.png"); + + skeletonDataAssetIcon = LoadIcon("SkeletonDataAsset Icon.png"); + + info = EditorGUIUtility.FindTexture("console.infoicon.sml"); + unity = EditorGUIUtility.FindTexture("SceneAsset Icon"); + } + + public static Texture2D GetAttachmentIcon (Attachment attachment) { + // Analysis disable once CanBeReplacedWithTryCastAndCheckForNull + if (attachment is RegionAttachment) + return Icons.image; + else if (attachment is MeshAttachment) + return ((MeshAttachment)attachment).IsWeighted() ? Icons.weights : Icons.mesh; + else if (attachment is BoundingBoxAttachment) + return Icons.boundingBox; + else if (attachment is PointAttachment) + return Icons.point; + else if (attachment is PathAttachment) + return Icons.path; + else if (attachment is ClippingAttachment) + return Icons.clipping; + else + return Icons.warning; + } + } + } +} diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/Utility/Icons.cs.meta b/box1/Assets/Spine/Editor/spine-unity/Editor/Utility/Icons.cs.meta new file mode 100644 index 00000000..c8cf2c28 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/Utility/Icons.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 8603301469b2a284db8eaa26dc60ada8 +timeCreated: 1563312057 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/Utility/Instantiation.cs b/box1/Assets/Spine/Editor/spine-unity/Editor/Utility/Instantiation.cs new file mode 100644 index 00000000..d76a7709 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/Utility/Instantiation.cs @@ -0,0 +1,193 @@ +/****************************************************************************** + * 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. + *****************************************************************************/ + +#pragma warning disable 0219 + +#define SPINE_SKELETONMECANIM + +using UnityEngine; +using UnityEditor; +using System.Collections.Generic; +using System.IO; +using System.Text; +using System.Linq; +using System.Reflection; +using System.Globalization; + +namespace Spine.Unity.Editor { + using EventType = UnityEngine.EventType; + + public partial class SpineEditorUtilities { + public static class DragAndDropInstantiation { + public struct SpawnMenuData { + public Vector3 spawnPoint; + public Transform parent; + public SkeletonDataAsset skeletonDataAsset; + public EditorInstantiation.InstantiateDelegate instantiateDelegate; + public bool isUI; + } + + public static void SceneViewDragAndDrop (SceneView sceneview) { + var current = UnityEngine.Event.current; + var references = DragAndDrop.objectReferences; + if (current.type == EventType.Layout) + return; + + // Allow drag and drop of one SkeletonDataAsset. + if (references.Length == 1) { + var skeletonDataAsset = references[0] as SkeletonDataAsset; + if (skeletonDataAsset != null) { + var mousePos = current.mousePosition; + + bool invalidSkeletonData = skeletonDataAsset.GetSkeletonData(true) == null; + if (invalidSkeletonData) { + DragAndDrop.visualMode = DragAndDropVisualMode.Rejected; + Handles.BeginGUI(); + GUI.Label(new Rect(mousePos + new Vector2(20f, 20f), new Vector2(400f, 40f)), new GUIContent(string.Format("{0} is invalid.\nCannot create new Spine GameObject.", skeletonDataAsset.name), SpineEditorUtilities.Icons.warning)); + Handles.EndGUI(); + return; + } else { + DragAndDrop.visualMode = DragAndDropVisualMode.Copy; + Handles.BeginGUI(); + GUI.Label(new Rect(mousePos + new Vector2(20f, 20f), new Vector2(400f, 20f)), new GUIContent(string.Format("Create Spine GameObject ({0})", skeletonDataAsset.skeletonJSON.name), SpineEditorUtilities.Icons.skeletonDataAssetIcon)); + Handles.EndGUI(); + + if (current.type == EventType.DragPerform) { + RectTransform rectTransform = (Selection.activeGameObject == null) ? null : Selection.activeGameObject.GetComponent(); + Plane plane = (rectTransform == null) ? new Plane(Vector3.back, Vector3.zero) : new Plane(-rectTransform.forward, rectTransform.position); + Vector3 spawnPoint = MousePointToWorldPoint2D(mousePos, sceneview.camera, plane); + ShowInstantiateContextMenu(skeletonDataAsset, spawnPoint, null); + DragAndDrop.AcceptDrag(); + current.Use(); + } + } + } + } + } + + public static void ShowInstantiateContextMenu (SkeletonDataAsset skeletonDataAsset, Vector3 spawnPoint, Transform parent) { + var menu = new GenericMenu(); + + // SkeletonAnimation + menu.AddItem(new GUIContent("SkeletonAnimation"), false, HandleSkeletonComponentDrop, new SpawnMenuData { + skeletonDataAsset = skeletonDataAsset, + spawnPoint = spawnPoint, + parent = parent, + instantiateDelegate = (data) => EditorInstantiation.InstantiateSkeletonAnimation(data), + isUI = false + }); + + // SkeletonGraphic + var skeletonGraphicInspectorType = System.Type.GetType("Spine.Unity.Editor.SkeletonGraphicInspector"); + if (skeletonGraphicInspectorType != null) { + var graphicInstantiateDelegate = skeletonGraphicInspectorType.GetMethod("SpawnSkeletonGraphicFromDrop", BindingFlags.Static | BindingFlags.Public); + if (graphicInstantiateDelegate != null) + menu.AddItem(new GUIContent("SkeletonGraphic (UI)"), false, HandleSkeletonComponentDrop, new SpawnMenuData { + skeletonDataAsset = skeletonDataAsset, + spawnPoint = spawnPoint, + parent = parent, + instantiateDelegate = System.Delegate.CreateDelegate(typeof(EditorInstantiation.InstantiateDelegate), graphicInstantiateDelegate) as EditorInstantiation.InstantiateDelegate, + isUI = true + }); + } + +#if SPINE_SKELETONMECANIM + menu.AddSeparator(""); + // SkeletonMecanim + menu.AddItem(new GUIContent("SkeletonMecanim"), false, HandleSkeletonComponentDrop, new SpawnMenuData { + skeletonDataAsset = skeletonDataAsset, + spawnPoint = spawnPoint, + parent = parent, + instantiateDelegate = (data) => EditorInstantiation.InstantiateSkeletonMecanim(data), + isUI = false + }); +#endif + + menu.ShowAsContext(); + } + + public static void HandleSkeletonComponentDrop (object spawnMenuData) { + var data = (SpawnMenuData)spawnMenuData; + + if (data.skeletonDataAsset.GetSkeletonData(true) == null) { + EditorUtility.DisplayDialog("Invalid SkeletonDataAsset", "Unable to create Spine GameObject.\n\nPlease check your SkeletonDataAsset.", "Ok"); + return; + } + + bool isUI = data.isUI; + + Component newSkeletonComponent = data.instantiateDelegate.Invoke(data.skeletonDataAsset); + GameObject newGameObject = newSkeletonComponent.gameObject; + Transform newTransform = newGameObject.transform; + + var usedParent = data.parent != null ? data.parent.gameObject : isUI ? Selection.activeGameObject : null; + if (usedParent) + newTransform.SetParent(usedParent.transform, false); + + newTransform.position = isUI ? data.spawnPoint : RoundVector(data.spawnPoint, 2); + + if (isUI) { + if (usedParent != null && usedParent.GetComponent() != null) { + ((SkeletonGraphic)newSkeletonComponent).MatchRectTransformWithBounds(); + } + else + Debug.Log("Created a UI Skeleton GameObject not under a RectTransform. It may not be visible until you parent it to a canvas."); + } + + if (!isUI && usedParent != null && usedParent.transform.localScale != Vector3.one) + Debug.Log("New Spine GameObject was parented to a scaled Transform. It may not be the intended size."); + + Selection.activeGameObject = newGameObject; + //EditorGUIUtility.PingObject(newGameObject); // Doesn't work when setting activeGameObject. + Undo.RegisterCreatedObjectUndo(newGameObject, "Create Spine GameObject"); + } + + /// + /// Rounds off vector components to a number of decimal digits. + /// + public static Vector3 RoundVector (Vector3 vector, int digits) { + vector.x = (float)System.Math.Round(vector.x, digits); + vector.y = (float)System.Math.Round(vector.y, digits); + vector.z = (float)System.Math.Round(vector.z, digits); + return vector; + } + + /// + /// Converts a mouse point to a world point on a plane. + /// + static Vector3 MousePointToWorldPoint2D (Vector2 mousePosition, Camera camera, Plane plane) { + var screenPos = new Vector3(mousePosition.x, camera.pixelHeight - mousePosition.y, 0f); + var ray = camera.ScreenPointToRay(screenPos); + float distance; + bool hit = plane.Raycast(ray, out distance); + return ray.GetPoint(distance); + } + } + } +} diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/Utility/Instantiation.cs.meta b/box1/Assets/Spine/Editor/spine-unity/Editor/Utility/Instantiation.cs.meta new file mode 100644 index 00000000..442ea7af --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/Utility/Instantiation.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 94ecc7f73dfc0484e848a0e6a1a11f2b +timeCreated: 1563311945 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/Utility/Preferences.cs b/box1/Assets/Spine/Editor/spine-unity/Editor/Utility/Preferences.cs new file mode 100644 index 00000000..f8af00bf --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/Utility/Preferences.cs @@ -0,0 +1,362 @@ +/****************************************************************************** + * 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. + *****************************************************************************/ + +#pragma warning disable 0219 + +#define SPINE_SKELETONMECANIM + +#if UNITY_2017_2_OR_NEWER +#define NEWPLAYMODECALLBACKS +#endif + +#if UNITY_2018_3 || UNITY_2019 || UNITY_2018_3_OR_NEWER +#define NEW_PREFAB_SYSTEM +#endif + +#if UNITY_2018_3_OR_NEWER +#define NEW_PREFERENCES_SETTINGS_PROVIDER +#endif + +using UnityEngine; +using UnityEditor; +using System.Collections.Generic; +using System.IO; +using System.Text; +using System.Linq; +using System.Reflection; +using System.Globalization; + +namespace Spine.Unity.Editor { + public partial class SpineEditorUtilities { + + #if NEW_PREFERENCES_SETTINGS_PROVIDER + static class SpineSettingsProviderRegistration + { + [SettingsProvider] + public static SettingsProvider CreateSpineSettingsProvider() + { + var provider = new SettingsProvider("Spine", SettingsScope.User) + { + label = "Spine", + guiHandler = (searchContext) => + { + var settings = SpinePreferences.GetOrCreateSettings(); + var serializedSettings = new SerializedObject(settings); + SpinePreferences.HandlePreferencesGUI(serializedSettings); + if (serializedSettings.ApplyModifiedProperties()) + OldPreferences.SaveToEditorPrefs(settings); + }, + + // Populate the search keywords to enable smart search filtering and label highlighting: + keywords = new HashSet(new[] { "Spine", "Preferences", "Skeleton", "Default", "Mix", "Duration" }) + }; + return provider; + } + } + #else + // Preferences entry point + [PreferenceItem("Spine")] + static void PreferencesGUI () { + Preferences.HandlePreferencesGUI(); + } + #endif + + #if NEW_PREFERENCES_SETTINGS_PROVIDER + public static SpinePreferences Preferences { + get { + return SpinePreferences.GetOrCreateSettings(); + } + } + #endif + + #if NEW_PREFERENCES_SETTINGS_PROVIDER + public static class OldPreferences { + #else + public static class Preferences { + #endif + const string DEFAULT_SCALE_KEY = "SPINE_DEFAULT_SCALE"; + public static float defaultScale = SpinePreferences.DEFAULT_DEFAULT_SCALE; + + const string DEFAULT_MIX_KEY = "SPINE_DEFAULT_MIX"; + public static float defaultMix = SpinePreferences.DEFAULT_DEFAULT_MIX; + + const string DEFAULT_SHADER_KEY = "SPINE_DEFAULT_SHADER"; + public static string defaultShader = SpinePreferences.DEFAULT_DEFAULT_SHADER; + + const string DEFAULT_ZSPACING_KEY = "SPINE_DEFAULT_ZSPACING"; + public static float defaultZSpacing = SpinePreferences.DEFAULT_DEFAULT_ZSPACING; + + const string DEFAULT_INSTANTIATE_LOOP_KEY = "SPINE_DEFAULT_INSTANTIATE_LOOP"; + public static bool defaultInstantiateLoop = SpinePreferences.DEFAULT_DEFAULT_INSTANTIATE_LOOP; + + const string SHOW_HIERARCHY_ICONS_KEY = "SPINE_SHOW_HIERARCHY_ICONS"; + public static bool showHierarchyIcons = SpinePreferences.DEFAULT_SHOW_HIERARCHY_ICONS; + + const string SET_TEXTUREIMPORTER_SETTINGS_KEY = "SPINE_SET_TEXTUREIMPORTER_SETTINGS"; + public static bool setTextureImporterSettings = SpinePreferences.DEFAULT_SET_TEXTUREIMPORTER_SETTINGS; + + const string TEXTURE_SETTINGS_REFERENCE_KEY = "SPINE_TEXTURE_SETTINGS_REFERENCE"; + public static string textureSettingsReference = SpinePreferences.DEFAULT_TEXTURE_SETTINGS_REFERENCE; + + const string ATLASTXT_WARNING_KEY = "SPINE_ATLASTXT_WARNING"; + public static bool atlasTxtImportWarning = SpinePreferences.DEFAULT_ATLASTXT_WARNING; + + const string TEXTUREIMPORTER_WARNING_KEY = "SPINE_TEXTUREIMPORTER_WARNING"; + public static bool textureImporterWarning = SpinePreferences.DEFAULT_TEXTUREIMPORTER_WARNING; + + public const float DEFAULT_MIPMAPBIAS = SpinePreferences.DEFAULT_MIPMAPBIAS; + + public const string SCENE_ICONS_SCALE_KEY = "SPINE_SCENE_ICONS_SCALE"; + public static float handleScale = SpinePreferences.DEFAULT_SCENE_ICONS_SCALE; + + const string AUTO_RELOAD_SCENESKELETONS_KEY = "SPINE_AUTO_RELOAD_SCENESKELETONS"; + public static bool autoReloadSceneSkeletons = SpinePreferences.DEFAULT_AUTO_RELOAD_SCENESKELETONS; + + const string MECANIM_EVENT_INCLUDE_FOLDERNAME_KEY = "SPINE_MECANIM_EVENT_INCLUDE_FOLDERNAME"; + public static bool mecanimEventIncludeFolderName = SpinePreferences.DEFAULT_MECANIM_EVENT_INCLUDE_FOLDERNAME; + + const string TIMELINE_USE_BLEND_DURATION_KEY = "SPINE_TIMELINE_USE_BLEND_DURATION_KEY"; + public static bool timelineUseBlendDuration = SpinePreferences.DEFAULT_TIMELINE_USE_BLEND_DURATION; + + + static bool preferencesLoaded = false; + + public static void Load () { + if (preferencesLoaded) + return; + + defaultMix = EditorPrefs.GetFloat(DEFAULT_MIX_KEY, SpinePreferences.DEFAULT_DEFAULT_MIX); + defaultScale = EditorPrefs.GetFloat(DEFAULT_SCALE_KEY, SpinePreferences.DEFAULT_DEFAULT_SCALE); + defaultZSpacing = EditorPrefs.GetFloat(DEFAULT_ZSPACING_KEY, SpinePreferences.DEFAULT_DEFAULT_ZSPACING); + defaultShader = EditorPrefs.GetString(DEFAULT_SHADER_KEY, SpinePreferences.DEFAULT_DEFAULT_SHADER); + showHierarchyIcons = EditorPrefs.GetBool(SHOW_HIERARCHY_ICONS_KEY, SpinePreferences.DEFAULT_SHOW_HIERARCHY_ICONS); + setTextureImporterSettings = EditorPrefs.GetBool(SET_TEXTUREIMPORTER_SETTINGS_KEY, SpinePreferences.DEFAULT_SET_TEXTUREIMPORTER_SETTINGS); + textureSettingsReference = EditorPrefs.GetString(TEXTURE_SETTINGS_REFERENCE_KEY, SpinePreferences.DEFAULT_TEXTURE_SETTINGS_REFERENCE); + autoReloadSceneSkeletons = EditorPrefs.GetBool(AUTO_RELOAD_SCENESKELETONS_KEY, SpinePreferences.DEFAULT_AUTO_RELOAD_SCENESKELETONS); + mecanimEventIncludeFolderName = EditorPrefs.GetBool(MECANIM_EVENT_INCLUDE_FOLDERNAME_KEY, SpinePreferences.DEFAULT_MECANIM_EVENT_INCLUDE_FOLDERNAME); + atlasTxtImportWarning = EditorPrefs.GetBool(ATLASTXT_WARNING_KEY, SpinePreferences.DEFAULT_ATLASTXT_WARNING); + textureImporterWarning = EditorPrefs.GetBool(TEXTUREIMPORTER_WARNING_KEY, SpinePreferences.DEFAULT_TEXTUREIMPORTER_WARNING); + timelineUseBlendDuration = EditorPrefs.GetBool(TIMELINE_USE_BLEND_DURATION_KEY, SpinePreferences.DEFAULT_TIMELINE_USE_BLEND_DURATION); + handleScale = EditorPrefs.GetFloat(SCENE_ICONS_SCALE_KEY, SpinePreferences.DEFAULT_SCENE_ICONS_SCALE); + preferencesLoaded = true; + } + +#if NEW_PREFERENCES_SETTINGS_PROVIDER + public static void CopyOldToNewPreferences(ref SpinePreferences newPreferences) { + newPreferences.defaultMix = EditorPrefs.GetFloat(DEFAULT_MIX_KEY, SpinePreferences.DEFAULT_DEFAULT_MIX); + newPreferences.defaultScale = EditorPrefs.GetFloat(DEFAULT_SCALE_KEY, SpinePreferences.DEFAULT_DEFAULT_SCALE); + newPreferences.defaultZSpacing = EditorPrefs.GetFloat(DEFAULT_ZSPACING_KEY, SpinePreferences.DEFAULT_DEFAULT_ZSPACING); + newPreferences.defaultShader = EditorPrefs.GetString(DEFAULT_SHADER_KEY, SpinePreferences.DEFAULT_DEFAULT_SHADER); + newPreferences.showHierarchyIcons = EditorPrefs.GetBool(SHOW_HIERARCHY_ICONS_KEY, SpinePreferences.DEFAULT_SHOW_HIERARCHY_ICONS); + newPreferences.setTextureImporterSettings = EditorPrefs.GetBool(SET_TEXTUREIMPORTER_SETTINGS_KEY, SpinePreferences.DEFAULT_SET_TEXTUREIMPORTER_SETTINGS); + newPreferences.textureSettingsReference = EditorPrefs.GetString(TEXTURE_SETTINGS_REFERENCE_KEY, SpinePreferences.DEFAULT_TEXTURE_SETTINGS_REFERENCE); + newPreferences.autoReloadSceneSkeletons = EditorPrefs.GetBool(AUTO_RELOAD_SCENESKELETONS_KEY, SpinePreferences.DEFAULT_AUTO_RELOAD_SCENESKELETONS); + newPreferences.mecanimEventIncludeFolderName = EditorPrefs.GetBool(MECANIM_EVENT_INCLUDE_FOLDERNAME_KEY, SpinePreferences.DEFAULT_MECANIM_EVENT_INCLUDE_FOLDERNAME); + newPreferences.atlasTxtImportWarning = EditorPrefs.GetBool(ATLASTXT_WARNING_KEY, SpinePreferences.DEFAULT_ATLASTXT_WARNING); + newPreferences.textureImporterWarning = EditorPrefs.GetBool(TEXTUREIMPORTER_WARNING_KEY, SpinePreferences.DEFAULT_TEXTUREIMPORTER_WARNING); + newPreferences.timelineUseBlendDuration = EditorPrefs.GetBool(TIMELINE_USE_BLEND_DURATION_KEY, SpinePreferences.DEFAULT_TIMELINE_USE_BLEND_DURATION); + newPreferences.handleScale = EditorPrefs.GetFloat(SCENE_ICONS_SCALE_KEY, SpinePreferences.DEFAULT_SCENE_ICONS_SCALE); + } + + public static void SaveToEditorPrefs(SpinePreferences preferences) { + EditorPrefs.SetFloat(DEFAULT_MIX_KEY, preferences.defaultMix); + EditorPrefs.SetFloat(DEFAULT_SCALE_KEY, preferences.defaultScale); + EditorPrefs.SetFloat(DEFAULT_ZSPACING_KEY, preferences.defaultZSpacing); + EditorPrefs.SetString(DEFAULT_SHADER_KEY, preferences.defaultShader); + EditorPrefs.SetBool(SHOW_HIERARCHY_ICONS_KEY, preferences.showHierarchyIcons); + EditorPrefs.SetBool(SET_TEXTUREIMPORTER_SETTINGS_KEY, preferences.setTextureImporterSettings); + EditorPrefs.SetString(TEXTURE_SETTINGS_REFERENCE_KEY, preferences.textureSettingsReference); + EditorPrefs.SetBool(AUTO_RELOAD_SCENESKELETONS_KEY, preferences.autoReloadSceneSkeletons); + EditorPrefs.SetBool(MECANIM_EVENT_INCLUDE_FOLDERNAME_KEY, preferences.mecanimEventIncludeFolderName); + EditorPrefs.SetBool(ATLASTXT_WARNING_KEY, preferences.atlasTxtImportWarning); + EditorPrefs.SetBool(TEXTUREIMPORTER_WARNING_KEY, preferences.textureImporterWarning); + EditorPrefs.SetBool(TIMELINE_USE_BLEND_DURATION_KEY, preferences.timelineUseBlendDuration); + EditorPrefs.SetFloat(SCENE_ICONS_SCALE_KEY, preferences.handleScale); + } +#endif + +#if !NEW_PREFERENCES_SETTINGS_PROVIDER + public static void HandlePreferencesGUI () { + if (!preferencesLoaded) + Load(); + + EditorGUI.BeginChangeCheck(); + showHierarchyIcons = EditorGUILayout.Toggle(new GUIContent("Show Hierarchy Icons", "Show relevant icons on GameObjects with Spine Components on them. Disable this if you have large, complex scenes."), showHierarchyIcons); + if (EditorGUI.EndChangeCheck()) { + EditorPrefs.SetBool(SHOW_HIERARCHY_ICONS_KEY, showHierarchyIcons); + #if NEWPLAYMODECALLBACKS + HierarchyHandler.IconsOnPlaymodeStateChanged(PlayModeStateChange.EnteredEditMode); + #else + HierarchyHandler.IconsOnPlaymodeStateChanged(); + #endif + } + + BoolPrefsField(ref autoReloadSceneSkeletons, AUTO_RELOAD_SCENESKELETONS_KEY, new GUIContent("Auto-reload scene components", "Reloads Skeleton components in the scene whenever their SkeletonDataAsset is modified. This makes it so changes in the SkeletonDataAsset inspector are immediately reflected. This may be slow when your scenes have large numbers of SkeletonRenderers or SkeletonGraphic.")); + + EditorGUILayout.Separator(); + EditorGUILayout.LabelField("Auto-Import Settings", EditorStyles.boldLabel); + { + SpineEditorUtilities.FloatPrefsField(ref defaultMix, DEFAULT_MIX_KEY, new GUIContent("Default Mix", "The Default Mix Duration for newly imported SkeletonDataAssets."), min: 0); + SpineEditorUtilities.FloatPrefsField(ref defaultScale, DEFAULT_SCALE_KEY, new GUIContent("Default SkeletonData Scale", "The Default skeleton import scale for newly imported SkeletonDataAssets."), min: 0.0000001f); + + EditorGUI.BeginChangeCheck(); + var shader = (EditorGUILayout.ObjectField("Default Shader", Shader.Find(defaultShader), typeof(Shader), false) as Shader); + defaultShader = shader != null ? shader.name : SpinePreferences.DEFAULT_DEFAULT_SHADER; + if (EditorGUI.EndChangeCheck()) + EditorPrefs.SetString(DEFAULT_SHADER_KEY, defaultShader); + + SpineEditorUtilities.BoolPrefsField(ref setTextureImporterSettings, SET_TEXTUREIMPORTER_SETTINGS_KEY, new GUIContent("Apply Atlas Texture Settings", "Apply the recommended settings for Texture Importers.")); + SpineEditorUtilities.Texture2DPrefsField(ref textureSettingsReference, TEXTURE_SETTINGS_REFERENCE_KEY, new GUIContent("Atlas Texture Reference Settings", "Apply the selected reference texture import settings at newly imported atlas textures. When exporting atlas textures from Spine with \"Premultiply alpha\" enabled (the default), you can leave it at \"PMAPresetTemplate\". If you have disabled \"Premultiply alpha\", set it to \"StraightAlphaPresetTemplate\". You can also create your own reference texture asset and assign it here.")); + if (string.IsNullOrEmpty(textureSettingsReference)) { + var pmaTextureSettingsReferenceGUIDS = AssetDatabase.FindAssets("PMAPresetTemplate"); + if (pmaTextureSettingsReferenceGUIDS.Length > 0) { + textureSettingsReference = AssetDatabase.GUIDToAssetPath(pmaTextureSettingsReferenceGUIDS[0]); + EditorPrefs.SetString(TEXTURE_SETTINGS_REFERENCE_KEY, textureSettingsReference); + } + } + } + + EditorGUILayout.Space(); + EditorGUILayout.LabelField("Warnings", EditorStyles.boldLabel); + { + SpineEditorUtilities.BoolPrefsField(ref atlasTxtImportWarning, ATLASTXT_WARNING_KEY, new GUIContent("Atlas Extension Warning", "Log a warning and recommendation whenever a `.atlas` file is found.")); + SpineEditorUtilities.BoolPrefsField(ref textureImporterWarning, TEXTUREIMPORTER_WARNING_KEY, new GUIContent("Texture Settings Warning", "Log a warning and recommendation whenever Texture Import Settings are detected that could lead to undesired effects, e.g. white border artifacts.")); + } + + EditorGUILayout.Space(); + EditorGUILayout.LabelField("Editor Instantiation", EditorStyles.boldLabel); + { + EditorGUI.BeginChangeCheck(); + defaultZSpacing = EditorGUILayout.Slider("Default Slot Z-Spacing", defaultZSpacing, -0.1f, 0f); + if (EditorGUI.EndChangeCheck()) + EditorPrefs.SetFloat(DEFAULT_ZSPACING_KEY, defaultZSpacing); + + SpineEditorUtilities.BoolPrefsField(ref defaultInstantiateLoop, DEFAULT_INSTANTIATE_LOOP_KEY, new GUIContent("Default Loop", "Spawn Spine GameObjects with loop enabled.")); + } + + EditorGUILayout.Space(); + EditorGUILayout.LabelField("Mecanim Bake Settings", EditorStyles.boldLabel); + { + SpineEditorUtilities.BoolPrefsField(ref mecanimEventIncludeFolderName, MECANIM_EVENT_INCLUDE_FOLDERNAME_KEY, new GUIContent("Include Folder Name in Event", "When enabled, Mecanim events will call methods named 'FolderNameEventName', when disabled it will call 'EventName'.")); + } + + EditorGUILayout.Space(); + EditorGUILayout.LabelField("Handles and Gizmos", EditorStyles.boldLabel); + { + EditorGUI.BeginChangeCheck(); + handleScale = EditorGUILayout.Slider("Editor Bone Scale", handleScale, 0.01f, 2f); + handleScale = Mathf.Max(0.01f, handleScale); + if (EditorGUI.EndChangeCheck()) { + EditorPrefs.SetFloat(SCENE_ICONS_SCALE_KEY, handleScale); + SceneView.RepaintAll(); + } + } + + #if SPINE_TK2D_DEFINE + bool isTK2DDefineSet = true; + #else + bool isTK2DDefineSet = false; + #endif + bool isTK2DAllowed = SpineTK2DEditorUtility.IsTK2DAllowed; + if (SpineTK2DEditorUtility.IsTK2DInstalled() || isTK2DDefineSet) { + GUILayout.Space(20); + EditorGUILayout.LabelField("3rd Party Settings", EditorStyles.boldLabel); + using (new GUILayout.HorizontalScope()) { + EditorGUILayout.PrefixLabel("Define TK2D"); + if (isTK2DAllowed && GUILayout.Button("Enable", GUILayout.Width(64))) + SpineTK2DEditorUtility.EnableTK2D(); + if (GUILayout.Button("Disable", GUILayout.Width(64))) + SpineTK2DEditorUtility.DisableTK2D(); + } + #if !SPINE_TK2D_DEFINE + if (!isTK2DAllowed) { + EditorGUILayout.LabelField("To allow TK2D support, please modify line 67 in", EditorStyles.boldLabel); + EditorGUILayout.LabelField("Spine/Editor/spine-unity/Editor/Util./BuildSettings.cs", EditorStyles.boldLabel); + } + #endif + } + + GUILayout.Space(20); + EditorGUILayout.LabelField("Timeline Extension", EditorStyles.boldLabel); + { + SpineEditorUtilities.BoolPrefsField(ref timelineUseBlendDuration, TIMELINE_USE_BLEND_DURATION_KEY, new GUIContent("Use Blend Duration", "When enabled, MixDuration will be synced with timeline clip transition duration 'Ease In Duration'.")); + } + } + #endif // !NEW_PREFERENCES_SETTINGS_PROVIDER + } + + static void BoolPrefsField (ref bool currentValue, string editorPrefsKey, GUIContent label) { + EditorGUI.BeginChangeCheck(); + currentValue = EditorGUILayout.Toggle(label, currentValue); + if (EditorGUI.EndChangeCheck()) + EditorPrefs.SetBool(editorPrefsKey, currentValue); + } + + static void FloatPrefsField (ref float currentValue, string editorPrefsKey, GUIContent label, float min = float.NegativeInfinity, float max = float.PositiveInfinity) { + EditorGUI.BeginChangeCheck(); + currentValue = EditorGUILayout.DelayedFloatField(label, currentValue); + if (EditorGUI.EndChangeCheck()) { + currentValue = Mathf.Clamp(currentValue, min, max); + EditorPrefs.SetFloat(editorPrefsKey, currentValue); + } + } + + static void Texture2DPrefsField (ref string currentValue, string editorPrefsKey, GUIContent label) { + EditorGUI.BeginChangeCheck(); + EditorGUIUtility.wideMode = true; + var texture = (EditorGUILayout.ObjectField(label, AssetDatabase.LoadAssetAtPath(currentValue), typeof(Object), false) as Texture2D); + currentValue = texture != null ? AssetDatabase.GetAssetPath(texture) : ""; + if (EditorGUI.EndChangeCheck()) { + EditorPrefs.SetString(editorPrefsKey, currentValue); + } + } + + public static void FloatPropertyField (SerializedProperty property, GUIContent label, float min = float.NegativeInfinity, float max = float.PositiveInfinity) { + EditorGUI.BeginChangeCheck(); + property.floatValue = EditorGUILayout.DelayedFloatField(label, property.floatValue); + if (EditorGUI.EndChangeCheck()) { + property.floatValue = Mathf.Clamp(property.floatValue, min, max); + } + } + + public static void ShaderPropertyField (SerializedProperty property, GUIContent label, string fallbackShaderName) { + var shader = (EditorGUILayout.ObjectField(label, Shader.Find(property.stringValue), typeof(Shader), false) as Shader); + property.stringValue = shader != null ? shader.name : fallbackShaderName; + } + + + #if NEW_PREFERENCES_SETTINGS_PROVIDER + public static void PresetAssetPropertyField (SerializedProperty property, GUIContent label) { + var texturePreset = (EditorGUILayout.ObjectField(label, AssetDatabase.LoadAssetAtPath(property.stringValue), typeof(UnityEditor.Presets.Preset), false) as UnityEditor.Presets.Preset); + bool isTexturePreset = texturePreset != null && texturePreset.GetTargetTypeName() == "TextureImporter"; + property.stringValue = isTexturePreset ? AssetDatabase.GetAssetPath(texturePreset) : ""; + } + #endif + } +} diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/Utility/Preferences.cs.meta b/box1/Assets/Spine/Editor/spine-unity/Editor/Utility/Preferences.cs.meta new file mode 100644 index 00000000..3c2d5ac3 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/Utility/Preferences.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 6d80c945a2e3436459a97b7a9a16ef46 +timeCreated: 1563311495 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/Utility/SpineEditorUtilities.cs b/box1/Assets/Spine/Editor/spine-unity/Editor/Utility/SpineEditorUtilities.cs new file mode 100644 index 00000000..fe841c71 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/Utility/SpineEditorUtilities.cs @@ -0,0 +1,442 @@ +/****************************************************************************** + * 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. + *****************************************************************************/ + +#pragma warning disable 0219 +#pragma warning disable 0618 // for 3.7 branch only. Avoids "PreferenceItem' is obsolete: '[PreferenceItem] is deprecated. Use [SettingsProvider] instead." + +// Original contribution by: Mitch Thompson + +#define SPINE_SKELETONMECANIM + +#if UNITY_2017_2_OR_NEWER +#define NEWPLAYMODECALLBACKS +#endif + +#if UNITY_2018 || UNITY_2019 || UNITY_2018_3_OR_NEWER +#define NEWHIERARCHYWINDOWCALLBACKS +#endif + +#if UNITY_2018_3_OR_NEWER +#define NEW_PREFERENCES_SETTINGS_PROVIDER +#endif + +#if UNITY_2017_1_OR_NEWER +#define BUILT_IN_SPRITE_MASK_COMPONENT +#endif + +using UnityEngine; +using UnityEditor; +using System.Collections.Generic; +using System.IO; +using System.Text; +using System.Linq; +using System.Reflection; +using System.Globalization; + +namespace Spine.Unity.Editor { + using EventType = UnityEngine.EventType; + + // Analysis disable once ConvertToStaticType + [InitializeOnLoad] + public partial class SpineEditorUtilities : AssetPostprocessor { + + public static string editorPath = ""; + public static string editorGUIPath = ""; + public static bool initialized; + private static List texturesWithoutMetaFile = new List(); + + // Auto-import entry point for textures + void OnPreprocessTexture () { + #if UNITY_2018_1_OR_NEWER + bool customTextureSettingsExist = !assetImporter.importSettingsMissing; + #else + bool customTextureSettingsExist = System.IO.File.Exists(assetImporter.assetPath + ".meta"); + #endif + if (!customTextureSettingsExist) { + texturesWithoutMetaFile.Add(assetImporter.assetPath); + } + } + + // Auto-import post process entry point for all assets + static void OnPostprocessAllAssets (string[] imported, string[] deleted, string[] moved, string[] movedFromAssetPaths) { + if (imported.Length == 0) + return; + + // we copy the list here to prevent nested calls to OnPostprocessAllAssets() triggering a Clear() of the list + // in the middle of execution. + var texturesWithoutMetaFileCopy = new List(texturesWithoutMetaFile); + AssetUtility.HandleOnPostprocessAllAssets(imported, texturesWithoutMetaFileCopy); + texturesWithoutMetaFile.Clear(); + } + +#region Initialization + static SpineEditorUtilities () { + Initialize(); + } + + static void Initialize () { + // Note: Preferences need to be loaded when changing play mode + // to initialize handle scale correctly. + #if !NEW_PREFERENCES_SETTINGS_PROVIDER + Preferences.Load(); + #else + SpinePreferences.Load(); + #endif + + if (EditorApplication.isPlayingOrWillChangePlaymode) return; + + string[] assets = AssetDatabase.FindAssets("t:script SpineEditorUtilities"); + string assetPath = AssetDatabase.GUIDToAssetPath(assets[0]); + editorPath = Path.GetDirectoryName(assetPath).Replace('\\', '/'); + + assets = AssetDatabase.FindAssets("t:texture icon-subMeshRenderer"); + if (assets.Length > 0) { + assetPath = AssetDatabase.GUIDToAssetPath(assets[0]); + editorGUIPath = Path.GetDirectoryName(assetPath).Replace('\\', '/'); + } + else { + editorGUIPath = editorPath.Replace("/Utility", "/GUI"); + } + Icons.Initialize(); + + // Drag and Drop + #if UNITY_2019_1_OR_NEWER + SceneView.duringSceneGui -= DragAndDropInstantiation.SceneViewDragAndDrop; + SceneView.duringSceneGui += DragAndDropInstantiation.SceneViewDragAndDrop; + #else + SceneView.onSceneGUIDelegate -= DragAndDropInstantiation.SceneViewDragAndDrop; + SceneView.onSceneGUIDelegate += DragAndDropInstantiation.SceneViewDragAndDrop; + #endif + + EditorApplication.hierarchyWindowItemOnGUI -= HierarchyHandler.HandleDragAndDrop; + EditorApplication.hierarchyWindowItemOnGUI += HierarchyHandler.HandleDragAndDrop; + + // Hierarchy Icons + #if NEWPLAYMODECALLBACKS + EditorApplication.playModeStateChanged -= HierarchyHandler.IconsOnPlaymodeStateChanged; + EditorApplication.playModeStateChanged += HierarchyHandler.IconsOnPlaymodeStateChanged; + HierarchyHandler.IconsOnPlaymodeStateChanged(PlayModeStateChange.EnteredEditMode); + #else + EditorApplication.playmodeStateChanged -= HierarchyHandler.IconsOnPlaymodeStateChanged; + EditorApplication.playmodeStateChanged += HierarchyHandler.IconsOnPlaymodeStateChanged; + HierarchyHandler.IconsOnPlaymodeStateChanged(); + #endif + + // Data Refresh Edit Mode. + // This prevents deserialized SkeletonData from persisting from play mode to edit mode. + #if NEWPLAYMODECALLBACKS + EditorApplication.playModeStateChanged -= DataReloadHandler.OnPlaymodeStateChanged; + EditorApplication.playModeStateChanged += DataReloadHandler.OnPlaymodeStateChanged; + DataReloadHandler.OnPlaymodeStateChanged(PlayModeStateChange.EnteredEditMode); + #else + EditorApplication.playmodeStateChanged -= DataReloadHandler.OnPlaymodeStateChanged; + EditorApplication.playmodeStateChanged += DataReloadHandler.OnPlaymodeStateChanged; + DataReloadHandler.OnPlaymodeStateChanged(); + #endif + + if (SpineEditorUtilities.Preferences.textureImporterWarning) { + IssueWarningsForUnrecommendedTextureSettings(); + } + + initialized = true; + } + + public static void ConfirmInitialization () { + if (!initialized || Icons.skeleton == null) + Initialize(); + } + + public static void IssueWarningsForUnrecommendedTextureSettings() { + + string[] atlasDescriptionGUIDs = AssetDatabase.FindAssets("t:textasset .atlas"); // Note: finds ".atlas.txt" but also ".atlas 1.txt" files. + for (int i = 0; i < atlasDescriptionGUIDs.Length; ++i) { + string atlasDescriptionPath = AssetDatabase.GUIDToAssetPath(atlasDescriptionGUIDs[i]); + if (!atlasDescriptionPath.EndsWith(".atlas.txt")) + continue; + + string texturePath = atlasDescriptionPath.Replace(".atlas.txt", ".png"); + + bool textureExists = IssueWarningsForUnrecommendedTextureSettings(texturePath); + if (!textureExists) { + texturePath = texturePath.Replace(".png", ".jpg"); + textureExists = IssueWarningsForUnrecommendedTextureSettings(texturePath); + } + if (!textureExists) { + continue; + } + } + } + + public static void ReloadSkeletonDataAssetAndComponent (SkeletonRenderer component) { + if (component == null) return; + ReloadSkeletonDataAsset(component.skeletonDataAsset); + ReinitializeComponent(component); + } + + public static void ReloadSkeletonDataAssetAndComponent (SkeletonGraphic component) { + if (component == null) return; + ReloadSkeletonDataAsset(component.skeletonDataAsset); + // Reinitialize. + ReinitializeComponent(component); + } + + public static void ReloadSkeletonDataAsset (SkeletonDataAsset skeletonDataAsset) { + if (skeletonDataAsset != null) { + foreach (AtlasAssetBase aa in skeletonDataAsset.atlasAssets) { + if (aa != null) aa.Clear(); + } + skeletonDataAsset.Clear(); + } + skeletonDataAsset.GetSkeletonData(true); + } + + public static void ReinitializeComponent (SkeletonRenderer component) { + if (component == null) return; + if (!SkeletonDataAssetIsValid(component.SkeletonDataAsset)) return; + + var stateComponent = component as IAnimationStateComponent; + AnimationState oldAnimationState = null; + if (stateComponent != null) { + oldAnimationState = stateComponent.AnimationState; + } + + component.Initialize(true); // implicitly clears any subscribers + + if (oldAnimationState != null) { + stateComponent.AnimationState.AssignEventSubscribersFrom(oldAnimationState); + } + + #if BUILT_IN_SPRITE_MASK_COMPONENT + SpineMaskUtilities.EditorAssignSpriteMaskMaterials(component); + #endif + component.LateUpdate(); + } + + public static void ReinitializeComponent (SkeletonGraphic component) { + if (component == null) return; + if (!SkeletonDataAssetIsValid(component.SkeletonDataAsset)) return; + component.Initialize(true); + component.LateUpdate(); + } + + public static bool SkeletonDataAssetIsValid (SkeletonDataAsset asset) { + return asset != null && asset.GetSkeletonData(quiet: true) != null; + } + + public static bool IssueWarningsForUnrecommendedTextureSettings(string texturePath) + { + TextureImporter texImporter = (TextureImporter)TextureImporter.GetAtPath(texturePath); + if (texImporter == null) { + return false; + } + + int extensionPos = texturePath.LastIndexOf('.'); + string materialPath = texturePath.Substring(0, extensionPos) + "_Material.mat"; + Material material = AssetDatabase.LoadAssetAtPath(materialPath); + + if (material == null) + return true; + + string errorMessage = null; + if (MaterialChecks.IsTextureSetupProblematic(material, PlayerSettings.colorSpace, + texImporter. sRGBTexture, texImporter. mipmapEnabled, texImporter. alphaIsTransparency, + texturePath, materialPath, ref errorMessage)) { + Debug.LogWarning(errorMessage, material); + } + return true; + } + #endregion + + public static class HierarchyHandler { + static Dictionary skeletonRendererTable = new Dictionary(); + static Dictionary skeletonUtilityBoneTable = new Dictionary(); + static Dictionary boundingBoxFollowerTable = new Dictionary(); + +#if NEWPLAYMODECALLBACKS + internal static void IconsOnPlaymodeStateChanged (PlayModeStateChange stateChange) { +#else + internal static void IconsOnPlaymodeStateChanged () { +#endif + skeletonRendererTable.Clear(); + skeletonUtilityBoneTable.Clear(); + boundingBoxFollowerTable.Clear(); + +#if NEWHIERARCHYWINDOWCALLBACKS + EditorApplication.hierarchyChanged -= IconsOnChanged; +#else + EditorApplication.hierarchyWindowChanged -= IconsOnChanged; +#endif + EditorApplication.hierarchyWindowItemOnGUI -= IconsOnGUI; + + if (!Application.isPlaying && Preferences.showHierarchyIcons) { +#if NEWHIERARCHYWINDOWCALLBACKS + EditorApplication.hierarchyChanged += IconsOnChanged; +#else + EditorApplication.hierarchyWindowChanged += IconsOnChanged; +#endif + EditorApplication.hierarchyWindowItemOnGUI += IconsOnGUI; + IconsOnChanged(); + } + } + + internal static void IconsOnChanged () { + skeletonRendererTable.Clear(); + skeletonUtilityBoneTable.Clear(); + boundingBoxFollowerTable.Clear(); + + SkeletonRenderer[] arr = Object.FindObjectsOfType(); + foreach (SkeletonRenderer r in arr) + skeletonRendererTable[r.gameObject.GetInstanceID()] = r.gameObject; + + SkeletonUtilityBone[] boneArr = Object.FindObjectsOfType(); + foreach (SkeletonUtilityBone b in boneArr) + skeletonUtilityBoneTable[b.gameObject.GetInstanceID()] = b; + + BoundingBoxFollower[] bbfArr = Object.FindObjectsOfType(); + foreach (BoundingBoxFollower bbf in bbfArr) + boundingBoxFollowerTable[bbf.gameObject.GetInstanceID()] = bbf; + } + + internal static void IconsOnGUI (int instanceId, Rect selectionRect) { + Rect r = new Rect(selectionRect); + if (skeletonRendererTable.ContainsKey(instanceId)) { + r.x = r.width - 15; + r.width = 15; + GUI.Label(r, Icons.spine); + } else if (skeletonUtilityBoneTable.ContainsKey(instanceId)) { + r.x -= 26; + if (skeletonUtilityBoneTable[instanceId] != null) { + if (skeletonUtilityBoneTable[instanceId].transform.childCount == 0) + r.x += 13; + r.y += 2; + r.width = 13; + r.height = 13; + if (skeletonUtilityBoneTable[instanceId].mode == SkeletonUtilityBone.Mode.Follow) + GUI.DrawTexture(r, Icons.bone); + else + GUI.DrawTexture(r, Icons.poseBones); + } + } else if (boundingBoxFollowerTable.ContainsKey(instanceId)) { + r.x -= 26; + if (boundingBoxFollowerTable[instanceId] != null) { + if (boundingBoxFollowerTable[instanceId].transform.childCount == 0) + r.x += 13; + r.y += 2; + r.width = 13; + r.height = 13; + GUI.DrawTexture(r, Icons.boundingBox); + } + } + } + + internal static void HandleDragAndDrop (int instanceId, Rect selectionRect) { + // HACK: Uses EditorApplication.hierarchyWindowItemOnGUI. + // Only works when there is at least one item in the scene. + var current = UnityEngine.Event.current; + var eventType = current.type; + bool isDraggingEvent = eventType == EventType.DragUpdated; + bool isDropEvent = eventType == EventType.DragPerform; + UnityEditor.DragAndDrop.visualMode = DragAndDropVisualMode.Copy; + + if (isDraggingEvent || isDropEvent) { + var mouseOverWindow = EditorWindow.mouseOverWindow; + if (mouseOverWindow != null) { + + // One, existing, valid SkeletonDataAsset + var references = UnityEditor.DragAndDrop.objectReferences; + if (references.Length == 1) { + var skeletonDataAsset = references[0] as SkeletonDataAsset; + if (skeletonDataAsset != null && skeletonDataAsset.GetSkeletonData(true) != null) { + + // Allow drag-and-dropping anywhere in the Hierarchy Window. + // HACK: string-compare because we can't get its type via reflection. + const string HierarchyWindow = "UnityEditor.SceneHierarchyWindow"; + const string GenericDataTargetID = "target"; + if (HierarchyWindow.Equals(mouseOverWindow.GetType().ToString(), System.StringComparison.Ordinal)) { + if (isDraggingEvent) { + var mouseOverTarget = UnityEditor.EditorUtility.InstanceIDToObject(instanceId); + if (mouseOverTarget) + DragAndDrop.SetGenericData(GenericDataTargetID, mouseOverTarget); + // Note: do not call current.Use(), otherwise we get the wrong drop-target parent. + } else if (isDropEvent) { + var parentGameObject = DragAndDrop.GetGenericData(GenericDataTargetID) as UnityEngine.GameObject; + Transform parent = parentGameObject != null ? parentGameObject.transform : null; + // when dragging into empty space in hierarchy below last node, last node would be parent. + if (IsLastNodeInHierarchy(parent)) + parent = null; + DragAndDropInstantiation.ShowInstantiateContextMenu(skeletonDataAsset, Vector3.zero, parent); + UnityEditor.DragAndDrop.AcceptDrag(); + current.Use(); + return; + } + } + } + } + } + } + } + + internal static bool IsLastNodeInHierarchy (Transform node) { + if (node == null) + return false; + + while (node.parent != null) { + if (node.GetSiblingIndex() != node.parent.childCount - 1) + return false; + node = node.parent; + } + + var rootNodes = UnityEngine.SceneManagement.SceneManager.GetActiveScene().GetRootGameObjects(); + bool isLastNode = (rootNodes.Length > 0 && rootNodes[rootNodes.Length - 1].transform == node); + return isLastNode; + } + } + } + + public class TextureModificationWarningProcessor : UnityEditor.AssetModificationProcessor + { + static string[] OnWillSaveAssets(string[] paths) + { + if (SpineEditorUtilities.Preferences.textureImporterWarning) { + foreach (string path in paths) { + if ((path != null) && + (path.EndsWith(".png.meta", System.StringComparison.Ordinal) || + path.EndsWith(".jpg.meta", System.StringComparison.Ordinal))) { + + string texturePath = System.IO.Path.ChangeExtension(path, null); // .meta removed + string atlasPath = System.IO.Path.ChangeExtension(texturePath, "atlas.txt"); + if (System.IO.File.Exists(atlasPath)) + SpineEditorUtilities.IssueWarningsForUnrecommendedTextureSettings(texturePath); + } + } + } + return paths; + } + } +} diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/Utility/SpineEditorUtilities.cs.meta b/box1/Assets/Spine/Editor/spine-unity/Editor/Utility/SpineEditorUtilities.cs.meta new file mode 100644 index 00000000..544e4776 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/Utility/SpineEditorUtilities.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: f834d5cd806ec4645915ac315edbdc60 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/Utility/SpineHandles.cs b/box1/Assets/Spine/Editor/spine-unity/Editor/Utility/SpineHandles.cs new file mode 100644 index 00000000..84f38278 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/Utility/SpineHandles.cs @@ -0,0 +1,501 @@ +/****************************************************************************** + * 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. + *****************************************************************************/ + +#pragma warning disable 0219 + +#define SPINE_SKELETONMECANIM + +using UnityEngine; +using UnityEditor; +using System.Collections.Generic; +using System.IO; +using System.Text; +using System.Linq; +using System.Reflection; +using System.Globalization; + +namespace Spine.Unity.Editor { + using EventType = UnityEngine.EventType; + + public static class SpineHandles { + public static Color BoneColor { get { return new Color(0.8f, 0.8f, 0.8f, 0.4f); } } + public static Color PathColor { get { return new Color(254/255f, 127/255f, 0); } } + public static Color TransformContraintColor { get { return new Color(170/255f, 226/255f, 35/255f); } } + public static Color IkColor { get { return new Color(228/255f,90/255f,43/255f); } } + public static Color PointColor { get { return new Color(1f, 1f, 0f, 1f); } } + + static Vector3[] _boneMeshVerts = { + new Vector3(0, 0, 0), + new Vector3(0.1f, 0.1f, 0), + new Vector3(1, 0, 0), + new Vector3(0.1f, -0.1f, 0) + }; + static Mesh _boneMesh; + public static Mesh BoneMesh { + get { + if (_boneMesh == null) { + _boneMesh = new Mesh { + vertices = _boneMeshVerts, + uv = new Vector2[4], + triangles = new [] { 0, 1, 2, 2, 3, 0 } + }; + _boneMesh.RecalculateBounds(); + _boneMesh.RecalculateNormals(); + } + return _boneMesh; + } + } + + static Mesh _arrowheadMesh; + public static Mesh ArrowheadMesh { + get { + if (_arrowheadMesh == null) { + _arrowheadMesh = new Mesh { + vertices = new [] { + new Vector3(0, 0), + new Vector3(-0.1f, 0.05f), + new Vector3(-0.1f, -0.05f) + }, + uv = new Vector2[3], + triangles = new [] { 0, 1, 2 } + }; + _arrowheadMesh.RecalculateBounds(); + _arrowheadMesh.RecalculateNormals(); + } + return _arrowheadMesh; + } + } + + static Material _boneMaterial; + static Material BoneMaterial { + get { + if (_boneMaterial == null) { + _boneMaterial = new Material(Shader.Find("Hidden/Spine/Bones")); + _boneMaterial.SetColor("_Color", SpineHandles.BoneColor); + } + + return _boneMaterial; + } + } + public static Material GetBoneMaterial () { + BoneMaterial.SetColor("_Color", SpineHandles.BoneColor); + return BoneMaterial; + } + + public static Material GetBoneMaterial (Color color) { + BoneMaterial.SetColor("_Color", color); + return BoneMaterial; + } + + static Material _ikMaterial; + public static Material IKMaterial { + get { + if (_ikMaterial == null) { + _ikMaterial = new Material(Shader.Find("Hidden/Spine/Bones")); + _ikMaterial.SetColor("_Color", SpineHandles.IkColor); + } + return _ikMaterial; + } + } + + static GUIStyle _boneNameStyle; + public static GUIStyle BoneNameStyle { + get { + if (_boneNameStyle == null) { + _boneNameStyle = new GUIStyle(EditorStyles.whiteMiniLabel) { + alignment = TextAnchor.MiddleCenter, + stretchWidth = true, + padding = new RectOffset(0, 0, 0, 0), + contentOffset = new Vector2(-5f, 0f) + }; + } + return _boneNameStyle; + } + } + + static GUIStyle _pathNameStyle; + public static GUIStyle PathNameStyle { + get { + if (_pathNameStyle == null) { + _pathNameStyle = new GUIStyle(SpineHandles.BoneNameStyle); + _pathNameStyle.normal.textColor = SpineHandles.PathColor; + } + return _pathNameStyle; + } + } + + static GUIStyle _pointNameStyle; + public static GUIStyle PointNameStyle { + get { + if (_pointNameStyle == null) { + _pointNameStyle = new GUIStyle(SpineHandles.BoneNameStyle); + _pointNameStyle.normal.textColor = SpineHandles.PointColor; + } + return _pointNameStyle; + } + } + + public static void DrawBoneNames (Transform transform, Skeleton skeleton, float positionScale = 1f) { + GUIStyle style = BoneNameStyle; + foreach (Bone b in skeleton.Bones) { + if (!b.Active) continue; + var pos = new Vector3(b.WorldX * positionScale, b.WorldY * positionScale, 0) + (new Vector3(b.A, b.C) * (b.Data.Length * 0.5f)); + pos = transform.TransformPoint(pos); + Handles.Label(pos, b.Data.Name, style); + } + } + + public static void DrawBones (Transform transform, Skeleton skeleton, float positionScale = 1f) { + float boneScale = 1.8f; // Draw the root bone largest; + DrawCrosshairs2D(skeleton.Bones.Items[0].GetWorldPosition(transform), 0.08f, positionScale); + + foreach (Bone b in skeleton.Bones) { + if (!b.Active) continue; + DrawBone(transform, b, boneScale, positionScale); + boneScale = 1f; + } + } + + static Vector3[] _boneWireBuffer = new Vector3[5]; + static Vector3[] GetBoneWireBuffer (Matrix4x4 m) { + for (int i = 0, n = _boneMeshVerts.Length; i < n; i++) + _boneWireBuffer[i] = m.MultiplyPoint(_boneMeshVerts[i]); + + _boneWireBuffer[4] = _boneWireBuffer[0]; // closed polygon. + return _boneWireBuffer; + } + public static void DrawBoneWireframe (Transform transform, Bone b, Color color, float skeletonRenderScale = 1f) { + Handles.color = color; + var pos = new Vector3(b.WorldX * skeletonRenderScale, b.WorldY * skeletonRenderScale, 0); + float length = b.Data.Length; + + if (length > 0) { + Quaternion rot = Quaternion.Euler(0, 0, b.WorldRotationX); + Vector3 scale = Vector3.one * length * b.WorldScaleX * skeletonRenderScale; + const float my = 1.5f; + scale.y *= (SpineEditorUtilities.Preferences.handleScale + 1) * 0.5f; + scale.y = Mathf.Clamp(scale.x, -my * skeletonRenderScale, my * skeletonRenderScale); + Handles.DrawPolyLine(GetBoneWireBuffer(transform.localToWorldMatrix * Matrix4x4.TRS(pos, rot, scale))); + var wp = transform.TransformPoint(pos); + DrawBoneCircle(wp, color, transform.forward, skeletonRenderScale); + } else { + var wp = transform.TransformPoint(pos); + DrawBoneCircle(wp, color, transform.forward, skeletonRenderScale); + } + } + + public static void DrawBone (Transform transform, Bone b, float boneScale, float skeletonRenderScale = 1f) { + var pos = new Vector3(b.WorldX * skeletonRenderScale, b.WorldY * skeletonRenderScale, 0); + float length = b.Data.Length; + if (length > 0) { + Quaternion rot = Quaternion.Euler(0, 0, b.WorldRotationX); + Vector3 scale = Vector3.one * length * b.WorldScaleX * skeletonRenderScale; + const float my = 1.5f; + scale.y *= (SpineEditorUtilities.Preferences.handleScale + 1f) * 0.5f; + scale.y = Mathf.Clamp(scale.x, -my * skeletonRenderScale, my * skeletonRenderScale); + SpineHandles.GetBoneMaterial().SetPass(0); + Graphics.DrawMeshNow(SpineHandles.BoneMesh, transform.localToWorldMatrix * Matrix4x4.TRS(pos, rot, scale)); + } else { + var wp = transform.TransformPoint(pos); + DrawBoneCircle(wp, SpineHandles.BoneColor, transform.forward, boneScale * skeletonRenderScale); + } + } + + public static void DrawBone (Transform transform, Bone b, float boneScale, Color color, float skeletonRenderScale = 1f) { + var pos = new Vector3(b.WorldX * skeletonRenderScale, b.WorldY * skeletonRenderScale, 0); + float length = b.Data.Length; + if (length > 0) { + Quaternion rot = Quaternion.Euler(0, 0, b.WorldRotationX); + Vector3 scale = Vector3.one * length * b.WorldScaleX; + const float my = 1.5f; + scale.y *= (SpineEditorUtilities.Preferences.handleScale + 1f) * 0.5f; + scale.y = Mathf.Clamp(scale.x, -my, my); + SpineHandles.GetBoneMaterial(color).SetPass(0); + Graphics.DrawMeshNow(SpineHandles.BoneMesh, transform.localToWorldMatrix * Matrix4x4.TRS(pos, rot, scale)); + } else { + var wp = transform.TransformPoint(pos); + DrawBoneCircle(wp, color, transform.forward, boneScale * skeletonRenderScale); + } + } + + public static void DrawPaths (Transform transform, Skeleton skeleton) { + foreach (Slot s in skeleton.DrawOrder) { + var p = s.Attachment as PathAttachment; + if (p != null) SpineHandles.DrawPath(s, p, transform, true); + } + } + + static float[] pathVertexBuffer; + public static void DrawPath (Slot s, PathAttachment p, Transform t, bool includeName) { + int worldVerticesLength = p.WorldVerticesLength; + + if (pathVertexBuffer == null || pathVertexBuffer.Length < worldVerticesLength) + pathVertexBuffer = new float[worldVerticesLength]; + + float[] pv = pathVertexBuffer; + p.ComputeWorldVertices(s, pv); + + var ocolor = Handles.color; + Handles.color = SpineHandles.PathColor; + + Matrix4x4 m = t.localToWorldMatrix; + const int step = 6; + int n = worldVerticesLength - step; + Vector3 p0, p1, p2, p3; + for (int i = 2; i < n; i += step) { + p0 = m.MultiplyPoint(new Vector3(pv[i], pv[i+1])); + p1 = m.MultiplyPoint(new Vector3(pv[i+2], pv[i+3])); + p2 = m.MultiplyPoint(new Vector3(pv[i+4], pv[i+5])); + p3 = m.MultiplyPoint(new Vector3(pv[i+6], pv[i+7])); + DrawCubicBezier(p0, p1, p2, p3); + } + + n += step; + if (p.Closed) { + p0 = m.MultiplyPoint(new Vector3(pv[n - 4], pv[n - 3])); + p1 = m.MultiplyPoint(new Vector3(pv[n - 2], pv[n - 1])); + p2 = m.MultiplyPoint(new Vector3(pv[0], pv[1])); + p3 = m.MultiplyPoint(new Vector3(pv[2], pv[3])); + DrawCubicBezier(p0, p1, p2, p3); + } + + const float endCapSize = 0.05f; + Vector3 firstPoint = m.MultiplyPoint(new Vector3(pv[2], pv[3])); + SpineHandles.DrawDot(firstPoint, endCapSize); + + //if (!p.Closed) SpineHandles.DrawDot(m.MultiplyPoint(new Vector3(pv[n - 4], pv[n - 3])), endCapSize); + if (includeName) Handles.Label(firstPoint + new Vector3(0,0.1f), p.Name, PathNameStyle); + + Handles.color = ocolor; + } + + public static void DrawDot (Vector3 position, float size) { + Handles.DotHandleCap(0, position, Quaternion.identity, size * HandleUtility.GetHandleSize(position), EventType.Ignore); //Handles.DotCap(0, position, Quaternion.identity, size * HandleUtility.GetHandleSize(position)); + } + + public static void DrawBoundingBoxes (Transform transform, Skeleton skeleton) { + foreach (var slot in skeleton.Slots) { + var bba = slot.Attachment as BoundingBoxAttachment; + if (bba != null) SpineHandles.DrawBoundingBox(slot, bba, transform); + } + } + + public static void DrawBoundingBox (Slot slot, BoundingBoxAttachment box, Transform t) { + if (box.Vertices.Length <= 2) return; // Handle cases where user creates a BoundingBoxAttachment but doesn't actually define it. + + var worldVerts = new float[box.WorldVerticesLength]; + box.ComputeWorldVertices(slot, worldVerts); + + Handles.color = Color.green; + Vector3 lastVert = Vector3.zero; + Vector3 vert = Vector3.zero; + Vector3 firstVert = t.TransformPoint(new Vector3(worldVerts[0], worldVerts[1], 0)); + for (int i = 0; i < worldVerts.Length; i += 2) { + vert.x = worldVerts[i]; + vert.y = worldVerts[i + 1]; + vert.z = 0; + + vert = t.TransformPoint(vert); + + if (i > 0) + Handles.DrawLine(lastVert, vert); + + lastVert = vert; + } + + Handles.DrawLine(lastVert, firstVert); + } + + public static void DrawPointAttachment (Bone bone, PointAttachment pointAttachment, Transform skeletonTransform) { + if (bone == null) return; + if (pointAttachment == null) return; + + Vector2 localPos; + pointAttachment.ComputeWorldPosition(bone, out localPos.x, out localPos.y); + float localRotation = pointAttachment.ComputeWorldRotation(bone); + Matrix4x4 m = Matrix4x4.TRS(localPos, Quaternion.Euler(0, 0, localRotation), Vector3.one) * Matrix4x4.TRS(Vector3.right * 0.25f, Quaternion.identity, Vector3.one); + + DrawBoneCircle(skeletonTransform.TransformPoint(localPos), SpineHandles.PointColor, Vector3.back, 1.3f); + DrawArrowhead(skeletonTransform.localToWorldMatrix * m); + } + + public static void DrawConstraints (Transform transform, Skeleton skeleton, float skeletonRenderScale = 1f) { + Vector3 targetPos; + Vector3 pos; + bool active; + Color handleColor; + const float Thickness = 4f; + Vector3 normal = transform.forward; + + // Transform Constraints + handleColor = SpineHandles.TransformContraintColor; + foreach (var tc in skeleton.TransformConstraints) { + var targetBone = tc.Target; + targetPos = targetBone.GetWorldPosition(transform, skeletonRenderScale); + + if (tc.TranslateMix > 0) { + if (tc.TranslateMix != 1f) { + Handles.color = handleColor; + foreach (var b in tc.Bones) { + pos = b.GetWorldPosition(transform, skeletonRenderScale); + Handles.DrawDottedLine(targetPos, pos, Thickness); + } + } + SpineHandles.DrawBoneCircle(targetPos, handleColor, normal, 1.3f * skeletonRenderScale); + Handles.color = handleColor; + SpineHandles.DrawCrosshairs(targetPos, 0.2f, targetBone.A, targetBone.B, targetBone.C, targetBone.D, transform, skeletonRenderScale); + } + } + + // IK Constraints + handleColor = SpineHandles.IkColor; + foreach (var ikc in skeleton.IkConstraints) { + Bone targetBone = ikc.Target; + targetPos = targetBone.GetWorldPosition(transform, skeletonRenderScale); + var bones = ikc.Bones; + active = ikc.Mix > 0; + if (active) { + pos = bones.Items[0].GetWorldPosition(transform, skeletonRenderScale); + switch (bones.Count) { + case 1: { + Handles.color = handleColor; + Handles.DrawLine(targetPos, pos); + SpineHandles.DrawBoneCircle(targetPos, handleColor, normal); + var m = bones.Items[0].GetMatrix4x4(); + m.m03 = targetBone.WorldX * skeletonRenderScale; + m.m13 = targetBone.WorldY * skeletonRenderScale; + SpineHandles.DrawArrowhead(transform.localToWorldMatrix * m); + break; + } + case 2: { + Bone childBone = bones.Items[1]; + Vector3 child = childBone.GetWorldPosition(transform, skeletonRenderScale); + Handles.color = handleColor; + Handles.DrawLine(child, pos); + Handles.DrawLine(targetPos, child); + SpineHandles.DrawBoneCircle(pos, handleColor, normal, 0.5f); + SpineHandles.DrawBoneCircle(child, handleColor, normal, 0.5f); + SpineHandles.DrawBoneCircle(targetPos, handleColor, normal); + var m = childBone.GetMatrix4x4(); + m.m03 = targetBone.WorldX * skeletonRenderScale; + m.m13 = targetBone.WorldY * skeletonRenderScale; + SpineHandles.DrawArrowhead(transform.localToWorldMatrix * m); + break; + } + } + } + //Handles.Label(targetPos, ikc.Data.Name, SpineHandles.BoneNameStyle); + } + + // Path Constraints + handleColor = SpineHandles.PathColor; + foreach (var pc in skeleton.PathConstraints) { + active = pc.TranslateMix > 0; + if (active) + foreach (var b in pc.Bones) + SpineHandles.DrawBoneCircle(b.GetWorldPosition(transform, skeletonRenderScale), handleColor, normal, 1f * skeletonRenderScale); + } + } + + static void DrawCrosshairs2D (Vector3 position, float scale, float skeletonRenderScale = 1f) { + scale *= SpineEditorUtilities.Preferences.handleScale * skeletonRenderScale; + Handles.DrawLine(position + new Vector3(-scale, 0), position + new Vector3(scale, 0)); + Handles.DrawLine(position + new Vector3(0, -scale), position + new Vector3(0, scale)); + } + + static void DrawCrosshairs (Vector3 position, float scale, float a, float b, float c, float d, Transform transform, float skeletonRenderScale = 1f) { + scale *= SpineEditorUtilities.Preferences.handleScale * skeletonRenderScale; + + var xOffset = (Vector3)(new Vector2(a, c).normalized * scale); + var yOffset = (Vector3)(new Vector2(b, d).normalized * scale); + xOffset = transform.TransformDirection(xOffset); + yOffset = transform.TransformDirection(yOffset); + + Handles.DrawLine(position + xOffset, position - xOffset); + Handles.DrawLine(position + yOffset, position - yOffset); + } + + static void DrawArrowhead2D (Vector3 pos, float localRotation, float scale = 1f) { + scale *= SpineEditorUtilities.Preferences.handleScale; + + SpineHandles.IKMaterial.SetPass(0); + Graphics.DrawMeshNow(SpineHandles.ArrowheadMesh, Matrix4x4.TRS(pos, Quaternion.Euler(0, 0, localRotation), new Vector3(scale, scale, scale))); + } + + static void DrawArrowhead (Vector3 pos, Quaternion worldQuaternion) { + Graphics.DrawMeshNow(SpineHandles.ArrowheadMesh, pos, worldQuaternion, 0); + } + + static void DrawArrowhead (Matrix4x4 m) { + float s = SpineEditorUtilities.Preferences.handleScale; + m.m00 *= s; + m.m01 *= s; + m.m02 *= s; + m.m10 *= s; + m.m11 *= s; + m.m12 *= s; + m.m20 *= s; + m.m21 *= s; + m.m22 *= s; + + SpineHandles.IKMaterial.SetPass(0); + Graphics.DrawMeshNow(SpineHandles.ArrowheadMesh, m); + } + + static void DrawBoneCircle (Vector3 pos, Color outlineColor, Vector3 normal, float scale = 1f) { + scale *= SpineEditorUtilities.Preferences.handleScale; + + Color o = Handles.color; + Handles.color = outlineColor; + float firstScale = 0.08f * scale; + Handles.DrawSolidDisc(pos, normal, firstScale); + const float Thickness = 0.03f; + float secondScale = firstScale - (Thickness * SpineEditorUtilities.Preferences.handleScale * scale); + + if (secondScale > 0f) { + Handles.color = new Color(0.3f, 0.3f, 0.3f, 0.5f); + Handles.DrawSolidDisc(pos, normal, secondScale); + } + + Handles.color = o; + } + + internal static void DrawCubicBezier (Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3) { + Handles.DrawBezier(p0, p3, p1, p2, Handles.color, Texture2D.whiteTexture, 2f); + // const float dotSize = 0.01f; + // Quaternion q = Quaternion.identity; + // Handles.DotCap(0, p0, q, dotSize); + // Handles.DotCap(0, p1, q, dotSize); + // Handles.DotCap(0, p2, q, dotSize); + // Handles.DotCap(0, p3, q, dotSize); + // Handles.DrawLine(p0, p1); + // Handles.DrawLine(p3, p2); + } + } +} diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/Utility/SpineHandles.cs.meta b/box1/Assets/Spine/Editor/spine-unity/Editor/Utility/SpineHandles.cs.meta new file mode 100644 index 00000000..6a1532b7 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/Utility/SpineHandles.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: f4c97e41d3d90e24bbb40d634e6cc336 +timeCreated: 1563313275 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/Utility/SpineInspectorUtility.cs b/box1/Assets/Spine/Editor/spine-unity/Editor/Utility/SpineInspectorUtility.cs new file mode 100644 index 00000000..7842686c --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/Utility/SpineInspectorUtility.cs @@ -0,0 +1,376 @@ +/****************************************************************************** + * 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 UnityEditor; +using System.Collections.Generic; +using System.Reflection; + +namespace Spine.Unity.Editor { + public static class SpineInspectorUtility { + + public static string Pluralize (int n, string singular, string plural) { + return n + " " + (n == 1 ? singular : plural); + } + + public static string PluralThenS (int n) { + return n == 1 ? "" : "s"; + } + + public static string EmDash { + get { return "\u2014"; } + } + + static GUIContent tempContent; + internal static GUIContent TempContent (string text, Texture2D image = null, string tooltip = null) { + if (tempContent == null) tempContent = new GUIContent(); + tempContent.text = text; + tempContent.image = image; + tempContent.tooltip = tooltip; + return tempContent; + } + + public static void PropertyFieldWideLabel (SerializedProperty property, GUIContent label = null, float minimumLabelWidth = 150) { + EditorGUIUtility.labelWidth = minimumLabelWidth; + EditorGUILayout.PropertyField(property, label ?? TempContent(property.displayName, null, property.tooltip)); + EditorGUIUtility.labelWidth = 0; // Resets to default + } + + public static void PropertyFieldFitLabel (SerializedProperty property, GUIContent label = null, float extraSpace = 5f) { + label = label ?? TempContent(property.displayName, null, property.tooltip); + float width = GUI.skin.label.CalcSize(TempContent(label.text)).x + extraSpace; + if (label.image != null) + width += EditorGUIUtility.singleLineHeight; + PropertyFieldWideLabel(property, label, width); + } + + /// Multi-edit-compatible version of EditorGUILayout.ToggleLeft(SerializedProperty) + public static void ToggleLeftLayout (SerializedProperty property, GUIContent label = null, float width = 120f) { + if (label == null) label = SpineInspectorUtility.TempContent(property.displayName, tooltip: property.tooltip); + + if (property.hasMultipleDifferentValues) { + bool previousShowMixedValue = EditorGUI.showMixedValue; + EditorGUI.showMixedValue = true; + + bool clicked = EditorGUILayout.ToggleLeft(label, property.boolValue, GUILayout.Width(width)); + if (clicked) property.boolValue = true; // Set all values to true when clicked. + + EditorGUI.showMixedValue = previousShowMixedValue; + } else { + property.boolValue = EditorGUILayout.ToggleLeft(label, property.boolValue, GUILayout.Width(width)); + } + } + + /// Multi-edit-compatible version of EditorGUILayout.ToggleLeft(SerializedProperty) + public static void ToggleLeft (Rect rect, SerializedProperty property, GUIContent label = null) { + if (label == null) label = SpineInspectorUtility.TempContent(property.displayName, tooltip: property.tooltip); + + if (property.hasMultipleDifferentValues) { + bool previousShowMixedValue = EditorGUI.showMixedValue; + EditorGUI.showMixedValue = true; + + bool clicked = EditorGUI.ToggleLeft(rect, label, property.boolValue); + if (clicked) property.boolValue = true; // Set all values to true when clicked. + + EditorGUI.showMixedValue = previousShowMixedValue; + } else { + property.boolValue = EditorGUI.ToggleLeft(rect, label, property.boolValue); + } + } + + public static bool UndoRedoPerformed (UnityEngine.Event current) { + return current.type == EventType.ValidateCommand && current.commandName == "UndoRedoPerformed"; + } + + public static Texture2D UnityIcon() { + return EditorGUIUtility.ObjectContent(null, typeof(T)).image as Texture2D; + } + + public static Texture2D UnityIcon(System.Type type) { + return EditorGUIUtility.ObjectContent(null, type).image as Texture2D; + } + + public static FieldInfo GetNonPublicField (System.Type type, string fieldName) { + return type.GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Instance); + } + + #region SerializedProperty Helpers + public static SerializedProperty FindBaseOrSiblingProperty (this SerializedProperty property, string propertyName) { + if (string.IsNullOrEmpty(propertyName)) return null; + + SerializedProperty relativeProperty = property.serializedObject.FindProperty(propertyName); // baseProperty + + // If base property is not found, look for the sibling property. + if (relativeProperty == null) { + string propertyPath = property.propertyPath; + int localPathLength = property.name.Length; + + string newPropertyPath = propertyPath.Remove(propertyPath.Length - localPathLength, localPathLength) + propertyName; + relativeProperty = property.serializedObject.FindProperty(newPropertyPath); + + // If a direct sibling property was not found, try to find the sibling of the array. + if (relativeProperty == null && property.isArray) { + int propertyPathLength = propertyPath.Length; + + int dotCount = 0; + const int SiblingOfListDotCount = 3; + for (int i = 1; i < propertyPathLength; i++) { + if (propertyPath[propertyPathLength - i] == '.') { + dotCount++; + if (dotCount >= SiblingOfListDotCount) { + localPathLength = i - 1; + break; + } + } + } + + newPropertyPath = propertyPath.Remove(propertyPath.Length - localPathLength, localPathLength) + propertyName; + relativeProperty = property.serializedObject.FindProperty(newPropertyPath); + } + } + + return relativeProperty; + } + #endregion + + #region Layout Scopes + static GUIStyle grayMiniLabel; + public static GUIStyle GrayMiniLabel { + get { + if (grayMiniLabel == null) { + grayMiniLabel = new GUIStyle(EditorStyles.centeredGreyMiniLabel) { + alignment = TextAnchor.UpperLeft + }; + } + return grayMiniLabel; + } + } + + public class LabelWidthScope : System.IDisposable { + public LabelWidthScope (float minimumLabelWidth = 190f) { + EditorGUIUtility.labelWidth = minimumLabelWidth; + } + + public void Dispose () { + EditorGUIUtility.labelWidth = 0f; + } + } + + public class IndentScope : System.IDisposable { + public IndentScope () { EditorGUI.indentLevel++; } + public void Dispose () { EditorGUI.indentLevel--; } + } + + public class BoxScope : System.IDisposable { + readonly bool indent; + + static GUIStyle boxScopeStyle; + public static GUIStyle BoxScopeStyle { + get { + if (boxScopeStyle == null) { + boxScopeStyle = new GUIStyle(EditorStyles.helpBox); + RectOffset p = boxScopeStyle.padding; // RectOffset is a class + p.right += 6; + p.top += 1; + p.left += 3; + } + + return boxScopeStyle; + } + } + + public BoxScope (bool indent = true) { + this.indent = indent; + EditorGUILayout.BeginVertical(BoxScopeStyle); + if (indent) EditorGUI.indentLevel++; + } + + public void Dispose () { + if (indent) EditorGUI.indentLevel--; + EditorGUILayout.EndVertical(); + } + } + #endregion + + #region Button + const float CenterButtonMaxWidth = 270f; + const float CenterButtonHeight = 30f; + static GUIStyle spineButtonStyle; + static GUIStyle SpineButtonStyle { + get { + if (spineButtonStyle == null) { + spineButtonStyle = new GUIStyle(GUI.skin.button); + spineButtonStyle.padding = new RectOffset(10, 10, 10, 10); + } + return spineButtonStyle; + } + } + + public static bool LargeCenteredButton (string label, bool sideSpace = true, float maxWidth = CenterButtonMaxWidth) { + if (sideSpace) { + bool clicked; + using (new EditorGUILayout.HorizontalScope()) { + EditorGUILayout.Space(); + clicked = GUILayout.Button(label, SpineButtonStyle, GUILayout.MaxWidth(maxWidth), GUILayout.Height(CenterButtonHeight)); + EditorGUILayout.Space(); + } + EditorGUILayout.Space(); + return clicked; + } else { + return GUILayout.Button(label, GUILayout.MaxWidth(CenterButtonMaxWidth), GUILayout.Height(CenterButtonHeight)); + } + } + + public static bool LargeCenteredButton (GUIContent content, bool sideSpace = true, float maxWidth = CenterButtonMaxWidth) { + if (sideSpace) { + bool clicked; + using (new EditorGUILayout.HorizontalScope()) { + EditorGUILayout.Space(); + clicked = GUILayout.Button(content, SpineButtonStyle, GUILayout.MaxWidth(maxWidth), GUILayout.Height(CenterButtonHeight)); + EditorGUILayout.Space(); + } + EditorGUILayout.Space(); + return clicked; + } else { + return GUILayout.Button(content, GUILayout.MaxWidth(CenterButtonMaxWidth), GUILayout.Height(CenterButtonHeight)); + } + } + + public static bool CenteredButton (GUIContent content, float height = 20f, bool sideSpace = true, float maxWidth = CenterButtonMaxWidth) { + if (sideSpace) { + bool clicked; + using (new EditorGUILayout.HorizontalScope()) { + EditorGUILayout.Space(); + clicked = GUILayout.Button(content, GUILayout.MaxWidth(maxWidth), GUILayout.Height(height)); + EditorGUILayout.Space(); + } + EditorGUILayout.Space(); + return clicked; + } else { + return GUILayout.Button(content, GUILayout.MaxWidth(maxWidth), GUILayout.Height(height)); + } + } + #endregion + + #region Multi-Editing Helpers + public static bool TargetsUseSameData (SerializedObject so) { + if (so.isEditingMultipleObjects) { + int n = so.targetObjects.Length; + var first = so.targetObjects[0] as IHasSkeletonDataAsset; + for (int i = 1; i < n; i++) { + var sr = so.targetObjects[i] as IHasSkeletonDataAsset; + if (sr != null && sr.SkeletonDataAsset != first.SkeletonDataAsset) + return false; + } + } + return true; + } + + public static SerializedObject GetRenderersSerializedObject (SerializedObject serializedObject) { + if (serializedObject.isEditingMultipleObjects) { + var renderers = new List(); + foreach (var o in serializedObject.targetObjects) { + var component = o as Component; + if (component != null) { + var renderer = component.GetComponent(); + if (renderer != null) + renderers.Add(renderer); + } + } + return new SerializedObject(renderers.ToArray()); + } else { + var component = serializedObject.targetObject as Component; + if (component != null) { + var renderer = component.GetComponent(); + if (renderer != null) + return new SerializedObject(renderer); + } + } + + return null; + } + #endregion + + #region Sorting Layer Field Helpers + static readonly GUIContent SortingLayerLabel = new GUIContent("Sorting Layer", "MeshRenderer.sortingLayerID"); + static readonly GUIContent OrderInLayerLabel = new GUIContent("Order in Layer", "MeshRenderer.sortingOrder"); + + static MethodInfo m_SortingLayerFieldMethod; + static MethodInfo SortingLayerFieldMethod { + get { + if (m_SortingLayerFieldMethod == null) + m_SortingLayerFieldMethod = typeof(EditorGUILayout).GetMethod("SortingLayerField", BindingFlags.Static | BindingFlags.NonPublic, null, new [] { typeof(GUIContent), typeof(SerializedProperty), typeof(GUIStyle) }, null); + + return m_SortingLayerFieldMethod; + } + } + + public struct SerializedSortingProperties { + public SerializedObject renderer; + public SerializedProperty sortingLayerID; + public SerializedProperty sortingOrder; + + public SerializedSortingProperties (Renderer r) : this(new SerializedObject(r)) {} + public SerializedSortingProperties (Object[] renderers) : this(new SerializedObject(renderers)) {} + + public SerializedSortingProperties (SerializedObject rendererSerializedObject) { + renderer = rendererSerializedObject; + sortingLayerID = renderer.FindProperty("m_SortingLayerID"); + sortingOrder = renderer.FindProperty("m_SortingOrder"); + } + + public void ApplyModifiedProperties () { + renderer.ApplyModifiedProperties(); + + // SetDirty + if (renderer.isEditingMultipleObjects) + foreach (var o in renderer.targetObjects) + EditorUtility.SetDirty(o); + else + EditorUtility.SetDirty(renderer.targetObject); + } + } + + public static void SortingPropertyFields (SerializedSortingProperties prop, bool applyModifiedProperties) { + if (applyModifiedProperties) + EditorGUI.BeginChangeCheck(); + + if (SpineInspectorUtility.SortingLayerFieldMethod != null && prop.sortingLayerID != null) + SpineInspectorUtility.SortingLayerFieldMethod.Invoke(null, new object[] { SortingLayerLabel, prop.sortingLayerID, EditorStyles.popup } ); + else + EditorGUILayout.PropertyField(prop.sortingLayerID); + + EditorGUILayout.PropertyField(prop.sortingOrder, OrderInLayerLabel); + + if (applyModifiedProperties && EditorGUI.EndChangeCheck()) + prop.ApplyModifiedProperties(); + } + #endregion + } +} diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/Utility/SpineInspectorUtility.cs.meta b/box1/Assets/Spine/Editor/spine-unity/Editor/Utility/SpineInspectorUtility.cs.meta new file mode 100644 index 00000000..3219ca0b --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/Utility/SpineInspectorUtility.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 663715b5714e2db499192c8d91ef1f86 +timeCreated: 1457404957 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/Utility/SpineMaskUtilities.cs b/box1/Assets/Spine/Editor/spine-unity/Editor/Utility/SpineMaskUtilities.cs new file mode 100644 index 00000000..f3e3dc26 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/Utility/SpineMaskUtilities.cs @@ -0,0 +1,246 @@ +/****************************************************************************** + * 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. + *****************************************************************************/ + +#pragma warning disable 0219 + +#define SPINE_SKELETONMECANIM + +#if UNITY_2017_2_OR_NEWER +#define NEWPLAYMODECALLBACKS +#endif + +#if UNITY_2018_3 || UNITY_2019 || UNITY_2018_3_OR_NEWER +#define NEW_PREFAB_SYSTEM +#endif + +#if UNITY_2018 || UNITY_2019 || UNITY_2018_3_OR_NEWER +#define NEWHIERARCHYWINDOWCALLBACKS +#endif + +#if UNITY_2017_1_OR_NEWER +#define BUILT_IN_SPRITE_MASK_COMPONENT +#endif + +#if BUILT_IN_SPRITE_MASK_COMPONENT + +using UnityEngine; +using UnityEditor; +using System.Collections.Generic; +using System.IO; +using System.Text; +using System.Linq; +using System.Reflection; + +namespace Spine.Unity.Editor { + + public class SpineMaskUtilities { + + private const string MATERIAL_FILENAME_SUFFIX_INSIDE_MASK = "_InsideMask"; + private const string MATERIAL_FILENAME_SUFFIX_OUTSIDE_MASK = "_OutsideMask"; + + public static void EditorAssignSpriteMaskMaterials(SkeletonRenderer skeleton) { + var maskMaterials = skeleton.maskMaterials; + var maskInteraction = skeleton.maskInteraction; + var meshRenderer = skeleton.GetComponent(); + + if (maskMaterials.materialsMaskDisabled.Length > 0 && maskMaterials.materialsMaskDisabled[0] != null && + maskInteraction == SpriteMaskInteraction.None) { + meshRenderer.materials = maskMaterials.materialsMaskDisabled; + } + else if (maskInteraction == SpriteMaskInteraction.VisibleInsideMask) { + if (maskMaterials.materialsInsideMask.Length == 0 || maskMaterials.materialsInsideMask[0] == null) + EditorInitSpriteMaskMaterialsInsideMask(skeleton); + meshRenderer.materials = maskMaterials.materialsInsideMask; + } + else if (maskInteraction == SpriteMaskInteraction.VisibleOutsideMask) { + if (maskMaterials.materialsOutsideMask.Length == 0 || maskMaterials.materialsOutsideMask[0] == null) + EditorInitSpriteMaskMaterialsOutsideMask(skeleton); + meshRenderer.materials = maskMaterials.materialsOutsideMask; + } + } + + public static bool AreMaskMaterialsMissing(SkeletonRenderer skeleton) { + var maskMaterials = skeleton.maskMaterials; + var maskInteraction = skeleton.maskInteraction; + + if (maskInteraction == SpriteMaskInteraction.VisibleInsideMask) { + return (maskMaterials.materialsInsideMask.Length == 0 || maskMaterials.materialsInsideMask[0] == null); + } + else if (maskInteraction == SpriteMaskInteraction.VisibleOutsideMask) { + return (maskMaterials.materialsOutsideMask.Length == 0 || maskMaterials.materialsOutsideMask[0] == null); + } + return false; + } + + public static void EditorInitMaskMaterials(SkeletonRenderer skeleton, SkeletonRenderer.SpriteMaskInteractionMaterials maskMaterials, SpriteMaskInteraction maskType) { + if (maskType == SpriteMaskInteraction.None) { + EditorConfirmDisabledMaskMaterialsInit(skeleton); + } + else if (maskType == SpriteMaskInteraction.VisibleInsideMask) { + EditorInitSpriteMaskMaterialsInsideMask(skeleton); + } + else if (maskType == SpriteMaskInteraction.VisibleOutsideMask) { + EditorInitSpriteMaskMaterialsOutsideMask(skeleton); + } + } + + public static void EditorDeleteMaskMaterials(SkeletonRenderer.SpriteMaskInteractionMaterials maskMaterials, SpriteMaskInteraction maskType) { + Material[] targetMaterials; + if (maskType == SpriteMaskInteraction.VisibleInsideMask) { + targetMaterials = maskMaterials.materialsInsideMask; + } + else if (maskType == SpriteMaskInteraction.VisibleOutsideMask) { + targetMaterials = maskMaterials.materialsOutsideMask; + } + else { + Debug.LogWarning("EditorDeleteMaskMaterials: Normal materials are kept as a reference and shall never be deleted."); + return; + } + + for (int i = 0; i < targetMaterials.Length; ++i) { + var material = targetMaterials[i]; + if (material != null) { + string materialPath = UnityEditor.AssetDatabase.GetAssetPath(material); + UnityEditor.AssetDatabase.DeleteAsset(materialPath); + Debug.Log(string.Concat("Deleted material '", materialPath, "'")); + } + } + + if (maskType == SpriteMaskInteraction.VisibleInsideMask) { + maskMaterials.materialsInsideMask = new Material[0]; + } + else if (maskType == SpriteMaskInteraction.VisibleOutsideMask) { + maskMaterials.materialsOutsideMask = new Material[0]; + } + } + + private static void EditorInitSpriteMaskMaterialsInsideMask(SkeletonRenderer skeleton) { + var maskMaterials = skeleton.maskMaterials; + EditorInitSpriteMaskMaterialsForMaskType(skeleton, SkeletonRenderer.STENCIL_COMP_MASKINTERACTION_VISIBLE_INSIDE, + ref maskMaterials.materialsInsideMask); + } + + private static void EditorInitSpriteMaskMaterialsOutsideMask(SkeletonRenderer skeleton) { + var maskMaterials = skeleton.maskMaterials; + EditorInitSpriteMaskMaterialsForMaskType(skeleton, SkeletonRenderer.STENCIL_COMP_MASKINTERACTION_VISIBLE_OUTSIDE, + ref maskMaterials.materialsOutsideMask); + } + + private static void EditorInitSpriteMaskMaterialsForMaskType(SkeletonRenderer skeleton, UnityEngine.Rendering.CompareFunction maskFunction, + ref Material[] materialsToFill) { + if (!EditorConfirmDisabledMaskMaterialsInit(skeleton)) + return; + + var maskMaterials = skeleton.maskMaterials; + var originalMaterials = maskMaterials.materialsMaskDisabled; + materialsToFill = new Material[originalMaterials.Length]; + for (int i = 0; i < originalMaterials.Length; i++) { + Material newMaterial = null; + + if (!Application.isPlaying) { + newMaterial = EditorCreateOrLoadMaskMaterialAsset(maskMaterials, maskFunction, originalMaterials[i]); + } + if (newMaterial == null) { + newMaterial = new Material(originalMaterials[i]); + newMaterial.SetFloat(SkeletonRenderer.STENCIL_COMP_PARAM_ID, (int)maskFunction); + } + materialsToFill[i] = newMaterial; + } + } + + private static bool EditorConfirmDisabledMaskMaterialsInit(SkeletonRenderer skeleton) { + var maskMaterials = skeleton.maskMaterials; + if (maskMaterials.materialsMaskDisabled.Length > 0 && maskMaterials.materialsMaskDisabled[0] != null) { + return true; + } + + var meshRenderer = skeleton.GetComponent(); + Material[] currentMaterials = meshRenderer.sharedMaterials; + + if (currentMaterials.Length == 0 || currentMaterials[0] == null) { + Debug.LogWarning("No materials found assigned at " + skeleton.name); + return false; + } + + // We have to be sure that there has not been a recompilation or similar events that led to + // inside- or outside-mask materials being assigned to meshRenderer.sharedMaterials. + string firstMaterialPath = UnityEditor.AssetDatabase.GetAssetPath(currentMaterials[0]); + if (firstMaterialPath.Contains(MATERIAL_FILENAME_SUFFIX_INSIDE_MASK) || + firstMaterialPath.Contains(MATERIAL_FILENAME_SUFFIX_OUTSIDE_MASK)) { + + maskMaterials.materialsMaskDisabled = new Material[currentMaterials.Length]; + for (int i = 0; i < currentMaterials.Length; ++i) { + string path = UnityEditor.AssetDatabase.GetAssetPath(currentMaterials[i]); + string correctPath = null; + if (path.Contains(MATERIAL_FILENAME_SUFFIX_INSIDE_MASK)) { + correctPath = path.Replace(MATERIAL_FILENAME_SUFFIX_INSIDE_MASK, ""); + } + else if (path.Contains(MATERIAL_FILENAME_SUFFIX_OUTSIDE_MASK)) { + correctPath = path.Replace(MATERIAL_FILENAME_SUFFIX_OUTSIDE_MASK, ""); + } + + if (correctPath != null) { + Material material = UnityEditor.AssetDatabase.LoadAssetAtPath(correctPath); + if (material == null) + Debug.LogWarning("No original ignore-mask material found for path " + correctPath); + maskMaterials.materialsMaskDisabled[i] = material; + } + } + } + else { + maskMaterials.materialsMaskDisabled = currentMaterials; + } + return true; + } + + public static Material EditorCreateOrLoadMaskMaterialAsset(SkeletonRenderer.SpriteMaskInteractionMaterials maskMaterials, + UnityEngine.Rendering.CompareFunction maskFunction, Material originalMaterial) { + string originalMaterialPath = UnityEditor.AssetDatabase.GetAssetPath(originalMaterial); + int posOfExtensionDot = originalMaterialPath.LastIndexOf('.'); + string materialPath = (maskFunction == SkeletonRenderer.STENCIL_COMP_MASKINTERACTION_VISIBLE_INSIDE) ? + originalMaterialPath.Insert(posOfExtensionDot, MATERIAL_FILENAME_SUFFIX_INSIDE_MASK) : + originalMaterialPath.Insert(posOfExtensionDot, MATERIAL_FILENAME_SUFFIX_OUTSIDE_MASK); + + Material material = UnityEditor.AssetDatabase.LoadAssetAtPath(materialPath); + if (material != null) { + return material; + } + + material = new Material(originalMaterial); + material.SetFloat(SkeletonRenderer.STENCIL_COMP_PARAM_ID, (int)maskFunction); + + UnityEditor.AssetDatabase.CreateAsset(material, materialPath); + Debug.Log(string.Concat("Created material '", materialPath, "' for mask interaction based on '", originalMaterialPath, "'.")); + UnityEditor.EditorUtility.SetDirty(material); + UnityEditor.AssetDatabase.SaveAssets(); + return material; + } + } +} +#endif // BUILT_IN_SPRITE_MASK_COMPONENT diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/Utility/SpineMaskUtilities.cs.meta b/box1/Assets/Spine/Editor/spine-unity/Editor/Utility/SpineMaskUtilities.cs.meta new file mode 100644 index 00000000..7d3b80bd --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/Utility/SpineMaskUtilities.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 7c1b3a9ddacb550458bb86affdf77bf5 +timeCreated: 1550564907 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/Windows.meta b/box1/Assets/Spine/Editor/spine-unity/Editor/Windows.meta new file mode 100644 index 00000000..ee5bf8b2 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/Windows.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: b6badf2758b1ea44e8c5ec62ef338e22 +folderAsset: yes +timeCreated: 1563305058 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/Windows/SkeletonBaker.cs b/box1/Assets/Spine/Editor/spine-unity/Editor/Windows/SkeletonBaker.cs new file mode 100644 index 00000000..49716df1 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/Windows/SkeletonBaker.cs @@ -0,0 +1,1490 @@ +/****************************************************************************** + * 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 + +#define SPINE_SKELETONMECANIM + +using UnityEngine; +using UnityEditor; +using UnityEditorInternal; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.IO; +using Spine; + +namespace Spine.Unity.Editor { + + /// + /// [SUPPORTS] + /// Linear, Constant, and Bezier Curves* + /// Inverse Kinematics* + /// Inherit Rotation + /// Translate Timeline + /// Rotate Timeline + /// Scale Timeline** + /// Event Timeline*** + /// Attachment Timeline + /// + /// RegionAttachment + /// MeshAttachment (optionally Skinned) + /// + /// [LIMITATIONS] + /// *Bezier Curves are baked into the animation at 60fps and are not realtime. Use bakeIncrement constant to adjust key density if desired. + /// *Inverse Kinematics is baked into the animation at 60fps and are not realtime. Use bakeIncrement constant to adjust key density if desired. + /// ***Events may only fire 1 type of data per event in Unity safely so priority to String data if present in Spine key, otherwise a Float is sent whether the Spine key was Int or Float with priority given to Int. + /// + /// [DOES NOT SUPPORT] + /// FFD (Unity does not provide access to BlendShapes with code) + /// Color Keys (Maybe one day when Unity supports full FBX standard and provides access with code) + /// Draw Order Keyframes + /// + public static class SkeletonBaker { + + #region SkeletonMecanim's Mecanim Clips + #if SPINE_SKELETONMECANIM + public static void UpdateMecanimClips (SkeletonDataAsset skeletonDataAsset) { + if (skeletonDataAsset.controller == null) + return; + + SkeletonBaker.GenerateMecanimAnimationClips(skeletonDataAsset); + } + + public static void GenerateMecanimAnimationClips (SkeletonDataAsset skeletonDataAsset) { + var data = skeletonDataAsset.GetSkeletonData(true); + if (data == null) { + Debug.LogError("SkeletonData loading failed!", skeletonDataAsset); + return; + } + + string dataPath = AssetDatabase.GetAssetPath(skeletonDataAsset); + string controllerPath = dataPath.Replace(AssetUtility.SkeletonDataSuffix, "_Controller").Replace(".asset", ".controller"); + UnityEditor.Animations.AnimatorController controller; + if (skeletonDataAsset.controller != null) { + controller = (UnityEditor.Animations.AnimatorController)skeletonDataAsset.controller; + controllerPath = AssetDatabase.GetAssetPath(controller); + } else { + if (File.Exists(controllerPath)) { + if (EditorUtility.DisplayDialog("Controller Overwrite Warning", "Unknown Controller already exists at: " + controllerPath, "Update", "Overwrite")) { + controller = (UnityEditor.Animations.AnimatorController)AssetDatabase.LoadAssetAtPath(controllerPath, typeof(RuntimeAnimatorController)); + } else { + controller = (UnityEditor.Animations.AnimatorController)UnityEditor.Animations.AnimatorController.CreateAnimatorControllerAtPath(controllerPath); + } + } else { + controller = (UnityEditor.Animations.AnimatorController)UnityEditor.Animations.AnimatorController.CreateAnimatorControllerAtPath(controllerPath); + } + + } + + skeletonDataAsset.controller = controller; + EditorUtility.SetDirty(skeletonDataAsset); + + UnityEngine.Object[] objs = AssetDatabase.LoadAllAssetsAtPath(controllerPath); + + var unityAnimationClipTable = new Dictionary(); + var spineAnimationTable = new Dictionary(); + + foreach (var o in objs) { + //Debug.LogFormat("({0}){1} : {3} + {2} + {4}", o.GetType(), o.name, o.hideFlags, o.GetInstanceID(), o.GetHashCode()); + // There is a bug in Unity 5.3.3 (and likely before) that creates + // a duplicate AnimationClip when you duplicate a Mecanim Animator State. + // These duplicates seem to be identifiable by their HideFlags, so we'll exclude them. + if (o is AnimationClip) { + var clip = o as AnimationClip; + if (!clip.HasFlag(HideFlags.HideInHierarchy)) { + if (unityAnimationClipTable.ContainsKey(clip.name)) { + Debug.LogWarningFormat("Duplicate AnimationClips were found named {0}", clip.name); + } + unityAnimationClipTable.Add(clip.name, clip); + } + } + } + + foreach (var animations in data.Animations) { + string animationName = animations.Name; // Review for unsafe names. Requires runtime implementation too. + spineAnimationTable.Add(animationName, animations); + + if (unityAnimationClipTable.ContainsKey(animationName) == false) { + AnimationClip newClip = new AnimationClip { + name = animationName + }; + //AssetDatabase.CreateAsset(newClip, Path.GetDirectoryName(dataPath) + "/" + animationName + ".asset"); + AssetDatabase.AddObjectToAsset(newClip, controller); + unityAnimationClipTable.Add(animationName, newClip); + } + + AnimationClip clip = unityAnimationClipTable[animationName]; + clip.SetCurve("", typeof(GameObject), "dummy", AnimationCurve.Linear(0, 0, animations.Duration, 0)); + var settings = AnimationUtility.GetAnimationClipSettings(clip); + settings.stopTime = animations.Duration; + SetAnimationSettings(clip, settings); + + AnimationUtility.SetAnimationEvents(clip, new AnimationEvent[0]); + foreach (Timeline t in animations.Timelines) { + if (t is EventTimeline) + ParseEventTimeline((EventTimeline)t, clip, SendMessageOptions.DontRequireReceiver); + } + + EditorUtility.SetDirty(clip); + unityAnimationClipTable.Remove(animationName); + } + + foreach (var clip in unityAnimationClipTable.Values) { + AnimationClip.DestroyImmediate(clip, true); + } + + AssetDatabase.Refresh(); + AssetDatabase.SaveAssets(); + } + + static bool HasFlag (this UnityEngine.Object o, HideFlags flagToCheck) { + return (o.hideFlags & flagToCheck) == flagToCheck; + } + #endif + #endregion + + #region Prefab and AnimationClip Baking + /// + /// Interval between key sampling for Bezier curves, IK controlled bones, and Inherit Rotation effected bones. + /// + const float BakeIncrement = 1 / 60f; + + public static void BakeToPrefab (SkeletonDataAsset skeletonDataAsset, ExposedList skins, string outputPath = "", bool bakeAnimations = true, bool bakeIK = true, SendMessageOptions eventOptions = SendMessageOptions.DontRequireReceiver) { + if (skeletonDataAsset == null || skeletonDataAsset.GetSkeletonData(true) == null) { + Debug.LogError("Could not export Spine Skeleton because SkeletonDataAsset is null or invalid!"); + return; + } + + if (outputPath == "") { + outputPath = System.IO.Path.GetDirectoryName(AssetDatabase.GetAssetPath(skeletonDataAsset)).Replace('\\', '/') + "/Baked"; + System.IO.Directory.CreateDirectory(outputPath); + } + + var skeletonData = skeletonDataAsset.GetSkeletonData(true); + bool hasAnimations = bakeAnimations && skeletonData.Animations.Count > 0; + UnityEditor.Animations.AnimatorController controller = null; + if (hasAnimations) { + string controllerPath = outputPath + "/" + skeletonDataAsset.skeletonJSON.name + " Controller.controller"; + bool newAnimContainer = false; + + var runtimeController = AssetDatabase.LoadAssetAtPath(controllerPath, typeof(RuntimeAnimatorController)); + + if (runtimeController != null) { + controller = (UnityEditor.Animations.AnimatorController)runtimeController; + } else { + controller = UnityEditor.Animations.AnimatorController.CreateAnimatorControllerAtPath(controllerPath); + newAnimContainer = true; + } + + var existingClipTable = new Dictionary(); + var unusedClipNames = new List(); + Object[] animObjs = AssetDatabase.LoadAllAssetsAtPath(controllerPath); + + foreach (Object o in animObjs) { + if (o is AnimationClip) { + var clip = (AnimationClip)o; + existingClipTable.Add(clip.name, clip); + unusedClipNames.Add(clip.name); + } + } + + Dictionary> slotLookup = new Dictionary>(); + + int skinCount = skins.Count; + + for (int s = 0; s < skeletonData.Slots.Count; s++) { + List attachmentNames = new List(); + for (int i = 0; i < skinCount; i++) { + var skin = skins.Items[i]; + var skinEntries = new List(); + skin.GetAttachments(s, skinEntries); + foreach (var entry in skinEntries) { + if (!attachmentNames.Contains(entry.Name)) + attachmentNames.Add(entry.Name); + } + } + slotLookup.Add(s, attachmentNames); + } + + foreach (var anim in skeletonData.Animations) { + + AnimationClip clip = null; + if (existingClipTable.ContainsKey(anim.Name)) { + clip = existingClipTable[anim.Name]; + } + + clip = ExtractAnimation(anim.Name, skeletonData, slotLookup, bakeIK, eventOptions, clip); + + if (unusedClipNames.Contains(clip.name)) { + unusedClipNames.Remove(clip.name); + } else { + AssetDatabase.AddObjectToAsset(clip, controller); + controller.AddMotion(clip); + } + } + + if (newAnimContainer) { + EditorUtility.SetDirty(controller); + AssetDatabase.SaveAssets(); + AssetDatabase.ImportAsset(controllerPath, ImportAssetOptions.ForceUpdate); + AssetDatabase.Refresh(); + } else { + + foreach (string str in unusedClipNames) { + AnimationClip.DestroyImmediate(existingClipTable[str], true); + } + + EditorUtility.SetDirty(controller); + AssetDatabase.SaveAssets(); + AssetDatabase.ImportAsset(controllerPath, ImportAssetOptions.ForceUpdate); + AssetDatabase.Refresh(); + } + } + + foreach (var skin in skins) { + bool newPrefab = false; + + string prefabPath = outputPath + "/" + skeletonDataAsset.skeletonJSON.name + " (" + skin.Name + ").prefab"; + + Object prefab = AssetDatabase.LoadAssetAtPath(prefabPath, typeof(GameObject)); + + if (prefab == null) { + #if NEW_PREFAB_SYSTEM + GameObject emptyGameObject = new GameObject(); + prefab = PrefabUtility.SaveAsPrefabAssetAndConnect(emptyGameObject, prefabPath, InteractionMode.AutomatedAction); + GameObject.DestroyImmediate(emptyGameObject); + #else + prefab = PrefabUtility.CreateEmptyPrefab(prefabPath); + #endif + newPrefab = true; + } + + Dictionary meshTable = new Dictionary(); + List unusedMeshNames = new List(); + Object[] assets = AssetDatabase.LoadAllAssetsAtPath(prefabPath); + foreach (var obj in assets) { + if (obj is Mesh) { + meshTable.Add(obj.name, (Mesh)obj); + unusedMeshNames.Add(obj.name); + } + } + + GameObject prefabRoot = EditorInstantiation.NewGameObject("root", true); + + Dictionary slotTable = new Dictionary(); + Dictionary boneTable = new Dictionary(); + List boneList = new List(); + + //create bones + for (int i = 0; i < skeletonData.Bones.Count; i++) { + var boneData = skeletonData.Bones.Items[i]; + Transform boneTransform = EditorInstantiation.NewGameObject(boneData.Name, true).transform; + boneTransform.parent = prefabRoot.transform; + boneTable.Add(boneTransform.name, boneTransform); + boneList.Add(boneTransform); + } + + for (int i = 0; i < skeletonData.Bones.Count; i++) { + + var boneData = skeletonData.Bones.Items[i]; + Transform boneTransform = boneTable[boneData.Name]; + Transform parentTransform = null; + if (i > 0) + parentTransform = boneTable[boneData.Parent.Name]; + else + parentTransform = boneTransform.parent; + + boneTransform.parent = parentTransform; + boneTransform.localPosition = new Vector3(boneData.X, boneData.Y, 0); + var tm = boneData.TransformMode; + if (tm.InheritsRotation()) + boneTransform.localRotation = Quaternion.Euler(0, 0, boneData.Rotation); + else + boneTransform.rotation = Quaternion.Euler(0, 0, boneData.Rotation); + + if (tm.InheritsScale()) + boneTransform.localScale = new Vector3(boneData.ScaleX, boneData.ScaleY, 1); + } + + //create slots and attachments + for (int slotIndex = 0; slotIndex < skeletonData.Slots.Count; slotIndex++) { + var slotData = skeletonData.Slots.Items[slotIndex]; + Transform slotTransform = EditorInstantiation.NewGameObject(slotData.Name, true).transform; + slotTransform.parent = prefabRoot.transform; + slotTable.Add(slotData.Name, slotTransform); + + var skinEntries = new List(); + skin.GetAttachments(slotIndex, skinEntries); + if (skin != skeletonData.DefaultSkin) + skeletonData.DefaultSkin.GetAttachments(slotIndex, skinEntries); + + for (int a = 0; a < skinEntries.Count; a++) { + var attachment = skinEntries[a].Attachment; + string attachmentName = skinEntries[a].Name; + string attachmentMeshName = "[" + slotData.Name + "] " + attachmentName; + Vector3 offset = Vector3.zero; + float rotation = 0; + Mesh mesh = null; + Material material = null; + bool isWeightedMesh = false; + + if (meshTable.ContainsKey(attachmentMeshName)) + mesh = meshTable[attachmentMeshName]; + if (attachment is RegionAttachment) { + var regionAttachment = (RegionAttachment)attachment; + offset.x = regionAttachment.X; + offset.y = regionAttachment.Y; + rotation = regionAttachment.Rotation; + mesh = ExtractRegionAttachment(attachmentMeshName, regionAttachment, mesh); + material = attachment.GetMaterial(); + unusedMeshNames.Remove(attachmentMeshName); + if (newPrefab || meshTable.ContainsKey(attachmentMeshName) == false) + AssetDatabase.AddObjectToAsset(mesh, prefab); + } else if (attachment is MeshAttachment) { + var meshAttachment = (MeshAttachment)attachment; + isWeightedMesh = (meshAttachment.Bones != null); + offset.x = 0; + offset.y = 0; + rotation = 0; + + if (isWeightedMesh) + mesh = ExtractWeightedMeshAttachment(attachmentMeshName, meshAttachment, slotIndex, skeletonData, boneList, mesh); + else + mesh = ExtractMeshAttachment(attachmentMeshName, meshAttachment, mesh); + + material = attachment.GetMaterial(); + unusedMeshNames.Remove(attachmentMeshName); + if (newPrefab || meshTable.ContainsKey(attachmentMeshName) == false) + AssetDatabase.AddObjectToAsset(mesh, prefab); + } else + continue; + + Transform attachmentTransform = EditorInstantiation.NewGameObject(attachmentName, true).transform; + + attachmentTransform.parent = slotTransform; + attachmentTransform.localPosition = offset; + attachmentTransform.localRotation = Quaternion.Euler(0, 0, rotation); + + if (isWeightedMesh) { + attachmentTransform.position = Vector3.zero; + attachmentTransform.rotation = Quaternion.identity; + var skinnedMeshRenderer = attachmentTransform.gameObject.AddComponent(); + skinnedMeshRenderer.rootBone = boneList[0]; + skinnedMeshRenderer.bones = boneList.ToArray(); + skinnedMeshRenderer.sharedMesh = mesh; + } else { + attachmentTransform.gameObject.AddComponent().sharedMesh = mesh; + attachmentTransform.gameObject.AddComponent(); + } + + attachmentTransform.GetComponent().sharedMaterial = material; + attachmentTransform.GetComponent().sortingOrder = slotIndex; + + if (attachmentName != slotData.AttachmentName) + attachmentTransform.gameObject.SetActive(false); + } + + } + + foreach (var slotData in skeletonData.Slots) { + Transform slotTransform = slotTable[slotData.Name]; + slotTransform.parent = boneTable[slotData.BoneData.Name]; + slotTransform.localPosition = Vector3.zero; + slotTransform.localRotation = Quaternion.identity; + slotTransform.localScale = Vector3.one; + } + + if (hasAnimations) { + var animator = prefabRoot.AddComponent(); + animator.applyRootMotion = false; + animator.runtimeAnimatorController = (RuntimeAnimatorController)controller; + EditorGUIUtility.PingObject(controller); + } + + if (newPrefab) { + #if NEW_PREFAB_SYSTEM + PrefabUtility.SaveAsPrefabAssetAndConnect(prefabRoot, prefabPath, InteractionMode.AutomatedAction); + #else + PrefabUtility.ReplacePrefab(prefabRoot, prefab, ReplacePrefabOptions.ConnectToPrefab); + #endif + } else { + + foreach (string str in unusedMeshNames) { + Mesh.DestroyImmediate(meshTable[str], true); + } + + #if NEW_PREFAB_SYSTEM + PrefabUtility.SaveAsPrefabAssetAndConnect(prefabRoot, prefabPath, InteractionMode.AutomatedAction); + #else + PrefabUtility.ReplacePrefab(prefabRoot, prefab, ReplacePrefabOptions.ReplaceNameBased); + #endif + } + + + EditorGUIUtility.PingObject(prefab); + + AssetDatabase.Refresh(); + AssetDatabase.SaveAssets(); + + GameObject.DestroyImmediate(prefabRoot); + + } + } + + #region Attachment Baking + static Bone DummyBone; + static Slot DummySlot; + + internal static Bone GetDummyBone () { + if (DummyBone != null) + return DummyBone; + + SkeletonData skelData = new SkeletonData(); + BoneData data = new BoneData(0, "temp", null) { + ScaleX = 1, + ScaleY = 1, + Length = 100 + }; + + skelData.Bones.Add(data); + + Skeleton skeleton = new Skeleton(skelData); + + Bone bone = new Bone(data, skeleton, null); + bone.UpdateWorldTransform(); + + DummyBone = bone; + + return DummyBone; + } + + internal static Slot GetDummySlot () { + if (DummySlot != null) + return DummySlot; + + Bone bone = GetDummyBone(); + + SlotData data = new SlotData(0, "temp", bone.Data); + Slot slot = new Slot(data, bone); + DummySlot = slot; + return DummySlot; + } + + internal static Mesh ExtractRegionAttachment (string name, RegionAttachment attachment, Mesh mesh = null, bool centered = true) { + var bone = GetDummyBone(); + + if (centered) { + bone.X = -attachment.X; + bone.Y = -attachment.Y; + } + + bone.UpdateWorldTransform(); + + Vector2[] uvs = ExtractUV(attachment.UVs); + float[] floatVerts = new float[8]; + attachment.ComputeWorldVertices(bone, floatVerts, 0); + Vector3[] verts = ExtractVerts(floatVerts); + + //unrotate verts now that they're centered + if (centered) { + for (int i = 0; i < verts.Length; i++) + verts[i] = Quaternion.Euler(0, 0, -attachment.Rotation) * verts[i]; + } + + int[] triangles = { 1, 3, 0, 2, 3, 1 }; + Color color = attachment.GetColor(); + + if (mesh == null) + mesh = new Mesh(); + + mesh.triangles = new int[0]; + + mesh.vertices = verts; + mesh.uv = uvs; + mesh.triangles = triangles; + mesh.colors = new [] { color, color, color, color }; + mesh.RecalculateBounds(); + mesh.RecalculateNormals(); + mesh.name = name; + + return mesh; + } + + internal static Mesh ExtractMeshAttachment (string name, MeshAttachment attachment, Mesh mesh = null) { + var slot = GetDummySlot(); + + slot.Bone.X = 0; + slot.Bone.Y = 0; + slot.Bone.UpdateWorldTransform(); + + Vector2[] uvs = ExtractUV(attachment.UVs); + float[] floatVerts = new float[attachment.WorldVerticesLength]; + attachment.ComputeWorldVertices(slot, floatVerts); + Vector3[] verts = ExtractVerts(floatVerts); + + int[] triangles = attachment.Triangles; + Color color = attachment.GetColor(); + + if (mesh == null) + mesh = new Mesh(); + + mesh.triangles = new int[0]; + + mesh.vertices = verts; + mesh.uv = uvs; + mesh.triangles = triangles; + Color[] colors = new Color[verts.Length]; + for (int i = 0; i < verts.Length; i++) + colors[i] = color; + + mesh.colors = colors; + mesh.RecalculateBounds(); + mesh.RecalculateNormals(); + mesh.name = name; + + return mesh; + } + + public class BoneWeightContainer { + public struct Pair { + public Transform bone; + public float weight; + + public Pair (Transform bone, float weight) { + this.bone = bone; + this.weight = weight; + } + } + + public List bones; + public List weights; + public List pairs; + + + public BoneWeightContainer () { + this.bones = new List(); + this.weights = new List(); + this.pairs = new List(); + } + + public void Add (Transform transform, float weight) { + bones.Add(transform); + weights.Add(weight); + + pairs.Add(new Pair(transform, weight)); + } + } + + internal static Mesh ExtractWeightedMeshAttachment (string name, MeshAttachment attachment, int slotIndex, SkeletonData skeletonData, List boneList, Mesh mesh = null) { + if (!attachment.IsWeighted()) + throw new System.ArgumentException("Mesh is not weighted.", "attachment"); + + Skeleton skeleton = new Skeleton(skeletonData); + skeleton.UpdateWorldTransform(); + + float[] floatVerts = new float[attachment.WorldVerticesLength]; + attachment.ComputeWorldVertices(skeleton.Slots.Items[slotIndex], floatVerts); + + Vector2[] uvs = ExtractUV(attachment.UVs); + Vector3[] verts = ExtractVerts(floatVerts); + + int[] triangles = attachment.Triangles; + Color color = new Color(attachment.R, attachment.G, attachment.B, attachment.A); + + mesh = mesh ?? new Mesh(); + + mesh.triangles = new int[0]; + + mesh.vertices = verts; + mesh.uv = uvs; + mesh.triangles = triangles; + Color[] colors = new Color[verts.Length]; + for (int i = 0; i < verts.Length; i++) + colors[i] = color; + + mesh.colors = colors; + mesh.name = name; + mesh.RecalculateNormals(); + mesh.RecalculateBounds(); + + // Handle weights and binding + var weightTable = new Dictionary(); + var warningBuilder = new System.Text.StringBuilder(); + + int[] bones = attachment.Bones; + float[] weights = attachment.Vertices; + for (int w = 0, v = 0, b = 0, n = bones.Length; v < n; w += 2) { + + int nn = bones[v++] + v; + for (; v < nn; v++, b += 3) { + Transform boneTransform = boneList[bones[v]]; + int vIndex = w / 2; + BoneWeightContainer container; + if (weightTable.ContainsKey(vIndex)) + container = weightTable[vIndex]; + else { + container = new BoneWeightContainer(); + weightTable.Add(vIndex, container); + } + + float weight = weights[b + 2]; + container.Add(boneTransform, weight); + } + } + + BoneWeight[] boneWeights = new BoneWeight[weightTable.Count]; + + for (int i = 0; i < weightTable.Count; i++) { + BoneWeight bw = new BoneWeight(); + var container = weightTable[i]; + + var pairs = container.pairs.OrderByDescending(pair => pair.weight).ToList(); + + for (int b = 0; b < pairs.Count; b++) { + if (b > 3) { + if (warningBuilder.Length == 0) + warningBuilder.Insert(0, "[Weighted Mesh: " + name + "]\r\nUnity only supports 4 weight influences per vertex! The 4 strongest influences will be used.\r\n"); + + warningBuilder.AppendFormat("{0} ignored on vertex {1}!\r\n", pairs[b].bone.name, i); + continue; + } + + int boneIndex = boneList.IndexOf(pairs[b].bone); + float weight = pairs[b].weight; + + switch (b) { + case 0: + bw.boneIndex0 = boneIndex; + bw.weight0 = weight; + break; + case 1: + bw.boneIndex1 = boneIndex; + bw.weight1 = weight; + break; + case 2: + bw.boneIndex2 = boneIndex; + bw.weight2 = weight; + break; + case 3: + bw.boneIndex3 = boneIndex; + bw.weight3 = weight; + break; + } + } + + boneWeights[i] = bw; + } + + Matrix4x4[] bindPoses = new Matrix4x4[boneList.Count]; + for (int i = 0; i < boneList.Count; i++) { + bindPoses[i] = boneList[i].worldToLocalMatrix; + } + + mesh.boneWeights = boneWeights; + mesh.bindposes = bindPoses; + + string warningString = warningBuilder.ToString(); + if (warningString.Length > 0) + Debug.LogWarning(warningString); + + + return mesh; + } + + internal static Vector2[] ExtractUV (float[] floats) { + Vector2[] arr = new Vector2[floats.Length / 2]; + + for (int i = 0; i < floats.Length; i += 2) { + arr[i / 2] = new Vector2(floats[i], floats[i + 1]); + } + + return arr; + } + + internal static Vector3[] ExtractVerts (float[] floats) { + Vector3[] arr = new Vector3[floats.Length / 2]; + + for (int i = 0; i < floats.Length; i += 2) { + arr[i / 2] = new Vector3(floats[i], floats[i + 1], 0);// *scale; + } + + return arr; + } +#endregion + +#region Animation Baking + static AnimationClip ExtractAnimation (string name, SkeletonData skeletonData, Dictionary> slotLookup, bool bakeIK, SendMessageOptions eventOptions, AnimationClip clip = null) { + var animation = skeletonData.FindAnimation(name); + + var timelines = animation.Timelines; + + if (clip == null) { + clip = new AnimationClip(); + } else { + clip.ClearCurves(); + AnimationUtility.SetAnimationEvents(clip, new AnimationEvent[0]); + } + + clip.name = name; + + Skeleton skeleton = new Skeleton(skeletonData); + + List ignoreRotateTimelineIndexes = new List(); + + if (bakeIK) { + foreach (IkConstraint i in skeleton.IkConstraints) { + foreach (Bone b in i.Bones) { + int index = skeleton.FindBoneIndex(b.Data.Name); + ignoreRotateTimelineIndexes.Add(index); + BakeBoneConstraints(b, animation, clip); + } + } + } + + foreach (Bone b in skeleton.Bones) { + if (!b.Data.TransformMode.InheritsRotation()) { + int index = skeleton.FindBoneIndex(b.Data.Name); + + if (ignoreRotateTimelineIndexes.Contains(index) == false) { + ignoreRotateTimelineIndexes.Add(index); + BakeBoneConstraints(b, animation, clip); + } + } + } + + foreach (Timeline t in timelines) { + skeleton.SetToSetupPose(); + + if (t is ScaleTimeline) { + ParseScaleTimeline(skeleton, (ScaleTimeline)t, clip); + } else if (t is TranslateTimeline) { + ParseTranslateTimeline(skeleton, (TranslateTimeline)t, clip); + } else if (t is RotateTimeline) { + //bypass any rotation keys if they're going to get baked anyway to prevent localEulerAngles vs Baked collision + if (ignoreRotateTimelineIndexes.Contains(((RotateTimeline)t).BoneIndex) == false) + ParseRotateTimeline(skeleton, (RotateTimeline)t, clip); + } else if (t is AttachmentTimeline) { + ParseAttachmentTimeline(skeleton, (AttachmentTimeline)t, slotLookup, clip); + } else if (t is EventTimeline) { + ParseEventTimeline((EventTimeline)t, clip, eventOptions); + } + + } + + var settings = AnimationUtility.GetAnimationClipSettings(clip); + settings.loopTime = true; + settings.stopTime = Mathf.Max(clip.length, 0.001f); + + SetAnimationSettings(clip, settings); + + clip.EnsureQuaternionContinuity(); + + EditorUtility.SetDirty(clip); + + return clip; + } + + static int BinarySearch (float[] values, float target) { + int low = 0; + int high = values.Length - 2; + if (high == 0) return 1; + int current = (int)((uint)high >> 1); + while (true) { + if (values[(current + 1)] <= target) + low = current + 1; + else + high = current; + + if (low == high) return (low + 1); + current = (int)((uint)(low + high) >> 1); + } + } + + static void BakeBoneConstraints (Bone bone, Spine.Animation animation, AnimationClip clip) { + Skeleton skeleton = bone.Skeleton; + bool inheritRotation = bone.Data.TransformMode.InheritsRotation(); + + animation.Apply(skeleton, 0, 0, false, null, 1f, MixBlend.Setup, MixDirection.In); + skeleton.UpdateWorldTransform(); + float duration = animation.Duration; + + AnimationCurve curve = new AnimationCurve(); + + List keys = new List(); + + float rotation = bone.AppliedRotation; + if (!inheritRotation) + rotation = GetUninheritedAppliedRotation(bone); + + keys.Add(new Keyframe(0, rotation, 0, 0)); + + int listIndex = 1; + + float r = rotation; + + int steps = Mathf.CeilToInt(duration / BakeIncrement); + + float currentTime = 0; + float angle = rotation; + + for (int i = 1; i <= steps; i++) { + currentTime += BakeIncrement; + if (i == steps) + currentTime = duration; + + animation.Apply(skeleton, 0, currentTime, true, null, 1f, MixBlend.Setup, MixDirection.In); + skeleton.UpdateWorldTransform(); + + int pIndex = listIndex - 1; + + Keyframe pk = keys[pIndex]; + + pk = keys[pIndex]; + + rotation = inheritRotation ? bone.AppliedRotation : GetUninheritedAppliedRotation(bone); + + angle += Mathf.DeltaAngle(angle, rotation); + + r = angle; + + float rOut = (r - pk.value) / (currentTime - pk.time); + + pk.outTangent = rOut; + + keys.Add(new Keyframe(currentTime, r, rOut, 0)); + + keys[pIndex] = pk; + + listIndex++; + } + + curve = EnsureCurveKeyCount(new AnimationCurve(keys.ToArray())); + + string path = GetPath(bone.Data); + string propertyName = "localEulerAnglesBaked"; + + EditorCurveBinding xBind = EditorCurveBinding.FloatCurve(path, typeof(Transform), propertyName + ".x"); + AnimationUtility.SetEditorCurve(clip, xBind, new AnimationCurve()); + EditorCurveBinding yBind = EditorCurveBinding.FloatCurve(path, typeof(Transform), propertyName + ".y"); + AnimationUtility.SetEditorCurve(clip, yBind, new AnimationCurve()); + EditorCurveBinding zBind = EditorCurveBinding.FloatCurve(path, typeof(Transform), propertyName + ".z"); + AnimationUtility.SetEditorCurve(clip, zBind, curve); + } + + static void ParseTranslateTimeline (Skeleton skeleton, TranslateTimeline timeline, AnimationClip clip) { + var boneData = skeleton.Data.Bones.Items[timeline.BoneIndex]; + var bone = skeleton.Bones.Items[timeline.BoneIndex]; + + AnimationCurve xCurve = new AnimationCurve(); + AnimationCurve yCurve = new AnimationCurve(); + AnimationCurve zCurve = new AnimationCurve(); + + float endTime = timeline.Frames[(timeline.FrameCount * 3) - 3]; + + float currentTime = timeline.Frames[0]; + + List xKeys = new List(); + List yKeys = new List(); + + xKeys.Add(new Keyframe(timeline.Frames[0], timeline.Frames[1] + boneData.X, 0, 0)); + yKeys.Add(new Keyframe(timeline.Frames[0], timeline.Frames[2] + boneData.Y, 0, 0)); + + int listIndex = 1; + int frameIndex = 1; + int f = 3; + float[] frames = timeline.Frames; + skeleton.SetToSetupPose(); + float lastTime = 0; + while (currentTime < endTime) { + int pIndex = listIndex - 1; + + float curveType = timeline.GetCurveType(frameIndex - 1); + if (curveType == 0) { + //linear + Keyframe px = xKeys[pIndex]; + Keyframe py = yKeys[pIndex]; + + float time = frames[f]; + float x = frames[f + 1] + boneData.X; + float y = frames[f + 2] + boneData.Y; + + float xOut = (x - px.value) / (time - px.time); + float yOut = (y - py.value) / (time - py.time); + + px.outTangent = xOut; + py.outTangent = yOut; + + xKeys.Add(new Keyframe(time, x, xOut, 0)); + yKeys.Add(new Keyframe(time, y, yOut, 0)); + + xKeys[pIndex] = px; + yKeys[pIndex] = py; + + currentTime = time; + + timeline.Apply(skeleton, lastTime, currentTime, null, 1, MixBlend.Setup, MixDirection.In); + + lastTime = time; + listIndex++; + } else if (curveType == 1) { + //stepped + Keyframe px = xKeys[pIndex]; + Keyframe py = yKeys[pIndex]; + + float time = frames[f]; + float x = frames[f + 1] + boneData.X; + float y = frames[f + 2] + boneData.Y; + + float xOut = float.PositiveInfinity; + float yOut = float.PositiveInfinity; + + px.outTangent = xOut; + py.outTangent = yOut; + + xKeys.Add(new Keyframe(time, x, xOut, 0)); + yKeys.Add(new Keyframe(time, y, yOut, 0)); + + xKeys[pIndex] = px; + yKeys[pIndex] = py; + + currentTime = time; + + timeline.Apply(skeleton, lastTime, currentTime, null, 1, MixBlend.Setup, MixDirection.In); + + lastTime = time; + listIndex++; + } else if (curveType == 2) { + + //bezier + Keyframe px = xKeys[pIndex]; + Keyframe py = yKeys[pIndex]; + + float time = frames[f]; + + int steps = Mathf.FloorToInt((time - px.time) / BakeIncrement); + + for (int i = 1; i <= steps; i++) { + currentTime += BakeIncrement; + if (i == steps) + currentTime = time; + + timeline.Apply(skeleton, lastTime, currentTime, null, 1, MixBlend.Setup, MixDirection.In); + + px = xKeys[listIndex - 1]; + py = yKeys[listIndex - 1]; + + float xOut = (bone.X - px.value) / (currentTime - px.time); + float yOut = (bone.Y - py.value) / (currentTime - py.time); + + px.outTangent = xOut; + py.outTangent = yOut; + + xKeys.Add(new Keyframe(currentTime, bone.X, xOut, 0)); + yKeys.Add(new Keyframe(currentTime, bone.Y, yOut, 0)); + + xKeys[listIndex - 1] = px; + yKeys[listIndex - 1] = py; + + listIndex++; + lastTime = currentTime; + } + } + + frameIndex++; + f += 3; + } + + xCurve = EnsureCurveKeyCount(new AnimationCurve(xKeys.ToArray())); + yCurve = EnsureCurveKeyCount(new AnimationCurve(yKeys.ToArray())); + + + + string path = GetPath(boneData); + const string propertyName = "localPosition"; + + clip.SetCurve(path, typeof(Transform), propertyName + ".x", xCurve); + clip.SetCurve(path, typeof(Transform), propertyName + ".y", yCurve); + clip.SetCurve(path, typeof(Transform), propertyName + ".z", zCurve); + } + + static void ParseScaleTimeline (Skeleton skeleton, ScaleTimeline timeline, AnimationClip clip) { + var boneData = skeleton.Data.Bones.Items[timeline.BoneIndex]; + var bone = skeleton.Bones.Items[timeline.BoneIndex]; + + AnimationCurve xCurve = new AnimationCurve(); + AnimationCurve yCurve = new AnimationCurve(); + AnimationCurve zCurve = new AnimationCurve(); + + float endTime = timeline.Frames[(timeline.FrameCount * 3) - 3]; + + float currentTime = timeline.Frames[0]; + + List xKeys = new List(); + List yKeys = new List(); + + xKeys.Add(new Keyframe(timeline.Frames[0], timeline.Frames[1] * boneData.ScaleX, 0, 0)); + yKeys.Add(new Keyframe(timeline.Frames[0], timeline.Frames[2] * boneData.ScaleY, 0, 0)); + + int listIndex = 1; + int frameIndex = 1; + int f = 3; + float[] frames = timeline.Frames; + skeleton.SetToSetupPose(); + float lastTime = 0; + while (currentTime < endTime) { + int pIndex = listIndex - 1; + float curveType = timeline.GetCurveType(frameIndex - 1); + + if (curveType == 0) { + //linear + Keyframe px = xKeys[pIndex]; + Keyframe py = yKeys[pIndex]; + + float time = frames[f]; + float x = frames[f + 1] * boneData.ScaleX; + float y = frames[f + 2] * boneData.ScaleY; + + float xOut = (x - px.value) / (time - px.time); + float yOut = (y - py.value) / (time - py.time); + + px.outTangent = xOut; + py.outTangent = yOut; + + xKeys.Add(new Keyframe(time, x, xOut, 0)); + yKeys.Add(new Keyframe(time, y, yOut, 0)); + + xKeys[pIndex] = px; + yKeys[pIndex] = py; + + currentTime = time; + + timeline.Apply(skeleton, lastTime, currentTime, null, 1, MixBlend.Setup, MixDirection.In); + + lastTime = time; + listIndex++; + } else if (curveType == 1) { + //stepped + Keyframe px = xKeys[pIndex]; + Keyframe py = yKeys[pIndex]; + + float time = frames[f]; + float x = frames[f + 1] * boneData.ScaleX; + float y = frames[f + 2] * boneData.ScaleY; + + float xOut = float.PositiveInfinity; + float yOut = float.PositiveInfinity; + + px.outTangent = xOut; + py.outTangent = yOut; + + xKeys.Add(new Keyframe(time, x, xOut, 0)); + yKeys.Add(new Keyframe(time, y, yOut, 0)); + + xKeys[pIndex] = px; + yKeys[pIndex] = py; + + currentTime = time; + + timeline.Apply(skeleton, lastTime, currentTime, null, 1, MixBlend.Setup, MixDirection.In); + + lastTime = time; + listIndex++; + } else if (curveType == 2) { + //bezier + Keyframe px = xKeys[pIndex]; + Keyframe py = yKeys[pIndex]; + + float time = frames[f]; + + int steps = Mathf.FloorToInt((time - px.time) / BakeIncrement); + + for (int i = 1; i <= steps; i++) { + currentTime += BakeIncrement; + if (i == steps) + currentTime = time; + + timeline.Apply(skeleton, lastTime, currentTime, null, 1, MixBlend.Setup, MixDirection.In); + + px = xKeys[listIndex - 1]; + py = yKeys[listIndex - 1]; + + float xOut = (bone.ScaleX - px.value) / (currentTime - px.time); + float yOut = (bone.ScaleY - py.value) / (currentTime - py.time); + + px.outTangent = xOut; + py.outTangent = yOut; + + xKeys.Add(new Keyframe(currentTime, bone.ScaleX, xOut, 0)); + yKeys.Add(new Keyframe(currentTime, bone.ScaleY, yOut, 0)); + + xKeys[listIndex - 1] = px; + yKeys[listIndex - 1] = py; + + listIndex++; + lastTime = currentTime; + } + } + + frameIndex++; + f += 3; + } + + xCurve = EnsureCurveKeyCount(new AnimationCurve(xKeys.ToArray())); + yCurve = EnsureCurveKeyCount(new AnimationCurve(yKeys.ToArray())); + + string path = GetPath(boneData); + string propertyName = "localScale"; + + clip.SetCurve(path, typeof(Transform), propertyName + ".x", xCurve); + clip.SetCurve(path, typeof(Transform), propertyName + ".y", yCurve); + clip.SetCurve(path, typeof(Transform), propertyName + ".z", zCurve); + } + + static void ParseRotateTimeline (Skeleton skeleton, RotateTimeline timeline, AnimationClip clip) { + var boneData = skeleton.Data.Bones.Items[timeline.BoneIndex]; + var bone = skeleton.Bones.Items[timeline.BoneIndex]; + + var curve = new AnimationCurve(); + + float endTime = timeline.Frames[(timeline.FrameCount * 2) - 2]; + + float currentTime = timeline.Frames[0]; + + var keys = new List(); + + float rotation = timeline.Frames[1] + boneData.Rotation; + + keys.Add(new Keyframe(timeline.Frames[0], rotation, 0, 0)); + + int listIndex = 1; + int frameIndex = 1; + int f = 2; + float[] frames = timeline.Frames; + skeleton.SetToSetupPose(); + float lastTime = 0; + float angle = rotation; + while (currentTime < endTime) { + int pIndex = listIndex - 1; + float curveType = timeline.GetCurveType(frameIndex - 1); + + if (curveType == 0) { + //linear + Keyframe pk = keys[pIndex]; + + float time = frames[f]; + + rotation = frames[f + 1] + boneData.Rotation; + angle += Mathf.DeltaAngle(angle, rotation); + float r = angle; + + float rOut = (r - pk.value) / (time - pk.time); + + pk.outTangent = rOut; + + keys.Add(new Keyframe(time, r, rOut, 0)); + + keys[pIndex] = pk; + + currentTime = time; + + timeline.Apply(skeleton, lastTime, currentTime, null, 1, MixBlend.Setup, MixDirection.In); + + lastTime = time; + listIndex++; + } else if (curveType == 1) { + //stepped + + Keyframe pk = keys[pIndex]; + + float time = frames[f]; + + rotation = frames[f + 1] + boneData.Rotation; + angle += Mathf.DeltaAngle(angle, rotation); + float r = angle; + + float rOut = float.PositiveInfinity; + + pk.outTangent = rOut; + + keys.Add(new Keyframe(time, r, rOut, 0)); + + keys[pIndex] = pk; + + currentTime = time; + + timeline.Apply(skeleton, lastTime, currentTime, null, 1, MixBlend.Setup, MixDirection.In); + + lastTime = time; + listIndex++; + } else if (curveType == 2) { + //bezier + Keyframe pk = keys[pIndex]; + + float time = frames[f]; + + timeline.Apply(skeleton, lastTime, currentTime, null, 1, MixBlend.Setup, MixDirection.In); + skeleton.UpdateWorldTransform(); + + rotation = frames[f + 1] + boneData.Rotation; + angle += Mathf.DeltaAngle(angle, rotation); + float r = angle; + + int steps = Mathf.FloorToInt((time - pk.time) / BakeIncrement); + + for (int i = 1; i <= steps; i++) { + currentTime += BakeIncrement; + if (i == steps) + currentTime = time; + + timeline.Apply(skeleton, lastTime, currentTime, null, 1, MixBlend.Setup, MixDirection.In); + skeleton.UpdateWorldTransform(); + pk = keys[listIndex - 1]; + + rotation = bone.Rotation; + angle += Mathf.DeltaAngle(angle, rotation); + r = angle; + + float rOut = (r - pk.value) / (currentTime - pk.time); + + pk.outTangent = rOut; + + keys.Add(new Keyframe(currentTime, r, rOut, 0)); + + keys[listIndex - 1] = pk; + + listIndex++; + lastTime = currentTime; + } + } + + frameIndex++; + f += 2; + } + + curve = EnsureCurveKeyCount(new AnimationCurve(keys.ToArray())); + + string path = GetPath(boneData); + const string propertyName = "localEulerAnglesBaked"; + + EditorCurveBinding xBind = EditorCurveBinding.FloatCurve(path, typeof(Transform), propertyName + ".x"); + AnimationUtility.SetEditorCurve(clip, xBind, new AnimationCurve()); + EditorCurveBinding yBind = EditorCurveBinding.FloatCurve(path, typeof(Transform), propertyName + ".y"); + AnimationUtility.SetEditorCurve(clip, yBind, new AnimationCurve()); + EditorCurveBinding zBind = EditorCurveBinding.FloatCurve(path, typeof(Transform), propertyName + ".z"); + AnimationUtility.SetEditorCurve(clip, zBind, curve); + } + + static void ParseEventTimeline (EventTimeline timeline, AnimationClip clip, SendMessageOptions eventOptions) { + float[] frames = timeline.Frames; + var events = timeline.Events; + + var animEvents = new List(); + for (int i = 0, n = frames.Length; i < n; i++) { + var spineEvent = events[i]; + string eventName = spineEvent.Data.Name; + if (SpineEditorUtilities.Preferences.mecanimEventIncludeFolderName) + eventName = eventName.Replace("/", ""); // calls method FolderNameEventName() + else + eventName = eventName.Substring(eventName.LastIndexOf('/') + 1); // calls method EventName() + var unityAnimationEvent = new AnimationEvent { + time = frames[i], + functionName = eventName, + messageOptions = eventOptions + }; + + if (!string.IsNullOrEmpty(spineEvent.String)) { + unityAnimationEvent.stringParameter = spineEvent.String; + } else if (spineEvent.Int != 0) { + unityAnimationEvent.intParameter = spineEvent.Int; + } else if (spineEvent.Float != 0) { + unityAnimationEvent.floatParameter = spineEvent.Float; + } // else, paramless function/Action. + + animEvents.Add(unityAnimationEvent); + } + + AnimationUtility.SetAnimationEvents(clip, animEvents.ToArray()); + } + + static void ParseAttachmentTimeline (Skeleton skeleton, AttachmentTimeline timeline, Dictionary> slotLookup, AnimationClip clip) { + var attachmentNames = slotLookup[timeline.SlotIndex]; + + string bonePath = GetPath(skeleton.Slots.Items[timeline.SlotIndex].Bone.Data); + string slotPath = bonePath + "/" + skeleton.Slots.Items[timeline.SlotIndex].Data.Name; + + Dictionary curveTable = new Dictionary(); + + foreach (string str in attachmentNames) { + curveTable.Add(str, new AnimationCurve()); + } + + float[] frames = timeline.Frames; + + if (frames[0] != 0) { + string startingName = skeleton.Slots.Items[timeline.SlotIndex].Data.AttachmentName; + foreach (var pair in curveTable) { + if (startingName == "" || startingName == null) { + pair.Value.AddKey(new Keyframe(0, 0, float.PositiveInfinity, float.PositiveInfinity)); + } else { + if (pair.Key == startingName) { + pair.Value.AddKey(new Keyframe(0, 1, float.PositiveInfinity, float.PositiveInfinity)); + } else { + pair.Value.AddKey(new Keyframe(0, 0, float.PositiveInfinity, float.PositiveInfinity)); + } + } + } + } + + float currentTime = timeline.Frames[0]; + float endTime = frames[frames.Length - 1]; + int f = 0; + while (currentTime < endTime) { + float time = frames[f]; + + int frameIndex = (time >= frames[frames.Length - 1] ? frames.Length : BinarySearch(frames, time)) - 1; + + string name = timeline.AttachmentNames[frameIndex]; + foreach (var pair in curveTable) { + if (name == "") { + pair.Value.AddKey(new Keyframe(time, 0, float.PositiveInfinity, float.PositiveInfinity)); + } else { + if (pair.Key == name) { + pair.Value.AddKey(new Keyframe(time, 1, float.PositiveInfinity, float.PositiveInfinity)); + } else { + pair.Value.AddKey(new Keyframe(time, 0, float.PositiveInfinity, float.PositiveInfinity)); + } + } + } + + currentTime = time; + f += 1; + } + + foreach (var pair in curveTable) { + string path = slotPath + "/" + pair.Key; + string prop = "m_IsActive"; + + clip.SetCurve(path, typeof(GameObject), prop, pair.Value); + } + } + + static AnimationCurve EnsureCurveKeyCount (AnimationCurve curve) { + if (curve.length == 1) + curve.AddKey(curve.keys[0].time + 0.25f, curve.keys[0].value); + + return curve; + } + + static float GetUninheritedAppliedRotation (Bone b) { + Bone parent = b.Parent; + float angle = b.AppliedRotation; + + while (parent != null) { + angle -= parent.AppliedRotation; + parent = parent.Parent; + } + + return angle; + } +#endregion +#endregion + +#region Region Baking + public static GameObject BakeRegion (SpineAtlasAsset atlasAsset, AtlasRegion region, bool autoSave = true) { + atlasAsset.GetAtlas(); // Initializes atlasAsset. + + string atlasAssetPath = AssetDatabase.GetAssetPath(atlasAsset); + string atlasAssetDirPath = Path.GetDirectoryName(atlasAssetPath).Replace('\\', '/'); + string bakedDirPath = Path.Combine(atlasAssetDirPath, atlasAsset.name); + string bakedPrefabPath = Path.Combine(bakedDirPath, AssetUtility.GetPathSafeName(region.name) + ".prefab").Replace("\\", "/"); + + GameObject prefab = (GameObject)AssetDatabase.LoadAssetAtPath(bakedPrefabPath, typeof(GameObject)); + GameObject root; + Mesh mesh; + bool isNewPrefab = false; + + if (!Directory.Exists(bakedDirPath)) + Directory.CreateDirectory(bakedDirPath); + + if (prefab == null) { + root = EditorInstantiation.NewGameObject("temp", true, typeof(MeshFilter), typeof(MeshRenderer)); + #if NEW_PREFAB_SYSTEM + prefab = PrefabUtility.SaveAsPrefabAsset(root, bakedPrefabPath); + #else + prefab = PrefabUtility.CreatePrefab(bakedPrefabPath, root); + #endif + + isNewPrefab = true; + Object.DestroyImmediate(root); + } + + mesh = (Mesh)AssetDatabase.LoadAssetAtPath(bakedPrefabPath, typeof(Mesh)); + + Material mat = null; + mesh = atlasAsset.GenerateMesh(region.name, mesh, out mat); + if (isNewPrefab) { + AssetDatabase.AddObjectToAsset(mesh, prefab); + prefab.GetComponent().sharedMesh = mesh; + } + + EditorUtility.SetDirty(mesh); + EditorUtility.SetDirty(prefab); + + if (autoSave) { + AssetDatabase.SaveAssets(); + AssetDatabase.Refresh(); + } + + prefab.GetComponent().sharedMaterial = mat; + + return prefab; + } +#endregion + + static string GetPath (BoneData b) { + return GetPathRecurse(b).Substring(1); + } + + static string GetPathRecurse (BoneData b) { + if (b == null) return ""; + return GetPathRecurse(b.Parent) + "/" + b.Name; + } + + static void SetAnimationSettings (AnimationClip clip, AnimationClipSettings settings) { + AnimationUtility.SetAnimationClipSettings(clip, settings); + } + + + } + +} diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/Windows/SkeletonBaker.cs.meta b/box1/Assets/Spine/Editor/spine-unity/Editor/Windows/SkeletonBaker.cs.meta new file mode 100644 index 00000000..37b13c99 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/Windows/SkeletonBaker.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 687d9be457ea4eb44bf09c35c95ee5cd +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/Windows/SkeletonBakingWindow.cs b/box1/Assets/Spine/Editor/spine-unity/Editor/Windows/SkeletonBakingWindow.cs new file mode 100644 index 00000000..62870d00 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/Windows/SkeletonBakingWindow.cs @@ -0,0 +1,174 @@ +/****************************************************************************** + * 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.Collections; +using System.Collections.Generic; +using UnityEngine; +using UnityEditor; + +namespace Spine.Unity.Editor { + + using Editor = UnityEditor.Editor; + using Icons = SpineEditorUtilities.Icons; + + public class SkeletonBakingWindow : EditorWindow { + const bool IsUtilityWindow = true; + + [MenuItem("CONTEXT/SkeletonDataAsset/Skeleton Baking", false, 5000)] + public static void Init (MenuCommand command) { + var window = EditorWindow.GetWindow(IsUtilityWindow); + window.minSize = new Vector2(330f, 530f); + window.maxSize = new Vector2(600f, 1000f); + window.titleContent = new GUIContent("Skeleton Baking", Icons.spine); + window.skeletonDataAsset = command.context as SkeletonDataAsset; + window.Show(); + } + + public SkeletonDataAsset skeletonDataAsset; + [SpineSkin(dataField:"skeletonDataAsset")] + public string skinToBake = "default"; + + // Settings + bool bakeAnimations = false; + bool bakeIK = true; + SendMessageOptions bakeEventOptions; + + SerializedObject so; + Skin bakeSkin; + + + void DataAssetChanged () { + bakeSkin = null; + } + + void OnGUI () { + so = so ?? new SerializedObject(this); + + EditorGUIUtility.wideMode = true; + EditorGUILayout.LabelField("Spine Skeleton Prefab Baking", EditorStyles.boldLabel); + + const string BakingWarningMessage = "\nSkeleton baking is not the primary use case for Spine skeletons." + + "\nUse baking if you have specialized uses, such as simplified skeletons with movement driven by physics." + + + "\n\nBaked Skeletons do not support the following:" + + "\n\tDisabled rotation or scale inheritance" + + "\n\tLocal Shear" + + "\n\tAll Constraint types" + + "\n\tWeighted mesh verts with more than 4 bound bones" + + + "\n\nBaked Animations do not support the following:" + + "\n\tMesh Deform Keys" + + "\n\tColor Keys" + + "\n\tDraw Order Keys" + + + "\n\nAnimation Curves are sampled at 60fps and are not realtime." + + "\nConstraint animations are also baked into animation curves." + + "\nSee SkeletonBaker.cs comments for full details.\n"; + + EditorGUILayout.HelpBox(BakingWarningMessage, MessageType.Info, true); + + EditorGUI.BeginChangeCheck(); + var skeletonDataAssetProperty = so.FindProperty("skeletonDataAsset"); + EditorGUILayout.PropertyField(skeletonDataAssetProperty, SpineInspectorUtility.TempContent("SkeletonDataAsset", Icons.spine)); + if (EditorGUI.EndChangeCheck()) { + so.ApplyModifiedProperties(); + DataAssetChanged(); + } + EditorGUILayout.Space(); + + if (skeletonDataAsset == null) return; + var skeletonData = skeletonDataAsset.GetSkeletonData(false); + if (skeletonData == null) return; + bool hasExtraSkins = skeletonData.Skins.Count > 1; + + using (new SpineInspectorUtility.BoxScope(false)) { + EditorGUILayout.LabelField(skeletonDataAsset.name, EditorStyles.boldLabel); + using (new SpineInspectorUtility.IndentScope()) { + EditorGUILayout.LabelField(SpineInspectorUtility.TempContent("Bones: " + skeletonData.Bones.Count, Icons.bone)); + EditorGUILayout.LabelField(SpineInspectorUtility.TempContent("Slots: " + skeletonData.Slots.Count, Icons.slotRoot)); + + if (hasExtraSkins) { + EditorGUILayout.LabelField(SpineInspectorUtility.TempContent("Skins: " + skeletonData.Skins.Count, Icons.skinsRoot)); + EditorGUILayout.LabelField(SpineInspectorUtility.TempContent("Current skin attachments: " + (bakeSkin == null ? 0 : bakeSkin.Attachments.Count), Icons.skinPlaceholder)); + } else if (skeletonData.Skins.Count == 1) { + EditorGUILayout.LabelField(SpineInspectorUtility.TempContent("Skins: 1 (only default Skin)", Icons.skinsRoot)); + } + + int totalAttachments = 0; + foreach (var s in skeletonData.Skins) + totalAttachments += s.Attachments.Count; + EditorGUILayout.LabelField(SpineInspectorUtility.TempContent("Total Attachments: " + totalAttachments, Icons.genericAttachment)); + } + } + using (new SpineInspectorUtility.BoxScope(false)) { + EditorGUILayout.LabelField("Animations", EditorStyles.boldLabel); + EditorGUILayout.LabelField(SpineInspectorUtility.TempContent("Animations: " + skeletonData.Animations.Count, Icons.animation)); + + using (new SpineInspectorUtility.IndentScope()) { + bakeAnimations = EditorGUILayout.Toggle(SpineInspectorUtility.TempContent("Bake Animations", Icons.animationRoot), bakeAnimations); + using (new EditorGUI.DisabledScope(!bakeAnimations)) { + using (new SpineInspectorUtility.IndentScope()) { + bakeIK = EditorGUILayout.Toggle(SpineInspectorUtility.TempContent("Bake IK", Icons.constraintIK), bakeIK); + bakeEventOptions = (SendMessageOptions)EditorGUILayout.EnumPopup(SpineInspectorUtility.TempContent("Event Options", Icons.userEvent), bakeEventOptions); + } + } + } + } + EditorGUILayout.Space(); + + if (!string.IsNullOrEmpty(skinToBake) && UnityEngine.Event.current.type == EventType.Repaint) + bakeSkin = skeletonData.FindSkin(skinToBake) ?? skeletonData.DefaultSkin; + + var prefabIcon = EditorGUIUtility.FindTexture("PrefabModel Icon"); + + if (hasExtraSkins) { + EditorGUI.BeginChangeCheck(); + EditorGUILayout.PropertyField(so.FindProperty("skinToBake")); + if (EditorGUI.EndChangeCheck()) { + so.ApplyModifiedProperties(); + Repaint(); + } + + if (SpineInspectorUtility.LargeCenteredButton(SpineInspectorUtility.TempContent(string.Format("Bake Skeleton with Skin ({0})", (bakeSkin == null ? "default" : bakeSkin.Name)), prefabIcon))) { + SkeletonBaker.BakeToPrefab(skeletonDataAsset, new ExposedList(new[] { bakeSkin }), "", bakeAnimations, bakeIK, bakeEventOptions); + } + + if (SpineInspectorUtility.LargeCenteredButton(SpineInspectorUtility.TempContent(string.Format("Bake All ({0} skins)", skeletonData.Skins.Count), prefabIcon))) { + SkeletonBaker.BakeToPrefab(skeletonDataAsset, skeletonData.Skins, "", bakeAnimations, bakeIK, bakeEventOptions); + } + } else { + if (SpineInspectorUtility.LargeCenteredButton(SpineInspectorUtility.TempContent("Bake Skeleton", prefabIcon))) { + SkeletonBaker.BakeToPrefab(skeletonDataAsset, new ExposedList(new[] { bakeSkin }), "", bakeAnimations, bakeIK, bakeEventOptions); + } + + } + + } + } +} diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/Windows/SkeletonBakingWindow.cs.meta b/box1/Assets/Spine/Editor/spine-unity/Editor/Windows/SkeletonBakingWindow.cs.meta new file mode 100644 index 00000000..4e1aa1dc --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/Windows/SkeletonBakingWindow.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 868b0caae5b3e65408ece1ab400c4a99 +timeCreated: 1495203966 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/Windows/SkeletonDebugWindow.cs b/box1/Assets/Spine/Editor/spine-unity/Editor/Windows/SkeletonDebugWindow.cs new file mode 100644 index 00000000..4170a554 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/Windows/SkeletonDebugWindow.cs @@ -0,0 +1,592 @@ +/****************************************************************************** + * 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. + *****************************************************************************/ + +// With contributions from: Mitch Thompson + +#if UNITY_2018_3 || UNITY_2019 || UNITY_2018_3_OR_NEWER +#define NEW_PREFAB_SYSTEM +#else +#define NO_PREFAB_MESH +#endif + +using System.Collections.Generic; +using UnityEngine; +using UnityEditor; +using UnityEditor.AnimatedValues; + +namespace Spine.Unity.Editor { + using Editor = UnityEditor.Editor; + using Icons = SpineEditorUtilities.Icons; + + public class SkeletonDebugWindow : EditorWindow { + + const bool IsUtilityWindow = true; + internal static bool showBoneNames, showPaths = true, showShapes = true, showConstraints = true; + + [MenuItem("CONTEXT/SkeletonRenderer/Open Skeleton Debug Window", false, 5000)] + public static void Init () { + var window = EditorWindow.GetWindow(IsUtilityWindow); + window.minSize = new Vector2(330f, 360f); + window.maxSize = new Vector2(600f, 4000f); + window.titleContent = new GUIContent("Skeleton Debug", Icons.spine); + window.Show(); + window.OnSelectionChange(); + } + + + static AnimBool showSkeleton = new AnimBool(true); + static AnimBool showSlotsTree = new AnimBool(false); + static AnimBool showConstraintsTree = new AnimBool(false); + static AnimBool showDrawOrderTree = new AnimBool(false); + static AnimBool showEventDataTree = new AnimBool(false); + static AnimBool showDataTree = new AnimBool(false); + static AnimBool showInspectBoneTree = new AnimBool(false); + + Vector2 scrollPos; + + GUIContent SlotsRootLabel, SkeletonRootLabel; + GUIStyle BoldFoldoutStyle; + + public SkeletonRenderer skeletonRenderer; + Skeleton skeleton; + Skin activeSkin; + bool isPrefab; + + SerializedProperty bpo; + Bone bone; + + [SpineBone(dataField:"skeletonRenderer")] + public string boneName; + + readonly Dictionary> attachmentTable = new Dictionary>(); + + static bool staticLostValues = true; + + void OnSceneGUI (SceneView sceneView) { + if (skeleton == null || skeletonRenderer == null || !skeletonRenderer.valid || isPrefab) + return; + + var transform = skeletonRenderer.transform; + if (showPaths) SpineHandles.DrawPaths(transform, skeleton); + if (showConstraints) SpineHandles.DrawConstraints(transform, skeleton); + if (showBoneNames) SpineHandles.DrawBoneNames(transform, skeleton); + if (showShapes) SpineHandles.DrawBoundingBoxes(transform, skeleton); + + if (bone != null) { + SpineHandles.DrawBone(skeletonRenderer.transform, bone, 1.5f, Color.cyan); + Handles.Label(bone.GetWorldPosition(skeletonRenderer.transform) + (Vector3.down * 0.15f), bone.Data.Name, SpineHandles.BoneNameStyle); + } + } + + void OnSelectionChange () { + #if UNITY_2019_1_OR_NEWER + SceneView.duringSceneGui -= this.OnSceneGUI; + SceneView.duringSceneGui += this.OnSceneGUI; + #else + SceneView.onSceneGUIDelegate -= this.OnSceneGUI; + SceneView.onSceneGUIDelegate += this.OnSceneGUI; + #endif + + bool noSkeletonRenderer = false; + + var selectedObject = Selection.activeGameObject; + if (selectedObject == null) { + noSkeletonRenderer = true; + } else { + var selectedSkeletonRenderer = selectedObject.GetComponent(); + if (selectedSkeletonRenderer == null) { + noSkeletonRenderer = true; + } else if (skeletonRenderer != selectedSkeletonRenderer) { + + bone = null; + if (skeletonRenderer != null && skeletonRenderer.SkeletonDataAsset != selectedSkeletonRenderer.SkeletonDataAsset) + boneName = null; + + skeletonRenderer = selectedSkeletonRenderer; + skeletonRenderer.Initialize(false); + skeletonRenderer.LateUpdate(); + skeleton = skeletonRenderer.skeleton; +#if NEW_PREFAB_SYSTEM + isPrefab = false; +#else + isPrefab |= PrefabUtility.GetPrefabType(selectedObject) == PrefabType.Prefab; +#endif + UpdateAttachments(); + } + } + + if (noSkeletonRenderer) Clear(); + Repaint(); + } + + void Clear () { + skeletonRenderer = null; + skeleton = null; + attachmentTable.Clear(); + isPrefab = false; + boneName = string.Empty; + bone = null; + #if UNITY_2019_1_OR_NEWER + SceneView.duringSceneGui -= this.OnSceneGUI; + #else + SceneView.onSceneGUIDelegate -= this.OnSceneGUI; + #endif + } + + void OnDestroy () { + Clear(); + } + + static void FalseDropDown (string label, string stringValue, Texture2D icon = null, bool disabledGroup = false) { + if (disabledGroup) EditorGUI.BeginDisabledGroup(true); + var pos = EditorGUILayout.GetControlRect(true); + pos = EditorGUI.PrefixLabel(pos, SpineInspectorUtility.TempContent(label)); + GUI.Button(pos, SpineInspectorUtility.TempContent(stringValue, icon), EditorStyles.popup); + if (disabledGroup) EditorGUI.EndDisabledGroup(); + } + + // Window GUI + void OnGUI () { + bool requireRepaint = false; + + if (staticLostValues) { + Clear(); + OnSelectionChange(); + staticLostValues = false; + requireRepaint = true; + } + + if (SlotsRootLabel == null) { + SlotsRootLabel = new GUIContent("Slots", Icons.slotRoot); + SkeletonRootLabel = new GUIContent("Skeleton", Icons.skeleton); + BoldFoldoutStyle = new GUIStyle(EditorStyles.foldout); + BoldFoldoutStyle.fontStyle = FontStyle.Bold; + BoldFoldoutStyle.stretchWidth = true; + BoldFoldoutStyle.fixedWidth = 0; + } + + + EditorGUILayout.Space(); + EditorGUI.BeginDisabledGroup(true); + EditorGUILayout.ObjectField(SpineInspectorUtility.TempContent("Debug Selection", Icons.spine), skeletonRenderer, typeof(SkeletonRenderer), true); + EditorGUI.EndDisabledGroup(); + + if (skeleton == null || skeletonRenderer == null) { + EditorGUILayout.HelpBox("No SkeletonRenderer Spine GameObject selected.", MessageType.Info); + return; + } + + if (isPrefab) { + EditorGUILayout.HelpBox("SkeletonDebug only debugs Spine GameObjects in the scene.", MessageType.Warning); + return; + } + + if (!skeletonRenderer.valid) { + EditorGUILayout.HelpBox("Spine Component is invalid. Check SkeletonData Asset.", MessageType.Error); + return; + } + + if (activeSkin != skeleton.Skin) + UpdateAttachments(); + + scrollPos = EditorGUILayout.BeginScrollView(scrollPos); + + using (new SpineInspectorUtility.BoxScope(false)) { + if (SpineInspectorUtility.CenteredButton(SpineInspectorUtility.TempContent("Skeleton.SetToSetupPose()"))) { + skeleton.SetToSetupPose(); + requireRepaint = true; + } + + EditorGUI.BeginChangeCheck(); + EditorGUILayout.LabelField("Scene View", EditorStyles.boldLabel); + using (new SpineInspectorUtility.LabelWidthScope()) { + showBoneNames = EditorGUILayout.Toggle("Show Bone Names", showBoneNames); + showPaths = EditorGUILayout.Toggle("Show Paths", showPaths); + showShapes = EditorGUILayout.Toggle("Show Shapes", showShapes); + showConstraints = EditorGUILayout.Toggle("Show Constraints", showConstraints); + } + requireRepaint |= EditorGUI.EndChangeCheck(); + + + // Skeleton + showSkeleton.target = EditorGUILayout.Foldout(showSkeleton.target, SkeletonRootLabel, BoldFoldoutStyle); + if (showSkeleton.faded > 0) { + using (new SpineInspectorUtility.IndentScope()) { + using (new EditorGUILayout.FadeGroupScope(showSkeleton.faded)) { + EditorGUI.BeginChangeCheck(); + + EditorGUI.BeginDisabledGroup(true); + FalseDropDown(".Skin", skeleton.Skin != null ? skeletonRenderer.Skeleton.Skin.Name : "", Icons.skin); + EditorGUI.EndDisabledGroup(); + + // Flip + skeleton.ScaleX = EditorGUILayout.DelayedFloatField(".ScaleX", skeleton.ScaleX); + skeleton.ScaleY = EditorGUILayout.DelayedFloatField(".ScaleY", skeleton.ScaleY); + //EditorGUILayout.BeginHorizontal(GUILayout.MaxWidth(160f)); + ////EditorGUILayout.LabelField("Scale", GUILayout.Width(EditorGUIUtility.labelWidth - 20f)); + //GUILayout.EndHorizontal(); + + // Color + skeleton.SetColor(EditorGUILayout.ColorField(".R .G .B .A", skeleton.GetColor())); + + requireRepaint |= EditorGUI.EndChangeCheck(); + } + } + } + + // Bone + showInspectBoneTree.target = EditorGUILayout.Foldout(showInspectBoneTree.target, SpineInspectorUtility.TempContent("Bone", Icons.bone), BoldFoldoutStyle); + if (showInspectBoneTree.faded > 0) { + using (new SpineInspectorUtility.IndentScope()) { + using (new EditorGUILayout.FadeGroupScope(showInspectBoneTree.faded)) { + showBoneNames = EditorGUILayout.Toggle("Show Bone Names", showBoneNames); + if (bpo == null) bpo = new SerializedObject(this).FindProperty("boneName"); + EditorGUILayout.PropertyField(bpo, SpineInspectorUtility.TempContent("Bone")); + if (!string.IsNullOrEmpty(bpo.stringValue)) { + if (bone == null || bone.Data.Name != bpo.stringValue) { + bone = skeleton.FindBone(bpo.stringValue); + } + + if (bone != null) { + using (new EditorGUI.DisabledGroupScope(true)) { + var wm = EditorGUIUtility.wideMode; + EditorGUIUtility.wideMode = true; + EditorGUILayout.Slider("Local Rotation", ViewRound(bone.Rotation), -180f, 180f); + EditorGUILayout.Vector2Field("Local Position", RoundVector2(bone.X, bone.Y)); + EditorGUILayout.Vector2Field("Local Scale", RoundVector2(bone.ScaleX, bone.ScaleY)); + EditorGUILayout.Vector2Field("Local Shear", RoundVector2(bone.ShearX, bone.ShearY)); + + EditorGUILayout.Space(); + + var boneParent = bone.Parent; + if (boneParent != null) FalseDropDown("Parent", boneParent.Data.Name, Icons.bone); + + const string RoundFormat = "0.##"; + var lw = EditorGUIUtility.labelWidth; + var fw = EditorGUIUtility.fieldWidth; + EditorGUIUtility.labelWidth *= 0.25f; + EditorGUIUtility.fieldWidth *= 0.5f; + EditorGUILayout.LabelField("LocalToWorld"); + + EditorGUILayout.BeginHorizontal(); + EditorGUILayout.Space(); + EditorGUILayout.TextField(".A", bone.A.ToString(RoundFormat)); + EditorGUILayout.TextField(".B", bone.B.ToString(RoundFormat)); + EditorGUILayout.EndHorizontal(); + EditorGUILayout.BeginHorizontal(); + EditorGUILayout.Space(); + EditorGUILayout.TextField(".C", bone.C.ToString(RoundFormat)); + EditorGUILayout.TextField(".D", bone.D.ToString(RoundFormat)); + EditorGUILayout.EndHorizontal(); + + EditorGUIUtility.labelWidth = lw * 0.5f; + EditorGUILayout.BeginHorizontal(); + EditorGUILayout.Space(); + EditorGUILayout.Space(); + EditorGUILayout.TextField(".WorldX", bone.WorldX.ToString(RoundFormat)); + EditorGUILayout.TextField(".WorldY", bone.WorldY.ToString(RoundFormat)); + EditorGUILayout.EndHorizontal(); + + EditorGUIUtility.labelWidth = lw; + EditorGUIUtility.fieldWidth = fw; + EditorGUIUtility.wideMode = wm; + + } + } + requireRepaint = true; + } else { + bone = null; + } + } + } + } + + // Slots + int preSlotsIndent = EditorGUI.indentLevel; + showSlotsTree.target = EditorGUILayout.Foldout(showSlotsTree.target, SlotsRootLabel, BoldFoldoutStyle); + if (showSlotsTree.faded > 0) { + using (new EditorGUILayout.FadeGroupScope(showSlotsTree.faded)) { + if (SpineInspectorUtility.CenteredButton(SpineInspectorUtility.TempContent("Skeleton.SetSlotsToSetupPose()"))) { + skeleton.SetSlotsToSetupPose(); + requireRepaint = true; + } + + int baseIndent = EditorGUI.indentLevel; + foreach (KeyValuePair> pair in attachmentTable) { + Slot slot = pair.Key; + + using (new EditorGUILayout.HorizontalScope()) { + EditorGUI.indentLevel = baseIndent + 1; + EditorGUILayout.LabelField(SpineInspectorUtility.TempContent(slot.Data.Name, Icons.slot), GUILayout.ExpandWidth(false)); + EditorGUI.BeginChangeCheck(); + Color c = EditorGUILayout.ColorField(new Color(slot.R, slot.G, slot.B, slot.A), GUILayout.Width(60)); + if (EditorGUI.EndChangeCheck()) { + slot.SetColor(c); + requireRepaint = true; + } + } + + foreach (var skinEntry in pair.Value) { + var attachment = skinEntry.Attachment; + GUI.contentColor = slot.Attachment == attachment ? Color.white : Color.grey; + EditorGUI.indentLevel = baseIndent + 2; + var icon = Icons.GetAttachmentIcon(attachment); + bool isAttached = (attachment == slot.Attachment); + bool swap = EditorGUILayout.ToggleLeft(SpineInspectorUtility.TempContent(attachment.Name, icon), attachment == slot.Attachment); + if (isAttached != swap) { + slot.Attachment = isAttached ? null : attachment; + requireRepaint = true; + } + GUI.contentColor = Color.white; + } + } + } + } + EditorGUI.indentLevel = preSlotsIndent; + + // Constraints + const string NoneText = ""; + showConstraintsTree.target = EditorGUILayout.Foldout(showConstraintsTree.target, SpineInspectorUtility.TempContent("Constraints", Icons.constraintRoot), BoldFoldoutStyle); + if (showConstraintsTree.faded > 0) { + using (new SpineInspectorUtility.IndentScope()) { + using (new EditorGUILayout.FadeGroupScope(showConstraintsTree.faded)) { + const float MixMin = 0f; + const float MixMax = 1f; + EditorGUI.BeginChangeCheck(); + showConstraints = EditorGUILayout.Toggle("Show Constraints", showConstraints); + requireRepaint |= EditorGUI.EndChangeCheck(); + + EditorGUILayout.Space(); + + EditorGUILayout.LabelField(SpineInspectorUtility.TempContent(string.Format("IK Constraints ({0})", skeleton.IkConstraints.Count), Icons.constraintIK), EditorStyles.boldLabel); + using (new SpineInspectorUtility.IndentScope()) { + if (skeleton.IkConstraints.Count > 0) { + foreach (var c in skeleton.IkConstraints) { + EditorGUILayout.LabelField(SpineInspectorUtility.TempContent(c.Data.Name, Icons.constraintIK)); + FalseDropDown("Goal", c.Data.Target.Name, Icons.bone, true); + using (new EditorGUI.DisabledGroupScope(true)) { + EditorGUILayout.Toggle(SpineInspectorUtility.TempContent("Data.Uniform", tooltip: "Uniformly scales a bone when Ik stretches or compresses."), c.Data.Uniform); + } + + EditorGUI.BeginChangeCheck(); + c.Mix = EditorGUILayout.Slider("Mix", c.Mix, MixMin, MixMax); + c.BendDirection = EditorGUILayout.Toggle(SpineInspectorUtility.TempContent("Bend Clockwise", tooltip: "IkConstraint.BendDirection == 1 if clockwise; -1 if counterclockwise."), c.BendDirection > 0) ? 1 : -1; + c.Compress = EditorGUILayout.Toggle(SpineInspectorUtility.TempContent("Compress", tooltip: "Compress single bone IK when the target too close. Not applied when parent bone has nonuniform scale."), c.Compress); + c.Stretch = EditorGUILayout.Toggle(SpineInspectorUtility.TempContent("Stretch", tooltip: "Stretch the parent bone when the target is out of range. Not applied when parent bone has nonuniform scale."), c.Stretch); + if (EditorGUI.EndChangeCheck()) requireRepaint = true; + + EditorGUILayout.Space(); + } + + } else { + EditorGUILayout.LabelField(NoneText); + } + } + + EditorGUILayout.LabelField(SpineInspectorUtility.TempContent(string.Format("Transform Constraints ({0})", skeleton.TransformConstraints.Count), Icons.constraintTransform), EditorStyles.boldLabel); + using (new SpineInspectorUtility.IndentScope()) { + if (skeleton.TransformConstraints.Count > 0) { + foreach (var c in skeleton.TransformConstraints) { + EditorGUILayout.LabelField(SpineInspectorUtility.TempContent(c.Data.Name, Icons.constraintTransform)); + EditorGUI.BeginDisabledGroup(true); + FalseDropDown("Goal", c.Data.Target.Name, Icons.bone); + EditorGUI.EndDisabledGroup(); + + EditorGUI.BeginChangeCheck(); + c.TranslateMix = EditorGUILayout.Slider("TranslateMix", c.TranslateMix, MixMin, MixMax); + c.RotateMix = EditorGUILayout.Slider("RotateMix", c.RotateMix, MixMin, MixMax); + c.ScaleMix = EditorGUILayout.Slider("ScaleMix", c.ScaleMix, MixMin, MixMax); + c.ShearMix = EditorGUILayout.Slider("ShearMix", c.ShearMix, MixMin, MixMax); + if (EditorGUI.EndChangeCheck()) requireRepaint = true; + + EditorGUILayout.Space(); + } + } else { + EditorGUILayout.LabelField(NoneText); + } + } + + EditorGUILayout.LabelField(SpineInspectorUtility.TempContent(string.Format("Path Constraints ({0})", skeleton.PathConstraints.Count), Icons.constraintPath), EditorStyles.boldLabel); + + EditorGUI.BeginChangeCheck(); + showPaths = EditorGUILayout.Toggle("Show Paths", showPaths); + requireRepaint |= EditorGUI.EndChangeCheck(); + + using (new SpineInspectorUtility.IndentScope()) { + if (skeleton.PathConstraints.Count > 0) { + foreach (var c in skeleton.PathConstraints) { + EditorGUILayout.LabelField(SpineInspectorUtility.TempContent(c.Data.Name, Icons.constraintPath)); + EditorGUI.BeginDisabledGroup(true); + FalseDropDown("Path Slot", c.Data.Target.Name, Icons.slot); + var activeAttachment = c.Target.Attachment; + FalseDropDown("Active Path", activeAttachment != null ? activeAttachment.Name : "", activeAttachment is PathAttachment ? Icons.path : null); + EditorGUILayout.LabelField("PositionMode." + c.Data.PositionMode); + EditorGUILayout.LabelField("SpacingMode." + c.Data.SpacingMode); + EditorGUILayout.LabelField("RotateMode." + c.Data.RotateMode); + EditorGUI.EndDisabledGroup(); + + EditorGUI.BeginChangeCheck(); + c.RotateMix = EditorGUILayout.Slider("RotateMix", c.RotateMix, MixMin, MixMax); + c.TranslateMix = EditorGUILayout.Slider("TranslateMix", c.TranslateMix, MixMin, MixMax); + c.Position = EditorGUILayout.FloatField("Position", c.Position); + c.Spacing = EditorGUILayout.FloatField("Spacing", c.Spacing); + if (EditorGUI.EndChangeCheck()) requireRepaint = true; + + EditorGUILayout.Space(); + } + + } else { + EditorGUILayout.LabelField(NoneText); + } + } + } + } + } + + showDrawOrderTree.target = EditorGUILayout.Foldout(showDrawOrderTree.target, SpineInspectorUtility.TempContent("Draw Order and Separators", Icons.slotRoot), BoldFoldoutStyle); + + //var separatorSlotNamesField = + //SpineInspectorUtility.ge + if (showDrawOrderTree.faded > 0) { + using (new SpineInspectorUtility.IndentScope()) { + using (new EditorGUILayout.FadeGroupScope(showDrawOrderTree.faded)) { + + const string SeparatorString = "------------- v SEPARATOR v -------------"; + + if (Application.isPlaying) { + foreach (var slot in skeleton.DrawOrder) { + if (skeletonRenderer.separatorSlots.Contains(slot)) EditorGUILayout.LabelField(SeparatorString); + + using (new EditorGUI.DisabledScope(!slot.Bone.Active)) { + EditorGUILayout.LabelField(SpineInspectorUtility.TempContent(slot.Data.Name, Icons.slot), GUILayout.ExpandWidth(false)); + } + } + } else { + foreach (var slot in skeleton.DrawOrder) { + var slotNames = SkeletonRendererInspector.GetSeparatorSlotNames(skeletonRenderer); + for (int i = 0, n = slotNames.Length; i < n; i++) { + if (string.Equals(slotNames[i], slot.Data.Name, System.StringComparison.Ordinal)) { + EditorGUILayout.LabelField(SeparatorString); + break; + } + } + using (new EditorGUI.DisabledScope(!slot.Bone.Active)) { + EditorGUILayout.LabelField(SpineInspectorUtility.TempContent(slot.Data.Name, Icons.slot), GUILayout.ExpandWidth(false)); + } + } + } + + } + } + } + + showEventDataTree.target = EditorGUILayout.Foldout(showEventDataTree.target, SpineInspectorUtility.TempContent("Events", Icons.userEvent), BoldFoldoutStyle); + if (showEventDataTree.faded > 0) { + using (new SpineInspectorUtility.IndentScope()) { + using (new EditorGUILayout.FadeGroupScope(showEventDataTree.faded)) { + if (skeleton.Data.Events.Count > 0) { + foreach (var e in skeleton.Data.Events) { + EditorGUILayout.LabelField(SpineInspectorUtility.TempContent(e.Name, Icons.userEvent)); + } + } else { + EditorGUILayout.LabelField(NoneText); + } + } + } + } + + showDataTree.target = EditorGUILayout.Foldout(showDataTree.target, SpineInspectorUtility.TempContent("Data Counts", Icons.spine), BoldFoldoutStyle); + if (showDataTree.faded > 0) { + using (new SpineInspectorUtility.IndentScope()) { + using (new EditorGUILayout.FadeGroupScope(showDataTree.faded)) { + using (new SpineInspectorUtility.LabelWidthScope()) { + var skeletonData = skeleton.Data; + EditorGUILayout.LabelField(SpineInspectorUtility.TempContent("Bones", Icons.bone, "Skeleton.Data.Bones"), new GUIContent(skeletonData.Bones.Count.ToString())); + EditorGUILayout.LabelField(SpineInspectorUtility.TempContent("Slots", Icons.slotRoot, "Skeleton.Data.Slots"), new GUIContent(skeletonData.Slots.Count.ToString())); + EditorGUILayout.LabelField(SpineInspectorUtility.TempContent("Skins", Icons.skinsRoot, "Skeleton.Data.Skins"), new GUIContent(skeletonData.Skins.Count.ToString())); + EditorGUILayout.LabelField(SpineInspectorUtility.TempContent("Events", Icons.userEvent, "Skeleton.Data.Events"), new GUIContent(skeletonData.Events.Count.ToString())); + EditorGUILayout.LabelField(SpineInspectorUtility.TempContent("IK Constraints", Icons.constraintIK, "Skeleton.Data.IkConstraints"), new GUIContent(skeletonData.IkConstraints.Count.ToString())); + EditorGUILayout.LabelField(SpineInspectorUtility.TempContent("Transform Constraints", Icons.constraintTransform, "Skeleton.Data.TransformConstraints"), new GUIContent(skeletonData.TransformConstraints.Count.ToString())); + EditorGUILayout.LabelField(SpineInspectorUtility.TempContent("Path Constraints", Icons.constraintPath, "Skeleton.Data.PathConstraints"), new GUIContent(skeletonData.PathConstraints.Count.ToString())); + } + } + } + } + + if (IsAnimating(showSlotsTree, showSkeleton, showConstraintsTree, showDrawOrderTree, showEventDataTree, showInspectBoneTree, showDataTree)) + Repaint(); + } + + if (requireRepaint) { + skeletonRenderer.LateUpdate(); + Repaint(); + SceneView.RepaintAll(); + } + + EditorGUILayout.EndScrollView(); + } + + static float ViewRound (float x) { + const float Factor = 100f; + const float Divisor = 1f/Factor; + return Mathf.Round(x * Factor) * Divisor; + } + + static Vector2 RoundVector2 (float x, float y) { + const float Factor = 100f; + const float Divisor = 1f/Factor; + return new Vector2(Mathf.Round(x * Factor) * Divisor, Mathf.Round(y * Factor) * Divisor); + } + + static bool IsAnimating (params AnimBool[] animBools) { + foreach (var a in animBools) + if (a.isAnimating) return true; + return false; + } + + void UpdateAttachments () { + //skeleton = skeletonRenderer.skeleton; + Skin defaultSkin = skeleton.Data.DefaultSkin; + Skin skin = skeleton.Skin ?? defaultSkin; + bool notDefaultSkin = skin != defaultSkin; + + attachmentTable.Clear(); + for (int i = skeleton.Slots.Count - 1; i >= 0; i--) { + var attachments = new List(); + attachmentTable.Add(skeleton.Slots.Items[i], attachments); + // Add skin attachments. + skin.GetAttachments(i, attachments); + if (notDefaultSkin && defaultSkin != null) // Add default skin attachments. + defaultSkin.GetAttachments(i, attachments); + } + + activeSkin = skeleton.Skin; + } + } +} diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/Windows/SkeletonDebugWindow.cs.meta b/box1/Assets/Spine/Editor/spine-unity/Editor/Windows/SkeletonDebugWindow.cs.meta new file mode 100644 index 00000000..d3697a05 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/Windows/SkeletonDebugWindow.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 7093e73ff3cf6c543ac5865980070b49 +timeCreated: 1494837950 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/Windows/SpinePreferences.cs b/box1/Assets/Spine/Editor/spine-unity/Editor/Windows/SpinePreferences.cs new file mode 100644 index 00000000..55166779 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/Windows/SpinePreferences.cs @@ -0,0 +1,229 @@ +/****************************************************************************** + * 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_2017_2_OR_NEWER +#define NEWPLAYMODECALLBACKS +#endif + +#if UNITY_2018_3_OR_NEWER +#define NEW_PREFERENCES_SETTINGS_PROVIDER +#endif + +using UnityEngine; +using UnityEditor; +using System.Threading; + +namespace Spine.Unity.Editor { + + public class SpinePreferences : ScriptableObject { + + #if NEW_PREFERENCES_SETTINGS_PROVIDER + static int wasPreferencesDirCreated = 0; + static int wasPreferencesAssetCreated = 0; + #endif + + public const string SPINE_SETTINGS_ASSET_PATH = "Assets/Editor/SpineSettings.asset"; + + #if SPINE_TK2D + internal const float DEFAULT_DEFAULT_SCALE = 1f; + #else + internal const float DEFAULT_DEFAULT_SCALE = 0.01f; + #endif + public float defaultScale = DEFAULT_DEFAULT_SCALE; + + internal const float DEFAULT_DEFAULT_MIX = 0.2f; + public float defaultMix = DEFAULT_DEFAULT_MIX; + + internal const string DEFAULT_DEFAULT_SHADER = "Spine/Skeleton"; + public string defaultShader = DEFAULT_DEFAULT_SHADER; + + internal const float DEFAULT_DEFAULT_ZSPACING = 0f; + public float defaultZSpacing = DEFAULT_DEFAULT_ZSPACING; + + internal const bool DEFAULT_DEFAULT_INSTANTIATE_LOOP = true; + public bool defaultInstantiateLoop = DEFAULT_DEFAULT_INSTANTIATE_LOOP; + + internal const bool DEFAULT_SHOW_HIERARCHY_ICONS = true; + public bool showHierarchyIcons = DEFAULT_SHOW_HIERARCHY_ICONS; + + internal const bool DEFAULT_SET_TEXTUREIMPORTER_SETTINGS = true; + public bool setTextureImporterSettings = DEFAULT_SET_TEXTUREIMPORTER_SETTINGS; + + internal const string DEFAULT_TEXTURE_SETTINGS_REFERENCE = ""; + public string textureSettingsReference = DEFAULT_TEXTURE_SETTINGS_REFERENCE; + + internal const bool DEFAULT_ATLASTXT_WARNING = true; + public bool atlasTxtImportWarning = DEFAULT_ATLASTXT_WARNING; + + internal const bool DEFAULT_TEXTUREIMPORTER_WARNING = true; + public bool textureImporterWarning = DEFAULT_TEXTUREIMPORTER_WARNING; + + public const float DEFAULT_MIPMAPBIAS = -0.5f; + + public const bool DEFAULT_AUTO_RELOAD_SCENESKELETONS = true; + public bool autoReloadSceneSkeletons = DEFAULT_AUTO_RELOAD_SCENESKELETONS; + + public const string SCENE_ICONS_SCALE_KEY = "SPINE_SCENE_ICONS_SCALE"; + internal const float DEFAULT_SCENE_ICONS_SCALE = 1f; + [Range(0.01f, 2f)] + public float handleScale = DEFAULT_SCENE_ICONS_SCALE; + + public const bool DEFAULT_MECANIM_EVENT_INCLUDE_FOLDERNAME = true; + public bool mecanimEventIncludeFolderName = DEFAULT_MECANIM_EVENT_INCLUDE_FOLDERNAME; + + // Timeline extension module + public const bool DEFAULT_TIMELINE_USE_BLEND_DURATION = true; + public bool timelineUseBlendDuration = DEFAULT_TIMELINE_USE_BLEND_DURATION; + +#if NEW_PREFERENCES_SETTINGS_PROVIDER + public static void Load () { + GetOrCreateSettings(); + } + + internal static SpinePreferences GetOrCreateSettings () { + var settings = AssetDatabase.LoadAssetAtPath(SPINE_SETTINGS_ASSET_PATH); + if (settings == null) + { + settings = ScriptableObject.CreateInstance(); + SpineEditorUtilities.OldPreferences.CopyOldToNewPreferences(ref settings); + // Multiple threads may be calling this method during import, creating the folder + // multiple times with ascending number suffix. Atomic wasPreferencesDirCreated int + // variable is used to prevent any redundant create operations. + if (!AssetDatabase.IsValidFolder("Assets/Editor") && Interlocked.Exchange(ref wasPreferencesDirCreated, 1) == 0) + AssetDatabase.CreateFolder("Assets", "Editor"); + if (Interlocked.Exchange(ref wasPreferencesAssetCreated, 1) == 0) + AssetDatabase.CreateAsset(settings, SPINE_SETTINGS_ASSET_PATH); + } + return settings; + } + + public static void HandlePreferencesGUI (SerializedObject settings) { + + float prevLabelWidth = EditorGUIUtility.labelWidth; + EditorGUIUtility.labelWidth = 250; + + using (new EditorGUI.IndentLevelScope()) { + EditorGUI.BeginChangeCheck(); + EditorGUILayout.PropertyField(settings.FindProperty("showHierarchyIcons"), new GUIContent("Show Hierarchy Icons", "Show relevant icons on GameObjects with Spine Components on them. Disable this if you have large, complex scenes.")); + if (EditorGUI.EndChangeCheck()) { +#if NEWPLAYMODECALLBACKS + SpineEditorUtilities.HierarchyHandler.IconsOnPlaymodeStateChanged(PlayModeStateChange.EnteredEditMode); +#else + SpineEditorUtilities.HierarchyHandler.IconsOnPlaymodeStateChanged(); +#endif + } + + EditorGUILayout.PropertyField(settings.FindProperty("autoReloadSceneSkeletons"), new GUIContent("Auto-reload scene components", "Reloads Skeleton components in the scene whenever their SkeletonDataAsset is modified. This makes it so changes in the SkeletonDataAsset inspector are immediately reflected. This may be slow when your scenes have large numbers of SkeletonRenderers or SkeletonGraphic.")); + + EditorGUILayout.Separator(); + EditorGUILayout.LabelField("Auto-Import Settings", EditorStyles.boldLabel); + { + SpineEditorUtilities.FloatPropertyField(settings.FindProperty("defaultMix"), new GUIContent("Default Mix", "The Default Mix Duration for newly imported SkeletonDataAssets."), min: 0f); + SpineEditorUtilities.FloatPropertyField(settings.FindProperty("defaultScale"), new GUIContent("Default SkeletonData Scale", "The Default skeleton import scale for newly imported SkeletonDataAssets."), min: 0.0000001f); + + SpineEditorUtilities.ShaderPropertyField(settings.FindProperty("defaultShader"), new GUIContent("Default Shader"), SpinePreferences.DEFAULT_DEFAULT_SHADER); + + EditorGUILayout.PropertyField(settings.FindProperty("setTextureImporterSettings"), new GUIContent("Apply Atlas Texture Settings", "Apply reference settings for Texture Importers.")); + var textureSettingsRef = settings.FindProperty("textureSettingsReference"); + SpineEditorUtilities.PresetAssetPropertyField(textureSettingsRef, new GUIContent("Atlas Texture Settings", "Apply the selected texture import settings at newly imported atlas textures. When exporting atlas textures from Spine with \"Premultiply alpha\" enabled (the default), you can leave it at \"PMATexturePreset\". If you have disabled \"Premultiply alpha\", set it to \"StraightAlphaTexturePreset\". You can also create your own TextureImporter Preset asset and assign it here.")); + if (string.IsNullOrEmpty(textureSettingsRef.stringValue)) { + var pmaTextureSettingsReferenceGUIDS = AssetDatabase.FindAssets("PMATexturePreset"); + if (pmaTextureSettingsReferenceGUIDS.Length > 0) { + textureSettingsRef.stringValue = AssetDatabase.GUIDToAssetPath(pmaTextureSettingsReferenceGUIDS[0]); + } + } + } + + EditorGUILayout.Space(); + EditorGUILayout.LabelField("Warnings", EditorStyles.boldLabel); + { + EditorGUILayout.PropertyField(settings.FindProperty("atlasTxtImportWarning"), new GUIContent("Atlas Extension Warning", "Log a warning and recommendation whenever a `.atlas` file is found.")); + EditorGUILayout.PropertyField(settings.FindProperty("textureImporterWarning"), new GUIContent("Texture Settings Warning", "Log a warning and recommendation whenever Texture Import Settings are detected that could lead to undesired effects, e.g. white border artifacts.")); + } + + EditorGUILayout.Space(); + EditorGUILayout.LabelField("Editor Instantiation", EditorStyles.boldLabel); + { + EditorGUILayout.Slider(settings.FindProperty("defaultZSpacing"), -0.1f, 0f, new GUIContent("Default Slot Z-Spacing")); + EditorGUILayout.PropertyField(settings.FindProperty("defaultInstantiateLoop"), new GUIContent("Default Loop", "Spawn Spine GameObjects with loop enabled.")); + } + + EditorGUILayout.Space(); + EditorGUILayout.LabelField("Mecanim Bake Settings", EditorStyles.boldLabel); + { + EditorGUILayout.PropertyField(settings.FindProperty("mecanimEventIncludeFolderName"), new GUIContent("Include Folder Name in Event", "When enabled, Mecanim events will call methods named 'FolderNameEventName', when disabled it will call 'EventName'.")); + } + + EditorGUILayout.Space(); + EditorGUILayout.LabelField("Handles and Gizmos", EditorStyles.boldLabel); + { + EditorGUI.BeginChangeCheck(); + var scaleProperty = settings.FindProperty("handleScale"); + EditorGUILayout.PropertyField(scaleProperty, new GUIContent("Editor Bone Scale")); + if (EditorGUI.EndChangeCheck()) { + EditorPrefs.SetFloat(SpinePreferences.SCENE_ICONS_SCALE_KEY, scaleProperty.floatValue); + SceneView.RepaintAll(); + } + } + + #if SPINE_TK2D_DEFINE + bool isTK2DDefineSet = true; + #else + bool isTK2DDefineSet = false; + #endif + bool isTK2DAllowed = SpineEditorUtilities.SpineTK2DEditorUtility.IsTK2DAllowed; + if (SpineEditorUtilities.SpineTK2DEditorUtility.IsTK2DInstalled() || isTK2DDefineSet) { + GUILayout.Space(20); + EditorGUILayout.LabelField("3rd Party Settings", EditorStyles.boldLabel); + using (new GUILayout.HorizontalScope()) { + EditorGUILayout.PrefixLabel("Define TK2D"); + if (isTK2DAllowed && GUILayout.Button("Enable", GUILayout.Width(64))) + SpineEditorUtilities.SpineTK2DEditorUtility.EnableTK2D(); + if (GUILayout.Button("Disable", GUILayout.Width(64))) + SpineEditorUtilities.SpineTK2DEditorUtility.DisableTK2D(); + } + #if !SPINE_TK2D_DEFINE + if (!isTK2DAllowed) { + EditorGUILayout.LabelField("To allow TK2D support, please modify line 67 in", EditorStyles.boldLabel); + EditorGUILayout.LabelField("Spine/Editor/spine-unity/Editor/Util./BuildSettings.cs", EditorStyles.boldLabel); + } + #endif + } + + GUILayout.Space(20); + EditorGUILayout.LabelField("Timeline Extension", EditorStyles.boldLabel); + { + EditorGUILayout.PropertyField(settings.FindProperty("timelineUseBlendDuration"), new GUIContent("Use Blend Duration", "When enabled, MixDuration will be synced with timeline clip transition duration 'Ease In Duration'.")); + } + } + EditorGUIUtility.labelWidth = prevLabelWidth; + } +#endif // NEW_PREFERENCES_SETTINGS_PROVIDER + } +} diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/Windows/SpinePreferences.cs.meta b/box1/Assets/Spine/Editor/spine-unity/Editor/Windows/SpinePreferences.cs.meta new file mode 100644 index 00000000..b473afef --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/Windows/SpinePreferences.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b29e98153ec2fbd44b8f7da1b41194e8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/Windows/SpriteAtlasImportWindow.cs b/box1/Assets/Spine/Editor/spine-unity/Editor/Windows/SpriteAtlasImportWindow.cs new file mode 100644 index 00000000..3e6d8662 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/Windows/SpriteAtlasImportWindow.cs @@ -0,0 +1,170 @@ +/****************************************************************************** + * 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.Collections; +using System.Collections.Generic; +using UnityEngine; +using UnityEditor; + +namespace Spine.Unity.Editor { + + using Editor = UnityEditor.Editor; + using Icons = SpineEditorUtilities.Icons; + + public class SpriteAtlasImportWindow : EditorWindow { + const bool IsUtilityWindow = false; + + [MenuItem("Window/Spine/SpriteAtlas Import", false, 5000)] + public static void Init (MenuCommand command) { + var window = EditorWindow.GetWindow(IsUtilityWindow); + window.minSize = new Vector2(284f, 256f); + window.maxSize = new Vector2(500f, 256f); + window.titleContent = new GUIContent("Spine SpriteAtlas Import", Icons.spine); + window.Show(); + } + + public UnityEngine.U2D.SpriteAtlas spriteAtlasAsset; + public TextAsset skeletonDataFile; + public SpineSpriteAtlasAsset spineSpriteAtlasAsset; + + SerializedObject so; + + void OnEnable () { + if (!SpineSpriteAtlasAsset.AnySpriteAtlasNeedsRegionsLoaded()) + return; + EditorApplication.update -= SpineSpriteAtlasAsset.UpdateWhenEditorPlayModeStarted; + EditorApplication.update += SpineSpriteAtlasAsset.UpdateWhenEditorPlayModeStarted; + } + + void OnDisable () { + EditorApplication.update -= SpineSpriteAtlasAsset.UpdateWhenEditorPlayModeStarted; + } + + void OnGUI () { + so = so ?? new SerializedObject(this); + + EditorGUIUtility.wideMode = true; + EditorGUILayout.LabelField("Spine SpriteAtlas Import", EditorStyles.boldLabel); + + using (new SpineInspectorUtility.BoxScope()) { + EditorGUI.BeginChangeCheck(); + var spriteAtlasAssetProperty = so.FindProperty("spriteAtlasAsset"); + EditorGUILayout.PropertyField(spriteAtlasAssetProperty, new GUIContent("SpriteAtlas", EditorGUIUtility.IconContent("SpriteAtlas Icon").image)); + if (EditorGUI.EndChangeCheck()) { + so.ApplyModifiedProperties(); + if (spriteAtlasAsset != null) { + if (AssetUtility.SpriteAtlasSettingsNeedAdjustment(spriteAtlasAsset)) { + AssetUtility.AdjustSpriteAtlasSettings(spriteAtlasAsset); + } + GenerateAssetsFromSpriteAtlas(spriteAtlasAsset); + } + } + + var spineSpriteAtlasAssetProperty = so.FindProperty("spineSpriteAtlasAsset"); + EditorGUI.BeginChangeCheck(); + EditorGUILayout.PropertyField(spineSpriteAtlasAssetProperty, new GUIContent("SpineSpriteAtlasAsset", EditorGUIUtility.IconContent("ScriptableObject Icon").image)); + if (spineSpriteAtlasAssetProperty.objectReferenceValue == null) { + spineSpriteAtlasAssetProperty.objectReferenceValue = spineSpriteAtlasAsset = FindSpineSpriteAtlasAsset(spriteAtlasAsset); + } + if (EditorGUI.EndChangeCheck()) { + so.ApplyModifiedProperties(); + } + EditorGUILayout.Space(); + + using (new EditorGUI.DisabledScope(spineSpriteAtlasAsset == null)) { + if (SpineInspectorUtility.LargeCenteredButton(new GUIContent("Load regions by entering Play mode"))) { + GenerateAssetsFromSpriteAtlas(spriteAtlasAsset); + SpineSpriteAtlasAsset.UpdateByStartingEditorPlayMode(); + } + } + + using (new SpineInspectorUtility.BoxScope()) { + if (spriteAtlasAsset == null) { + EditorGUILayout.LabelField(SpineInspectorUtility.TempContent("Please assign SpriteAtlas file.", Icons.warning), GUILayout.Height(46)); + } + else if (spineSpriteAtlasAsset == null || spineSpriteAtlasAsset.RegionsNeedLoading) { + EditorGUILayout.LabelField(SpineInspectorUtility.TempContent("Please hit 'Load regions ..' to load\nregion info. Play mode is started\nand stopped automatically.", Icons.warning), GUILayout.Height(54)); + } + else { + EditorGUILayout.LabelField(SpineInspectorUtility.TempContent("SpriteAtlas imported\nsuccessfully.", Icons.spine), GUILayout.Height(46)); + } + } + } + + bool isAtlasComplete = (spineSpriteAtlasAsset != null && !spineSpriteAtlasAsset.RegionsNeedLoading); + bool canImportSkeleton = (spriteAtlasAsset != null && skeletonDataFile != null); + using (new SpineInspectorUtility.BoxScope()) { + + using (new EditorGUI.DisabledScope(!isAtlasComplete)) { + var skeletonDataAssetProperty = so.FindProperty("skeletonDataFile"); + EditorGUI.BeginChangeCheck(); + EditorGUILayout.PropertyField(skeletonDataAssetProperty, SpineInspectorUtility.TempContent("Skeleton json/skel file", Icons.spine)); + if (EditorGUI.EndChangeCheck()) { + so.ApplyModifiedProperties(); + } + EditorGUILayout.Space(); + } + using (new EditorGUI.DisabledScope(!canImportSkeleton)) { + if (SpineInspectorUtility.LargeCenteredButton(new GUIContent("Import Skeleton"))) { + //AssetUtility.IngestSpriteAtlas(spriteAtlasAsset, null); + string skeletonPath = AssetDatabase.GetAssetPath(skeletonDataFile); + string[] skeletons = new string[] { skeletonPath }; + AssetUtility.ImportSpineContent(skeletons, null); + } + } + } + } + + void GenerateAssetsFromSpriteAtlas (UnityEngine.U2D.SpriteAtlas spriteAtlasAsset) { + AssetUtility.IngestSpriteAtlas(spriteAtlasAsset, null); + string texturePath; + if (AssetUtility.GeneratePngFromSpriteAtlas(spriteAtlasAsset, out texturePath)) { + Debug.Log(string.Format("Generated SpriteAtlas texture '{0}'", texturePath), spriteAtlasAsset); + } + } + + SpineSpriteAtlasAsset FindSpineSpriteAtlasAsset (UnityEngine.U2D.SpriteAtlas spriteAtlasAsset) { + string path = AssetDatabase.GetAssetPath(spriteAtlasAsset).Replace(".spriteatlas", AssetUtility.SpriteAtlasSuffix + ".asset"); + if (System.IO.File.Exists(path)) { + return AssetDatabase.LoadAssetAtPath(path); + } + return null; + } + + SkeletonDataAsset FindSkeletonDataAsset (TextAsset skeletonDataFile) { + string path = AssetDatabase.GetAssetPath(skeletonDataFile); + path = path.Replace(".json", AssetUtility.SkeletonDataSuffix + ".asset"); + path = path.Replace(".skel.bytes", AssetUtility.SkeletonDataSuffix + ".asset"); + if (System.IO.File.Exists(path)) { + return AssetDatabase.LoadAssetAtPath(path); + } + return null; + } + } +} diff --git a/box1/Assets/Spine/Editor/spine-unity/Editor/Windows/SpriteAtlasImportWindow.cs.meta b/box1/Assets/Spine/Editor/spine-unity/Editor/Windows/SpriteAtlasImportWindow.cs.meta new file mode 100644 index 00000000..2eb64bdc --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Editor/Windows/SpriteAtlasImportWindow.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a5b99b091defeef439a0cb8c99fd8a51 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Editor/spine-unity/Modules.meta b/box1/Assets/Spine/Editor/spine-unity/Modules.meta new file mode 100644 index 00000000..51ffc9e5 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Modules.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: ef0ff8deb3a288646a1dd7243a918196 +folderAsset: yes +timeCreated: 1527569389 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Editor/spine-unity/Modules/SkeletonRenderSeparator.meta b/box1/Assets/Spine/Editor/spine-unity/Modules/SkeletonRenderSeparator.meta new file mode 100644 index 00000000..40aec39a --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Modules/SkeletonRenderSeparator.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 1bf8fd476d074f449bbae932a1c8a360 +folderAsset: yes +timeCreated: 1527569465 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Editor/spine-unity/Modules/SkeletonRenderSeparator/Editor.meta b/box1/Assets/Spine/Editor/spine-unity/Modules/SkeletonRenderSeparator/Editor.meta new file mode 100644 index 00000000..1d2ca48c --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Modules/SkeletonRenderSeparator/Editor.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 211465c9f045fd142abe552a6ffdc799 +folderAsset: yes +timeCreated: 1457405813 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Editor/spine-unity/Modules/SkeletonRenderSeparator/Editor/SkeletonPartsRendererInspector.cs b/box1/Assets/Spine/Editor/spine-unity/Modules/SkeletonRenderSeparator/Editor/SkeletonPartsRendererInspector.cs new file mode 100644 index 00000000..79d4d9e4 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Modules/SkeletonRenderSeparator/Editor/SkeletonPartsRendererInspector.cs @@ -0,0 +1,58 @@ +/****************************************************************************** + * 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 UnityEditor; +using Spine.Unity.Editor; + +namespace Spine.Unity.Examples { + [CustomEditor(typeof(SkeletonPartsRenderer))] + public class SkeletonRenderPartInspector : UnityEditor.Editor { + SpineInspectorUtility.SerializedSortingProperties sortingProperties; + + void OnEnable () { + sortingProperties = new SpineInspectorUtility.SerializedSortingProperties(SpineInspectorUtility.GetRenderersSerializedObject(serializedObject)); + } + + public override void OnInspectorGUI () { + SpineInspectorUtility.SortingPropertyFields(sortingProperties, true); + + if (!serializedObject.isEditingMultipleObjects) { + EditorGUILayout.Space(); + if (SpineInspectorUtility.LargeCenteredButton(new GUIContent("Select SkeletonRenderer", SpineEditorUtilities.Icons.spine))) { + var thisSkeletonPartsRenderer = target as SkeletonPartsRenderer; + var srs = thisSkeletonPartsRenderer.GetComponentInParent(); + if (srs != null && srs.partsRenderers.Contains(thisSkeletonPartsRenderer) && srs.SkeletonRenderer != null) + Selection.activeGameObject = srs.SkeletonRenderer.gameObject; + } + } + } + } + +} diff --git a/box1/Assets/Spine/Editor/spine-unity/Modules/SkeletonRenderSeparator/Editor/SkeletonPartsRendererInspector.cs.meta b/box1/Assets/Spine/Editor/spine-unity/Modules/SkeletonRenderSeparator/Editor/SkeletonPartsRendererInspector.cs.meta new file mode 100644 index 00000000..a97d6621 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Modules/SkeletonRenderSeparator/Editor/SkeletonPartsRendererInspector.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 30e43037bf4433645ad70266f34c1c8b +timeCreated: 1458051036 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Editor/spine-unity/Modules/SkeletonRenderSeparator/Editor/SkeletonRenderSeparatorInspector.cs b/box1/Assets/Spine/Editor/spine-unity/Modules/SkeletonRenderSeparator/Editor/SkeletonRenderSeparatorInspector.cs new file mode 100644 index 00000000..19712597 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Modules/SkeletonRenderSeparator/Editor/SkeletonRenderSeparatorInspector.cs @@ -0,0 +1,323 @@ +/****************************************************************************** + * 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 UnityEngine; +using UnityEditor; + +using System.Collections.Generic; + +using Spine.Unity; +using Spine.Unity.Editor; + +namespace Spine.Unity.Examples { + + [CustomEditor(typeof(SkeletonRenderSeparator))] + public class SkeletonRenderSeparatorInspector : UnityEditor.Editor { + SkeletonRenderSeparator component; + + // Properties + SerializedProperty skeletonRenderer_, copyPropertyBlock_, copyMeshRendererFlags_, partsRenderers_; + static bool partsRenderersExpanded = false; + + // For separator field. + SerializedObject skeletonRendererSerializedObject; + SerializedProperty separatorNamesProp; + static bool skeletonRendererExpanded = true; + bool slotsReapplyRequired = false; + bool partsRendererInitRequired = false; + + void OnEnable () { + if (component == null) + component = target as SkeletonRenderSeparator; + + skeletonRenderer_ = serializedObject.FindProperty("skeletonRenderer"); + copyPropertyBlock_ = serializedObject.FindProperty("copyPropertyBlock"); + copyMeshRendererFlags_ = serializedObject.FindProperty("copyMeshRendererFlags"); + + var partsRenderers = component.partsRenderers; + partsRenderers_ = serializedObject.FindProperty("partsRenderers"); + partsRenderers_.isExpanded = partsRenderersExpanded || // last state + partsRenderers.Contains(null) || // null items found + partsRenderers.Count < 1 || // no parts renderers + (skeletonRenderer_.objectReferenceValue != null && SkeletonRendererSeparatorCount + 1 > partsRenderers.Count); // not enough parts renderers + } + + int SkeletonRendererSeparatorCount { + get { + if (Application.isPlaying) + return component.SkeletonRenderer.separatorSlots.Count; + else + return separatorNamesProp == null ? 0 : separatorNamesProp.arraySize; + } + } + + public override void OnInspectorGUI () { + + // Restore mesh part for undo logic after undo of "Add Parts Renderer". + // Triggers regeneration and assignment of the mesh filter's mesh. + + bool isMeshFilterAlwaysNull = false; + #if UNITY_EDITOR && NEW_PREFAB_SYSTEM + // Don't store mesh or material at the prefab, otherwise it will permanently reload + var prefabType = UnityEditor.PrefabUtility.GetPrefabAssetType(component); + if (UnityEditor.PrefabUtility.IsPartOfPrefabAsset(component) && + (prefabType == UnityEditor.PrefabAssetType.Regular || prefabType == UnityEditor.PrefabAssetType.Variant)) { + isMeshFilterAlwaysNull = true; + } + #endif + + if (!isMeshFilterAlwaysNull && component.GetComponent() && component.GetComponent().sharedMesh == null) { + component.OnDisable(); + component.OnEnable(); + } + + var componentRenderers = component.partsRenderers; + int totalParts; + + using (new SpineInspectorUtility.LabelWidthScope()) { + bool componentEnabled = component.enabled; + bool checkBox = EditorGUILayout.Toggle("Enable Separator", componentEnabled); + if (checkBox != componentEnabled) + component.enabled = checkBox; + if (component.SkeletonRenderer.disableRenderingOnOverride && !component.enabled) + EditorGUILayout.HelpBox("By default, SkeletonRenderer's MeshRenderer is disabled while the SkeletonRenderSeparator takes over rendering. It is re-enabled when SkeletonRenderSeparator is disabled.", MessageType.Info); + + EditorGUILayout.PropertyField(copyPropertyBlock_); + EditorGUILayout.PropertyField(copyMeshRendererFlags_); + } + + // SkeletonRenderer Box + using (new SpineInspectorUtility.BoxScope(false)) { + // Fancy SkeletonRenderer foldout reference field + { + EditorGUI.indentLevel++; + EditorGUI.BeginChangeCheck(); + var foldoutSkeletonRendererRect = EditorGUILayout.GetControlRect(true, EditorGUIUtility.singleLineHeight); + EditorGUI.PropertyField(foldoutSkeletonRendererRect, skeletonRenderer_); + if (EditorGUI.EndChangeCheck()) + serializedObject.ApplyModifiedProperties(); + if (component.SkeletonRenderer != null) { + skeletonRendererExpanded = EditorGUI.Foldout(foldoutSkeletonRendererRect, skeletonRendererExpanded, ""); + } + EditorGUI.indentLevel--; + } + + int separatorCount = 0; + EditorGUI.BeginChangeCheck(); + if (component.SkeletonRenderer != null) { + // Separators from SkeletonRenderer + { + bool skeletonRendererMismatch = skeletonRendererSerializedObject != null && skeletonRendererSerializedObject.targetObject != component.SkeletonRenderer; + if (separatorNamesProp == null || skeletonRendererMismatch) { + if (component.SkeletonRenderer != null) { + skeletonRendererSerializedObject = new SerializedObject(component.SkeletonRenderer); + separatorNamesProp = skeletonRendererSerializedObject.FindProperty("separatorSlotNames"); + separatorNamesProp.isExpanded = true; + } + } + + if (separatorNamesProp != null) { + if (skeletonRendererExpanded) { + EditorGUI.indentLevel++; + SkeletonRendererInspector.SeparatorsField(separatorNamesProp); + EditorGUI.indentLevel--; + } + separatorCount = this.SkeletonRendererSeparatorCount; + } + } + + if (SkeletonRendererSeparatorCount == 0) { + EditorGUILayout.HelpBox("Separators are empty. Change the size to 1 and choose a slot if you want the render to be separated.", MessageType.Info); + } + } + + if (EditorGUI.EndChangeCheck()) { + skeletonRendererSerializedObject.ApplyModifiedProperties(); + + if (!Application.isPlaying) + slotsReapplyRequired = true; + } + + + totalParts = separatorCount + 1; + var counterStyle = skeletonRendererExpanded ? EditorStyles.label : EditorStyles.miniLabel; + EditorGUILayout.LabelField(string.Format("{0}: separates into {1}.", SpineInspectorUtility.Pluralize(separatorCount, "separator", "separators"), SpineInspectorUtility.Pluralize(totalParts, "part", "parts") ), counterStyle); + } + + // Parts renderers + using (new SpineInspectorUtility.BoxScope(false)) { + EditorGUI.indentLevel++; + EditorGUILayout.PropertyField(this.partsRenderers_, true); + EditorGUI.indentLevel--; + + // Null items warning + bool nullItemsFound = componentRenderers.Contains(null); + if (nullItemsFound) + EditorGUILayout.HelpBox("Some items in the parts renderers list are null and may cause problems.\n\nYou can right-click on that element and choose 'Delete Array Element' to remove it.", MessageType.Warning); + + // (Button) Match Separators count + if (separatorNamesProp != null) { + int currentRenderers = 0; + foreach (var r in componentRenderers) { + if (r != null) + currentRenderers++; + } + int extraRenderersNeeded = totalParts - currentRenderers; + + if (component.enabled && component.SkeletonRenderer != null && extraRenderersNeeded > 0) { + EditorGUILayout.HelpBox(string.Format("Insufficient parts renderers. Some parts will not be rendered."), MessageType.Warning); + string addMissingLabel = string.Format("Add the missing renderer{1} ({0}) ", extraRenderersNeeded, SpineInspectorUtility.PluralThenS(extraRenderersNeeded)); + if (GUILayout.Button(addMissingLabel, GUILayout.Height(30f))) { + AddPartsRenderer(extraRenderersNeeded); + DetectOrphanedPartsRenderers(component); + partsRendererInitRequired = true; + } + } + } + + if (partsRenderers_.isExpanded != partsRenderersExpanded) partsRenderersExpanded = partsRenderers_.isExpanded; + if (partsRenderers_.isExpanded) { + using (new EditorGUILayout.HorizontalScope()) { + // (Button) Destroy Renderers button + if (componentRenderers.Count > 0) { + if (GUILayout.Button("Clear Parts Renderers")) { + // Do you really want to destroy all? + Undo.RegisterCompleteObjectUndo(component, "Clear Parts Renderers"); + if (EditorUtility.DisplayDialog("Destroy Renderers", "Do you really want to destroy all the Parts Renderer GameObjects in the list?", "Destroy", "Cancel")) { + foreach (var r in componentRenderers) { + if (r != null) + Undo.DestroyObjectImmediate(r.gameObject); + } + componentRenderers.Clear(); + // Do you also want to destroy orphans? (You monster.) + DetectOrphanedPartsRenderers(component); + } + } + } + + // (Button) Add Part Renderer button + if (GUILayout.Button("Add Parts Renderer")) { + AddPartsRenderer(1); + partsRendererInitRequired = true; + } + } + } + } + + serializedObject.ApplyModifiedProperties(); + + if (partsRendererInitRequired) { + Undo.RegisterCompleteObjectUndo(component.GetComponent(), "Add Parts Renderers"); + component.OnEnable(); + partsRendererInitRequired = false; + } + + if (slotsReapplyRequired && UnityEngine.Event.current.type == EventType.Repaint) { + component.SkeletonRenderer.ReapplySeparatorSlotNames(); + component.SkeletonRenderer.LateUpdate(); + SceneView.RepaintAll(); + slotsReapplyRequired = false; + } + } + + public void AddPartsRenderer (int count) { + var componentRenderers = component.partsRenderers; + bool emptyFound = componentRenderers.Contains(null); + if (emptyFound) { + bool userClearEntries = EditorUtility.DisplayDialog("Empty entries found", "Null entries found. Do you want to remove null entries before adding the new renderer? ", "Clear Empty Entries", "Don't Clear"); + if (userClearEntries) componentRenderers.RemoveAll(x => x == null); + } + + Undo.RegisterCompleteObjectUndo(component, "Add Parts Renderers"); + for (int i = 0; i < count; i++) { + int index = componentRenderers.Count; + var smr = SkeletonPartsRenderer.NewPartsRendererGameObject(component.transform, index.ToString()); + Undo.RegisterCreatedObjectUndo(smr.gameObject, "New Parts Renderer GameObject."); + componentRenderers.Add(smr); + + // increment renderer sorting order. + if (index == 0) continue; + var prev = componentRenderers[index - 1]; if (prev == null) continue; + + var prevMeshRenderer = prev.GetComponent(); + var currentMeshRenderer = smr.GetComponent(); + if (prevMeshRenderer == null || currentMeshRenderer == null) continue; + + int prevSortingLayer = prevMeshRenderer.sortingLayerID; + int prevSortingOrder = prevMeshRenderer.sortingOrder; + currentMeshRenderer.sortingLayerID = prevSortingLayer; + currentMeshRenderer.sortingOrder = prevSortingOrder + SkeletonRenderSeparator.DefaultSortingOrderIncrement; + } + + } + + /// Detects orphaned parts renderers and offers to delete them. + public void DetectOrphanedPartsRenderers (SkeletonRenderSeparator component) { + var children = component.GetComponentsInChildren(); + + var orphans = new System.Collections.Generic.List(); + foreach (var r in children) { + if (!component.partsRenderers.Contains(r)) + orphans.Add(r); + } + + if (orphans.Count > 0) { + if (EditorUtility.DisplayDialog("Destroy Submesh Renderers", "Unassigned renderers were found. Do you want to delete them? (These may belong to another Render Separator in the same hierarchy. If you don't have another Render Separator component in the children of this GameObject, it's likely safe to delete. Warning: This operation cannot be undone.)", "Delete", "Cancel")) { + foreach (var o in orphans) { + Undo.DestroyObjectImmediate(o.gameObject); + } + } + } + } + + #region SkeletonRenderer Context Menu Item + [MenuItem ("CONTEXT/SkeletonRenderer/Add Skeleton Render Separator")] + static void AddRenderSeparatorComponent (MenuCommand cmd) { + var skeletonRenderer = cmd.context as SkeletonRenderer; + var newComponent = skeletonRenderer.gameObject.AddComponent(); + + Undo.RegisterCreatedObjectUndo(newComponent, "Add SkeletonRenderSeparator"); + } + + // Validate + [MenuItem ("CONTEXT/SkeletonRenderer/Add Skeleton Render Separator", true)] + static bool ValidateAddRenderSeparatorComponent (MenuCommand cmd) { + var skeletonRenderer = cmd.context as SkeletonRenderer; + var separator = skeletonRenderer.GetComponent(); + bool separatorNotOnObject = separator == null; + return separatorNotOnObject; + } + #endregion + + } +} diff --git a/box1/Assets/Spine/Editor/spine-unity/Modules/SkeletonRenderSeparator/Editor/SkeletonRenderSeparatorInspector.cs.meta b/box1/Assets/Spine/Editor/spine-unity/Modules/SkeletonRenderSeparator/Editor/SkeletonRenderSeparatorInspector.cs.meta new file mode 100644 index 00000000..7e8e6589 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Modules/SkeletonRenderSeparator/Editor/SkeletonRenderSeparatorInspector.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: d2a5062cfe5dd4344831cda4723128af +timeCreated: 1458067064 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Editor/spine-unity/Modules/SlotBlendModes.meta b/box1/Assets/Spine/Editor/spine-unity/Modules/SlotBlendModes.meta new file mode 100644 index 00000000..34d8d7e0 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Modules/SlotBlendModes.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 18ee2876d53412642bbfa1070a1b947f +folderAsset: yes +timeCreated: 1527569487 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Editor/spine-unity/Modules/SlotBlendModes/Editor.meta b/box1/Assets/Spine/Editor/spine-unity/Modules/SlotBlendModes/Editor.meta new file mode 100644 index 00000000..80a6cfcf --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Modules/SlotBlendModes/Editor.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 1ad4318c20ec5674a9f4d7f786afd681 +folderAsset: yes +timeCreated: 1496449217 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Editor/spine-unity/Modules/SlotBlendModes/Editor/SlotBlendModesEditor.cs b/box1/Assets/Spine/Editor/spine-unity/Modules/SlotBlendModes/Editor/SlotBlendModesEditor.cs new file mode 100644 index 00000000..88999520 --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Modules/SlotBlendModes/Editor/SlotBlendModesEditor.cs @@ -0,0 +1,47 @@ +/****************************************************************************** + * 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 UnityEditor; +using Spine.Unity.Deprecated; +using System; + +namespace Spine.Unity.Editor { + using Editor = UnityEditor.Editor; + + [Obsolete("The spine-unity 3.7 runtime introduced SkeletonDataModifierAssets BlendModeMaterials which replaced SlotBlendModes. Will be removed in spine-unity 3.9.", false)] + public class SlotBlendModesEditor : Editor { + + [MenuItem("CONTEXT/SkeletonRenderer/Add Slot Blend Modes Component")] + static void AddSlotBlendModesComponent (MenuCommand command) { + var skeletonRenderer = (SkeletonRenderer)command.context; + skeletonRenderer.gameObject.AddComponent(); + } + } +} diff --git a/box1/Assets/Spine/Editor/spine-unity/Modules/SlotBlendModes/Editor/SlotBlendModesEditor.cs.meta b/box1/Assets/Spine/Editor/spine-unity/Modules/SlotBlendModes/Editor/SlotBlendModesEditor.cs.meta new file mode 100644 index 00000000..21d0e26f --- /dev/null +++ b/box1/Assets/Spine/Editor/spine-unity/Modules/SlotBlendModes/Editor/SlotBlendModesEditor.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: cbec7dc66dca80a419477536c23b7a0d +timeCreated: 1496449255 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime.meta b/box1/Assets/Spine/Runtime.meta new file mode 100644 index 00000000..b6b0c1b1 --- /dev/null +++ b/box1/Assets/Spine/Runtime.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: ddb0e27aa2258854a8d171196f395b87 +folderAsset: yes +timeCreated: 1527569312 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-csharp.meta b/box1/Assets/Spine/Runtime/spine-csharp.meta new file mode 100644 index 00000000..81ebc4e4 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-csharp.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: a60dd41ef13d98647b9f963089feb7b0 +folderAsset: yes +timeCreated: 1456265151 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-csharp/Animation.cs b/box1/Assets/Spine/Runtime/spine-csharp/Animation.cs new file mode 100644 index 00000000..70c1b33e --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-csharp/Animation.cs @@ -0,0 +1,1819 @@ +/****************************************************************************** + * 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; + +namespace Spine { + + /// + /// A simple container for a list of timelines and a name. + public class Animation { + internal String name; + internal ExposedList timelines; + internal HashSet timelineIds; + internal float duration; + + public Animation (string name, ExposedList timelines, float duration) { + if (name == null) throw new ArgumentNullException("name", "name cannot be null."); + if (timelines == null) throw new ArgumentNullException("timelines", "timelines cannot be null."); + // Note: avoiding reallocations by adding all hash set entries at + // once (EnsureCapacity() is only available in newer .Net versions). + int[] propertyIDs = new int[timelines.Count]; + for (int i = 0; i < timelines.Count; ++i) { + propertyIDs[i] = timelines.Items[i].PropertyId; + } + this.timelineIds = new HashSet(propertyIDs); + this.name = name; + this.timelines = timelines; + this.duration = duration; + } + + public ExposedList Timelines { get { return timelines; } set { timelines = value; } } + + /// The duration of the animation in seconds, which is the highest time of all keys in the timeline. + public float Duration { get { return duration; } set { duration = value; } } + + /// The animation's name, which is unique across all animations in the skeleton. + public string Name { get { return name; } } + + /// Whether the timeline with the property id is contained in this animation. + public bool HasTimeline (int id) { + return timelineIds.Contains(id); + } + + /// Applies all the animation's timelines to the specified skeleton. + /// + public void Apply (Skeleton skeleton, float lastTime, float time, bool loop, ExposedList events, float alpha, MixBlend blend, + MixDirection direction) { + if (skeleton == null) throw new ArgumentNullException("skeleton", "skeleton cannot be null."); + + if (loop && duration != 0) { + time %= duration; + if (lastTime > 0) lastTime %= duration; + } + + ExposedList timelines = this.timelines; + for (int i = 0, n = timelines.Count; i < n; i++) + timelines.Items[i].Apply(skeleton, lastTime, time, events, alpha, blend, direction); + } + + override public string ToString () { + return name; + } + + /// After the first and before the last entry. + /// Index of first value greater than the target. + internal static int BinarySearch (float[] values, float target, int step) { + int low = 0; + int high = values.Length / step - 2; + if (high == 0) return step; + int current = (int)((uint)high >> 1); + while (true) { + if (values[(current + 1) * step] <= target) + low = current + 1; + else + high = current; + if (low == high) return (low + 1) * step; + current = (int)((uint)(low + high) >> 1); + } + } + + /// After the first and before the last entry. + internal static int BinarySearch (float[] values, float target) { + int low = 0; + int high = values.Length - 2; + if (high == 0) return 1; + int current = (int)((uint)high >> 1); + while (true) { + if (values[current + 1] <= target) + low = current + 1; + else + high = current; + if (low == high) return (low + 1); + current = (int)((uint)(low + high) >> 1); + } + } + + internal static int LinearSearch (float[] values, float target, int step) { + for (int i = 0, last = values.Length - step; i <= last; i += step) + if (values[i] > target) return i; + return -1; + } + } + + /// + /// The interface for all timelines. + public interface Timeline { + /// Applies this timeline to the skeleton. + /// The skeleton the timeline is being applied to. This provides access to the bones, slots, and other + /// skeleton components the timeline may change. + /// The time this timeline was last applied. Timelines such as trigger only at specific + /// times rather than every frame. In that case, the timeline triggers everything between lastTime + /// (exclusive) and time (inclusive). + /// The time within the animation. Most timelines find the key before and the key after this time so they can + /// interpolate between the keys. + /// If any events are fired, they are added to this list. Can be null to ignore firing events or if the + /// timeline does not fire events. + /// 0 applies the current or setup value (depending on blend). 1 applies the timeline value. + /// Between 0 and 1 applies a value between the current or setup value and the timeline value. By adjusting + /// alpha over time, an animation can be mixed in or out. alpha can also be useful to + /// apply animations on top of each other (layered). + /// Controls how mixing is applied when alpha < 1. + /// Indicates whether the timeline is mixing in or out. Used by timelines which perform instant transitions, + /// such as or , and other such as {@link ScaleTimeline}. + void Apply (Skeleton skeleton, float lastTime, float time, ExposedList events, float alpha, MixBlend blend, MixDirection direction); + /// Uniquely encodes both the type of this timeline and the skeleton property that it affects. + int PropertyId { get; } + } + + /// + /// Controls how a timeline is mixed with the setup or current pose. + /// + public enum MixBlend { + + /// Transitions from the setup value to the timeline value (the current value is not used). Before the first key, the setup + /// value is set. + Setup, + + /// + /// + /// Transitions from the current value to the timeline value. Before the first key, transitions from the current value to + /// the setup value. Timelines which perform instant transitions, such as or + /// , use the setup value before the first key. + /// + /// First is intended for the first animations applied, not for animations layered on top of those. + /// + First, + + /// + /// + /// Transitions from the current value to the timeline value. No change is made before the first key (the current value is + /// kept until the first key). + /// + /// Replace is intended for animations layered on top of others, not for the first animations applied. + /// + Replace, + + /// + /// + /// Transitions from the current value to the current value plus the timeline value. No change is made before the first key + /// (the current value is kept until the first key). + /// + /// Add is intended for animations layered on top of others, not for the first animations applied. + /// + Add + } + + /// + /// Indicates whether a timeline's alpha is mixing out over time toward 0 (the setup or current pose value) or + /// mixing in toward 1 (the timeline's value). + /// + public enum MixDirection { + In, + Out + } + + internal enum TimelineType { + Rotate = 0, Translate, Scale, Shear, // + Attachment, Color, Deform, // + Event, DrawOrder, // + IkConstraint, TransformConstraint, // + PathConstraintPosition, PathConstraintSpacing, PathConstraintMix, // + TwoColor + } + + /// An interface for timelines which change the property of a bone. + public interface IBoneTimeline { + /// The index of the bone in that will be changed. + int BoneIndex { get; } + } + + /// An interface for timelines which change the property of a slot. + public interface ISlotTimeline { + /// The index of the slot in that will be changed. + int SlotIndex { get; } + } + + /// The base class for timelines that use interpolation between key frame values. + abstract public class CurveTimeline : Timeline { + protected const float LINEAR = 0, STEPPED = 1, BEZIER = 2; + protected const int BEZIER_SIZE = 10 * 2 - 1; + + internal float[] curves; // type, x, y, ... + /// The number of key frames for this timeline. + public int FrameCount { get { return curves.Length / BEZIER_SIZE + 1; } } + + public CurveTimeline (int frameCount) { + if (frameCount <= 0) throw new ArgumentOutOfRangeException("frameCount must be > 0: "); + curves = new float[(frameCount - 1) * BEZIER_SIZE]; + } + + abstract public void Apply (Skeleton skeleton, float lastTime, float time, ExposedList firedEvents, float alpha, MixBlend blend, MixDirection direction); + + abstract public int PropertyId { get; } + + /// Sets the specified key frame to linear interpolation. + public void SetLinear (int frameIndex) { + curves[frameIndex * BEZIER_SIZE] = LINEAR; + } + + /// Sets the specified key frame to stepped interpolation. + public void SetStepped (int frameIndex) { + curves[frameIndex * BEZIER_SIZE] = STEPPED; + } + + /// Returns the interpolation type for the specified key frame. + /// Linear is 0, stepped is 1, Bezier is 2. + public float GetCurveType (int frameIndex) { + int index = frameIndex * BEZIER_SIZE; + if (index == curves.Length) return LINEAR; + float type = curves[index]; + if (type == LINEAR) return LINEAR; + if (type == STEPPED) return STEPPED; + return BEZIER; + } + + /// Sets the specified key frame to Bezier interpolation. cx1 and cx2 are from 0 to 1, + /// representing the percent of time between the two key frames. cy1 and cy2 are the percent of the + /// difference between the key frame's values. + public void SetCurve (int frameIndex, float cx1, float cy1, float cx2, float cy2) { + float tmpx = (-cx1 * 2 + cx2) * 0.03f, tmpy = (-cy1 * 2 + cy2) * 0.03f; + float dddfx = ((cx1 - cx2) * 3 + 1) * 0.006f, dddfy = ((cy1 - cy2) * 3 + 1) * 0.006f; + float ddfx = tmpx * 2 + dddfx, ddfy = tmpy * 2 + dddfy; + float dfx = cx1 * 0.3f + tmpx + dddfx * 0.16666667f, dfy = cy1 * 0.3f + tmpy + dddfy * 0.16666667f; + + int i = frameIndex * BEZIER_SIZE; + float[] curves = this.curves; + curves[i++] = BEZIER; + + float x = dfx, y = dfy; + for (int n = i + BEZIER_SIZE - 1; i < n; i += 2) { + curves[i] = x; + curves[i + 1] = y; + dfx += ddfx; + dfy += ddfy; + ddfx += dddfx; + ddfy += dddfy; + x += dfx; + y += dfy; + } + } + + /// Returns the interpolated percentage for the specified key frame and linear percentage. + public float GetCurvePercent (int frameIndex, float percent) { + percent = MathUtils.Clamp (percent, 0, 1); + float[] curves = this.curves; + int i = frameIndex * BEZIER_SIZE; + float type = curves[i]; + if (type == LINEAR) return percent; + if (type == STEPPED) return 0; + i++; + float x = 0; + for (int start = i, n = i + BEZIER_SIZE - 1; i < n; i += 2) { + x = curves[i]; + if (x >= percent) { + if (i == start) return curves[i + 1] * percent / x; // First point is 0,0. + float prevX = curves[i - 2], prevY = curves[i - 1]; + return prevY + (curves[i + 1] - prevY) * (percent - prevX) / (x - prevX); + } + } + float y = curves[i - 1]; + return y + (1 - y) * (percent - x) / (1 - x); // Last point is 1,1. + } + } + + /// Changes a bone's local . + public class RotateTimeline : CurveTimeline, IBoneTimeline { + public const int ENTRIES = 2; + internal const int PREV_TIME = -2, PREV_ROTATION = -1; + internal const int ROTATION = 1; + + internal int boneIndex; + internal float[] frames; // time, degrees, ... + + public RotateTimeline (int frameCount) + : base(frameCount) { + frames = new float[frameCount << 1]; + } + + override public int PropertyId { + get { return ((int)TimelineType.Rotate << 24) + boneIndex; } + } + /// The index of the bone in that will be changed. + public int BoneIndex { + set { + if (value < 0) throw new ArgumentOutOfRangeException("index must be >= 0."); + this.boneIndex = value; + } + get { + return boneIndex; + } + } + /// The time in seconds and rotation in degrees for each key frame. + public float[] Frames { get { return frames; } set { frames = value; } } + + /// Sets the time in seconds and the rotation in degrees for the specified key frame. + public void SetFrame (int frameIndex, float time, float degrees) { + frameIndex <<= 1; + frames[frameIndex] = time; + frames[frameIndex + ROTATION] = degrees; + } + + override public void Apply (Skeleton skeleton, float lastTime, float time, ExposedList firedEvents, float alpha, MixBlend blend, + MixDirection direction) { + Bone bone = skeleton.bones.Items[boneIndex]; + if (!bone.active) return; + float[] frames = this.frames; + if (time < frames[0]) { // Time is before first frame. + switch (blend) { + case MixBlend.Setup: + bone.rotation = bone.data.rotation; + return; + case MixBlend.First: + float r = bone.data.rotation - bone.rotation; + bone.rotation += (r - (16384 - (int)(16384.499999999996 - r / 360)) * 360) * alpha; + return; + } + return; + } + + if (time >= frames[frames.Length - ENTRIES]) { // Time is after last frame. + float r = frames[frames.Length + PREV_ROTATION]; + switch (blend) { + case MixBlend.Setup: + bone.rotation = bone.data.rotation + r * alpha; + break; + case MixBlend.First: + case MixBlend.Replace: + r += bone.data.rotation - bone.rotation; + r -= (16384 - (int)(16384.499999999996 - r / 360)) * 360; + goto case MixBlend.Add; // Fall through. + + case MixBlend.Add: + bone.rotation += r * alpha; + break; + } + return; + } + + // Interpolate between the previous frame and the current frame. + int frame = Animation.BinarySearch(frames, time, ENTRIES); + float prevRotation = frames[frame + PREV_ROTATION]; + float frameTime = frames[frame]; + float percent = GetCurvePercent((frame >> 1) - 1, 1 - (time - frameTime) / (frames[frame + PREV_TIME] - frameTime)); + // scope for 'r' to prevent compile error. + { + float r = frames[frame + ROTATION] - prevRotation; + r = prevRotation + (r - (16384 - (int)(16384.499999999996 - r / 360)) * 360) * percent; + switch (blend) { + case MixBlend.Setup: + bone.rotation = bone.data.rotation + (r - (16384 - (int)(16384.499999999996 - r / 360)) * 360) * alpha; + break; + case MixBlend.First: + case MixBlend.Replace: + r += bone.data.rotation - bone.rotation; + goto case MixBlend.Add; // Fall through. + case MixBlend.Add: + bone.rotation += (r - (16384 - (int)(16384.499999999996 - r / 360)) * 360) * alpha; + break; + } + } + } + } + + /// Changes a bone's local and . + public class TranslateTimeline : CurveTimeline, IBoneTimeline { + public const int ENTRIES = 3; + protected const int PREV_TIME = -3, PREV_X = -2, PREV_Y = -1; + protected const int X = 1, Y = 2; + + internal int boneIndex; + internal float[] frames; // time, x, y, ... + + public TranslateTimeline (int frameCount) + : base(frameCount) { + frames = new float[frameCount * ENTRIES]; + } + + override public int PropertyId { + get { return ((int)TimelineType.Translate << 24) + boneIndex; } + } + + /// The index of the bone in that will be changed. + public int BoneIndex { + set { + if (value < 0) throw new ArgumentOutOfRangeException("index must be >= 0."); + this.boneIndex = value; + } + get { + return boneIndex; + } + } + /// The time in seconds, x, and y values for each key frame. + public float[] Frames { get { return frames; } set { frames = value; } } + + + /// Sets the time in seconds, x, and y values for the specified key frame. + public void SetFrame (int frameIndex, float time, float x, float y) { + frameIndex *= ENTRIES; + frames[frameIndex] = time; + frames[frameIndex + X] = x; + frames[frameIndex + Y] = y; + } + + override public void Apply (Skeleton skeleton, float lastTime, float time, ExposedList firedEvents, float alpha, MixBlend blend, + MixDirection direction) { + Bone bone = skeleton.bones.Items[boneIndex]; + if (!bone.active) return; + float[] frames = this.frames; + if (time < frames[0]) { // Time is before first frame. + switch (blend) { + case MixBlend.Setup: + bone.x = bone.data.x; + bone.y = bone.data.y; + return; + case MixBlend.First: + bone.x += (bone.data.x - bone.x) * alpha; + bone.y += (bone.data.y - bone.y) * alpha; + return; + } + return; + } + + float x, y; + if (time >= frames[frames.Length - ENTRIES]) { // Time is after last frame. + x = frames[frames.Length + PREV_X]; + y = frames[frames.Length + PREV_Y]; + } else { + // Interpolate between the previous frame and the current frame. + int frame = Animation.BinarySearch(frames, time, ENTRIES); + x = frames[frame + PREV_X]; + y = frames[frame + PREV_Y]; + float frameTime = frames[frame]; + float percent = GetCurvePercent(frame / ENTRIES - 1, + 1 - (time - frameTime) / (frames[frame + PREV_TIME] - frameTime)); + + x += (frames[frame + X] - x) * percent; + y += (frames[frame + Y] - y) * percent; + } + switch (blend) { + case MixBlend.Setup: + bone.x = bone.data.x + x * alpha; + bone.y = bone.data.y + y * alpha; + break; + case MixBlend.First: + case MixBlend.Replace: + bone.x += (bone.data.x + x - bone.x) * alpha; + bone.y += (bone.data.y + y - bone.y) * alpha; + break; + case MixBlend.Add: + bone.x += x * alpha; + bone.y += y * alpha; + break; + } + } + } + + /// Changes a bone's local and . + public class ScaleTimeline : TranslateTimeline, IBoneTimeline { + public ScaleTimeline (int frameCount) + : base(frameCount) { + } + + override public int PropertyId { + get { return ((int)TimelineType.Scale << 24) + boneIndex; } + } + + override public void Apply (Skeleton skeleton, float lastTime, float time, ExposedList firedEvents, float alpha, MixBlend blend, + MixDirection direction) { + Bone bone = skeleton.bones.Items[boneIndex]; + if (!bone.active) return; + float[] frames = this.frames; + if (time < frames[0]) { // Time is before first frame. + switch (blend) { + case MixBlend.Setup: + bone.scaleX = bone.data.scaleX; + bone.scaleY = bone.data.scaleY; + return; + case MixBlend.First: + bone.scaleX += (bone.data.scaleX - bone.scaleX) * alpha; + bone.scaleY += (bone.data.scaleY - bone.scaleY) * alpha; + return; + } + return; + } + + float x, y; + if (time >= frames[frames.Length - ENTRIES]) { // Time is after last frame. + x = frames[frames.Length + PREV_X] * bone.data.scaleX; + y = frames[frames.Length + PREV_Y] * bone.data.scaleY; + } else { + // Interpolate between the previous frame and the current frame. + int frame = Animation.BinarySearch(frames, time, ENTRIES); + x = frames[frame + PREV_X]; + y = frames[frame + PREV_Y]; + float frameTime = frames[frame]; + float percent = GetCurvePercent(frame / ENTRIES - 1, + 1 - (time - frameTime) / (frames[frame + PREV_TIME] - frameTime)); + + x = (x + (frames[frame + X] - x) * percent) * bone.data.scaleX; + y = (y + (frames[frame + Y] - y) * percent) * bone.data.scaleY; + } + if (alpha == 1) { + if (blend == MixBlend.Add) { + bone.scaleX += x - bone.data.scaleX; + bone.scaleY += y - bone.data.scaleY; + } else { + bone.scaleX = x; + bone.scaleY = y; + } + } else { + // Mixing out uses sign of setup or current pose, else use sign of key. + float bx, by; + if (direction == MixDirection.Out) { + switch (blend) { + case MixBlend.Setup: + bx = bone.data.scaleX; + by = bone.data.scaleY; + bone.scaleX = bx + (Math.Abs(x) * Math.Sign(bx) - bx) * alpha; + bone.scaleY = by + (Math.Abs(y) * Math.Sign(by) - by) * alpha; + break; + case MixBlend.First: + case MixBlend.Replace: + bx = bone.scaleX; + by = bone.scaleY; + bone.scaleX = bx + (Math.Abs(x) * Math.Sign(bx) - bx) * alpha; + bone.scaleY = by + (Math.Abs(y) * Math.Sign(by) - by) * alpha; + break; + case MixBlend.Add: + bx = bone.scaleX; + by = bone.scaleY; + bone.scaleX = bx + (Math.Abs(x) * Math.Sign(bx) - bone.data.scaleX) * alpha; + bone.scaleY = by + (Math.Abs(y) * Math.Sign(by) - bone.data.scaleY) * alpha; + break; + } + } else { + switch (blend) { + case MixBlend.Setup: + bx = Math.Abs(bone.data.scaleX) * Math.Sign(x); + by = Math.Abs(bone.data.scaleY) * Math.Sign(y); + bone.scaleX = bx + (x - bx) * alpha; + bone.scaleY = by + (y - by) * alpha; + break; + case MixBlend.First: + case MixBlend.Replace: + bx = Math.Abs(bone.scaleX) * Math.Sign(x); + by = Math.Abs(bone.scaleY) * Math.Sign(y); + bone.scaleX = bx + (x - bx) * alpha; + bone.scaleY = by + (y - by) * alpha; + break; + case MixBlend.Add: + bx = Math.Sign(x); + by = Math.Sign(y); + bone.scaleX = Math.Abs(bone.scaleX) * bx + (x - Math.Abs(bone.data.scaleX) * bx) * alpha; + bone.scaleY = Math.Abs(bone.scaleY) * by + (y - Math.Abs(bone.data.scaleY) * by) * alpha; + break; + } + } + } + } + } + + /// Changes a bone's local and . + public class ShearTimeline : TranslateTimeline, IBoneTimeline { + public ShearTimeline (int frameCount) + : base(frameCount) { + } + + override public int PropertyId { + get { return ((int)TimelineType.Shear << 24) + boneIndex; } + } + + override public void Apply (Skeleton skeleton, float lastTime, float time, ExposedList firedEvents, float alpha, MixBlend blend, + MixDirection direction) { + Bone bone = skeleton.bones.Items[boneIndex]; + if (!bone.active) return; + float[] frames = this.frames; + if (time < frames[0]) { // Time is before first frame. + switch (blend) { + case MixBlend.Setup: + bone.shearX = bone.data.shearX; + bone.shearY = bone.data.shearY; + return; + case MixBlend.First: + bone.shearX += (bone.data.shearX - bone.shearX) * alpha; + bone.shearY += (bone.data.shearY - bone.shearY) * alpha; + return; + } + return; + } + + float x, y; + if (time >= frames[frames.Length - ENTRIES]) { // Time is after last frame. + x = frames[frames.Length + PREV_X]; + y = frames[frames.Length + PREV_Y]; + } else { + // Interpolate between the previous frame and the current frame. + int frame = Animation.BinarySearch(frames, time, ENTRIES); + x = frames[frame + PREV_X]; + y = frames[frame + PREV_Y]; + float frameTime = frames[frame]; + float percent = GetCurvePercent(frame / ENTRIES - 1, + 1 - (time - frameTime) / (frames[frame + PREV_TIME] - frameTime)); + + x = x + (frames[frame + X] - x) * percent; + y = y + (frames[frame + Y] - y) * percent; + } + switch (blend) { + case MixBlend.Setup: + bone.shearX = bone.data.shearX + x * alpha; + bone.shearY = bone.data.shearY + y * alpha; + break; + case MixBlend.First: + case MixBlend.Replace: + bone.shearX += (bone.data.shearX + x - bone.shearX) * alpha; + bone.shearY += (bone.data.shearY + y - bone.shearY) * alpha; + break; + case MixBlend.Add: + bone.shearX += x * alpha; + bone.shearY += y * alpha; + break; + } + } + } + + /// Changes a slot's . + public class ColorTimeline : CurveTimeline, ISlotTimeline { + public const int ENTRIES = 5; + protected const int PREV_TIME = -5, PREV_R = -4, PREV_G = -3, PREV_B = -2, PREV_A = -1; + protected const int R = 1, G = 2, B = 3, A = 4; + + internal int slotIndex; + internal float[] frames; // time, r, g, b, a, ... + + public ColorTimeline (int frameCount) + : base(frameCount) { + frames = new float[frameCount * ENTRIES]; + } + + override public int PropertyId { + get { return ((int)TimelineType.Color << 24) + slotIndex; } + } + + /// The index of the slot in that will be changed. + public int SlotIndex { + set { + if (value < 0) throw new ArgumentOutOfRangeException("index must be >= 0."); + this.slotIndex = value; + } + get { + return slotIndex; + } + } + /// The time in seconds, red, green, blue, and alpha values for each key frame. + public float[] Frames { get { return frames; } set { frames = value; } } + + /// Sets the time in seconds, red, green, blue, and alpha for the specified key frame. + public void SetFrame (int frameIndex, float time, float r, float g, float b, float a) { + frameIndex *= ENTRIES; + frames[frameIndex] = time; + frames[frameIndex + R] = r; + frames[frameIndex + G] = g; + frames[frameIndex + B] = b; + frames[frameIndex + A] = a; + } + + override public void Apply (Skeleton skeleton, float lastTime, float time, ExposedList firedEvents, float alpha, MixBlend blend, + MixDirection direction) { + Slot slot = skeleton.slots.Items[slotIndex]; + if (!slot.bone.active) return; + float[] frames = this.frames; + if (time < frames[0]) { // Time is before first frame. + var slotData = slot.data; + switch (blend) { + case MixBlend.Setup: + slot.r = slotData.r; + slot.g = slotData.g; + slot.b = slotData.b; + slot.a = slotData.a; + return; + case MixBlend.First: + slot.r += (slotData.r - slot.r) * alpha; + slot.g += (slotData.g - slot.g) * alpha; + slot.b += (slotData.b - slot.b) * alpha; + slot.a += (slotData.a - slot.a) * alpha; + slot.ClampColor(); + return; + } + return; + } + + float r, g, b, a; + if (time >= frames[frames.Length - ENTRIES]) { // Time is after last frame. + int i = frames.Length; + r = frames[i + PREV_R]; + g = frames[i + PREV_G]; + b = frames[i + PREV_B]; + a = frames[i + PREV_A]; + } else { + // Interpolate between the previous frame and the current frame. + int frame = Animation.BinarySearch(frames, time, ENTRIES); + r = frames[frame + PREV_R]; + g = frames[frame + PREV_G]; + b = frames[frame + PREV_B]; + a = frames[frame + PREV_A]; + float frameTime = frames[frame]; + float percent = GetCurvePercent(frame / ENTRIES - 1, + 1 - (time - frameTime) / (frames[frame + PREV_TIME] - frameTime)); + + r += (frames[frame + R] - r) * percent; + g += (frames[frame + G] - g) * percent; + b += (frames[frame + B] - b) * percent; + a += (frames[frame + A] - a) * percent; + } + if (alpha == 1) { + slot.r = r; + slot.g = g; + slot.b = b; + slot.a = a; + slot.ClampColor(); + } else { + float br, bg, bb, ba; + if (blend == MixBlend.Setup) { + br = slot.data.r; + bg = slot.data.g; + bb = slot.data.b; + ba = slot.data.a; + } else { + br = slot.r; + bg = slot.g; + bb = slot.b; + ba = slot.a; + } + slot.r = br + ((r - br) * alpha); + slot.g = bg + ((g - bg) * alpha); + slot.b = bb + ((b - bb) * alpha); + slot.a = ba + ((a - ba) * alpha); + slot.ClampColor(); + } + } + } + + /// Changes a slot's and for two color tinting. + public class TwoColorTimeline : CurveTimeline, ISlotTimeline { + public const int ENTRIES = 8; + protected const int PREV_TIME = -8, PREV_R = -7, PREV_G = -6, PREV_B = -5, PREV_A = -4; + protected const int PREV_R2 = -3, PREV_G2 = -2, PREV_B2 = -1; + protected const int R = 1, G = 2, B = 3, A = 4, R2 = 5, G2 = 6, B2 = 7; + + internal int slotIndex; + internal float[] frames; // time, r, g, b, a, r2, g2, b2, ... + + public TwoColorTimeline (int frameCount) : + base(frameCount) { + frames = new float[frameCount * ENTRIES]; + } + + override public int PropertyId { + get { return ((int)TimelineType.TwoColor << 24) + slotIndex; } + } + + /// The index of the slot in that will be changed. + public int SlotIndex { + set { + if (value < 0) throw new ArgumentOutOfRangeException("index must be >= 0."); + this.slotIndex = value; + } + get { + return slotIndex; + } + } + /// The time in seconds, red, green, blue, and alpha values for each key frame. + public float[] Frames { get { return frames; } } + + /// Sets the time in seconds, light, and dark colors for the specified key frame.. + public void SetFrame (int frameIndex, float time, float r, float g, float b, float a, float r2, float g2, float b2) { + frameIndex *= ENTRIES; + frames[frameIndex] = time; + frames[frameIndex + R] = r; + frames[frameIndex + G] = g; + frames[frameIndex + B] = b; + frames[frameIndex + A] = a; + frames[frameIndex + R2] = r2; + frames[frameIndex + G2] = g2; + frames[frameIndex + B2] = b2; + } + + override public void Apply (Skeleton skeleton, float lastTime, float time, ExposedList firedEvents, float alpha, MixBlend blend, + MixDirection direction) { + Slot slot = skeleton.slots.Items[slotIndex]; + if (!slot.bone.active) return; + float[] frames = this.frames; + if (time < frames[0]) { // Time is before first frame. + var slotData = slot.data; + switch (blend) { + case MixBlend.Setup: + // slot.color.set(slot.data.color); + // slot.darkColor.set(slot.data.darkColor); + slot.r = slotData.r; + slot.g = slotData.g; + slot.b = slotData.b; + slot.a = slotData.a; + slot.ClampColor(); + slot.r2 = slotData.r2; + slot.g2 = slotData.g2; + slot.b2 = slotData.b2; + slot.ClampSecondColor(); + return; + case MixBlend.First: + slot.r += (slot.r - slotData.r) * alpha; + slot.g += (slot.g - slotData.g) * alpha; + slot.b += (slot.b - slotData.b) * alpha; + slot.a += (slot.a - slotData.a) * alpha; + slot.ClampColor(); + slot.r2 += (slot.r2 - slotData.r2) * alpha; + slot.g2 += (slot.g2 - slotData.g2) * alpha; + slot.b2 += (slot.b2 - slotData.b2) * alpha; + slot.ClampSecondColor(); + return; + } + return; + } + + float r, g, b, a, r2, g2, b2; + if (time >= frames[frames.Length - ENTRIES]) { // Time is after last frame. + int i = frames.Length; + r = frames[i + PREV_R]; + g = frames[i + PREV_G]; + b = frames[i + PREV_B]; + a = frames[i + PREV_A]; + r2 = frames[i + PREV_R2]; + g2 = frames[i + PREV_G2]; + b2 = frames[i + PREV_B2]; + } else { + // Interpolate between the previous frame and the current frame. + int frame = Animation.BinarySearch(frames, time, ENTRIES); + r = frames[frame + PREV_R]; + g = frames[frame + PREV_G]; + b = frames[frame + PREV_B]; + a = frames[frame + PREV_A]; + r2 = frames[frame + PREV_R2]; + g2 = frames[frame + PREV_G2]; + b2 = frames[frame + PREV_B2]; + float frameTime = frames[frame]; + float percent = GetCurvePercent(frame / ENTRIES - 1, + 1 - (time - frameTime) / (frames[frame + PREV_TIME] - frameTime)); + + r += (frames[frame + R] - r) * percent; + g += (frames[frame + G] - g) * percent; + b += (frames[frame + B] - b) * percent; + a += (frames[frame + A] - a) * percent; + r2 += (frames[frame + R2] - r2) * percent; + g2 += (frames[frame + G2] - g2) * percent; + b2 += (frames[frame + B2] - b2) * percent; + } + if (alpha == 1) { + slot.r = r; + slot.g = g; + slot.b = b; + slot.a = a; + slot.ClampColor(); + slot.r2 = r2; + slot.g2 = g2; + slot.b2 = b2; + slot.ClampSecondColor(); + } else { + float br, bg, bb, ba, br2, bg2, bb2; + if (blend == MixBlend.Setup) { + br = slot.data.r; + bg = slot.data.g; + bb = slot.data.b; + ba = slot.data.a; + br2 = slot.data.r2; + bg2 = slot.data.g2; + bb2 = slot.data.b2; + } else { + br = slot.r; + bg = slot.g; + bb = slot.b; + ba = slot.a; + br2 = slot.r2; + bg2 = slot.g2; + bb2 = slot.b2; + } + slot.r = br + ((r - br) * alpha); + slot.g = bg + ((g - bg) * alpha); + slot.b = bb + ((b - bb) * alpha); + slot.a = ba + ((a - ba) * alpha); + slot.ClampColor(); + slot.r2 = br2 + ((r2 - br2) * alpha); + slot.g2 = bg2 + ((g2 - bg2) * alpha); + slot.b2 = bb2 + ((b2 - bb2) * alpha); + slot.ClampSecondColor(); + } + } + + } + + /// Changes a slot's . + public class AttachmentTimeline : Timeline, ISlotTimeline { + internal int slotIndex; + internal float[] frames; // time, ... + internal string[] attachmentNames; + + public AttachmentTimeline (int frameCount) { + frames = new float[frameCount]; + attachmentNames = new String[frameCount]; + } + + public int PropertyId { + get { return ((int)TimelineType.Attachment << 24) + slotIndex; } + } + + /// The number of key frames for this timeline. + public int FrameCount { get { return frames.Length; } } + + /// The index of the slot in that will be changed. + public int SlotIndex { + set { + if (value < 0) throw new ArgumentOutOfRangeException("index must be >= 0."); + this.slotIndex = value; + } + get { + return slotIndex; + } + } + + /// The time in seconds for each key frame. + public float[] Frames { get { return frames; } set { frames = value; } } + + /// The attachment name for each key frame. May contain null values to clear the attachment. + public string[] AttachmentNames { get { return attachmentNames; } set { attachmentNames = value; } } + + /// Sets the time in seconds and the attachment name for the specified key frame. + public void SetFrame (int frameIndex, float time, String attachmentName) { + frames[frameIndex] = time; + attachmentNames[frameIndex] = attachmentName; + } + + public void Apply (Skeleton skeleton, float lastTime, float time, ExposedList firedEvents, float alpha, MixBlend blend, + MixDirection direction) { + Slot slot = skeleton.slots.Items[slotIndex]; + if (!slot.bone.active) return; + if (direction == MixDirection.Out) { + if (blend == MixBlend.Setup) SetAttachment(skeleton, slot, slot.data.attachmentName); + return; + } + + float[] frames = this.frames; + if (time < frames[0]) { // Time is before first frame. + if (blend == MixBlend.Setup || blend == MixBlend.First) SetAttachment(skeleton, slot, slot.data.attachmentName); + return; + } + + int frameIndex; + if (time >= frames[frames.Length - 1]) // Time is after last frame. + frameIndex = frames.Length - 1; + else + frameIndex = Animation.BinarySearch(frames, time) - 1; + + SetAttachment(skeleton, slot, attachmentNames[frameIndex]); + } + + private void SetAttachment (Skeleton skeleton, Slot slot, string attachmentName) { + slot.Attachment = attachmentName == null ? null : skeleton.GetAttachment(slotIndex, attachmentName); + } + } + + /// Changes a slot's to deform a . + public class DeformTimeline : CurveTimeline, ISlotTimeline { + internal int slotIndex; + internal VertexAttachment attachment; + internal float[] frames; // time, ... + internal float[][] frameVertices; + + public DeformTimeline (int frameCount) + : base(frameCount) { + frames = new float[frameCount]; + frameVertices = new float[frameCount][]; + } + + override public int PropertyId { + get { return ((int)TimelineType.Deform << 27) + attachment.id + slotIndex; } + } + + /// The index of the slot in that will be changed. + public int SlotIndex { + set { + if (value < 0) throw new ArgumentOutOfRangeException("index must be >= 0."); + this.slotIndex = value; + } + get { + return slotIndex; + } + } + /// The attachment that will be deformed. + public VertexAttachment Attachment { get { return attachment; } set { attachment = value; } } + + /// The time in seconds for each key frame. + public float[] Frames { get { return frames; } set { frames = value; } } + + /// The vertices for each key frame. + public float[][] Vertices { get { return frameVertices; } set { frameVertices = value; } } + + + /// Sets the time in seconds and the vertices for the specified key frame. + /// Vertex positions for an unweighted VertexAttachment, or deform offsets if it has weights. + public void SetFrame (int frameIndex, float time, float[] vertices) { + frames[frameIndex] = time; + frameVertices[frameIndex] = vertices; + } + + override public void Apply (Skeleton skeleton, float lastTime, float time, ExposedList firedEvents, float alpha, MixBlend blend, + MixDirection direction) { + Slot slot = skeleton.slots.Items[slotIndex]; + if (!slot.bone.active) return; + VertexAttachment vertexAttachment = slot.attachment as VertexAttachment; + if (vertexAttachment == null || vertexAttachment.DeformAttachment != attachment) return; + + var deformArray = slot.Deform; + if (deformArray.Count == 0) blend = MixBlend.Setup; + + float[][] frameVertices = this.frameVertices; + int vertexCount = frameVertices[0].Length; + float[] frames = this.frames; + float[] deform; + + if (time < frames[0]) { // Time is before first frame. + + switch (blend) { + case MixBlend.Setup: + deformArray.Clear(); + return; + case MixBlend.First: + if (alpha == 1) { + deformArray.Clear(); + return; + } + + // deformArray.SetSize(vertexCount) // Ensure size and preemptively set count. + if (deformArray.Capacity < vertexCount) deformArray.Capacity = vertexCount; + deformArray.Count = vertexCount; + deform = deformArray.Items; + + if (vertexAttachment.bones == null) { + // Unweighted vertex positions. + float[] setupVertices = vertexAttachment.vertices; + for (int i = 0; i < vertexCount; i++) + deform[i] += (setupVertices[i] - deform[i]) * alpha; + } else { + // Weighted deform offsets. + alpha = 1 - alpha; + for (int i = 0; i < vertexCount; i++) + deform[i] *= alpha; + } + return; + default: + return; + } + + } + + // deformArray.SetSize(vertexCount) // Ensure size and preemptively set count. + if (deformArray.Capacity < vertexCount) deformArray.Capacity = vertexCount; + deformArray.Count = vertexCount; + deform = deformArray.Items; + + if (time >= frames[frames.Length - 1]) { // Time is after last frame. + + float[] lastVertices = frameVertices[frames.Length - 1]; + if (alpha == 1) { + if (blend == MixBlend.Add) { + if (vertexAttachment.bones == null) { + // Unweighted vertex positions, no alpha. + float[] setupVertices = vertexAttachment.vertices; + for (int i = 0; i < vertexCount; i++) + deform[i] += lastVertices[i] - setupVertices[i]; + } else { + // Weighted deform offsets, no alpha. + for (int i = 0; i < vertexCount; i++) + deform[i] += lastVertices[i]; + } + } else { + // Vertex positions or deform offsets, no alpha. + Array.Copy(lastVertices, 0, deform, 0, vertexCount); + } + } else { + switch (blend) { + case MixBlend.Setup: { + if (vertexAttachment.bones == null) { + // Unweighted vertex positions, with alpha. + float[] setupVertices = vertexAttachment.vertices; + for (int i = 0; i < vertexCount; i++) { + float setup = setupVertices[i]; + deform[i] = setup + (lastVertices[i] - setup) * alpha; + } + } else { + // Weighted deform offsets, with alpha. + for (int i = 0; i < vertexCount; i++) + deform[i] = lastVertices[i] * alpha; + } + break; + } + case MixBlend.First: + case MixBlend.Replace: + // Vertex positions or deform offsets, with alpha. + for (int i = 0; i < vertexCount; i++) + deform[i] += (lastVertices[i] - deform[i]) * alpha; + break; + case MixBlend.Add: + if (vertexAttachment.bones == null) { + // Unweighted vertex positions, no alpha. + float[] setupVertices = vertexAttachment.vertices; + for (int i = 0; i < vertexCount; i++) + deform[i] += (lastVertices[i] - setupVertices[i]) * alpha; + } else { + // Weighted deform offsets, alpha. + for (int i = 0; i < vertexCount; i++) + deform[i] += lastVertices[i] * alpha; + } + break; + } + } + return; + } + + // Interpolate between the previous frame and the current frame. + int frame = Animation.BinarySearch(frames, time); + float[] prevVertices = frameVertices[frame - 1]; + float[] nextVertices = frameVertices[frame]; + float frameTime = frames[frame]; + float percent = GetCurvePercent(frame - 1, 1 - (time - frameTime) / (frames[frame - 1] - frameTime)); + + if (alpha == 1) { + if (blend == MixBlend.Add) { + if (vertexAttachment.bones == null) { + // Unweighted vertex positions, no alpha. + float[] setupVertices = vertexAttachment.vertices; + for (int i = 0; i < vertexCount; i++) { + float prev = prevVertices[i]; + deform[i] += prev + (nextVertices[i] - prev) * percent - setupVertices[i]; + } + } else { + // Weighted deform offsets, no alpha. + for (int i = 0; i < vertexCount; i++) { + float prev = prevVertices[i]; + deform[i] += prev + (nextVertices[i] - prev) * percent; + } + } + } else { + // Vertex positions or deform offsets, no alpha. + for (int i = 0; i < vertexCount; i++) { + float prev = prevVertices[i]; + deform[i] = prev + (nextVertices[i] - prev) * percent; + } + } + } else { + switch (blend) { + case MixBlend.Setup: { + if (vertexAttachment.bones == null) { + // Unweighted vertex positions, with alpha. + float[] setupVertices = vertexAttachment.vertices; + for (int i = 0; i < vertexCount; i++) { + float prev = prevVertices[i], setup = setupVertices[i]; + deform[i] = setup + (prev + (nextVertices[i] - prev) * percent - setup) * alpha; + } + } else { + // Weighted deform offsets, with alpha. + for (int i = 0; i < vertexCount; i++) { + float prev = prevVertices[i]; + deform[i] = (prev + (nextVertices[i] - prev) * percent) * alpha; + } + } + break; + } + case MixBlend.First: + case MixBlend.Replace: { + // Vertex positions or deform offsets, with alpha. + for (int i = 0; i < vertexCount; i++) { + float prev = prevVertices[i]; + deform[i] += (prev + (nextVertices[i] - prev) * percent - deform[i]) * alpha; + } + break; + } + case MixBlend.Add: { + if (vertexAttachment.bones == null) { + // Unweighted vertex positions, with alpha. + float[] setupVertices = vertexAttachment.vertices; + for (int i = 0; i < vertexCount; i++) { + float prev = prevVertices[i]; + deform[i] += (prev + (nextVertices[i] - prev) * percent - setupVertices[i]) * alpha; + } + } else { + // Weighted deform offsets, with alpha. + for (int i = 0; i < vertexCount; i++) { + float prev = prevVertices[i]; + deform[i] += (prev + (nextVertices[i] - prev) * percent) * alpha; + } + } + break; + } + } + } + } + } + + /// Fires an when specific animation times are reached. + public class EventTimeline : Timeline { + internal float[] frames; // time, ... + private Event[] events; + + public EventTimeline (int frameCount) { + frames = new float[frameCount]; + events = new Event[frameCount]; + } + + public int PropertyId { + get { return ((int)TimelineType.Event << 24); } + } + + /// The number of key frames for this timeline. + public int FrameCount { get { return frames.Length; } } + + /// The time in seconds for each key frame. + public float[] Frames { get { return frames; } set { frames = value; } } + + /// The event for each key frame. + public Event[] Events { get { return events; } set { events = value; } } + + /// Sets the time in seconds and the event for the specified key frame. + public void SetFrame (int frameIndex, Event e) { + frames[frameIndex] = e.Time; + events[frameIndex] = e; + } + + /// Fires events for frames > lastTime and <= time. + public void Apply (Skeleton skeleton, float lastTime, float time, ExposedList firedEvents, float alpha, MixBlend blend, + MixDirection direction) { + if (firedEvents == null) return; + float[] frames = this.frames; + int frameCount = frames.Length; + + if (lastTime > time) { // Fire events after last time for looped animations. + Apply(skeleton, lastTime, int.MaxValue, firedEvents, alpha, blend, direction); + lastTime = -1f; + } else if (lastTime >= frames[frameCount - 1]) // Last time is after last frame. + return; + if (time < frames[0]) return; // Time is before first frame. + + int frame; + if (lastTime < frames[0]) + frame = 0; + else { + frame = Animation.BinarySearch(frames, lastTime); + float frameTime = frames[frame]; + while (frame > 0) { // Fire multiple events with the same frame. + if (frames[frame - 1] != frameTime) break; + frame--; + } + } + for (; frame < frameCount && time >= frames[frame]; frame++) + firedEvents.Add(events[frame]); + } + } + + /// Changes a skeleton's . + public class DrawOrderTimeline : Timeline { + internal float[] frames; // time, ... + private int[][] drawOrders; + + public DrawOrderTimeline (int frameCount) { + frames = new float[frameCount]; + drawOrders = new int[frameCount][]; + } + + public int PropertyId { + get { return ((int)TimelineType.DrawOrder << 24); } + } + + /// The number of key frames for this timeline. + public int FrameCount { get { return frames.Length; } } + + /// The time in seconds for each key frame. + public float[] Frames { get { return frames; } set { frames = value; } } // time, ... + + /// The draw order for each key frame. + /// . + public int[][] DrawOrders { get { return drawOrders; } set { drawOrders = value; } } + + /// Sets the time in seconds and the draw order for the specified key frame. + /// For each slot in the index of the new draw order. May be null to use setup pose + /// draw order.. + public void SetFrame (int frameIndex, float time, int[] drawOrder) { + frames[frameIndex] = time; + drawOrders[frameIndex] = drawOrder; + } + + public void Apply (Skeleton skeleton, float lastTime, float time, ExposedList firedEvents, float alpha, MixBlend blend, + MixDirection direction) { + ExposedList drawOrder = skeleton.drawOrder; + ExposedList slots = skeleton.slots; + if (direction == MixDirection.Out) { + if (blend == MixBlend.Setup) Array.Copy(slots.Items, 0, drawOrder.Items, 0, slots.Count); + return; + } + + float[] frames = this.frames; + if (time < frames[0]) { // Time is before first frame. + if (blend == MixBlend.Setup || blend == MixBlend.First) Array.Copy(slots.Items, 0, drawOrder.Items, 0, slots.Count); + return; + } + + int frame; + if (time >= frames[frames.Length - 1]) // Time is after last frame. + frame = frames.Length - 1; + else + frame = Animation.BinarySearch(frames, time) - 1; + + int[] drawOrderToSetupIndex = drawOrders[frame]; + if (drawOrderToSetupIndex == null) { + Array.Copy(slots.Items, 0, drawOrder.Items, 0, slots.Count); + } else { + var drawOrderItems = drawOrder.Items; + var slotsItems = slots.Items; + for (int i = 0, n = drawOrderToSetupIndex.Length; i < n; i++) + drawOrderItems[i] = slotsItems[drawOrderToSetupIndex[i]]; + } + } + } + + /// Changes an IK constraint's , , + /// , , and . + public class IkConstraintTimeline : CurveTimeline { + public const int ENTRIES = 6; + private const int PREV_TIME = -6, PREV_MIX = -5, PREV_SOFTNESS = -4, PREV_BEND_DIRECTION = -3, PREV_COMPRESS = -2, + PREV_STRETCH = -1; + private const int MIX = 1, SOFTNESS = 2, BEND_DIRECTION = 3, COMPRESS = 4, STRETCH = 5; + + internal int ikConstraintIndex; + internal float[] frames; // time, mix, softness, bendDirection, compress, stretch, ... + + public IkConstraintTimeline (int frameCount) + : base(frameCount) { + frames = new float[frameCount * ENTRIES]; + } + + override public int PropertyId { + get { return ((int)TimelineType.IkConstraint << 24) + ikConstraintIndex; } + } + + /// The index of the IK constraint slot in that will be changed. + public int IkConstraintIndex { + set { + if (value < 0) throw new ArgumentOutOfRangeException("index must be >= 0."); + this.ikConstraintIndex = value; + } + get { + return ikConstraintIndex; + } + } + + /// The time in seconds, mix, softness, bend direction, compress, and stretch for each key frame. + public float[] Frames { get { return frames; } set { frames = value; } } + + /// Sets the time in seconds, mix, softness, bend direction, compress, and stretch for the specified key frame. + public void SetFrame (int frameIndex, float time, float mix, float softness, int bendDirection, bool compress, + bool stretch) { + frameIndex *= ENTRIES; + frames[frameIndex] = time; + frames[frameIndex + MIX] = mix; + frames[frameIndex + SOFTNESS] = softness; + frames[frameIndex + BEND_DIRECTION] = bendDirection; + frames[frameIndex + COMPRESS] = compress ? 1 : 0; + frames[frameIndex + STRETCH] = stretch ? 1 : 0; + } + + override public void Apply (Skeleton skeleton, float lastTime, float time, ExposedList firedEvents, float alpha, MixBlend blend, + MixDirection direction) { + IkConstraint constraint = skeleton.ikConstraints.Items[ikConstraintIndex]; + if (!constraint.active) return; + float[] frames = this.frames; + if (time < frames[0]) { // Time is before first frame. + switch (blend) { + case MixBlend.Setup: + constraint.mix = constraint.data.mix; + constraint.softness = constraint.data.softness; + constraint.bendDirection = constraint.data.bendDirection; + constraint.compress = constraint.data.compress; + constraint.stretch = constraint.data.stretch; + return; + case MixBlend.First: + constraint.mix += (constraint.data.mix - constraint.mix) * alpha; + constraint.softness += (constraint.data.softness - constraint.softness) * alpha; + constraint.bendDirection = constraint.data.bendDirection; + constraint.compress = constraint.data.compress; + constraint.stretch = constraint.data.stretch; + return; + } + return; + } + + if (time >= frames[frames.Length - ENTRIES]) { // Time is after last frame. + if (blend == MixBlend.Setup) { + constraint.mix = constraint.data.mix + (frames[frames.Length + PREV_MIX] - constraint.data.mix) * alpha; + constraint.softness = constraint.data.softness + + (frames[frames.Length + PREV_SOFTNESS] - constraint.data.softness) * alpha; + if (direction == MixDirection.Out) { + constraint.bendDirection = constraint.data.bendDirection; + constraint.compress = constraint.data.compress; + constraint.stretch = constraint.data.stretch; + } else { + constraint.bendDirection = (int)frames[frames.Length + PREV_BEND_DIRECTION]; + constraint.compress = frames[frames.Length + PREV_COMPRESS] != 0; + constraint.stretch = frames[frames.Length + PREV_STRETCH] != 0; + } + } else { + constraint.mix += (frames[frames.Length + PREV_MIX] - constraint.mix) * alpha; + constraint.softness += (frames[frames.Length + PREV_SOFTNESS] - constraint.softness) * alpha; + if (direction == MixDirection.In) { + constraint.bendDirection = (int)frames[frames.Length + PREV_BEND_DIRECTION]; + constraint.compress = frames[frames.Length + PREV_COMPRESS] != 0; + constraint.stretch = frames[frames.Length + PREV_STRETCH] != 0; + } + } + return; + } + + // Interpolate between the previous frame and the current frame. + int frame = Animation.BinarySearch(frames, time, ENTRIES); + float mix = frames[frame + PREV_MIX]; + float softness = frames[frame + PREV_SOFTNESS]; + float frameTime = frames[frame]; + float percent = GetCurvePercent(frame / ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + PREV_TIME] - frameTime)); + + if (blend == MixBlend.Setup) { + constraint.mix = constraint.data.mix + (mix + (frames[frame + MIX] - mix) * percent - constraint.data.mix) * alpha; + constraint.softness = constraint.data.softness + + (softness + (frames[frame + SOFTNESS] - softness) * percent - constraint.data.softness) * alpha; + if (direction == MixDirection.Out) { + constraint.bendDirection = constraint.data.bendDirection; + constraint.compress = constraint.data.compress; + constraint.stretch = constraint.data.stretch; + } else { + constraint.bendDirection = (int)frames[frame + PREV_BEND_DIRECTION]; + constraint.compress = frames[frame + PREV_COMPRESS] != 0; + constraint.stretch = frames[frame + PREV_STRETCH] != 0; + } + } else { + constraint.mix += (mix + (frames[frame + MIX] - mix) * percent - constraint.mix) * alpha; + constraint.softness += (softness + (frames[frame + SOFTNESS] - softness) * percent - constraint.softness) * alpha; + if (direction == MixDirection.In) { + constraint.bendDirection = (int)frames[frame + PREV_BEND_DIRECTION]; + constraint.compress = frames[frame + PREV_COMPRESS] != 0; + constraint.stretch = frames[frame + PREV_STRETCH] != 0; + } + } + } + } + + /// Changes a transform constraint's mixes. + public class TransformConstraintTimeline : CurveTimeline { + public const int ENTRIES = 5; + private const int PREV_TIME = -5, PREV_ROTATE = -4, PREV_TRANSLATE = -3, PREV_SCALE = -2, PREV_SHEAR = -1; + private const int ROTATE = 1, TRANSLATE = 2, SCALE = 3, SHEAR = 4; + + internal int transformConstraintIndex; + internal float[] frames; // time, rotate mix, translate mix, scale mix, shear mix, ... + + public TransformConstraintTimeline (int frameCount) + : base(frameCount) { + frames = new float[frameCount * ENTRIES]; + } + + override public int PropertyId { + get { return ((int)TimelineType.TransformConstraint << 24) + transformConstraintIndex; } + } + + /// The index of the transform constraint slot in that will be changed. + public int TransformConstraintIndex { + set { + if (value < 0) throw new ArgumentOutOfRangeException("index must be >= 0."); + this.transformConstraintIndex = value; + } + get { + return transformConstraintIndex; + } + } + + /// The time in seconds, rotate mix, translate mix, scale mix, and shear mix for each key frame. + public float[] Frames { get { return frames; } set { frames = value; } } // time, rotate mix, translate mix, scale mix, shear mix, ... + + /// The time in seconds, rotate mix, translate mix, scale mix, and shear mix for the specified key frame. + public void SetFrame (int frameIndex, float time, float rotateMix, float translateMix, float scaleMix, float shearMix) { + frameIndex *= ENTRIES; + frames[frameIndex] = time; + frames[frameIndex + ROTATE] = rotateMix; + frames[frameIndex + TRANSLATE] = translateMix; + frames[frameIndex + SCALE] = scaleMix; + frames[frameIndex + SHEAR] = shearMix; + } + + override public void Apply (Skeleton skeleton, float lastTime, float time, ExposedList firedEvents, float alpha, MixBlend blend, + MixDirection direction) { + TransformConstraint constraint = skeleton.transformConstraints.Items[transformConstraintIndex]; + if (!constraint.active) return; + float[] frames = this.frames; + if (time < frames[0]) { // Time is before first frame. + TransformConstraintData data = constraint.data; + switch (blend) { + case MixBlend.Setup: + constraint.rotateMix = data.rotateMix; + constraint.translateMix = data.translateMix; + constraint.scaleMix = data.scaleMix; + constraint.shearMix = data.shearMix; + return; + case MixBlend.First: + constraint.rotateMix += (data.rotateMix - constraint.rotateMix) * alpha; + constraint.translateMix += (data.translateMix - constraint.translateMix) * alpha; + constraint.scaleMix += (data.scaleMix - constraint.scaleMix) * alpha; + constraint.shearMix += (data.shearMix - constraint.shearMix) * alpha; + return; + } + return; + } + + float rotate, translate, scale, shear; + if (time >= frames[frames.Length - ENTRIES]) { // Time is after last frame. + int i = frames.Length; + rotate = frames[i + PREV_ROTATE]; + translate = frames[i + PREV_TRANSLATE]; + scale = frames[i + PREV_SCALE]; + shear = frames[i + PREV_SHEAR]; + } else { + // Interpolate between the previous frame and the current frame. + int frame = Animation.BinarySearch(frames, time, ENTRIES); + rotate = frames[frame + PREV_ROTATE]; + translate = frames[frame + PREV_TRANSLATE]; + scale = frames[frame + PREV_SCALE]; + shear = frames[frame + PREV_SHEAR]; + float frameTime = frames[frame]; + float percent = GetCurvePercent(frame / ENTRIES - 1, + 1 - (time - frameTime) / (frames[frame + PREV_TIME] - frameTime)); + + rotate += (frames[frame + ROTATE] - rotate) * percent; + translate += (frames[frame + TRANSLATE] - translate) * percent; + scale += (frames[frame + SCALE] - scale) * percent; + shear += (frames[frame + SHEAR] - shear) * percent; + } + if (blend == MixBlend.Setup) { + TransformConstraintData data = constraint.data; + constraint.rotateMix = data.rotateMix + (rotate - data.rotateMix) * alpha; + constraint.translateMix = data.translateMix + (translate - data.translateMix) * alpha; + constraint.scaleMix = data.scaleMix + (scale - data.scaleMix) * alpha; + constraint.shearMix = data.shearMix + (shear - data.shearMix) * alpha; + } else { + constraint.rotateMix += (rotate - constraint.rotateMix) * alpha; + constraint.translateMix += (translate - constraint.translateMix) * alpha; + constraint.scaleMix += (scale - constraint.scaleMix) * alpha; + constraint.shearMix += (shear - constraint.shearMix) * alpha; + } + } + } + + /// Changes a path constraint's . + public class PathConstraintPositionTimeline : CurveTimeline { + public const int ENTRIES = 2; + protected const int PREV_TIME = -2, PREV_VALUE = -1; + protected const int VALUE = 1; + + internal int pathConstraintIndex; + internal float[] frames; // time, position, ... + + public PathConstraintPositionTimeline (int frameCount) + : base(frameCount) { + frames = new float[frameCount * ENTRIES]; + } + + override public int PropertyId { + get { return ((int)TimelineType.PathConstraintPosition << 24) + pathConstraintIndex; } + } + + /// The index of the path constraint slot in that will be changed. + public int PathConstraintIndex { + set { + if (value < 0) throw new ArgumentOutOfRangeException("index must be >= 0."); + this.pathConstraintIndex = value; + } + get { + return pathConstraintIndex; + } + } + + /// The time in seconds and path constraint position for each key frame. + public float[] Frames { get { return frames; } set { frames = value; } } // time, position, ... + + /// Sets the time in seconds and path constraint position for the specified key frame. + public void SetFrame (int frameIndex, float time, float position) { + frameIndex *= ENTRIES; + frames[frameIndex] = time; + frames[frameIndex + VALUE] = position; + } + + override public void Apply (Skeleton skeleton, float lastTime, float time, ExposedList firedEvents, float alpha, MixBlend blend, + MixDirection direction) { + PathConstraint constraint = skeleton.pathConstraints.Items[pathConstraintIndex]; + if (!constraint.active) return; + float[] frames = this.frames; + if (time < frames[0]) { // Time is before first frame. + switch (blend) { + case MixBlend.Setup: + constraint.position = constraint.data.position; + return; + case MixBlend.First: + constraint.position += (constraint.data.position - constraint.position) * alpha; + return; + } + return; + } + + float position; + if (time >= frames[frames.Length - ENTRIES]) // Time is after last frame. + position = frames[frames.Length + PREV_VALUE]; + else { + // Interpolate between the previous frame and the current frame. + int frame = Animation.BinarySearch(frames, time, ENTRIES); + position = frames[frame + PREV_VALUE]; + float frameTime = frames[frame]; + float percent = GetCurvePercent(frame / ENTRIES - 1, + 1 - (time - frameTime) / (frames[frame + PREV_TIME] - frameTime)); + + position += (frames[frame + VALUE] - position) * percent; + } + if (blend == MixBlend.Setup) + constraint.position = constraint.data.position + (position - constraint.data.position) * alpha; + else + constraint.position += (position - constraint.position) * alpha; + } + } + + /// Changes a path constraint's . + public class PathConstraintSpacingTimeline : PathConstraintPositionTimeline { + public PathConstraintSpacingTimeline (int frameCount) + : base(frameCount) { + } + + override public int PropertyId { + get { return ((int)TimelineType.PathConstraintSpacing << 24) + pathConstraintIndex; } + } + + override public void Apply (Skeleton skeleton, float lastTime, float time, ExposedList events, float alpha, MixBlend blend, + MixDirection direction) { + PathConstraint constraint = skeleton.pathConstraints.Items[pathConstraintIndex]; + if (!constraint.active) return; + float[] frames = this.frames; + if (time < frames[0]) { // Time is before first frame. + switch (blend) { + case MixBlend.Setup: + constraint.spacing = constraint.data.spacing; + return; + case MixBlend.First: + constraint.spacing += (constraint.data.spacing - constraint.spacing) * alpha; + return; + } + return; + } + + float spacing; + if (time >= frames[frames.Length - ENTRIES]) // Time is after last frame. + spacing = frames[frames.Length + PREV_VALUE]; + else { + // Interpolate between the previous frame and the current frame. + int frame = Animation.BinarySearch(frames, time, ENTRIES); + spacing = frames[frame + PREV_VALUE]; + float frameTime = frames[frame]; + float percent = GetCurvePercent(frame / ENTRIES - 1, + 1 - (time - frameTime) / (frames[frame + PREV_TIME] - frameTime)); + + spacing += (frames[frame + VALUE] - spacing) * percent; + } + + if (blend == MixBlend.Setup) + constraint.spacing = constraint.data.spacing + (spacing - constraint.data.spacing) * alpha; + else + constraint.spacing += (spacing - constraint.spacing) * alpha; + } + } + + /// Changes a path constraint's mixes. + public class PathConstraintMixTimeline : CurveTimeline { + public const int ENTRIES = 3; + private const int PREV_TIME = -3, PREV_ROTATE = -2, PREV_TRANSLATE = -1; + private const int ROTATE = 1, TRANSLATE = 2; + + internal int pathConstraintIndex; + internal float[] frames; // time, rotate mix, translate mix, ... + + public PathConstraintMixTimeline (int frameCount) + : base(frameCount) { + frames = new float[frameCount * ENTRIES]; + } + + override public int PropertyId { + get { return ((int)TimelineType.PathConstraintMix << 24) + pathConstraintIndex; } + } + + /// The index of the path constraint slot in that will be changed. + public int PathConstraintIndex { + set { + if (value < 0) throw new ArgumentOutOfRangeException("index must be >= 0."); + this.pathConstraintIndex = value; + } + get { + return pathConstraintIndex; + } + } + + /// The time in seconds, rotate mix, and translate mix for each key frame. + public float[] Frames { get { return frames; } set { frames = value; } } // time, rotate mix, translate mix, ... + + /// The time in seconds, rotate mix, and translate mix for the specified key frame. + public void SetFrame (int frameIndex, float time, float rotateMix, float translateMix) { + frameIndex *= ENTRIES; + frames[frameIndex] = time; + frames[frameIndex + ROTATE] = rotateMix; + frames[frameIndex + TRANSLATE] = translateMix; + } + + override public void Apply (Skeleton skeleton, float lastTime, float time, ExposedList firedEvents, float alpha, MixBlend blend, + MixDirection direction) { + PathConstraint constraint = skeleton.pathConstraints.Items[pathConstraintIndex]; + if (!constraint.active) return; + float[] frames = this.frames; + if (time < frames[0]) { // Time is before first frame. + switch (blend) { + case MixBlend.Setup: + constraint.rotateMix = constraint.data.rotateMix; + constraint.translateMix = constraint.data.translateMix; + return; + case MixBlend.First: + constraint.rotateMix += (constraint.data.rotateMix - constraint.rotateMix) * alpha; + constraint.translateMix += (constraint.data.translateMix - constraint.translateMix) * alpha; + return; + } + return; + } + + float rotate, translate; + if (time >= frames[frames.Length - ENTRIES]) { // Time is after last frame. + rotate = frames[frames.Length + PREV_ROTATE]; + translate = frames[frames.Length + PREV_TRANSLATE]; + } else { + // Interpolate between the previous frame and the current frame. + int frame = Animation.BinarySearch(frames, time, ENTRIES); + rotate = frames[frame + PREV_ROTATE]; + translate = frames[frame + PREV_TRANSLATE]; + float frameTime = frames[frame]; + float percent = GetCurvePercent(frame / ENTRIES - 1, + 1 - (time - frameTime) / (frames[frame + PREV_TIME] - frameTime)); + + rotate += (frames[frame + ROTATE] - rotate) * percent; + translate += (frames[frame + TRANSLATE] - translate) * percent; + } + + if (blend == MixBlend.Setup) { + constraint.rotateMix = constraint.data.rotateMix + (rotate - constraint.data.rotateMix) * alpha; + constraint.translateMix = constraint.data.translateMix + (translate - constraint.data.translateMix) * alpha; + } else { + constraint.rotateMix += (rotate - constraint.rotateMix) * alpha; + constraint.translateMix += (translate - constraint.translateMix) * alpha; + } + } + } +} diff --git a/box1/Assets/Spine/Runtime/spine-csharp/Animation.cs.meta b/box1/Assets/Spine/Runtime/spine-csharp/Animation.cs.meta new file mode 100644 index 00000000..cde730f9 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-csharp/Animation.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: fb7099b9c6ce91740b7041dabb0752c2 +timeCreated: 1456265156 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-csharp/AnimationState.cs b/box1/Assets/Spine/Runtime/spine-csharp/AnimationState.cs new file mode 100644 index 00000000..e1c132a1 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-csharp/AnimationState.cs @@ -0,0 +1,1334 @@ +/****************************************************************************** + * 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; + +namespace Spine { + + /// + /// + /// Applies animations over time, queues animations for later playback, mixes (crossfading) between animations, and applies + /// multiple animations on top of each other (layering). + /// + /// See Applying Animations in the Spine Runtimes Guide. + /// + public class AnimationState { + static readonly Animation EmptyAnimation = new Animation("", new ExposedList(), 0); + + /// 1) A previously applied timeline has set this property. + /// Result: Mix from the current pose to the timeline pose. + internal const int Subsequent = 0; + /// 1) This is the first timeline to set this property. + /// 2) The next track entry applied after this one does not have a timeline to set this property. + /// Result: Mix from the setup pose to the timeline pose. + internal const int First = 1; + /// 1) A previously applied timeline has set this property.
+ /// 2) The next track entry to be applied does have a timeline to set this property.
+ /// 3) The next track entry after that one does not have a timeline to set this property.
+ /// Result: Mix from the current pose to the timeline pose, but do not mix out. This avoids "dipping" when crossfading + /// animations that key the same property. A subsequent timeline will set this property using a mix. + internal const int HoldSubsequent = 2; + /// 1) This is the first timeline to set this property. + /// 2) The next track entry to be applied does have a timeline to set this property. + /// 3) The next track entry after that one does not have a timeline to set this property. + /// Result: Mix from the setup pose to the timeline pose, but do not mix out. This avoids "dipping" when crossfading animations + /// that key the same property. A subsequent timeline will set this property using a mix. + internal const int HoldFirst = 3; + /// 1) This is the first timeline to set this property. + /// 2) The next track entry to be applied does have a timeline to set this property. + /// 3) The next track entry after that one does have a timeline to set this property. + /// 4) timelineHoldMix stores the first subsequent track entry that does not have a timeline to set this property. + /// Result: The same as HOLD except the mix percentage from the timelineHoldMix track entry is used. This handles when more than + /// 2 track entries in a row have a timeline that sets the same property. + /// Eg, A -> B -> C -> D where A, B, and C have a timeline setting same property, but D does not. When A is applied, to avoid + /// "dipping" A is not mixed out, however D (the first entry that doesn't set the property) mixing in is used to mix out A + /// (which affects B and C). Without using D to mix out, A would be applied fully until mixing completes, then snap to the mixed + /// out position. + internal const int HoldMix = 4; + + internal const int Setup = 1, Current = 2; + + protected AnimationStateData data; + private readonly ExposedList tracks = new ExposedList(); + private readonly ExposedList events = new ExposedList(); + // difference to libgdx reference: delegates are used for event callbacks instead of 'final SnapshotArray listeners'. + internal void OnStart (TrackEntry entry) { if (Start != null) Start(entry); } + internal void OnInterrupt (TrackEntry entry) { if (Interrupt != null) Interrupt(entry); } + internal void OnEnd (TrackEntry entry) { if (End != null) End(entry); } + internal void OnDispose (TrackEntry entry) { if (Dispose != null) Dispose(entry); } + internal void OnComplete (TrackEntry entry) { if (Complete != null) Complete(entry); } + internal void OnEvent (TrackEntry entry, Event e) { if (Event != null) Event(entry, e); } + + public delegate void TrackEntryDelegate (TrackEntry trackEntry); + public event TrackEntryDelegate Start, Interrupt, End, Dispose, Complete; + + public delegate void TrackEntryEventDelegate (TrackEntry trackEntry, Event e); + public event TrackEntryEventDelegate Event; + + public void AssignEventSubscribersFrom (AnimationState src) { + Event = src.Event; + Start = src.Start; + Interrupt = src.Interrupt; + End = src.End; + Dispose = src.Dispose; + Complete = src.Complete; + } + + public void AddEventSubscribersFrom (AnimationState src) { + Event += src.Event; + Start += src.Start; + Interrupt += src.Interrupt; + End += src.End; + Dispose += src.Dispose; + Complete += src.Complete; + } + + // end of difference + private readonly EventQueue queue; // Initialized by constructor. + private readonly HashSet propertyIDs = new HashSet(); + private bool animationsChanged; + private float timeScale = 1; + private int unkeyedState; + + private readonly Pool trackEntryPool = new Pool(); + + public AnimationState (AnimationStateData data) { + if (data == null) throw new ArgumentNullException("data", "data cannot be null."); + this.data = data; + this.queue = new EventQueue( + this, + delegate { this.animationsChanged = true; }, + trackEntryPool + ); + } + + /// + /// Increments the track entry , setting queued animations as current if needed. + /// delta time + public void Update (float delta) { + delta *= timeScale; + var tracksItems = tracks.Items; + for (int i = 0, n = tracks.Count; i < n; i++) { + TrackEntry current = tracksItems[i]; + if (current == null) continue; + + current.animationLast = current.nextAnimationLast; + current.trackLast = current.nextTrackLast; + + float currentDelta = delta * current.timeScale; + + if (current.delay > 0) { + current.delay -= currentDelta; + if (current.delay > 0) continue; + currentDelta = -current.delay; + current.delay = 0; + } + + TrackEntry next = current.next; + if (next != null) { + // When the next entry's delay is passed, change to the next entry, preserving leftover time. + float nextTime = current.trackLast - next.delay; + if (nextTime >= 0) { + next.delay = 0; + next.trackTime += current.timeScale == 0 ? 0 : (nextTime / current.timeScale + delta) * next.timeScale; + current.trackTime += currentDelta; + SetCurrent(i, next, true); + while (next.mixingFrom != null) { + next.mixTime += delta; + next = next.mixingFrom; + } + continue; + } + } else if (current.trackLast >= current.trackEnd && current.mixingFrom == null) { + // Clear the track when there is no next entry, the track end time is reached, and there is no mixingFrom. + tracksItems[i] = null; + queue.End(current); + DisposeNext(current); + continue; + } + if (current.mixingFrom != null && UpdateMixingFrom(current, delta)) { + // End mixing from entries once all have completed. + TrackEntry from = current.mixingFrom; + current.mixingFrom = null; + if (from != null) from.mixingTo = null; + while (from != null) { + queue.End(from); + from = from.mixingFrom; + } + } + + current.trackTime += currentDelta; + } + + queue.Drain(); + } + + /// Returns true when all mixing from entries are complete. + private bool UpdateMixingFrom (TrackEntry to, float delta) { + TrackEntry from = to.mixingFrom; + if (from == null) return true; + + bool finished = UpdateMixingFrom(from, delta); + + from.animationLast = from.nextAnimationLast; + from.trackLast = from.nextTrackLast; + + // Require mixTime > 0 to ensure the mixing from entry was applied at least once. + if (to.mixTime > 0 && to.mixTime >= to.mixDuration) { + // Require totalAlpha == 0 to ensure mixing is complete, unless mixDuration == 0 (the transition is a single frame). + if (from.totalAlpha == 0 || to.mixDuration == 0) { + to.mixingFrom = from.mixingFrom; + if (from.mixingFrom != null) from.mixingFrom.mixingTo = to; + to.interruptAlpha = from.interruptAlpha; + queue.End(from); + } + return finished; + } + + from.trackTime += delta * from.timeScale; + to.mixTime += delta; + return false; + } + + /// + /// Poses the skeleton using the track entry animations. The animation state is not changed, so can be applied to multiple + /// skeletons to pose them identically. + /// True if any animations were applied. + public bool Apply (Skeleton skeleton) { + if (skeleton == null) throw new ArgumentNullException("skeleton", "skeleton cannot be null."); + if (animationsChanged) AnimationsChanged(); + + var events = this.events; + bool applied = false; + var tracksItems = tracks.Items; + for (int i = 0, n = tracks.Count; i < n; i++) { + TrackEntry current = tracksItems[i]; + if (current == null || current.delay > 0) continue; + applied = true; + + // Track 0 animations aren't for layering, so do not show the previously applied animations before the first key. + MixBlend blend = i == 0 ? MixBlend.First : current.mixBlend; + + // Apply mixing from entries first. + float mix = current.alpha; + if (current.mixingFrom != null) + mix *= ApplyMixingFrom(current, skeleton, blend); + else if (current.trackTime >= current.trackEnd && current.next == null) // + mix = 0; // Set to setup pose the last time the entry will be applied. + + // Apply current entry. + float animationLast = current.animationLast, animationTime = current.AnimationTime; + int timelineCount = current.animation.timelines.Count; + var timelines = current.animation.timelines; + var timelinesItems = timelines.Items; + if ((i == 0 && mix == 1) || blend == MixBlend.Add) { + for (int ii = 0; ii < timelineCount; ii++) { + var timeline = timelinesItems[ii]; + if (timeline is AttachmentTimeline) + ApplyAttachmentTimeline((AttachmentTimeline)timeline, skeleton, animationTime, blend, true); + else + timeline.Apply(skeleton, animationLast, animationTime, events, mix, blend, MixDirection.In); + } + } else { + var timelineMode = current.timelineMode.Items; + + bool firstFrame = current.timelinesRotation.Count != timelineCount << 1; + if (firstFrame) current.timelinesRotation.Resize(timelines.Count << 1); + var timelinesRotation = current.timelinesRotation.Items; + + for (int ii = 0; ii < timelineCount; ii++) { + Timeline timeline = timelinesItems[ii]; + MixBlend timelineBlend = timelineMode[ii] == AnimationState.Subsequent ? blend : MixBlend.Setup; + var rotateTimeline = timeline as RotateTimeline; + if (rotateTimeline != null) + ApplyRotateTimeline(rotateTimeline, skeleton, animationTime, mix, timelineBlend, timelinesRotation, + ii << 1, firstFrame); + else if (timeline is AttachmentTimeline) + ApplyAttachmentTimeline((AttachmentTimeline)timeline, skeleton, animationTime, blend, true); + else + timeline.Apply(skeleton, animationLast, animationTime, events, mix, timelineBlend, MixDirection.In); + } + } + QueueEvents(current, animationTime); + events.Clear(false); + current.nextAnimationLast = animationTime; + current.nextTrackLast = current.trackTime; + } + + // Set slots attachments to the setup pose, if needed. This occurs if an animation that is mixing out sets attachments so + // subsequent timelines see any deform, but the subsequent timelines don't set an attachment (eg they are also mixing out or + // the time is before the first key). + int setupState = unkeyedState + Setup; + var slots = skeleton.slots.Items; + for (int i = 0, n = skeleton.slots.Count; i < n; i++) { + Slot slot = (Slot)slots[i]; + if (slot.attachmentState == setupState) { + string attachmentName = slot.data.attachmentName; + slot.Attachment = (attachmentName == null ? null : skeleton.GetAttachment(slot.data.index, attachmentName)); + } + } + unkeyedState += 2; // Increasing after each use avoids the need to reset attachmentState for every slot. + + queue.Drain(); + return applied; + } + + private float ApplyMixingFrom (TrackEntry to, Skeleton skeleton, MixBlend blend) { + TrackEntry from = to.mixingFrom; + if (from.mixingFrom != null) ApplyMixingFrom(from, skeleton, blend); + + float mix; + if (to.mixDuration == 0) { // Single frame mix to undo mixingFrom changes. + mix = 1; + if (blend == MixBlend.First) blend = MixBlend.Setup; // Tracks > 0 are transparent and can't reset to setup pose. + } else { + mix = to.mixTime / to.mixDuration; + if (mix > 1) mix = 1; + if (blend != MixBlend.First) blend = from.mixBlend; // Track 0 ignores track mix blend. + } + + var eventBuffer = mix < from.eventThreshold ? this.events : null; + bool attachments = mix < from.attachmentThreshold, drawOrder = mix < from.drawOrderThreshold; + float animationLast = from.animationLast, animationTime = from.AnimationTime; + var timelines = from.animation.timelines; + int timelineCount = timelines.Count; + var timelinesItems = timelines.Items; + float alphaHold = from.alpha * to.interruptAlpha, alphaMix = alphaHold * (1 - mix); + + if (blend == MixBlend.Add) { + for (int i = 0; i < timelineCount; i++) + timelinesItems[i].Apply(skeleton, animationLast, animationTime, eventBuffer, alphaMix, blend, MixDirection.Out); + } else { + var timelineMode = from.timelineMode.Items; + var timelineHoldMix = from.timelineHoldMix.Items; + + bool firstFrame = from.timelinesRotation.Count != timelineCount << 1; + if (firstFrame) from.timelinesRotation.Resize(timelines.Count << 1); // from.timelinesRotation.setSize + var timelinesRotation = from.timelinesRotation.Items; + + from.totalAlpha = 0; + for (int i = 0; i < timelineCount; i++) { + Timeline timeline = timelinesItems[i]; + MixDirection direction = MixDirection.Out; + MixBlend timelineBlend; + float alpha; + switch (timelineMode[i]) { + case AnimationState.Subsequent: + if (!drawOrder && timeline is DrawOrderTimeline) continue; + timelineBlend = blend; + alpha = alphaMix; + break; + case AnimationState.First: + timelineBlend = MixBlend.Setup; + alpha = alphaMix; + break; + case AnimationState.HoldSubsequent: + timelineBlend = blend; + alpha = alphaHold; + break; + case AnimationState.HoldFirst: + timelineBlend = MixBlend.Setup; + alpha = alphaHold; + break; + default: // HoldMix + timelineBlend = MixBlend.Setup; + TrackEntry holdMix = timelineHoldMix[i]; + alpha = alphaHold * Math.Max(0, 1 - holdMix.mixTime / holdMix.mixDuration); + break; + } + from.totalAlpha += alpha; + var rotateTimeline = timeline as RotateTimeline; + if (rotateTimeline != null) { + ApplyRotateTimeline(rotateTimeline, skeleton, animationTime, alpha, timelineBlend, timelinesRotation, + i << 1, firstFrame); + } else if (timeline is AttachmentTimeline) { + ApplyAttachmentTimeline((AttachmentTimeline)timeline, skeleton, animationTime, timelineBlend, attachments); + } else { + if (drawOrder && timeline is DrawOrderTimeline && timelineBlend == MixBlend.Setup) + direction = MixDirection.In; + timeline.Apply(skeleton, animationLast, animationTime, eventBuffer, alpha, timelineBlend, direction); + } + } + } + + if (to.mixDuration > 0) QueueEvents(from, animationTime); + this.events.Clear(false); + from.nextAnimationLast = animationTime; + from.nextTrackLast = from.trackTime; + + return mix; + } + + /// Applies the attachment timeline and sets . + /// False when: 1) the attachment timeline is mixing out, 2) mix < attachmentThreshold, and 3) the timeline + /// is not the last timeline to set the slot's attachment. In that case the timeline is applied only so subsequent + /// timelines see any deform. + private void ApplyAttachmentTimeline (AttachmentTimeline timeline, Skeleton skeleton, float time, MixBlend blend, + bool attachments) { + + Slot slot = skeleton.slots.Items[timeline.slotIndex]; + if (!slot.bone.active) return; + + float[] frames = timeline.frames; + if (time < frames[0]) { // Time is before first frame. + if (blend == MixBlend.Setup || blend == MixBlend.First) + SetAttachment(skeleton, slot, slot.data.attachmentName, attachments); + } + else { + int frameIndex; + if (time >= frames[frames.Length - 1]) // Time is after last frame. + frameIndex = frames.Length - 1; + else + frameIndex = Animation.BinarySearch(frames, time) - 1; + SetAttachment(skeleton, slot, timeline.attachmentNames[frameIndex], attachments); + } + + // If an attachment wasn't set (ie before the first frame or attachments is false), set the setup attachment later. + if (slot.attachmentState <= unkeyedState) slot.attachmentState = unkeyedState + Setup; + } + + private void SetAttachment (Skeleton skeleton, Slot slot, String attachmentName, bool attachments) { + slot.Attachment = attachmentName == null ? null : skeleton.GetAttachment(slot.data.index, attachmentName); + if (attachments) slot.attachmentState = unkeyedState + Current; + } + + /// + /// Applies the rotate timeline, mixing with the current pose while keeping the same rotation direction chosen as the shortest + /// the first time the mixing was applied. + static private void ApplyRotateTimeline (RotateTimeline timeline, Skeleton skeleton, float time, float alpha, MixBlend blend, + float[] timelinesRotation, int i, bool firstFrame) { + + if (firstFrame) timelinesRotation[i] = 0; + + if (alpha == 1) { + timeline.Apply(skeleton, 0, time, null, 1, blend, MixDirection.In); + return; + } + + Bone bone = skeleton.bones.Items[timeline.boneIndex]; + if (!bone.active) return; + + float[] frames = timeline.frames; + float r1, r2; + if (time < frames[0]) { // Time is before first frame. + switch (blend) { + case MixBlend.Setup: + bone.rotation = bone.data.rotation; + return; + default: + return; + case MixBlend.First: + r1 = bone.rotation; + r2 = bone.data.rotation; + break; + } + } else { + r1 = blend == MixBlend.Setup ? bone.data.rotation : bone.rotation; + if (time >= frames[frames.Length - RotateTimeline.ENTRIES]) // Time is after last frame. + r2 = bone.data.rotation + frames[frames.Length + RotateTimeline.PREV_ROTATION]; + else { + // Interpolate between the previous frame and the current frame. + int frame = Animation.BinarySearch(frames, time, RotateTimeline.ENTRIES); + float prevRotation = frames[frame + RotateTimeline.PREV_ROTATION]; + float frameTime = frames[frame]; + float percent = timeline.GetCurvePercent((frame >> 1) - 1, + 1 - (time - frameTime) / (frames[frame + RotateTimeline.PREV_TIME] - frameTime)); + + r2 = frames[frame + RotateTimeline.ROTATION] - prevRotation; + r2 -= (16384 - (int)(16384.499999999996 - r2 / 360)) * 360; + r2 = prevRotation + r2 * percent + bone.data.rotation; + r2 -= (16384 - (int)(16384.499999999996 - r2 / 360)) * 360; + } + } + + // Mix between rotations using the direction of the shortest route on the first frame. + float total, diff = r2 - r1; + diff -= (16384 - (int)(16384.499999999996 - diff / 360)) * 360; + if (diff == 0) { + total = timelinesRotation[i]; + } else { + float lastTotal, lastDiff; + if (firstFrame) { + lastTotal = 0; + lastDiff = diff; + } else { + lastTotal = timelinesRotation[i]; // Angle and direction of mix, including loops. + lastDiff = timelinesRotation[i + 1]; // Difference between bones. + } + bool current = diff > 0, dir = lastTotal >= 0; + // Detect cross at 0 (not 180). + if (Math.Sign(lastDiff) != Math.Sign(diff) && Math.Abs(lastDiff) <= 90) { + // A cross after a 360 rotation is a loop. + if (Math.Abs(lastTotal) > 180) lastTotal += 360 * Math.Sign(lastTotal); + dir = current; + } + total = diff + lastTotal - lastTotal % 360; // Store loops as part of lastTotal. + if (dir != current) total += 360 * Math.Sign(lastTotal); + timelinesRotation[i] = total; + } + timelinesRotation[i + 1] = diff; + r1 += total * alpha; + bone.rotation = r1 - (16384 - (int)(16384.499999999996 - r1 / 360)) * 360; + } + + private void QueueEvents (TrackEntry entry, float animationTime) { + float animationStart = entry.animationStart, animationEnd = entry.animationEnd; + float duration = animationEnd - animationStart; + float trackLastWrapped = entry.trackLast % duration; + + // Queue events before complete. + var events = this.events; + var eventsItems = events.Items; + int i = 0, n = events.Count; + for (; i < n; i++) { + Event e = eventsItems[i]; + if (e.time < trackLastWrapped) break; + if (e.time > animationEnd) continue; // Discard events outside animation start/end. + queue.Event(entry, e); + } + + // Queue complete if completed a loop iteration or the animation. + bool complete = false; + if (entry.loop) + complete = duration == 0 || (trackLastWrapped > entry.trackTime % duration); + else + complete = animationTime >= animationEnd && entry.animationLast < animationEnd; + if (complete) queue.Complete(entry); + + // Queue events after complete. + for (; i < n; i++) { + Event e = eventsItems[i]; + if (e.time < animationStart) continue; // Discard events outside animation start/end. + queue.Event(entry, eventsItems[i]); + } + } + + /// + /// Removes all animations from all tracks, leaving skeletons in their current pose. + /// + /// It may be desired to use to mix the skeletons back to the setup pose, + /// rather than leaving them in their current pose. + /// + public void ClearTracks () { + bool oldDrainDisabled = queue.drainDisabled; + queue.drainDisabled = true; + for (int i = 0, n = tracks.Count; i < n; i++) { + ClearTrack(i); + } + tracks.Clear(); + queue.drainDisabled = oldDrainDisabled; + queue.Drain(); + } + + /// + /// Removes all animations from the track, leaving skeletons in their current pose. + /// + /// It may be desired to use to mix the skeletons back to the setup pose, + /// rather than leaving them in their current pose. + /// + public void ClearTrack (int trackIndex) { + if (trackIndex >= tracks.Count) return; + TrackEntry current = tracks.Items[trackIndex]; + if (current == null) return; + + queue.End(current); + + DisposeNext(current); + + TrackEntry entry = current; + while (true) { + TrackEntry from = entry.mixingFrom; + if (from == null) break; + queue.End(from); + entry.mixingFrom = null; + entry.mixingTo = null; + entry = from; + } + + tracks.Items[current.trackIndex] = null; + + queue.Drain(); + } + + /// Sets the active TrackEntry for a given track number. + private void SetCurrent (int index, TrackEntry current, bool interrupt) { + TrackEntry from = ExpandToIndex(index); + tracks.Items[index] = current; + + if (from != null) { + if (interrupt) queue.Interrupt(from); + current.mixingFrom = from; + from.mixingTo = current; + current.mixTime = 0; + + // Store the interrupted mix percentage. + if (from.mixingFrom != null && from.mixDuration > 0) + current.interruptAlpha *= Math.Min(1, from.mixTime / from.mixDuration); + + from.timelinesRotation.Clear(); // Reset rotation for mixing out, in case entry was mixed in. + } + + queue.Start(current); // triggers AnimationsChanged + } + + + /// Sets an animation by name. + public TrackEntry SetAnimation (int trackIndex, string animationName, bool loop) { + Animation animation = data.skeletonData.FindAnimation(animationName); + if (animation == null) throw new ArgumentException("Animation not found: " + animationName, "animationName"); + return SetAnimation(trackIndex, animation, loop); + } + + /// Sets the current animation for a track, discarding any queued animations. If the formerly current track entry was never + /// applied to a skeleton, it is replaced (not mixed from). + /// If true, the animation will repeat. If false it will not, instead its last frame is applied if played beyond its + /// duration. In either case determines when the track is cleared. + /// A track entry to allow further customization of animation playback. References to the track entry must not be kept + /// after the event occurs. + public TrackEntry SetAnimation (int trackIndex, Animation animation, bool loop) { + if (animation == null) throw new ArgumentNullException("animation", "animation cannot be null."); + bool interrupt = true; + TrackEntry current = ExpandToIndex(trackIndex); + if (current != null) { + if (current.nextTrackLast == -1) { + // Don't mix from an entry that was never applied. + tracks.Items[trackIndex] = current.mixingFrom; + queue.Interrupt(current); + queue.End(current); + DisposeNext(current); + current = current.mixingFrom; + interrupt = false; // mixingFrom is current again, but don't interrupt it twice. + } else { + DisposeNext(current); + } + } + TrackEntry entry = NewTrackEntry(trackIndex, animation, loop, current); + SetCurrent(trackIndex, entry, interrupt); + queue.Drain(); + return entry; + } + + /// Queues an animation by name. + /// + public TrackEntry AddAnimation (int trackIndex, string animationName, bool loop, float delay) { + Animation animation = data.skeletonData.FindAnimation(animationName); + if (animation == null) throw new ArgumentException("Animation not found: " + animationName, "animationName"); + return AddAnimation(trackIndex, animation, loop, delay); + } + + /// Adds an animation to be played after the current or last queued animation for a track. If the track is empty, it is + /// equivalent to calling . + /// + /// If > 0, sets . If <= 0, the delay set is the duration of the previous track entry + /// minus any mix duration (from the {@link AnimationStateData}) plus the specified Delay (ie the mix + /// ends at (Delay = 0) or before (Delay < 0) the previous track entry duration). If the + /// previous entry is looping, its next loop completion is used instead of its duration. + /// + /// A track entry to allow further customization of animation playback. References to the track entry must not be kept + /// after the event occurs. + public TrackEntry AddAnimation (int trackIndex, Animation animation, bool loop, float delay) { + if (animation == null) throw new ArgumentNullException("animation", "animation cannot be null."); + + TrackEntry last = ExpandToIndex(trackIndex); + if (last != null) { + while (last.next != null) + last = last.next; + } + + TrackEntry entry = NewTrackEntry(trackIndex, animation, loop, last); + + if (last == null) { + SetCurrent(trackIndex, entry, true); + queue.Drain(); + } else { + last.next = entry; + if (delay <= 0) { + float duration = last.animationEnd - last.animationStart; + if (duration != 0) { + if (last.loop) { + delay += duration * (1 + (int)(last.trackTime / duration)); // Completion of next loop. + } else { + delay += Math.Max(duration, last.trackTime); // After duration, else next update. + } + delay -= data.GetMix(last.animation, animation); + } else + delay = last.trackTime; // Next update. + } + } + + entry.delay = delay; + return entry; + } + + /// + /// Sets an empty animation for a track, discarding any queued animations, and sets the track entry's + /// . An empty animation has no timelines and serves as a placeholder for mixing in or out. + /// + /// Mixing out is done by setting an empty animation with a mix duration using either , + /// , or . Mixing to an empty animation causes + /// the previous animation to be applied less and less over the mix duration. Properties keyed in the previous animation + /// transition to the value from lower tracks or to the setup pose value if no lower tracks key the property. A mix duration of + /// 0 still mixes out over one frame. + /// + /// Mixing in is done by first setting an empty animation, then adding an animation using + /// and on the returned track entry, set the + /// . Mixing from an empty animation causes the new animation to be applied more and + /// more over the mix duration. Properties keyed in the new animation transition from the value from lower tracks or from the + /// setup pose value if no lower tracks key the property to the value keyed in the new animation. + /// + public TrackEntry SetEmptyAnimation (int trackIndex, float mixDuration) { + TrackEntry entry = SetAnimation(trackIndex, AnimationState.EmptyAnimation, false); + entry.mixDuration = mixDuration; + entry.trackEnd = mixDuration; + return entry; + } + + /// + /// Adds an empty animation to be played after the current or last queued animation for a track, and sets the track entry's + /// . If the track is empty, it is equivalent to calling + /// . + /// + /// Track number. + /// Mix duration. + /// If > 0, sets . If <= 0, the delay set is the duration of the previous track entry + /// minus any mix duration plus the specified Delay (ie the mix ends at (Delay = 0) or + /// before (Delay < 0) the previous track entry duration). If the previous entry is looping, its next + /// loop completion is used instead of its duration. + /// A track entry to allow further customization of animation playback. References to the track entry must not be kept + /// after the event occurs. + /// + public TrackEntry AddEmptyAnimation (int trackIndex, float mixDuration, float delay) { + if (delay <= 0) delay -= mixDuration; + TrackEntry entry = AddAnimation(trackIndex, AnimationState.EmptyAnimation, false, delay); + entry.mixDuration = mixDuration; + entry.trackEnd = mixDuration; + return entry; + } + + /// + /// Sets an empty animation for every track, discarding any queued animations, and mixes to it over the specified mix + /// duration. + public void SetEmptyAnimations (float mixDuration) { + bool oldDrainDisabled = queue.drainDisabled; + queue.drainDisabled = true; + for (int i = 0, n = tracks.Count; i < n; i++) { + TrackEntry current = tracks.Items[i]; + if (current != null) SetEmptyAnimation(current.trackIndex, mixDuration); + } + queue.drainDisabled = oldDrainDisabled; + queue.Drain(); + } + + private TrackEntry ExpandToIndex (int index) { + if (index < tracks.Count) return tracks.Items[index]; + tracks.Resize(index + 1); + return null; + } + + /// Object-pooling version of new TrackEntry. Obtain an unused TrackEntry from the pool and clear/initialize its values. + /// May be null. + private TrackEntry NewTrackEntry (int trackIndex, Animation animation, bool loop, TrackEntry last) { + TrackEntry entry = trackEntryPool.Obtain(); // Pooling + entry.trackIndex = trackIndex; + entry.animation = animation; + entry.loop = loop; + entry.holdPrevious = false; + + entry.eventThreshold = 0; + entry.attachmentThreshold = 0; + entry.drawOrderThreshold = 0; + + entry.animationStart = 0; + entry.animationEnd = animation.Duration; + entry.animationLast = -1; + entry.nextAnimationLast = -1; + + entry.delay = 0; + entry.trackTime = 0; + entry.trackLast = -1; + entry.nextTrackLast = -1; // nextTrackLast == -1 signifies a TrackEntry that wasn't applied yet. + entry.trackEnd = float.MaxValue; // loop ? float.MaxValue : animation.Duration; + entry.timeScale = 1; + + entry.alpha = 1; + entry.interruptAlpha = 1; + entry.mixTime = 0; + entry.mixDuration = (last == null) ? 0 : data.GetMix(last.animation, animation); + return entry; + } + + /// Dispose all track entries queued after the given TrackEntry. + private void DisposeNext (TrackEntry entry) { + TrackEntry next = entry.next; + while (next != null) { + queue.Dispose(next); + next = next.next; + } + entry.next = null; + } + + private void AnimationsChanged () { + animationsChanged = false; + + // Process in the order that animations are applied. + propertyIDs.Clear(); + + var tracksItems = tracks.Items; + for (int i = 0, n = tracks.Count; i < n; i++) { + TrackEntry entry = tracksItems[i]; + if (entry == null) continue; + while (entry.mixingFrom != null) // Move to last entry, then iterate in reverse. + entry = entry.mixingFrom; + + do { + if (entry.mixingTo == null || entry.mixBlend != MixBlend.Add) ComputeHold(entry); + entry = entry.mixingTo; + } while (entry != null); + } + } + + private void ComputeHold (TrackEntry entry) { + TrackEntry to = entry.mixingTo; + var timelines = entry.animation.timelines.Items; + int timelinesCount = entry.animation.timelines.Count; + var timelineMode = entry.timelineMode.Resize(timelinesCount).Items; //timelineMode.setSize(timelinesCount); + entry.timelineHoldMix.Clear(); + var timelineHoldMix = entry.timelineHoldMix.Resize(timelinesCount).Items; //timelineHoldMix.setSize(timelinesCount); + var propertyIDs = this.propertyIDs; + + if (to != null && to.holdPrevious) { + for (int i = 0; i < timelinesCount; i++) + timelineMode[i] = propertyIDs.Add(timelines[i].PropertyId) ? AnimationState.HoldFirst : AnimationState.HoldSubsequent; + + return; + } + + // outer: + for (int i = 0; i < timelinesCount; i++) { + Timeline timeline = timelines[i]; + int id = timeline.PropertyId; + if (!propertyIDs.Add(id)) + timelineMode[i] = AnimationState.Subsequent; + else if (to == null || timeline is AttachmentTimeline || timeline is DrawOrderTimeline + || timeline is EventTimeline || !to.animation.HasTimeline(id)) { + timelineMode[i] = AnimationState.First; + } else { + for (TrackEntry next = to.mixingTo; next != null; next = next.mixingTo) { + if (next.animation.HasTimeline(id)) continue; + if (next.mixDuration > 0) { + timelineMode[i] = AnimationState.HoldMix; + timelineHoldMix[i] = next; + goto continue_outer; // continue outer; + } + break; + } + timelineMode[i] = AnimationState.HoldFirst; + } + continue_outer: {} + } + } + + /// The track entry for the animation currently playing on the track, or null if no animation is currently playing. + public TrackEntry GetCurrent (int trackIndex) { + if (trackIndex >= tracks.Count) return null; + return tracks.Items[trackIndex]; + } + + /// Discards all listener notifications that have not yet been delivered. This can be useful to call from an + /// AnimationState event subscriber when it is known that further notifications that may have been already queued for delivery + /// are not wanted because new animations are being set. + public void ClearListenerNotifications () { + queue.Clear(); + } + + /// + /// Multiplier for the delta time when the animation state is updated, causing time for all animations and mixes to play slower + /// or faster. Defaults to 1. + /// + /// See TrackEntry for affecting a single animation. + /// + public float TimeScale { get { return timeScale; } set { timeScale = value; } } + + /// The AnimationStateData to look up mix durations. + public AnimationStateData Data { + get { + return data; + } + set { + if (data == null) throw new ArgumentNullException("data", "data cannot be null."); + this.data = value; + } + } + + /// A list of tracks that have animations, which may contain nulls. + public ExposedList Tracks { get { return tracks; } } + + override public string ToString () { + var buffer = new System.Text.StringBuilder(); + for (int i = 0, n = tracks.Count; i < n; i++) { + TrackEntry entry = tracks.Items[i]; + if (entry == null) continue; + if (buffer.Length > 0) buffer.Append(", "); + buffer.Append(entry.ToString()); + } + if (buffer.Length == 0) return ""; + return buffer.ToString(); + } + } + + /// + /// + /// Stores settings and other state for the playback of an animation on an track. + /// + /// References to a track entry must not be kept after the event occurs. + /// + public class TrackEntry : Pool.IPoolable { + internal Animation animation; + + internal TrackEntry next, mixingFrom, mixingTo; + // difference to libgdx reference: delegates are used for event callbacks instead of 'AnimationStateListener listener'. + public event AnimationState.TrackEntryDelegate Start, Interrupt, End, Dispose, Complete; + public event AnimationState.TrackEntryEventDelegate Event; + internal void OnStart () { if (Start != null) Start(this); } + internal void OnInterrupt () { if (Interrupt != null) Interrupt(this); } + internal void OnEnd () { if (End != null) End(this); } + internal void OnDispose () { if (Dispose != null) Dispose(this); } + internal void OnComplete () { if (Complete != null) Complete(this); } + internal void OnEvent (Event e) { if (Event != null) Event(this, e); } + + internal int trackIndex; + + internal bool loop, holdPrevious; + internal float eventThreshold, attachmentThreshold, drawOrderThreshold; + internal float animationStart, animationEnd, animationLast, nextAnimationLast; + internal float delay, trackTime, trackLast, nextTrackLast, trackEnd, timeScale = 1f; + internal float alpha, mixTime, mixDuration, interruptAlpha, totalAlpha; + internal MixBlend mixBlend = MixBlend.Replace; + internal readonly ExposedList timelineMode = new ExposedList(); + internal readonly ExposedList timelineHoldMix = new ExposedList(); + internal readonly ExposedList timelinesRotation = new ExposedList(); + + // IPoolable.Reset() + public void Reset () { + next = null; + mixingFrom = null; + mixingTo = null; + animation = null; + // replaces 'listener = null;' since delegates are used for event callbacks + Start = null; + Interrupt = null; + End = null; + Dispose = null; + Complete = null; + Event = null; + timelineMode.Clear(); + timelineHoldMix.Clear(); + timelinesRotation.Clear(); + } + + /// The index of the track where this entry is either current or queued. + /// + public int TrackIndex { get { return trackIndex; } } + + /// The animation to apply for this track entry. + public Animation Animation { get { return animation; } } + + /// + /// If true, the animation will repeat. If false it will not, instead its last frame is applied if played beyond its + /// duration. + public bool Loop { get { return loop; } set { loop = value; } } + + /// + /// + /// Seconds to postpone playing the animation. When this track entry is the current track entry, Delay + /// postpones incrementing the . When this track entry is queued, Delay is the time from + /// the start of the previous animation to when this track entry will become the current track entry (ie when the previous + /// track entry >= this track entry's Delay). + /// + /// affects the delay. + /// + public float Delay { get { return delay; } set { delay = value; } } + + /// + /// Current time in seconds this track entry has been the current track entry. The track time determines + /// . The track time can be set to start the animation at a time other than 0, without affecting + /// looping. + public float TrackTime { get { return trackTime; } set { trackTime = value; } } + + /// + /// + /// The track time in seconds when this animation will be removed from the track. Defaults to the highest possible float + /// value, meaning the animation will be applied until a new animation is set or the track is cleared. If the track end time + /// is reached, no other animations are queued for playback, and mixing from any previous animations is complete, then the + /// properties keyed by the animation are set to the setup pose and the track is cleared. + /// + /// It may be desired to use rather than have the animation + /// abruptly cease being applied. + /// + public float TrackEnd { get { return trackEnd; } set { trackEnd = value; } } + + /// + /// + /// Seconds when this animation starts, both initially and after looping. Defaults to 0. + /// + /// When changing the AnimationStart time, it often makes sense to set to the same + /// value to prevent timeline keys before the start time from triggering. + /// + public float AnimationStart { get { return animationStart; } set { animationStart = value; } } + + /// + /// Seconds for the last frame of this animation. Non-looping animations won't play past this time. Looping animations will + /// loop back to at this time. Defaults to the animation . + /// + public float AnimationEnd { get { return animationEnd; } set { animationEnd = value; } } + + /// + /// The time in seconds this animation was last applied. Some timelines use this for one-time triggers. Eg, when this + /// animation is applied, event timelines will fire all events between the AnimationLast time (exclusive) and + /// AnimationTime (inclusive). Defaults to -1 to ensure triggers on frame 0 happen the first time this animation + /// is applied. + public float AnimationLast { + get { return animationLast; } + set { + animationLast = value; + nextAnimationLast = value; + } + } + + /// + /// Uses to compute the AnimationTime, which is between + /// and . When the TrackTime is 0, the AnimationTime is equal to the + /// AnimationStart time. + /// + public float AnimationTime { + get { + if (loop) { + float duration = animationEnd - animationStart; + if (duration == 0) return animationStart; + return (trackTime % duration) + animationStart; + } + return Math.Min(trackTime + animationStart, animationEnd); + } + } + + /// + /// + /// Multiplier for the delta time when this track entry is updated, causing time for this animation to pass slower or + /// faster. Defaults to 1. + /// + /// is not affected by track entry time scale, so may need to be adjusted to + /// match the animation speed. + /// + /// When using with a Delay <= 0, note the + /// { is set using the mix duration from the , assuming time scale to be 1. If + /// the time scale is not 1, the delay may need to be adjusted. + /// + /// See AnimationState for affecting all animations. + /// + public float TimeScale { get { return timeScale; } set { timeScale = value; } } + + /// + /// + /// Values < 1 mix this animation with the skeleton's current pose (usually the pose resulting from lower tracks). Defaults + /// to 1, which overwrites the skeleton's current pose with this animation. + /// + /// Typically track 0 is used to completely pose the skeleton, then alpha is used on higher tracks. It doesn't make sense to + /// use alpha on track 0 if the skeleton pose is from the last frame render. + /// + public float Alpha { get { return alpha; } set { alpha = value; } } + + /// + /// When the mix percentage ( / ) is less than the + /// EventThreshold, event timelines are applied while this animation is being mixed out. Defaults to 0, so event + /// timelines are not applied while this animation is being mixed out. + /// + public float EventThreshold { get { return eventThreshold; } set { eventThreshold = value; } } + + /// + /// When the mix percentage ( / ) is less than the + /// AttachmentThreshold, attachment timelines are applied while this animation is being mixed out. Defaults to + /// 0, so attachment timelines are not applied while this animation is being mixed out. + /// + public float AttachmentThreshold { get { return attachmentThreshold; } set { attachmentThreshold = value; } } + + /// + /// When the mix percentage ( / ) is less than the + /// DrawOrderThreshold, draw order timelines are applied while this animation is being mixed out. Defaults to 0, + /// so draw order timelines are not applied while this animation is being mixed out. + /// + public float DrawOrderThreshold { get { return drawOrderThreshold; } set { drawOrderThreshold = value; } } + + /// + /// The animation queued to start after this animation, or null. Next makes up a linked list. + public TrackEntry Next { get { return next; } } + + /// + /// Returns true if at least one loop has been completed. + /// + public bool IsComplete { + get { return trackTime >= animationEnd - animationStart; } + } + + /// + /// Seconds from 0 to the when mixing from the previous animation to this animation. May be + /// slightly more than MixDuration when the mix is complete. + public float MixTime { get { return mixTime; } set { mixTime = value; } } + + /// + /// + /// Seconds for mixing from the previous animation to this animation. Defaults to the value provided by AnimationStateData + /// based on the animation before this animation (if any). + /// + /// The MixDuration can be set manually rather than use the value from + /// . In that case, the MixDuration can be set for a new + /// track entry only before is first called. + /// + /// When using with a Delay <= 0, note the + /// is set using the mix duration from the , not a mix duration set + /// afterward. + /// + public float MixDuration { get { return mixDuration; } set { mixDuration = value; } } + + /// + /// + /// Controls how properties keyed in the animation are mixed with lower tracks. Defaults to , which + /// replaces the values from the lower tracks with the animation values. adds the animation values to + /// the values from the lower tracks. + /// + /// The MixBlend can be set for a new track entry only before is first + /// called. + /// + public MixBlend MixBlend { get { return mixBlend; } set { mixBlend = value; } } + + /// + /// The track entry for the previous animation when mixing from the previous animation to this animation, or null if no + /// mixing is currently occuring. When mixing from multiple animations, MixingFrom makes up a linked list. + public TrackEntry MixingFrom { get { return mixingFrom; } } + + /// + /// The track entry for the next animation when mixing from this animation to the next animation, or null if no mixing is + /// currently occuring. When mixing to multiple animations, MixingTo makes up a linked list. + public TrackEntry MixingTo { get { return mixingTo; } } + + /// + /// + /// If true, when mixing from the previous animation to this animation, the previous animation is applied as normal instead + /// of being mixed out. + /// + /// When mixing between animations that key the same property, if a lower track also keys that property then the value will + /// briefly dip toward the lower track value during the mix. This happens because the first animation mixes from 100% to 0% + /// while the second animation mixes from 0% to 100%. Setting HoldPrevious to true applies the first animation + /// at 100% during the mix so the lower track value is overwritten. Such dipping does not occur on the lowest track which + /// keys the property, only when a higher track also keys the property. + /// + /// Snapping will occur if HoldPrevious is true and this animation does not key all the same properties as the + /// previous animation. + /// + public bool HoldPrevious { get { return holdPrevious; } set { holdPrevious = value; } } + + /// + /// + /// Resets the rotation directions for mixing this entry's rotate timelines. This can be useful to avoid bones rotating the + /// long way around when using and starting animations on other tracks. + /// + /// Mixing with involves finding a rotation between two others, which has two possible solutions: + /// the short way or the long way around. The two rotations likely change over time, so which direction is the short or long + /// way also changes. If the short way was always chosen, bones would flip to the other side when that direction became the + /// long way. TrackEntry chooses the short way the first time it is applied and remembers that direction. + /// + public void ResetRotationDirections () { + timelinesRotation.Clear(); + } + + override public string ToString () { + return animation == null ? "" : animation.name; + } + } + + class EventQueue { + private readonly List eventQueueEntries = new List(); + internal bool drainDisabled; + + private readonly AnimationState state; + private readonly Pool trackEntryPool; + internal event Action AnimationsChanged; + + internal EventQueue (AnimationState state, Action HandleAnimationsChanged, Pool trackEntryPool) { + this.state = state; + this.AnimationsChanged += HandleAnimationsChanged; + this.trackEntryPool = trackEntryPool; + } + + struct EventQueueEntry { + public EventType type; + public TrackEntry entry; + public Event e; + + public EventQueueEntry (EventType eventType, TrackEntry trackEntry, Event e = null) { + this.type = eventType; + this.entry = trackEntry; + this.e = e; + } + } + + enum EventType { + Start, Interrupt, End, Dispose, Complete, Event + } + + internal void Start (TrackEntry entry) { + eventQueueEntries.Add(new EventQueueEntry(EventType.Start, entry)); + if (AnimationsChanged != null) AnimationsChanged(); + } + + internal void Interrupt (TrackEntry entry) { + eventQueueEntries.Add(new EventQueueEntry(EventType.Interrupt, entry)); + } + + internal void End (TrackEntry entry) { + eventQueueEntries.Add(new EventQueueEntry(EventType.End, entry)); + if (AnimationsChanged != null) AnimationsChanged(); + } + + internal void Dispose (TrackEntry entry) { + eventQueueEntries.Add(new EventQueueEntry(EventType.Dispose, entry)); + } + + internal void Complete (TrackEntry entry) { + eventQueueEntries.Add(new EventQueueEntry(EventType.Complete, entry)); + } + + internal void Event (TrackEntry entry, Event e) { + eventQueueEntries.Add(new EventQueueEntry(EventType.Event, entry, e)); + } + + /// Raises all events in the queue and drains the queue. + internal void Drain () { + if (drainDisabled) return; + drainDisabled = true; + + var entries = this.eventQueueEntries; + AnimationState state = this.state; + + // Don't cache entries.Count so callbacks can queue their own events (eg, call SetAnimation in AnimationState_Complete). + for (int i = 0; i < entries.Count; i++) { + var queueEntry = entries[i]; + TrackEntry trackEntry = queueEntry.entry; + + switch (queueEntry.type) { + case EventType.Start: + trackEntry.OnStart(); + state.OnStart(trackEntry); + break; + case EventType.Interrupt: + trackEntry.OnInterrupt(); + state.OnInterrupt(trackEntry); + break; + case EventType.End: + trackEntry.OnEnd(); + state.OnEnd(trackEntry); + goto case EventType.Dispose; // Fall through. (C#) + case EventType.Dispose: + trackEntry.OnDispose(); + state.OnDispose(trackEntry); + trackEntryPool.Free(trackEntry); // Pooling + break; + case EventType.Complete: + trackEntry.OnComplete(); + state.OnComplete(trackEntry); + break; + case EventType.Event: + trackEntry.OnEvent(queueEntry.e); + state.OnEvent(trackEntry, queueEntry.e); + break; + } + } + eventQueueEntries.Clear(); + + drainDisabled = false; + } + + internal void Clear () { + eventQueueEntries.Clear(); + } + } + + public class Pool where T : class, new() { + public readonly int max; + readonly Stack freeObjects; + + public int Count { get { return freeObjects.Count; } } + public int Peak { get; private set; } + + public Pool (int initialCapacity = 16, int max = int.MaxValue) { + freeObjects = new Stack(initialCapacity); + this.max = max; + } + + public T Obtain () { + return freeObjects.Count == 0 ? new T() : freeObjects.Pop(); + } + + public void Free (T obj) { + if (obj == null) throw new ArgumentNullException("obj", "obj cannot be null"); + if (freeObjects.Count < max) { + freeObjects.Push(obj); + Peak = Math.Max(Peak, freeObjects.Count); + } + Reset(obj); + } + +// protected void FreeAll (List objects) { +// if (objects == null) throw new ArgumentNullException("objects", "objects cannot be null."); +// var freeObjects = this.freeObjects; +// int max = this.max; +// for (int i = 0; i < objects.Count; i++) { +// T obj = objects[i]; +// if (obj == null) continue; +// if (freeObjects.Count < max) freeObjects.Push(obj); +// Reset(obj); +// } +// Peak = Math.Max(Peak, freeObjects.Count); +// } + + public void Clear () { + freeObjects.Clear(); + } + + protected void Reset (T obj) { + var poolable = obj as IPoolable; + if (poolable != null) poolable.Reset(); + } + + public interface IPoolable { + void Reset (); + } + } + +} diff --git a/box1/Assets/Spine/Runtime/spine-csharp/AnimationState.cs.meta b/box1/Assets/Spine/Runtime/spine-csharp/AnimationState.cs.meta new file mode 100644 index 00000000..a6522a75 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-csharp/AnimationState.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: ec2f0e7143c8a174994595883f4b1e33 +timeCreated: 1456265155 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-csharp/AnimationStateData.cs b/box1/Assets/Spine/Runtime/spine-csharp/AnimationStateData.cs new file mode 100644 index 00000000..6cda146f --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-csharp/AnimationStateData.cs @@ -0,0 +1,114 @@ +/****************************************************************************** + * 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; + +namespace Spine { + + /// Stores mix (crossfade) durations to be applied when AnimationState animations are changed. + public class AnimationStateData { + internal SkeletonData skeletonData; + readonly Dictionary animationToMixTime = new Dictionary(AnimationPairComparer.Instance); + internal float defaultMix; + + /// The SkeletonData to look up animations when they are specified by name. + public SkeletonData SkeletonData { get { return skeletonData; } } + + /// + /// The mix duration to use when no mix duration has been specifically defined between two animations. + public float DefaultMix { get { return defaultMix; } set { defaultMix = value; } } + + public AnimationStateData (SkeletonData skeletonData) { + if (skeletonData == null) throw new ArgumentException("skeletonData cannot be null.", "skeletonData"); + this.skeletonData = skeletonData; + } + + /// Sets a mix duration by animation names. + public void SetMix (string fromName, string toName, float duration) { + Animation from = skeletonData.FindAnimation(fromName); + if (from == null) throw new ArgumentException("Animation not found: " + fromName, "fromName"); + Animation to = skeletonData.FindAnimation(toName); + if (to == null) throw new ArgumentException("Animation not found: " + toName, "toName"); + SetMix(from, to, duration); + } + + /// Sets a mix duration when changing from the specified animation to the other. + /// See TrackEntry.MixDuration. + public void SetMix (Animation from, Animation to, float duration) { + if (from == null) throw new ArgumentNullException("from", "from cannot be null."); + if (to == null) throw new ArgumentNullException("to", "to cannot be null."); + AnimationPair key = new AnimationPair(from, to); + animationToMixTime.Remove(key); + animationToMixTime.Add(key, duration); + } + + /// + /// The mix duration to use when changing from the specified animation to the other, + /// or the DefaultMix if no mix duration has been set. + /// + public float GetMix (Animation from, Animation to) { + if (from == null) throw new ArgumentNullException("from", "from cannot be null."); + if (to == null) throw new ArgumentNullException("to", "to cannot be null."); + AnimationPair key = new AnimationPair(from, to); + float duration; + if (animationToMixTime.TryGetValue(key, out duration)) return duration; + return defaultMix; + } + + public struct AnimationPair { + public readonly Animation a1; + public readonly Animation a2; + + public AnimationPair (Animation a1, Animation a2) { + this.a1 = a1; + this.a2 = a2; + } + + public override string ToString () { + return a1.name + "->" + a2.name; + } + } + + // Avoids boxing in the dictionary. + public class AnimationPairComparer : IEqualityComparer { + public static readonly AnimationPairComparer Instance = new AnimationPairComparer(); + + bool IEqualityComparer.Equals (AnimationPair x, AnimationPair y) { + return ReferenceEquals(x.a1, y.a1) && ReferenceEquals(x.a2, y.a2); + } + + int IEqualityComparer.GetHashCode (AnimationPair obj) { + // from Tuple.CombineHashCodes // return (((h1 << 5) + h1) ^ h2); + int h1 = obj.a1.GetHashCode(); + return (((h1 << 5) + h1) ^ obj.a2.GetHashCode()); + } + } + } +} diff --git a/box1/Assets/Spine/Runtime/spine-csharp/AnimationStateData.cs.meta b/box1/Assets/Spine/Runtime/spine-csharp/AnimationStateData.cs.meta new file mode 100644 index 00000000..9890a1fb --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-csharp/AnimationStateData.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: e03d60c517d9b974db35b9fd144a1d09 +timeCreated: 1456265155 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-csharp/Atlas.cs b/box1/Assets/Spine/Runtime/spine-csharp/Atlas.cs new file mode 100644 index 00000000..3ef27c5d --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-csharp/Atlas.cs @@ -0,0 +1,327 @@ +/****************************************************************************** + * 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_5 || UNITY_5_3_OR_NEWER || UNITY_WSA || UNITY_WP8 || UNITY_WP8_1) +#define IS_UNITY +#endif + +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Reflection; + +#if WINDOWS_STOREAPP +using System.Threading.Tasks; +using Windows.Storage; +#endif + +namespace Spine { + public class Atlas : IEnumerable { + readonly List pages = new List(); + List regions = new List(); + TextureLoader textureLoader; + + #region IEnumerable implementation + public IEnumerator GetEnumerator () { + return regions.GetEnumerator(); + } + + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator () { + return regions.GetEnumerator(); + } + #endregion + + #if !(IS_UNITY) + #if WINDOWS_STOREAPP + private async Task ReadFile(string path, TextureLoader textureLoader) { + var folder = Windows.ApplicationModel.Package.Current.InstalledLocation; + var file = await folder.GetFileAsync(path).AsTask().ConfigureAwait(false); + using (var reader = new StreamReader(await file.OpenStreamForReadAsync().ConfigureAwait(false))) { + try { + Load(reader, Path.GetDirectoryName(path), textureLoader); + } catch (Exception ex) { + throw new Exception("Error reading atlas file: " + path, ex); + } + } + } + + public Atlas(string path, TextureLoader textureLoader) { + this.ReadFile(path, textureLoader).Wait(); + } + #else + + public Atlas (string path, TextureLoader textureLoader) { + + #if WINDOWS_PHONE + Stream stream = Microsoft.Xna.Framework.TitleContainer.OpenStream(path); + using (StreamReader reader = new StreamReader(stream)) { + #else + using (StreamReader reader = new StreamReader(path)) { + #endif // WINDOWS_PHONE + + try { + Load(reader, Path.GetDirectoryName(path), textureLoader); + } catch (Exception ex) { + throw new Exception("Error reading atlas file: " + path, ex); + } + + } + } + #endif // WINDOWS_STOREAPP + + #endif + + public Atlas (TextReader reader, string dir, TextureLoader textureLoader) { + Load(reader, dir, textureLoader); + } + + public Atlas (List pages, List regions) { + this.pages = pages; + this.regions = regions; + this.textureLoader = null; + } + + private void Load (TextReader reader, string imagesDir, TextureLoader textureLoader) { + if (textureLoader == null) throw new ArgumentNullException("textureLoader", "textureLoader cannot be null."); + this.textureLoader = textureLoader; + + string[] tuple = new string[4]; + AtlasPage page = null; + while (true) { + string line = reader.ReadLine(); + if (line == null) break; + if (line.Trim().Length == 0) + page = null; + else if (page == null) { + page = new AtlasPage(); + page.name = line; + + if (ReadTuple(reader, tuple) == 2) { // size is only optional for an atlas packed with an old TexturePacker. + page.width = int.Parse(tuple[0], CultureInfo.InvariantCulture); + page.height = int.Parse(tuple[1], CultureInfo.InvariantCulture); + ReadTuple(reader, tuple); + } + page.format = (Format)Enum.Parse(typeof(Format), tuple[0], false); + + ReadTuple(reader, tuple); + page.minFilter = (TextureFilter)Enum.Parse(typeof(TextureFilter), tuple[0], false); + page.magFilter = (TextureFilter)Enum.Parse(typeof(TextureFilter), tuple[1], false); + + string direction = ReadValue(reader); + page.uWrap = TextureWrap.ClampToEdge; + page.vWrap = TextureWrap.ClampToEdge; + if (direction == "x") + page.uWrap = TextureWrap.Repeat; + else if (direction == "y") + page.vWrap = TextureWrap.Repeat; + else if (direction == "xy") + page.uWrap = page.vWrap = TextureWrap.Repeat; + + textureLoader.Load(page, Path.Combine(imagesDir, line)); + + pages.Add(page); + + } else { + AtlasRegion region = new AtlasRegion(); + region.name = line; + region.page = page; + + string rotateValue = ReadValue(reader); + if (rotateValue == "true") + region.degrees = 90; + else if (rotateValue == "false") + region.degrees = 0; + else + region.degrees = int.Parse(rotateValue); + region.rotate = region.degrees == 90; + + ReadTuple(reader, tuple); + int x = int.Parse(tuple[0], CultureInfo.InvariantCulture); + int y = int.Parse(tuple[1], CultureInfo.InvariantCulture); + + ReadTuple(reader, tuple); + int width = int.Parse(tuple[0], CultureInfo.InvariantCulture); + int height = int.Parse(tuple[1], CultureInfo.InvariantCulture); + + region.u = x / (float)page.width; + region.v = y / (float)page.height; + if (region.rotate) { + region.u2 = (x + height) / (float)page.width; + region.v2 = (y + width) / (float)page.height; + } else { + region.u2 = (x + width) / (float)page.width; + region.v2 = (y + height) / (float)page.height; + } + region.x = x; + region.y = y; + region.width = Math.Abs(width); + region.height = Math.Abs(height); + + if (ReadTuple(reader, tuple) == 4) { // split is optional + region.splits = new [] {int.Parse(tuple[0], CultureInfo.InvariantCulture), + int.Parse(tuple[1], CultureInfo.InvariantCulture), + int.Parse(tuple[2], CultureInfo.InvariantCulture), + int.Parse(tuple[3], CultureInfo.InvariantCulture)}; + + if (ReadTuple(reader, tuple) == 4) { // pad is optional, but only present with splits + region.pads = new [] {int.Parse(tuple[0], CultureInfo.InvariantCulture), + int.Parse(tuple[1], CultureInfo.InvariantCulture), + int.Parse(tuple[2], CultureInfo.InvariantCulture), + int.Parse(tuple[3], CultureInfo.InvariantCulture)}; + + ReadTuple(reader, tuple); + } + } + + region.originalWidth = int.Parse(tuple[0], CultureInfo.InvariantCulture); + region.originalHeight = int.Parse(tuple[1], CultureInfo.InvariantCulture); + + ReadTuple(reader, tuple); + region.offsetX = int.Parse(tuple[0], CultureInfo.InvariantCulture); + region.offsetY = int.Parse(tuple[1], CultureInfo.InvariantCulture); + + region.index = int.Parse(ReadValue(reader), CultureInfo.InvariantCulture); + + regions.Add(region); + } + } + } + + static string ReadValue (TextReader reader) { + string line = reader.ReadLine(); + int colon = line.IndexOf(':'); + if (colon == -1) throw new Exception("Invalid line: " + line); + return line.Substring(colon + 1).Trim(); + } + + /// Returns the number of tuple values read (1, 2 or 4). + static int ReadTuple (TextReader reader, string[] tuple) { + string line = reader.ReadLine(); + int colon = line.IndexOf(':'); + if (colon == -1) throw new Exception("Invalid line: " + line); + int i = 0, lastMatch = colon + 1; + for (; i < 3; i++) { + int comma = line.IndexOf(',', lastMatch); + if (comma == -1) break; + tuple[i] = line.Substring(lastMatch, comma - lastMatch).Trim(); + lastMatch = comma + 1; + } + tuple[i] = line.Substring(lastMatch).Trim(); + return i + 1; + } + + public void FlipV () { + for (int i = 0, n = regions.Count; i < n; i++) { + AtlasRegion region = regions[i]; + region.v = 1 - region.v; + region.v2 = 1 - region.v2; + } + } + + /// Returns the first region found with the specified name. This method uses string comparison to find the region, so the result + /// should be cached rather than calling this method multiple times. + /// The region, or null. + public AtlasRegion FindRegion (string name) { + for (int i = 0, n = regions.Count; i < n; i++) + if (regions[i].name == name) return regions[i]; + return null; + } + + public void Dispose () { + if (textureLoader == null) return; + for (int i = 0, n = pages.Count; i < n; i++) + textureLoader.Unload(pages[i].rendererObject); + } + } + + public enum Format { + Alpha, + Intensity, + LuminanceAlpha, + RGB565, + RGBA4444, + RGB888, + RGBA8888 + } + + public enum TextureFilter { + Nearest, + Linear, + MipMap, + MipMapNearestNearest, + MipMapLinearNearest, + MipMapNearestLinear, + MipMapLinearLinear + } + + public enum TextureWrap { + MirroredRepeat, + ClampToEdge, + Repeat + } + + public class AtlasPage { + public string name; + public Format format; + public TextureFilter minFilter; + public TextureFilter magFilter; + public TextureWrap uWrap; + public TextureWrap vWrap; + public object rendererObject; + public int width, height; + + public AtlasPage Clone () { + return MemberwiseClone() as AtlasPage; + } + } + + public class AtlasRegion { + public AtlasPage page; + public string name; + public int x, y, width, height; + public float u, v, u2, v2; + public float offsetX, offsetY; + public int originalWidth, originalHeight; + public int index; + public bool rotate; + public int degrees; + public int[] splits; + public int[] pads; + + public AtlasRegion Clone () { + return MemberwiseClone() as AtlasRegion; + } + } + + public interface TextureLoader { + void Load (AtlasPage page, string path); + void Unload (Object texture); + } +} diff --git a/box1/Assets/Spine/Runtime/spine-csharp/Atlas.cs.meta b/box1/Assets/Spine/Runtime/spine-csharp/Atlas.cs.meta new file mode 100644 index 00000000..8fcbba58 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-csharp/Atlas.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 60626307629cc034bafd42c53a901fff +timeCreated: 1456265154 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-csharp/Attachments.meta b/box1/Assets/Spine/Runtime/spine-csharp/Attachments.meta new file mode 100644 index 00000000..e1b89fe2 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-csharp/Attachments.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 2afe1c6b912aac54abb5925ca4ac52c2 +folderAsset: yes +timeCreated: 1456265152 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-csharp/Attachments/AtlasAttachmentLoader.cs b/box1/Assets/Spine/Runtime/spine-csharp/Attachments/AtlasAttachmentLoader.cs new file mode 100644 index 00000000..52b40598 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-csharp/Attachments/AtlasAttachmentLoader.cs @@ -0,0 +1,109 @@ +/****************************************************************************** + * 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; + +namespace Spine { + + /// + /// An AttachmentLoader that configures attachments using texture regions from an Atlas. + /// See Loading Skeleton Data in the Spine Runtimes Guide. + /// + public class AtlasAttachmentLoader : AttachmentLoader { + private Atlas[] atlasArray; + + public AtlasAttachmentLoader (params Atlas[] atlasArray) { + if (atlasArray == null) throw new ArgumentNullException("atlas array cannot be null."); + this.atlasArray = atlasArray; + } + + public RegionAttachment NewRegionAttachment (Skin skin, string name, string path) { + AtlasRegion region = FindRegion(path); + if (region == null) throw new ArgumentException(string.Format("Region not found in atlas: {0} (region attachment: {1})", path, name)); + RegionAttachment attachment = new RegionAttachment(name); + attachment.RendererObject = region; + attachment.SetUVs(region.u, region.v, region.u2, region.v2, region.rotate); + attachment.regionOffsetX = region.offsetX; + attachment.regionOffsetY = region.offsetY; + attachment.regionWidth = region.width; + attachment.regionHeight = region.height; + attachment.regionOriginalWidth = region.originalWidth; + attachment.regionOriginalHeight = region.originalHeight; + return attachment; + } + + public MeshAttachment NewMeshAttachment (Skin skin, string name, string path) { + AtlasRegion region = FindRegion(path); + if (region == null) throw new ArgumentException(string.Format("Region not found in atlas: {0} (region attachment: {1})", path, name)); + MeshAttachment attachment = new MeshAttachment(name); + attachment.RendererObject = region; + attachment.RegionU = region.u; + attachment.RegionV = region.v; + attachment.RegionU2 = region.u2; + attachment.RegionV2 = region.v2; + attachment.RegionRotate = region.rotate; + attachment.RegionDegrees = region.degrees; + attachment.regionOffsetX = region.offsetX; + attachment.regionOffsetY = region.offsetY; + attachment.regionWidth = region.width; + attachment.regionHeight = region.height; + attachment.regionOriginalWidth = region.originalWidth; + attachment.regionOriginalHeight = region.originalHeight; + return attachment; + } + + public BoundingBoxAttachment NewBoundingBoxAttachment (Skin skin, string name) { + return new BoundingBoxAttachment(name); + } + + public PathAttachment NewPathAttachment (Skin skin, string name) { + return new PathAttachment(name); + } + + public PointAttachment NewPointAttachment (Skin skin, string name) { + return new PointAttachment(name); + } + + public ClippingAttachment NewClippingAttachment(Skin skin, string name) { + return new ClippingAttachment(name); + } + + public AtlasRegion FindRegion (string name) { + AtlasRegion region; + + for (int i = 0; i < atlasArray.Length; i++) { + region = atlasArray[i].FindRegion(name); + if (region != null) + return region; + } + + return null; + } + } +} diff --git a/box1/Assets/Spine/Runtime/spine-csharp/Attachments/AtlasAttachmentLoader.cs.meta b/box1/Assets/Spine/Runtime/spine-csharp/Attachments/AtlasAttachmentLoader.cs.meta new file mode 100644 index 00000000..7b0e50ea --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-csharp/Attachments/AtlasAttachmentLoader.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 3e6ff30e27c28344bad3e67d308c94cd +timeCreated: 1466772712 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-csharp/Attachments/Attachment.cs b/box1/Assets/Spine/Runtime/spine-csharp/Attachments/Attachment.cs new file mode 100644 index 00000000..80918bc6 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-csharp/Attachments/Attachment.cs @@ -0,0 +1,52 @@ +/****************************************************************************** + * 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; + +namespace Spine { + abstract public class Attachment { + public string Name { get; private set; } + + protected Attachment (string name) { + if (name == null) throw new ArgumentNullException("name", "name cannot be null"); + Name = name; + } + + override public string ToString () { + return Name; + } + + ///Returns a copy of the attachment. + public abstract Attachment Copy (); + } + + public interface IHasRendererObject { + object RendererObject { get; set; } + } +} diff --git a/box1/Assets/Spine/Runtime/spine-csharp/Attachments/Attachment.cs.meta b/box1/Assets/Spine/Runtime/spine-csharp/Attachments/Attachment.cs.meta new file mode 100644 index 00000000..f396651f --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-csharp/Attachments/Attachment.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 05b56321b2ddd8145a888746bc6ab917 +timeCreated: 1456265153 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-csharp/Attachments/AttachmentLoader.cs b/box1/Assets/Spine/Runtime/spine-csharp/Attachments/AttachmentLoader.cs new file mode 100644 index 00000000..962376b6 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-csharp/Attachments/AttachmentLoader.cs @@ -0,0 +1,48 @@ +/****************************************************************************** + * 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. + *****************************************************************************/ + +namespace Spine { + public interface AttachmentLoader { + /// May be null to not load any attachment. + RegionAttachment NewRegionAttachment (Skin skin, string name, string path); + + /// May be null to not load any attachment. + MeshAttachment NewMeshAttachment (Skin skin, string name, string path); + + /// May be null to not load any attachment. + BoundingBoxAttachment NewBoundingBoxAttachment (Skin skin, string name); + + /// May be null to not load any attachment + PathAttachment NewPathAttachment (Skin skin, string name); + + PointAttachment NewPointAttachment (Skin skin, string name); + + ClippingAttachment NewClippingAttachment (Skin skin, string name); + } +} diff --git a/box1/Assets/Spine/Runtime/spine-csharp/Attachments/AttachmentLoader.cs.meta b/box1/Assets/Spine/Runtime/spine-csharp/Attachments/AttachmentLoader.cs.meta new file mode 100644 index 00000000..6e765cff --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-csharp/Attachments/AttachmentLoader.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 95466a4f5a30dca4aa69e8ee7df8ae85 +timeCreated: 1466772712 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-csharp/Attachments/AttachmentType.cs b/box1/Assets/Spine/Runtime/spine-csharp/Attachments/AttachmentType.cs new file mode 100644 index 00000000..09000e52 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-csharp/Attachments/AttachmentType.cs @@ -0,0 +1,34 @@ +/****************************************************************************** + * 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. + *****************************************************************************/ + +namespace Spine { + public enum AttachmentType { + Region, Boundingbox, Mesh, Linkedmesh, Path, Point, Clipping + } +} diff --git a/box1/Assets/Spine/Runtime/spine-csharp/Attachments/AttachmentType.cs.meta b/box1/Assets/Spine/Runtime/spine-csharp/Attachments/AttachmentType.cs.meta new file mode 100644 index 00000000..3eb0eb4b --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-csharp/Attachments/AttachmentType.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: d6b1941960a9f6f47be3e865554d8695 +timeCreated: 1466772712 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-csharp/Attachments/BoundingBoxAttachment.cs b/box1/Assets/Spine/Runtime/spine-csharp/Attachments/BoundingBoxAttachment.cs new file mode 100644 index 00000000..f9b73692 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-csharp/Attachments/BoundingBoxAttachment.cs @@ -0,0 +1,45 @@ +/****************************************************************************** + * 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; + +namespace Spine { + /// Attachment that has a polygon for bounds checking. + public class BoundingBoxAttachment : VertexAttachment { + public BoundingBoxAttachment (string name) + : base(name) { + } + + public override Attachment Copy () { + BoundingBoxAttachment copy = new BoundingBoxAttachment(this.Name); + CopyTo(copy); + return copy; + } + } +} diff --git a/box1/Assets/Spine/Runtime/spine-csharp/Attachments/BoundingBoxAttachment.cs.meta b/box1/Assets/Spine/Runtime/spine-csharp/Attachments/BoundingBoxAttachment.cs.meta new file mode 100644 index 00000000..eba3432e --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-csharp/Attachments/BoundingBoxAttachment.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: cd8ad8fc0f5bce448ba26d096ab32e85 +timeCreated: 1466772712 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-csharp/Attachments/ClippingAttachment.cs b/box1/Assets/Spine/Runtime/spine-csharp/Attachments/ClippingAttachment.cs new file mode 100644 index 00000000..b0aa8db6 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-csharp/Attachments/ClippingAttachment.cs @@ -0,0 +1,48 @@ +/****************************************************************************** + * 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; + +namespace Spine { + public class ClippingAttachment : VertexAttachment { + internal SlotData endSlot; + + public SlotData EndSlot { get { return endSlot; } set { endSlot = value; } } + + public ClippingAttachment(string name) : base(name) { + } + + public override Attachment Copy () { + ClippingAttachment copy = new ClippingAttachment(this.Name); + CopyTo(copy); + copy.endSlot = endSlot; + return copy; + } + } +} diff --git a/box1/Assets/Spine/Runtime/spine-csharp/Attachments/ClippingAttachment.cs.meta b/box1/Assets/Spine/Runtime/spine-csharp/Attachments/ClippingAttachment.cs.meta new file mode 100644 index 00000000..fb2404fd --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-csharp/Attachments/ClippingAttachment.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 3380954b107f38b4c85a4cdfeceace42 +timeCreated: 1492744746 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-csharp/Attachments/MeshAttachment.cs b/box1/Assets/Spine/Runtime/spine-csharp/Attachments/MeshAttachment.cs new file mode 100644 index 00000000..fad2ee1d --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-csharp/Attachments/MeshAttachment.cs @@ -0,0 +1,224 @@ +/****************************************************************************** + * 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; + +namespace Spine { + /// Attachment that displays a texture region using a mesh. + public class MeshAttachment : VertexAttachment, IHasRendererObject { + internal float regionOffsetX, regionOffsetY, regionWidth, regionHeight, regionOriginalWidth, regionOriginalHeight; + private MeshAttachment parentMesh; + internal float[] uvs, regionUVs; + internal int[] triangles; + internal float r = 1, g = 1, b = 1, a = 1; + internal int hulllength; + + public int HullLength { get { return hulllength; } set { hulllength = value; } } + public float[] RegionUVs { get { return regionUVs; } set { regionUVs = value; } } + /// The UV pair for each vertex, normalized within the entire texture. + public float[] UVs { get { return uvs; } set { uvs = value; } } + public int[] Triangles { get { return triangles; } set { triangles = value; } } + + public float R { get { return r; } set { r = value; } } + public float G { get { return g; } set { g = value; } } + public float B { get { return b; } set { b = value; } } + public float A { get { return a; } set { a = value; } } + + public string Path { get; set; } + public object RendererObject { get; set; } + public float RegionU { get; set; } + public float RegionV { get; set; } + public float RegionU2 { get; set; } + public float RegionV2 { get; set; } + public bool RegionRotate { get; set; } + public int RegionDegrees { get; set; } + public float RegionOffsetX { get { return regionOffsetX; } set { regionOffsetX = value; } } + public float RegionOffsetY { get { return regionOffsetY; } set { regionOffsetY = value; } } // Pixels stripped from the bottom left, unrotated. + public float RegionWidth { get { return regionWidth; } set { regionWidth = value; } } + public float RegionHeight { get { return regionHeight; } set { regionHeight = value; } } // Unrotated, stripped size. + public float RegionOriginalWidth { get { return regionOriginalWidth; } set { regionOriginalWidth = value; } } + public float RegionOriginalHeight { get { return regionOriginalHeight; } set { regionOriginalHeight = value; } } // Unrotated, unstripped size. + + public MeshAttachment ParentMesh { + get { return parentMesh; } + set { + parentMesh = value; + if (value != null) { + bones = value.bones; + vertices = value.vertices; + worldVerticesLength = value.worldVerticesLength; + regionUVs = value.regionUVs; + triangles = value.triangles; + HullLength = value.HullLength; + Edges = value.Edges; + Width = value.Width; + Height = value.Height; + } + } + } + + // Nonessential. + public int[] Edges { get; set; } + public float Width { get; set; } + public float Height { get; set; } + + public MeshAttachment (string name) + : base(name) { + } + + public void UpdateUVs () { + float[] regionUVs = this.regionUVs; + if (this.uvs == null || this.uvs.Length != regionUVs.Length) this.uvs = new float[regionUVs.Length]; + float[] uvs = this.uvs; + float u = RegionU, v = RegionV, width = 0, height = 0; + + if (RegionDegrees == 90) { + float textureHeight = this.regionWidth / (RegionV2 - RegionV); + float textureWidth = this.regionHeight / (RegionU2 - RegionU); + u -= (RegionOriginalHeight - RegionOffsetY - RegionHeight) / textureWidth; + v -= (RegionOriginalWidth - RegionOffsetX - RegionWidth) / textureHeight; + width = RegionOriginalHeight / textureWidth; + height = RegionOriginalWidth / textureHeight; + + for (int i = 0, n = uvs.Length; i < n; i += 2) { + uvs[i] = u + regionUVs[i + 1] * width; + uvs[i + 1] = v + (1 - regionUVs[i]) * height; + } + } else if (RegionDegrees == 180) { + float textureWidth = this.regionWidth / (RegionU2 - RegionU); + float textureHeight = this.regionHeight / (RegionV2 - RegionV); + u -= (RegionOriginalWidth - RegionOffsetX - RegionWidth) / textureWidth; + v -= RegionOffsetY / textureHeight; + width = RegionOriginalWidth / textureWidth; + height = RegionOriginalHeight / textureHeight; + + for (int i = 0, n = uvs.Length; i < n; i += 2) { + uvs[i] = u + (1 - regionUVs[i]) * width; + uvs[i + 1] = v + (1 - regionUVs[i + 1]) * height; + } + } else if (RegionDegrees == 270) { + float textureWidth = this.regionWidth / (RegionU2 - RegionU); + float textureHeight = this.regionHeight / (RegionV2 - RegionV); + u -= RegionOffsetY / textureWidth; + v -= RegionOffsetX / textureHeight; + width = RegionOriginalHeight / textureWidth; + height = RegionOriginalWidth / textureHeight; + + for (int i = 0, n = uvs.Length; iReturns a new mesh with this mesh set as the . + public MeshAttachment NewLinkedMesh () { + MeshAttachment mesh = new MeshAttachment(Name); + mesh.RendererObject = RendererObject; + mesh.regionOffsetX = regionOffsetX; + mesh.regionOffsetY = regionOffsetY; + mesh.regionWidth = regionWidth; + mesh.regionHeight = regionHeight; + mesh.regionOriginalWidth = regionOriginalWidth; + mesh.regionOriginalHeight = regionOriginalHeight; + mesh.RegionDegrees = RegionDegrees; + mesh.RegionRotate = RegionRotate; + mesh.RegionU = RegionU; + mesh.RegionV = RegionV; + mesh.RegionU2 = RegionU2; + mesh.RegionV2 = RegionV2; + + mesh.Path = Path; + mesh.r = r; + mesh.g = g; + mesh.b = b; + mesh.a = a; + + mesh.deformAttachment = deformAttachment; + mesh.ParentMesh = parentMesh != null ? parentMesh : this; + mesh.UpdateUVs(); + return mesh; + } + } +} diff --git a/box1/Assets/Spine/Runtime/spine-csharp/Attachments/MeshAttachment.cs.meta b/box1/Assets/Spine/Runtime/spine-csharp/Attachments/MeshAttachment.cs.meta new file mode 100644 index 00000000..72ca3dd5 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-csharp/Attachments/MeshAttachment.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: b7f7514a003143844b6d01ecc93ed4d5 +timeCreated: 1466772712 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-csharp/Attachments/PathAttachment.cs b/box1/Assets/Spine/Runtime/spine-csharp/Attachments/PathAttachment.cs new file mode 100644 index 00000000..375379d5 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-csharp/Attachments/PathAttachment.cs @@ -0,0 +1,57 @@ +/****************************************************************************** + * 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; + +namespace Spine { + public class PathAttachment : VertexAttachment { + internal float[] lengths; + internal bool closed, constantSpeed; + + /// The length in the setup pose from the start of the path to the end of each curve. + public float[] Lengths { get { return lengths; } set { lengths = value; } } + public bool Closed { get { return closed; } set { closed = value; } } + public bool ConstantSpeed { get { return constantSpeed; } set { constantSpeed = value; } } + + public PathAttachment (String name) + : base(name) { + } + + public override Attachment Copy () { + PathAttachment copy = new PathAttachment(this.Name); + CopyTo(copy); + copy.lengths = new float[lengths.Length]; + Array.Copy(lengths, 0, copy.lengths, 0, lengths.Length); + copy.closed = closed; + copy.constantSpeed = constantSpeed; + return copy; + } + } +} diff --git a/box1/Assets/Spine/Runtime/spine-csharp/Attachments/PathAttachment.cs.meta b/box1/Assets/Spine/Runtime/spine-csharp/Attachments/PathAttachment.cs.meta new file mode 100644 index 00000000..f9feef94 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-csharp/Attachments/PathAttachment.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: c77d9bf384a1e9f41966464e7e3b4870 +timeCreated: 1466772712 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-csharp/Attachments/PointAttachment.cs b/box1/Assets/Spine/Runtime/spine-csharp/Attachments/PointAttachment.cs new file mode 100644 index 00000000..be4668ec --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-csharp/Attachments/PointAttachment.cs @@ -0,0 +1,67 @@ +/****************************************************************************** + * 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. + *****************************************************************************/ + +namespace Spine { + /// + /// An attachment which is a single point and a rotation. This can be used to spawn projectiles, particles, etc. A bone can be + /// used in similar ways, but a PointAttachment is slightly less expensive to compute and can be hidden, shown, and placed in a + /// skin. + ///

+ /// See Point Attachments in the Spine User Guide. + ///

+ public class PointAttachment : Attachment { + internal float x, y, rotation; + public float X { get { return x; } set { x = value; } } + public float Y { get { return y; } set { y = value; } } + public float Rotation { get { return rotation; } set { rotation = value; } } + + public PointAttachment (string name) + : base(name) { + } + + public void ComputeWorldPosition (Bone bone, out float ox, out float oy) { + bone.LocalToWorld(this.x, this.y, out ox, out oy); + } + + public float ComputeWorldRotation (Bone bone) { + float cos = MathUtils.CosDeg(rotation), sin = MathUtils.SinDeg(rotation); + float ix = cos * bone.a + sin * bone.b; + float iy = cos * bone.c + sin * bone.d; + return MathUtils.Atan2(iy, ix) * MathUtils.RadDeg; + } + + public override Attachment Copy () { + PointAttachment copy = new PointAttachment(this.Name); + copy.x = x; + copy.y = y; + copy.rotation = rotation; + return copy; + } + } +} diff --git a/box1/Assets/Spine/Runtime/spine-csharp/Attachments/PointAttachment.cs.meta b/box1/Assets/Spine/Runtime/spine-csharp/Attachments/PointAttachment.cs.meta new file mode 100644 index 00000000..7e28782d --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-csharp/Attachments/PointAttachment.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 4fdde4cc4df0952468946f4f913dcb36 +timeCreated: 1485603478 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-csharp/Attachments/RegionAttachment.cs b/box1/Assets/Spine/Runtime/spine-csharp/Attachments/RegionAttachment.cs new file mode 100644 index 00000000..460f9b8f --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-csharp/Attachments/RegionAttachment.cs @@ -0,0 +1,208 @@ +/****************************************************************************** + * 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; + +namespace Spine { + /// Attachment that displays a texture region. + public class RegionAttachment : Attachment, IHasRendererObject { + public const int BLX = 0; + public const int BLY = 1; + public const int ULX = 2; + public const int ULY = 3; + public const int URX = 4; + public const int URY = 5; + public const int BRX = 6; + public const int BRY = 7; + + internal float x, y, rotation, scaleX = 1, scaleY = 1, width, height; + internal float regionOffsetX, regionOffsetY, regionWidth, regionHeight, regionOriginalWidth, regionOriginalHeight; + internal float[] offset = new float[8], uvs = new float[8]; + internal float r = 1, g = 1, b = 1, a = 1; + + public float X { get { return x; } set { x = value; } } + public float Y { get { return y; } set { y = value; } } + public float Rotation { get { return rotation; } set { rotation = value; } } + public float ScaleX { get { return scaleX; } set { scaleX = value; } } + public float ScaleY { get { return scaleY; } set { scaleY = value; } } + public float Width { get { return width; } set { width = value; } } + public float Height { get { return height; } set { height = value; } } + + public float R { get { return r; } set { r = value; } } + public float G { get { return g; } set { g = value; } } + public float B { get { return b; } set { b = value; } } + public float A { get { return a; } set { a = value; } } + + public string Path { get; set; } + public object RendererObject { get; set; } + public float RegionOffsetX { get { return regionOffsetX; } set { regionOffsetX = value; } } + public float RegionOffsetY { get { return regionOffsetY; } set { regionOffsetY = value; } } // Pixels stripped from the bottom left, unrotated. + public float RegionWidth { get { return regionWidth; } set { regionWidth = value; } } + public float RegionHeight { get { return regionHeight; } set { regionHeight = value; } } // Unrotated, stripped size. + public float RegionOriginalWidth { get { return regionOriginalWidth; } set { regionOriginalWidth = value; } } + public float RegionOriginalHeight { get { return regionOriginalHeight; } set { regionOriginalHeight = value; } } // Unrotated, unstripped size. + + public float[] Offset { get { return offset; } } + public float[] UVs { get { return uvs; } } + + public RegionAttachment (string name) + : base(name) { + } + + public void UpdateOffset () { + float width = this.width; + float height = this.height; + float localX2 = width * 0.5f; + float localY2 = height * 0.5f; + float localX = -localX2; + float localY = -localY2; + if (regionOriginalWidth != 0) { // if (region != null) + localX += regionOffsetX / regionOriginalWidth * width; + localY += regionOffsetY / regionOriginalHeight * height; + localX2 -= (regionOriginalWidth - regionOffsetX - regionWidth) / regionOriginalWidth * width; + localY2 -= (regionOriginalHeight - regionOffsetY - regionHeight) / regionOriginalHeight * height; + } + float scaleX = this.scaleX; + float scaleY = this.scaleY; + localX *= scaleX; + localY *= scaleY; + localX2 *= scaleX; + localY2 *= scaleY; + float rotation = this.rotation; + float cos = MathUtils.CosDeg(rotation); + float sin = MathUtils.SinDeg(rotation); + float x = this.x; + float y = this.y; + float localXCos = localX * cos + x; + float localXSin = localX * sin; + float localYCos = localY * cos + y; + float localYSin = localY * sin; + float localX2Cos = localX2 * cos + x; + float localX2Sin = localX2 * sin; + float localY2Cos = localY2 * cos + y; + float localY2Sin = localY2 * sin; + float[] offset = this.offset; + offset[BLX] = localXCos - localYSin; + offset[BLY] = localYCos + localXSin; + offset[ULX] = localXCos - localY2Sin; + offset[ULY] = localY2Cos + localXSin; + offset[URX] = localX2Cos - localY2Sin; + offset[URY] = localY2Cos + localX2Sin; + offset[BRX] = localX2Cos - localYSin; + offset[BRY] = localYCos + localX2Sin; + } + + public void SetUVs (float u, float v, float u2, float v2, bool rotate) { + float[] uvs = this.uvs; + // UV values differ from RegionAttachment.java + if (rotate) { + uvs[URX] = u; + uvs[URY] = v2; + uvs[BRX] = u; + uvs[BRY] = v; + uvs[BLX] = u2; + uvs[BLY] = v; + uvs[ULX] = u2; + uvs[ULY] = v2; + } else { + uvs[ULX] = u; + uvs[ULY] = v2; + uvs[URX] = u; + uvs[URY] = v; + uvs[BRX] = u2; + uvs[BRY] = v; + uvs[BLX] = u2; + uvs[BLY] = v2; + } + } + + /// Transforms the attachment's four vertices to world coordinates. + /// The parent bone. + /// The output world vertices. Must have a length greater than or equal to offset + 8. + /// The worldVertices index to begin writing values. + /// The number of worldVertices entries between the value pairs written. + public void ComputeWorldVertices (Bone bone, float[] worldVertices, int offset, int stride = 2) { + float[] vertexOffset = this.offset; + float bwx = bone.worldX, bwy = bone.worldY; + float a = bone.a, b = bone.b, c = bone.c, d = bone.d; + float offsetX, offsetY; + + // Vertex order is different from RegionAttachment.java + offsetX = vertexOffset[BRX]; // 0 + offsetY = vertexOffset[BRY]; // 1 + worldVertices[offset] = offsetX * a + offsetY * b + bwx; // bl + worldVertices[offset + 1] = offsetX * c + offsetY * d + bwy; + offset += stride; + + offsetX = vertexOffset[BLX]; // 2 + offsetY = vertexOffset[BLY]; // 3 + worldVertices[offset] = offsetX * a + offsetY * b + bwx; // ul + worldVertices[offset + 1] = offsetX * c + offsetY * d + bwy; + offset += stride; + + offsetX = vertexOffset[ULX]; // 4 + offsetY = vertexOffset[ULY]; // 5 + worldVertices[offset] = offsetX * a + offsetY * b + bwx; // ur + worldVertices[offset + 1] = offsetX * c + offsetY * d + bwy; + offset += stride; + + offsetX = vertexOffset[URX]; // 6 + offsetY = vertexOffset[URY]; // 7 + worldVertices[offset] = offsetX * a + offsetY * b + bwx; // br + worldVertices[offset + 1] = offsetX * c + offsetY * d + bwy; + //offset += stride; + } + + public override Attachment Copy () { + RegionAttachment copy = new RegionAttachment(this.Name); + copy.RendererObject = RendererObject; + copy.regionOffsetX = regionOffsetX; + copy.regionOffsetY = regionOffsetY; + copy.regionWidth = regionWidth; + copy.regionHeight = regionHeight; + copy.regionOriginalWidth = regionOriginalWidth; + copy.regionOriginalHeight = regionOriginalHeight; + copy.Path = Path; + copy.x = x; + copy.y = y; + copy.scaleX = scaleX; + copy.scaleY = scaleY; + copy.rotation = rotation; + copy.width = width; + copy.height = height; + Array.Copy(uvs, 0, copy.uvs, 0, 8); + Array.Copy(offset, 0, copy.offset, 0, 8); + copy.r = r; + copy.g = g; + copy.b = b; + copy.a = a; + return copy; + } + } +} diff --git a/box1/Assets/Spine/Runtime/spine-csharp/Attachments/RegionAttachment.cs.meta b/box1/Assets/Spine/Runtime/spine-csharp/Attachments/RegionAttachment.cs.meta new file mode 100644 index 00000000..0477ce40 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-csharp/Attachments/RegionAttachment.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 89cefdd024734a941952a05d2b5dff71 +timeCreated: 1466772712 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-csharp/Attachments/VertexAttachment.cs b/box1/Assets/Spine/Runtime/spine-csharp/Attachments/VertexAttachment.cs new file mode 100644 index 00000000..2c534def --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-csharp/Attachments/VertexAttachment.cs @@ -0,0 +1,156 @@ +/****************************************************************************** + * 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; + +namespace Spine { + /// >An attachment with vertices that are transformed by one or more bones and can be deformed by a slot's + /// . + public abstract class VertexAttachment : Attachment { + static int nextID = 0; + static readonly Object nextIdLock = new Object(); + + internal readonly int id; + internal int[] bones; + internal float[] vertices; + internal int worldVerticesLength; + internal VertexAttachment deformAttachment; + + /// Gets a unique ID for this attachment. + public int Id { get { return id; } } + public int[] Bones { get { return bones; } set { bones = value; } } + public float[] Vertices { get { return vertices; } set { vertices = value; } } + public int WorldVerticesLength { get { return worldVerticesLength; } set { worldVerticesLength = value; } } + ///Deform keys for the deform attachment are also applied to this attachment. + /// May be null if no deform keys should be applied. + public VertexAttachment DeformAttachment { get { return deformAttachment; } set { deformAttachment = value; } } + + public VertexAttachment (string name) + : base(name) { + + deformAttachment = this; + lock (VertexAttachment.nextIdLock) { + id = (VertexAttachment.nextID++ & 65535) << 11; + } + } + + public void ComputeWorldVertices (Slot slot, float[] worldVertices) { + ComputeWorldVertices(slot, 0, worldVerticesLength, worldVertices, 0); + } + + /// + /// Transforms the attachment's local to world coordinates. If the slot's is + /// not empty, it is used to deform the vertices. + /// + /// See World transforms in the Spine + /// Runtimes Guide. + /// + /// The index of the first value to transform. Each vertex has 2 values, x and y. + /// The number of world vertex values to output. Must be less than or equal to - start. + /// The output world vertices. Must have a length greater than or equal to + . + /// The index to begin writing values. + /// The number of entries between the value pairs written. + public void ComputeWorldVertices (Slot slot, int start, int count, float[] worldVertices, int offset, int stride = 2) { + count = offset + (count >> 1) * stride; + Skeleton skeleton = slot.bone.skeleton; + var deformArray = slot.deform; + float[] vertices = this.vertices; + int[] bones = this.bones; + if (bones == null) { + if (deformArray.Count > 0) vertices = deformArray.Items; + Bone bone = slot.bone; + float x = bone.worldX, y = bone.worldY; + float a = bone.a, b = bone.b, c = bone.c, d = bone.d; + for (int vv = start, w = offset; w < count; vv += 2, w += stride) { + float vx = vertices[vv], vy = vertices[vv + 1]; + worldVertices[w] = vx * a + vy * b + x; + worldVertices[w + 1] = vx * c + vy * d + y; + } + return; + } + int v = 0, skip = 0; + for (int i = 0; i < start; i += 2) { + int n = bones[v]; + v += n + 1; + skip += n; + } + var skeletonBones = skeleton.bones.Items; + if (deformArray.Count == 0) { + for (int w = offset, b = skip * 3; w < count; w += stride) { + float wx = 0, wy = 0; + int n = bones[v++]; + n += v; + for (; v < n; v++, b += 3) { + Bone bone = skeletonBones[bones[v]]; + float vx = vertices[b], vy = vertices[b + 1], weight = vertices[b + 2]; + wx += (vx * bone.a + vy * bone.b + bone.worldX) * weight; + wy += (vx * bone.c + vy * bone.d + bone.worldY) * weight; + } + worldVertices[w] = wx; + worldVertices[w + 1] = wy; + } + } else { + float[] deform = deformArray.Items; + for (int w = offset, b = skip * 3, f = skip << 1; w < count; w += stride) { + float wx = 0, wy = 0; + int n = bones[v++]; + n += v; + for (; v < n; v++, b += 3, f += 2) { + Bone bone = skeletonBones[bones[v]]; + float vx = vertices[b] + deform[f], vy = vertices[b + 1] + deform[f + 1], weight = vertices[b + 2]; + wx += (vx * bone.a + vy * bone.b + bone.worldX) * weight; + wy += (vx * bone.c + vy * bone.d + bone.worldY) * weight; + } + worldVertices[w] = wx; + worldVertices[w + 1] = wy; + } + } + } + + ///Does not copy id (generated) or name (set on construction). + internal void CopyTo (VertexAttachment attachment) { + if (bones != null) { + attachment.bones = new int[bones.Length]; + Array.Copy(bones, 0, attachment.bones, 0, bones.Length); + } + else + attachment.bones = null; + + if (vertices != null) { + attachment.vertices = new float[vertices.Length]; + Array.Copy(vertices, 0, attachment.vertices, 0, vertices.Length); + } + else + attachment.vertices = null; + + attachment.worldVerticesLength = worldVerticesLength; + attachment.deformAttachment = deformAttachment; + } + } +} diff --git a/box1/Assets/Spine/Runtime/spine-csharp/Attachments/VertexAttachment.cs.meta b/box1/Assets/Spine/Runtime/spine-csharp/Attachments/VertexAttachment.cs.meta new file mode 100644 index 00000000..8481a70f --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-csharp/Attachments/VertexAttachment.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 8b40cfb462a8b774891e1604e5360d32 +timeCreated: 1466772712 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-csharp/BlendMode.cs b/box1/Assets/Spine/Runtime/spine-csharp/BlendMode.cs new file mode 100644 index 00000000..03754033 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-csharp/BlendMode.cs @@ -0,0 +1,34 @@ +/****************************************************************************** + * 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. + *****************************************************************************/ + +namespace Spine { + public enum BlendMode { + Normal, Additive, Multiply, Screen + } +} diff --git a/box1/Assets/Spine/Runtime/spine-csharp/BlendMode.cs.meta b/box1/Assets/Spine/Runtime/spine-csharp/BlendMode.cs.meta new file mode 100644 index 00000000..c60eb236 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-csharp/BlendMode.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: b08ef68b8e39f40498ef24ef12cca281 +timeCreated: 1456265155 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-csharp/Bone.cs b/box1/Assets/Spine/Runtime/spine-csharp/Bone.cs new file mode 100644 index 00000000..5031e24c --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-csharp/Bone.cs @@ -0,0 +1,366 @@ +/****************************************************************************** + * 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; + +namespace Spine { + /// + /// Stores a bone's current pose. + /// + /// A bone has a local transform which is used to compute its world transform. A bone also has an applied transform, which is a + /// local transform that can be applied to compute the world transform. The local transform and applied transform may differ if a + /// constraint or application code modifies the world transform after it was computed from the local transform. + /// + /// + public class Bone : IUpdatable { + static public bool yDown; + + internal BoneData data; + internal Skeleton skeleton; + internal Bone parent; + internal ExposedList children = new ExposedList(); + internal float x, y, rotation, scaleX, scaleY, shearX, shearY; + internal float ax, ay, arotation, ascaleX, ascaleY, ashearX, ashearY; + internal bool appliedValid; + + internal float a, b, worldX; + internal float c, d, worldY; + + internal bool sorted, active; + + public BoneData Data { get { return data; } } + public Skeleton Skeleton { get { return skeleton; } } + public Bone Parent { get { return parent; } } + public ExposedList Children { get { return children; } } + /// Returns false when the bone has not been computed because is true and the + /// active skin does not contain this bone. + public bool Active { get { return active; } } + /// The local X translation. + public float X { get { return x; } set { x = value; } } + /// The local Y translation. + public float Y { get { return y; } set { y = value; } } + /// The local rotation. + public float Rotation { get { return rotation; } set { rotation = value; } } + + /// The local scaleX. + public float ScaleX { get { return scaleX; } set { scaleX = value; } } + + /// The local scaleY. + public float ScaleY { get { return scaleY; } set { scaleY = value; } } + + /// The local shearX. + public float ShearX { get { return shearX; } set { shearX = value; } } + + /// The local shearY. + public float ShearY { get { return shearY; } set { shearY = value; } } + + /// The rotation, as calculated by any constraints. + public float AppliedRotation { get { return arotation; } set { arotation = value; } } + + /// The applied local x translation. + public float AX { get { return ax; } set { ax = value; } } + + /// The applied local y translation. + public float AY { get { return ay; } set { ay = value; } } + + /// The applied local scaleX. + public float AScaleX { get { return ascaleX; } set { ascaleX = value; } } + + /// The applied local scaleY. + public float AScaleY { get { return ascaleY; } set { ascaleY = value; } } + + /// The applied local shearX. + public float AShearX { get { return ashearX; } set { ashearX = value; } } + + /// The applied local shearY. + public float AShearY { get { return ashearY; } set { ashearY = value; } } + + public float A { get { return a; } } + public float B { get { return b; } } + public float C { get { return c; } } + public float D { get { return d; } } + + public float WorldX { get { return worldX; } } + public float WorldY { get { return worldY; } } + public float WorldRotationX { get { return MathUtils.Atan2(c, a) * MathUtils.RadDeg; } } + public float WorldRotationY { get { return MathUtils.Atan2(d, b) * MathUtils.RadDeg; } } + + /// Returns the magnitide (always positive) of the world scale X. + public float WorldScaleX { get { return (float)Math.Sqrt(a * a + c * c); } } + /// Returns the magnitide (always positive) of the world scale Y. + public float WorldScaleY { get { return (float)Math.Sqrt(b * b + d * d); } } + + /// May be null. + public Bone (BoneData data, Skeleton skeleton, Bone parent) { + if (data == null) throw new ArgumentNullException("data", "data cannot be null."); + if (skeleton == null) throw new ArgumentNullException("skeleton", "skeleton cannot be null."); + this.data = data; + this.skeleton = skeleton; + this.parent = parent; + SetToSetupPose(); + } + + /// Same as . This method exists for Bone to implement . + public void Update () { + UpdateWorldTransform(x, y, rotation, scaleX, scaleY, shearX, shearY); + } + + /// Computes the world transform using the parent bone and this bone's local transform. + public void UpdateWorldTransform () { + UpdateWorldTransform(x, y, rotation, scaleX, scaleY, shearX, shearY); + } + + /// Computes the world transform using the parent bone and the specified local transform. + public void UpdateWorldTransform (float x, float y, float rotation, float scaleX, float scaleY, float shearX, float shearY) { + ax = x; + ay = y; + arotation = rotation; + ascaleX = scaleX; + ascaleY = scaleY; + ashearX = shearX; + ashearY = shearY; + appliedValid = true; + Skeleton skeleton = this.skeleton; + + Bone parent = this.parent; + if (parent == null) { // Root bone. + float rotationY = rotation + 90 + shearY, sx = skeleton.ScaleX, sy = skeleton.ScaleY; + a = MathUtils.CosDeg(rotation + shearX) * scaleX * sx; + b = MathUtils.CosDeg(rotationY) * scaleY * sx; + c = MathUtils.SinDeg(rotation + shearX) * scaleX * sy; + d = MathUtils.SinDeg(rotationY) * scaleY * sy; + worldX = x * sx + skeleton.x; + worldY = y * sy + skeleton.y; + return; + } + + float pa = parent.a, pb = parent.b, pc = parent.c, pd = parent.d; + worldX = pa * x + pb * y + parent.worldX; + worldY = pc * x + pd * y + parent.worldY; + + switch (data.transformMode) { + case TransformMode.Normal: { + float rotationY = rotation + 90 + shearY; + float la = MathUtils.CosDeg(rotation + shearX) * scaleX; + float lb = MathUtils.CosDeg(rotationY) * scaleY; + float lc = MathUtils.SinDeg(rotation + shearX) * scaleX; + float ld = MathUtils.SinDeg(rotationY) * scaleY; + a = pa * la + pb * lc; + b = pa * lb + pb * ld; + c = pc * la + pd * lc; + d = pc * lb + pd * ld; + return; + } + case TransformMode.OnlyTranslation: { + float rotationY = rotation + 90 + shearY; + a = MathUtils.CosDeg(rotation + shearX) * scaleX; + b = MathUtils.CosDeg(rotationY) * scaleY; + c = MathUtils.SinDeg(rotation + shearX) * scaleX; + d = MathUtils.SinDeg(rotationY) * scaleY; + break; + } + case TransformMode.NoRotationOrReflection: { + float s = pa * pa + pc * pc, prx; + if (s > 0.0001f) { + s = Math.Abs(pa * pd - pb * pc) / s; + pa /= skeleton.ScaleX; + pc /= skeleton.ScaleY; + pb = pc * s; + pd = pa * s; + prx = MathUtils.Atan2(pc, pa) * MathUtils.RadDeg; + } else { + pa = 0; + pc = 0; + prx = 90 - MathUtils.Atan2(pd, pb) * MathUtils.RadDeg; + } + float rx = rotation + shearX - prx; + float ry = rotation + shearY - prx + 90; + float la = MathUtils.CosDeg(rx) * scaleX; + float lb = MathUtils.CosDeg(ry) * scaleY; + float lc = MathUtils.SinDeg(rx) * scaleX; + float ld = MathUtils.SinDeg(ry) * scaleY; + a = pa * la - pb * lc; + b = pa * lb - pb * ld; + c = pc * la + pd * lc; + d = pc * lb + pd * ld; + break; + } + case TransformMode.NoScale: + case TransformMode.NoScaleOrReflection: { + float cos = MathUtils.CosDeg(rotation), sin = MathUtils.SinDeg(rotation); + float za = (pa * cos + pb * sin) / skeleton.ScaleX; + float zc = (pc * cos + pd * sin) / skeleton.ScaleY; + float s = (float)Math.Sqrt(za * za + zc * zc); + if (s > 0.00001f) s = 1 / s; + za *= s; + zc *= s; + s = (float)Math.Sqrt(za * za + zc * zc); + if (data.transformMode == TransformMode.NoScale + && (pa * pd - pb * pc < 0) != (skeleton.ScaleX < 0 != skeleton.ScaleY < 0)) s = -s; + + float r = MathUtils.PI / 2 + MathUtils.Atan2(zc, za); + float zb = MathUtils.Cos(r) * s; + float zd = MathUtils.Sin(r) * s; + float la = MathUtils.CosDeg(shearX) * scaleX; + float lb = MathUtils.CosDeg(90 + shearY) * scaleY; + float lc = MathUtils.SinDeg(shearX) * scaleX; + float ld = MathUtils.SinDeg(90 + shearY) * scaleY; + a = za * la + zb * lc; + b = za * lb + zb * ld; + c = zc * la + zd * lc; + d = zc * lb + zd * ld; + break; + } + } + + a *= skeleton.ScaleX; + b *= skeleton.ScaleX; + c *= skeleton.ScaleY; + d *= skeleton.ScaleY; + } + + public void SetToSetupPose () { + BoneData data = this.data; + x = data.x; + y = data.y; + rotation = data.rotation; + scaleX = data.scaleX; + scaleY = data.scaleY; + shearX = data.shearX; + shearY = data.shearY; + } + + /// + /// Computes the individual applied transform values from the world transform. This can be useful to perform processing using + /// the applied transform after the world transform has been modified directly (eg, by a constraint).. + /// + /// Some information is ambiguous in the world transform, such as -1,-1 scale versus 180 rotation. + /// + internal void UpdateAppliedTransform () { + appliedValid = true; + Bone parent = this.parent; + if (parent == null) { + ax = worldX; + ay = worldY; + arotation = MathUtils.Atan2(c, a) * MathUtils.RadDeg; + ascaleX = (float)Math.Sqrt(a * a + c * c); + ascaleY = (float)Math.Sqrt(b * b + d * d); + ashearX = 0; + ashearY = MathUtils.Atan2(a * b + c * d, a * d - b * c) * MathUtils.RadDeg; + return; + } + float pa = parent.a, pb = parent.b, pc = parent.c, pd = parent.d; + float pid = 1 / (pa * pd - pb * pc); + float dx = worldX - parent.worldX, dy = worldY - parent.worldY; + ax = (dx * pd * pid - dy * pb * pid); + ay = (dy * pa * pid - dx * pc * pid); + float ia = pid * pd; + float id = pid * pa; + float ib = pid * pb; + float ic = pid * pc; + float ra = ia * a - ib * c; + float rb = ia * b - ib * d; + float rc = id * c - ic * a; + float rd = id * d - ic * b; + ashearX = 0; + ascaleX = (float)Math.Sqrt(ra * ra + rc * rc); + if (ascaleX > 0.0001f) { + float det = ra * rd - rb * rc; + ascaleY = det / ascaleX; + ashearY = MathUtils.Atan2(ra * rb + rc * rd, det) * MathUtils.RadDeg; + arotation = MathUtils.Atan2(rc, ra) * MathUtils.RadDeg; + } else { + ascaleX = 0; + ascaleY = (float)Math.Sqrt(rb * rb + rd * rd); + ashearY = 0; + arotation = 90 - MathUtils.Atan2(rd, rb) * MathUtils.RadDeg; + } + } + + public void WorldToLocal (float worldX, float worldY, out float localX, out float localY) { + float a = this.a, b = this.b, c = this.c, d = this.d; + float invDet = 1 / (a * d - b * c); + float x = worldX - this.worldX, y = worldY - this.worldY; + localX = (x * d * invDet - y * b * invDet); + localY = (y * a * invDet - x * c * invDet); + } + + public void LocalToWorld (float localX, float localY, out float worldX, out float worldY) { + worldX = localX * a + localY * b + this.worldX; + worldY = localX * c + localY * d + this.worldY; + } + + public float WorldToLocalRotationX { + get { + Bone parent = this.parent; + if (parent == null) return arotation; + float pa = parent.a, pb = parent.b, pc = parent.c, pd = parent.d, a = this.a, c = this.c; + return MathUtils.Atan2(pa * c - pc * a, pd * a - pb * c) * MathUtils.RadDeg; + } + } + + public float WorldToLocalRotationY { + get { + Bone parent = this.parent; + if (parent == null) return arotation; + float pa = parent.a, pb = parent.b, pc = parent.c, pd = parent.d, b = this.b, d = this.d; + return MathUtils.Atan2(pa * d - pc * b, pd * b - pb * d) * MathUtils.RadDeg; + } + } + + public float WorldToLocalRotation (float worldRotation) { + float sin = MathUtils.SinDeg(worldRotation), cos = MathUtils.CosDeg(worldRotation); + return MathUtils.Atan2(a * sin - c * cos, d * cos - b * sin) * MathUtils.RadDeg + rotation - shearX; + } + + public float LocalToWorldRotation (float localRotation) { + localRotation -= rotation - shearX; + float sin = MathUtils.SinDeg(localRotation), cos = MathUtils.CosDeg(localRotation); + return MathUtils.Atan2(cos * c + sin * d, cos * a + sin * b) * MathUtils.RadDeg; + } + + /// + /// Rotates the world transform the specified amount and sets isAppliedValid to false. + /// + /// Degrees. + public void RotateWorld (float degrees) { + float a = this.a, b = this.b, c = this.c, d = this.d; + float cos = MathUtils.CosDeg(degrees), sin = MathUtils.SinDeg(degrees); + this.a = cos * a - sin * c; + this.b = cos * b - sin * d; + this.c = sin * a + cos * c; + this.d = sin * b + cos * d; + appliedValid = false; + } + + override public string ToString () { + return data.name; + } + } +} diff --git a/box1/Assets/Spine/Runtime/spine-csharp/Bone.cs.meta b/box1/Assets/Spine/Runtime/spine-csharp/Bone.cs.meta new file mode 100644 index 00000000..687d6b98 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-csharp/Bone.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: ed00e3a4b386a964fb0f1c7ffd5544e5 +timeCreated: 1456265155 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-csharp/BoneData.cs b/box1/Assets/Spine/Runtime/spine-csharp/BoneData.cs new file mode 100644 index 00000000..4cb4664c --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-csharp/BoneData.cs @@ -0,0 +1,105 @@ +/****************************************************************************** + * 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; + +namespace Spine { + public class BoneData { + internal int index; + internal string name; + internal BoneData parent; + internal float length; + internal float x, y, rotation, scaleX = 1, scaleY = 1, shearX, shearY; + internal TransformMode transformMode = TransformMode.Normal; + internal bool skinRequired; + + /// The index of the bone in Skeleton.Bones + public int Index { get { return index; } } + + /// The name of the bone, which is unique across all bones in the skeleton. + public string Name { get { return name; } } + + /// May be null. + public BoneData Parent { get { return parent; } } + + public float Length { get { return length; } set { length = value; } } + + /// Local X translation. + public float X { get { return x; } set { x = value; } } + + /// Local Y translation. + public float Y { get { return y; } set { y = value; } } + + /// Local rotation. + public float Rotation { get { return rotation; } set { rotation = value; } } + + /// Local scaleX. + public float ScaleX { get { return scaleX; } set { scaleX = value; } } + + /// Local scaleY. + public float ScaleY { get { return scaleY; } set { scaleY = value; } } + + /// Local shearX. + public float ShearX { get { return shearX; } set { shearX = value; } } + + /// Local shearY. + public float ShearY { get { return shearY; } set { shearY = value; } } + + /// The transform mode for how parent world transforms affect this bone. + public TransformMode TransformMode { get { return transformMode; } set { transformMode = value; } } + + ///When true, only updates this bone if the contains this + /// bone. + /// + public bool SkinRequired { get { return skinRequired; } set { skinRequired = value; } } + + /// May be null. + public BoneData (int index, string name, BoneData parent) { + if (index < 0) throw new ArgumentException("index must be >= 0", "index"); + if (name == null) throw new ArgumentNullException("name", "name cannot be null."); + this.index = index; + this.name = name; + this.parent = parent; + } + + override public string ToString () { + return name; + } + } + + [Flags] + public enum TransformMode { + //0000 0 Flip Scale Rotation + Normal = 0, // 0000 + OnlyTranslation = 7, // 0111 + NoRotationOrReflection = 1, // 0001 + NoScale = 2, // 0010 + NoScaleOrReflection = 6, // 0110 + } +} diff --git a/box1/Assets/Spine/Runtime/spine-csharp/BoneData.cs.meta b/box1/Assets/Spine/Runtime/spine-csharp/BoneData.cs.meta new file mode 100644 index 00000000..006e3ecc --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-csharp/BoneData.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 2cf831005966832449a5de742752e578 +timeCreated: 1456265153 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-csharp/Collections.meta b/box1/Assets/Spine/Runtime/spine-csharp/Collections.meta new file mode 100644 index 00000000..86d3d73a --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-csharp/Collections.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: b41ddd57048a62b41951dbbfd453ab98 +folderAsset: yes +timeCreated: 1565181882 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-csharp/Collections/OrderedDictionary.cs b/box1/Assets/Spine/Runtime/spine-csharp/Collections/OrderedDictionary.cs new file mode 100644 index 00000000..6af4cc4a --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-csharp/Collections/OrderedDictionary.cs @@ -0,0 +1,633 @@ +/****************************************************************************** + * 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. + *****************************************************************************/ + +/****************************************************************************** + * Thanks to Travis Parks + * https://github.com/jehugaleahsa/truncon.collections.OrderedDictionary + *****************************************************************************/ + +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.Diagnostics; +using System.Linq; + +namespace Spine.Collections +{ + /// + /// Represents a dictionary that tracks the order that items were added. + /// + /// The type of the dictionary keys. + /// The type of the dictionary values. + /// + /// This dictionary makes it possible to get the index of a key and a key based on an index. + /// It can be costly to find the index of a key because it must be searched for linearly. + /// It can be costly to insert a key/value pair because other key's indexes must be adjusted. + /// It can be costly to remove a key/value pair because other keys' indexes must be adjusted. + /// + [DebuggerDisplay("Count = {Count}")] + [DebuggerTypeProxy(typeof(OrderedDictionaryDebugView<,>))] + public sealed class OrderedDictionary : IDictionary, IList> + { + private readonly Dictionary dictionary; + private readonly List keys; + private readonly List values; + private int version; + + private const string CollectionModifiedMessage = "Collection was modified; enumeration operation may not execute."; + private const string EditReadOnlyListMessage = "An attempt was made to edit a read-only list."; + private const string IndexOutOfRangeMessage = "The index is negative or outside the bounds of the collection."; + + /// + /// Initializes a new instance of an OrderedDictionary. + /// + public OrderedDictionary () + : this(0, null) { + } + + /// + /// Initializes a new instance of an OrderedDictionary. + /// + /// The initial capacity of the dictionary. + /// The capacity is less than zero. + public OrderedDictionary (int capacity) + : this(capacity, null) { + } + + /// + /// Initializes a new instance of an OrderedDictionary. + /// + /// The equality comparer to use to compare keys. + public OrderedDictionary (IEqualityComparer comparer) + : this(0, comparer) { + } + + /// + /// Initializes a new instance of an OrderedDictionary. + /// + /// The initial capacity of the dictionary. + /// The equality comparer to use to compare keys. + public OrderedDictionary (int capacity, IEqualityComparer comparer) { + dictionary = new Dictionary(capacity, comparer ?? EqualityComparer.Default); + keys = new List(capacity); + values = new List(capacity); + } + + /// + /// Gets the equality comparer used to compare keys. + /// + public IEqualityComparer Comparer { + get { + return dictionary.Comparer; + } + } + + /// + /// Adds the given key/value pair to the dictionary. + /// + /// The key to add to the dictionary. + /// The value to associated with the key. + /// The given key already exists in the dictionary. + /// The key is null. + public void Add (TKey key, TValue value) { + dictionary.Add(key, values.Count); + keys.Add(key); + values.Add(value); + ++version; + } + + /// + /// Inserts the given key/value pair at the specified index. + /// + /// The index to insert the key/value pair. + /// The key to insert. + /// The value to insert. + /// The given key already exists in the dictionary. + /// The key is null. + /// The index is negative -or- larger than the size of the dictionary. + public void Insert (int index, TKey key, TValue value) { + if (index < 0 || index > values.Count) { + throw new ArgumentOutOfRangeException("index", index, IndexOutOfRangeMessage); + } + dictionary.Add(key, index); + for (int keyIndex = index; keyIndex != keys.Count; ++keyIndex) { + var otherKey = keys[keyIndex]; + dictionary[otherKey] += 1; + } + keys.Insert(index, key); + values.Insert(index, value); + ++version; + } + + /// + /// Determines whether the given key exists in the dictionary. + /// + /// The key to look for. + /// True if the key exists in the dictionary; otherwise, false. + /// The key is null. + public bool ContainsKey (TKey key) { + return dictionary.ContainsKey(key); + } + + /// + /// Gets the key at the given index. + /// + /// The index of the key to get. + /// The key at the given index. + /// The index is negative -or- larger than the number of keys. + public TKey GetKey (int index) { + return keys[index]; + } + + /// + /// Gets the index of the given key. + /// + /// The key to get the index of. + /// The index of the key in the dictionary -or- -1 if the key is not found. + /// The operation runs in O(n). + public int IndexOf (TKey key) { + int index; + if (dictionary.TryGetValue(key, out index)) { + return index; + } + return -1; + } + + /// + /// Gets the keys in the dictionary in the order they were added. + /// + public KeyCollection Keys { + get { + return new KeyCollection(this.dictionary); + } + } + + /// + /// Removes the key/value pair with the given key from the dictionary. + /// + /// The key of the pair to remove. + /// True if the key was found and the pair removed; otherwise, false. + /// The key is null. + public bool Remove (TKey key) { + int index; + if (dictionary.TryGetValue(key, out index)) { + RemoveAt(index); + return true; + } + return false; + } + + /// + /// Removes the key/value pair at the given index. + /// + /// The index of the key/value pair to remove. + /// The index is negative -or- larger than the size of the dictionary. + public void RemoveAt (int index) { + var key = keys[index]; + for (int keyIndex = index + 1; keyIndex < keys.Count; ++keyIndex) { + var otherKey = keys[keyIndex]; + dictionary[otherKey] -= 1; + } + dictionary.Remove(key); + keys.RemoveAt(index); + values.RemoveAt(index); + ++version; + } + + /// + /// Tries to get the value associated with the given key. If the key is not found, + /// default(TValue) value is stored in the value. + /// + /// The key to get the value for. + /// The value used to hold the results. + /// True if the key was found; otherwise, false. + /// The key is null. + public bool TryGetValue (TKey key, out TValue value) { + int index; + if (dictionary.TryGetValue(key, out index)) { + value = values[index]; + return true; + } + value = default(TValue); + return false; + } + + /// + /// Gets the values in the dictionary. + /// + public ValueCollection Values { + get { + return new ValueCollection(values); + } + } + + /// + /// Gets or sets the value at the given index. + /// + /// The index of the value to get. + /// The value at the given index. + /// The index is negative -or- beyond the length of the dictionary. + public TValue this[int index] { + get { + return values[index]; + } + + set { + values[index] = value; + } + } + + /// + /// Gets or sets the value associated with the given key. + /// + /// The key to get the associated value by or to associate with the value. + /// The value associated with the given key. + /// The key is null. + /// The key is not in the dictionary. + public TValue this[TKey key] { + get { + return values[dictionary[key]]; + } + set { + int index; + if (dictionary.TryGetValue(key, out index)) { + keys[index] = key; + values[index] = value; + } + else { + Add(key, value); + } + } + } + + /// + /// Removes all key/value pairs from the dictionary. + /// + public void Clear () { + dictionary.Clear(); + keys.Clear(); + values.Clear(); + ++version; + } + + /// + /// Gets the number of key/value pairs in the dictionary. + /// + public int Count { + get { + return dictionary.Count; + } + } + + /// + /// Gets the key/value pairs in the dictionary in the order they were added. + /// + /// An enumerator over the key/value pairs in the dictionary. + public IEnumerator> GetEnumerator () { + int startVersion = version; + for (int index = 0; index != keys.Count; ++index) { + var key = keys[index]; + var value = values[index]; + yield return new KeyValuePair(key, value); + if (version != startVersion) { + throw new InvalidOperationException(CollectionModifiedMessage); + } + } + } + + int IList>.IndexOf (KeyValuePair item) { + int index; + if (dictionary.TryGetValue(item.Key, out index) && Equals(values[index], item.Value)) { + return index; + } + return -1; + } + + void IList>.Insert (int index, KeyValuePair item) { + Insert(index, item.Key, item.Value); + } + + KeyValuePair IList>.this[int index] { + get { + TKey key = keys[index]; + TValue value = values[index]; + return new KeyValuePair(key, value); + } + set { + TKey key = keys[index]; + if (dictionary.Comparer.Equals(key, value.Key)) { + dictionary[value.Key] = index; + } + else { + dictionary.Add(value.Key, index); // will throw if key already exists + dictionary.Remove(key); + } + keys[index] = value.Key; + values[index] = value.Value; + } + } + + ICollection IDictionary.Keys { + get { + return Keys; + } + } + + ICollection IDictionary.Values { + get { + return Values; + } + } + + void ICollection>.Add (KeyValuePair item) { + Add(item.Key, item.Value); + } + + bool ICollection>.Contains (KeyValuePair item) { + int index; + if (dictionary.TryGetValue(item.Key, out index) && Equals(values[index], item.Value)) { + return true; + } + return false; + } + + void ICollection>.CopyTo (KeyValuePair[] array, int arrayIndex) { + if (array == null) { + throw new ArgumentNullException("array"); + } + if (arrayIndex < 0) { + throw new ArgumentOutOfRangeException("arrayIndex", arrayIndex, IndexOutOfRangeMessage); + } + for (int index = 0; index != keys.Count && arrayIndex < array.Length; ++index, ++arrayIndex) { + var key = keys[index]; + var value = values[index]; + array[arrayIndex] = new KeyValuePair(key, value); + } + } + + bool ICollection>.IsReadOnly { + get { + return false; + } + } + + bool ICollection>.Remove (KeyValuePair item) { + ICollection> self = this; + if (self.Contains(item)) { + return Remove(item.Key); + } + return false; + } + + IEnumerator IEnumerable.GetEnumerator () { + return GetEnumerator(); + } + + /// + /// Wraps the keys in an OrderDictionary. + /// + public sealed class KeyCollection : ICollection + { + private readonly Dictionary dictionary; + + /// + /// Initializes a new instance of a KeyCollection. + /// + /// The OrderedDictionary whose keys to wrap. + /// The dictionary is null. + internal KeyCollection (Dictionary dictionary) { + this.dictionary = dictionary; + } + + /// + /// Copies the keys from the OrderedDictionary to the given array, starting at the given index. + /// + /// The array to copy the keys to. + /// The index into the array to start copying the keys. + /// The array is null. + /// The arrayIndex is negative. + /// The array, starting at the given index, is not large enough to contain all the keys. + public void CopyTo (TKey[] array, int arrayIndex) { + dictionary.Keys.CopyTo(array, arrayIndex); + } + + /// + /// Gets the number of keys in the OrderedDictionary. + /// + public int Count { + get { + return dictionary.Count; + } + } + + /// + /// Gets an enumerator over the keys in the OrderedDictionary. + /// + /// The enumerator. + public IEnumerator GetEnumerator () { + return dictionary.Keys.GetEnumerator(); + } + + [EditorBrowsable(EditorBrowsableState.Never)] + bool ICollection.Contains (TKey item) { + return dictionary.ContainsKey(item); + } + + [EditorBrowsable(EditorBrowsableState.Never)] + void ICollection.Add (TKey item) { + throw new NotSupportedException(EditReadOnlyListMessage); + } + + [EditorBrowsable(EditorBrowsableState.Never)] + void ICollection.Clear () { + throw new NotSupportedException(EditReadOnlyListMessage); + } + + [EditorBrowsable(EditorBrowsableState.Never)] + bool ICollection.IsReadOnly { + get { + return true; + } + } + + [EditorBrowsable(EditorBrowsableState.Never)] + bool ICollection.Remove (TKey item) { + throw new NotSupportedException(EditReadOnlyListMessage); + } + + IEnumerator IEnumerable.GetEnumerator () { + return GetEnumerator(); + } + } + + /// + /// Wraps the keys in an OrderDictionary. + /// + public sealed class ValueCollection : ICollection + { + private readonly List values; + + /// + /// Initializes a new instance of a ValueCollection. + /// + /// The OrderedDictionary whose keys to wrap. + /// The dictionary is null. + internal ValueCollection (List values) { + this.values = values; + } + + /// + /// Copies the values from the OrderedDictionary to the given array, starting at the given index. + /// + /// The array to copy the values to. + /// The index into the array to start copying the values. + /// The array is null. + /// The arrayIndex is negative. + /// The array, starting at the given index, is not large enough to contain all the values. + public void CopyTo (TValue[] array, int arrayIndex) { + values.CopyTo(array, arrayIndex); + } + + /// + /// Gets the number of values in the OrderedDictionary. + /// + public int Count { + get { + return values.Count; + } + } + + /// + /// Gets an enumerator over the values in the OrderedDictionary. + /// + /// The enumerator. + public IEnumerator GetEnumerator () { + return values.GetEnumerator(); + } + + [EditorBrowsable(EditorBrowsableState.Never)] + bool ICollection.Contains (TValue item) { + return values.Contains(item); + } + + [EditorBrowsable(EditorBrowsableState.Never)] + void ICollection.Add (TValue item) { + throw new NotSupportedException(EditReadOnlyListMessage); + } + + [EditorBrowsable(EditorBrowsableState.Never)] + void ICollection.Clear () { + throw new NotSupportedException(EditReadOnlyListMessage); + } + + [EditorBrowsable(EditorBrowsableState.Never)] + bool ICollection.IsReadOnly { + get { + return true; + } + } + + [EditorBrowsable(EditorBrowsableState.Never)] + bool ICollection.Remove (TValue item) { + throw new NotSupportedException(EditReadOnlyListMessage); + } + + IEnumerator IEnumerable.GetEnumerator () { + return GetEnumerator(); + } + } + } + + internal class OrderedDictionaryDebugView + { + private readonly OrderedDictionary dictionary; + + public OrderedDictionaryDebugView (OrderedDictionary dictionary) { + this.dictionary = dictionary; + } + + [DebuggerBrowsable(DebuggerBrowsableState.RootHidden)] + public KeyValuePair[] Items { + get { + return dictionary.ToArray(); + } + } + } + + /// + /// Provides extensions methods for constructing instances of . + /// + public static class CollectionExtensions + { + #region ToOrderedDictionary + + /// + /// Creates a new OrderedDictionary from the given collection, using the key selector to extract the key. + /// + /// The type of the items in the collection. + /// The type of the key. + /// The items to created the OrderedDictionary from. + /// A delegate that can extract a key from an item in the collection. + /// An OrderedDictionary mapping the extracted keys to their values. + public static OrderedDictionary ToOrderedDictionary (this IEnumerable source, Func keySelector) { + return ToOrderedDictionary(source, keySelector, null); + } + + /// + /// Creates a new OrderedDictionary from the given collection, using the key selector to extract the key. + /// The key comparer is passed to the OrderedDictionary for comparing the extracted keys. + /// + /// The type of the items in the collection. + /// The type of the key. + /// The items to created the OrderedDictionary from. + /// A delegate that can extract a key from an item in the collection. + /// The key equality comparer to use to compare keys in the dictionary. + /// An OrderedDictionary mapping the extracted keys to their values. + public static OrderedDictionary ToOrderedDictionary ( + this IEnumerable source, + Func keySelector, + IEqualityComparer comparer) { + if (source == null) { + throw new ArgumentNullException("source"); + } + if (keySelector == null) { + throw new ArgumentNullException("keySelector"); + } + var dictionary = new OrderedDictionary(comparer); + foreach (TSource item in source) { + TKey key = keySelector(item); + dictionary.Add(key, item); + } + return dictionary; + } + + #endregion + } +} diff --git a/box1/Assets/Spine/Runtime/spine-csharp/Collections/OrderedDictionary.cs.meta b/box1/Assets/Spine/Runtime/spine-csharp/Collections/OrderedDictionary.cs.meta new file mode 100644 index 00000000..c292f6c3 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-csharp/Collections/OrderedDictionary.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: ca4b738078ed756469d5d97bcca93e6f +timeCreated: 1599849714 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-csharp/ConstraintData.cs b/box1/Assets/Spine/Runtime/spine-csharp/ConstraintData.cs new file mode 100644 index 00000000..d4f95032 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-csharp/ConstraintData.cs @@ -0,0 +1,62 @@ +/****************************************************************************** + * 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; + +namespace Spine +{ + /// The base class for all constraint datas. + public abstract class ConstraintData { + internal readonly string name; + internal int order; + internal bool skinRequired; + + public ConstraintData (string name) { + if (name == null) throw new ArgumentNullException("name", "name cannot be null."); + this.name = name; + } + + /// The constraint's name, which is unique across all constraints in the skeleton of the same type. + public string Name { get { return name; } } + + ///The ordinal of this constraint for the order a skeleton's constraints will be applied by + /// . + public int Order { get { return order; } set { order = value; } } + + ///When true, only updates this constraint if the contains + /// this constraint. + /// + public bool SkinRequired { get { return skinRequired; } set { skinRequired = value; } } + + override public string ToString () { + return name; + } + } +} diff --git a/box1/Assets/Spine/Runtime/spine-csharp/ConstraintData.cs.meta b/box1/Assets/Spine/Runtime/spine-csharp/ConstraintData.cs.meta new file mode 100644 index 00000000..9b181328 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-csharp/ConstraintData.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 55d3827079aca3a4687535c3ede7ec5f +timeCreated: 1599849714 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-csharp/Event.cs b/box1/Assets/Spine/Runtime/spine-csharp/Event.cs new file mode 100644 index 00000000..72c3b70d --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-csharp/Event.cs @@ -0,0 +1,64 @@ +/****************************************************************************** + * 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; + +namespace Spine { + /// Stores the current pose values for an Event. + public class Event { + internal readonly EventData data; + internal readonly float time; + internal int intValue; + internal float floatValue; + internal string stringValue; + internal float volume; + internal float balance; + + public EventData Data { get { return data; } } + /// The animation time this event was keyed. + public float Time { get { return time; } } + + public int Int { get { return intValue; } set { intValue = value; } } + public float Float { get { return floatValue; } set { floatValue = value; } } + public string String { get { return stringValue; } set { stringValue = value; } } + + public float Volume { get { return volume; } set { volume = value; } } + public float Balance { get { return balance; } set { balance = value; } } + + public Event (float time, EventData data) { + if (data == null) throw new ArgumentNullException("data", "data cannot be null."); + this.time = time; + this.data = data; + } + + override public string ToString () { + return this.data.Name; + } + } +} diff --git a/box1/Assets/Spine/Runtime/spine-csharp/Event.cs.meta b/box1/Assets/Spine/Runtime/spine-csharp/Event.cs.meta new file mode 100644 index 00000000..dbdbc598 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-csharp/Event.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: dec0d9d780605944eb4514125ab6350b +timeCreated: 1456265155 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-csharp/EventData.cs b/box1/Assets/Spine/Runtime/spine-csharp/EventData.cs new file mode 100644 index 00000000..39094f41 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-csharp/EventData.cs @@ -0,0 +1,56 @@ +/****************************************************************************** + * 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; + +namespace Spine { + /// Stores the setup pose values for an Event. + public class EventData { + internal string name; + + /// The name of the event, which is unique across all events in the skeleton. + public string Name { get { return name; } } + public int Int { get; set; } + public float Float { get; set; } + public string @String { get; set; } + + public string AudioPath { get; set; } + public float Volume { get; set; } + public float Balance { get; set; } + + public EventData (string name) { + if (name == null) throw new ArgumentNullException("name", "name cannot be null."); + this.name = name; + } + + override public string ToString () { + return Name; + } + } +} diff --git a/box1/Assets/Spine/Runtime/spine-csharp/EventData.cs.meta b/box1/Assets/Spine/Runtime/spine-csharp/EventData.cs.meta new file mode 100644 index 00000000..941b359e --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-csharp/EventData.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 37bbfb9fb268a644ba75052961a42b81 +timeCreated: 1456265153 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-csharp/ExposedList.cs b/box1/Assets/Spine/Runtime/spine-csharp/ExposedList.cs new file mode 100644 index 00000000..7d0b6971 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-csharp/ExposedList.cs @@ -0,0 +1,641 @@ +// +// System.Collections.Generic.List +// +// Authors: +// Ben Maurer (bmaurer@ximian.com) +// Martin Baulig (martin@ximian.com) +// Carlos Alberto Cortez (calberto.cortez@gmail.com) +// David Waite (mass@akuma.org) +// +// Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com) +// Copyright (C) 2005 David Waite +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Diagnostics; + +namespace Spine { + [DebuggerDisplay("Count={Count}")] + public class ExposedList : IEnumerable { + public T[] Items; + public int Count; + private const int DefaultCapacity = 4; + private static readonly T[] EmptyArray = new T[0]; + private int version; + + public ExposedList () { + Items = EmptyArray; + } + + public ExposedList (IEnumerable collection) { + CheckCollection(collection); + + // initialize to needed size (if determinable) + ICollection c = collection as ICollection; + if (c == null) { + Items = EmptyArray; + AddEnumerable(collection); + } else { + Items = new T[c.Count]; + AddCollection(c); + } + } + + public ExposedList (int capacity) { + if (capacity < 0) + throw new ArgumentOutOfRangeException("capacity"); + Items = new T[capacity]; + } + + internal ExposedList (T[] data, int size) { + Items = data; + Count = size; + } + + public void Add (T item) { + // If we check to see if we need to grow before trying to grow + // we can speed things up by 25% + if (Count == Items.Length) + GrowIfNeeded(1); + Items[Count++] = item; + version++; + } + + public void GrowIfNeeded (int addedCount) { + int minimumSize = Count + addedCount; + if (minimumSize > Items.Length) + Capacity = Math.Max(Math.Max(Capacity * 2, DefaultCapacity), minimumSize); + } + + public ExposedList Resize (int newSize) { + int itemsLength = Items.Length; + var oldItems = Items; + if (newSize > itemsLength) { + Array.Resize(ref Items, newSize); +// var newItems = new T[newSize]; +// Array.Copy(oldItems, newItems, Count); +// Items = newItems; + } else if (newSize < itemsLength) { + // Allow nulling of T reference type to allow GC. + for (int i = newSize; i < itemsLength; i++) + oldItems[i] = default(T); + } + Count = newSize; + return this; + } + + public void EnsureCapacity (int min) { + if (Items.Length < min) { + int newCapacity = Items.Length == 0 ? DefaultCapacity : Items.Length * 2; + //if ((uint)newCapacity > Array.MaxArrayLength) newCapacity = Array.MaxArrayLength; + if (newCapacity < min) newCapacity = min; + Capacity = newCapacity; + } + } + + private void CheckRange (int index, int count) { + if (index < 0) + throw new ArgumentOutOfRangeException("index"); + + if (count < 0) + throw new ArgumentOutOfRangeException("count"); + + if ((uint)index + (uint)count > (uint)Count) + throw new ArgumentException("index and count exceed length of list"); + } + + private void AddCollection (ICollection collection) { + int collectionCount = collection.Count; + if (collectionCount == 0) + return; + + GrowIfNeeded(collectionCount); + collection.CopyTo(Items, Count); + Count += collectionCount; + } + + private void AddEnumerable (IEnumerable enumerable) { + foreach (T t in enumerable) { + Add(t); + } + } + + // Additional overload provided because ExposedList only implements IEnumerable, + // leading to sub-optimal behavior: It grows multiple times as it assumes not + // to know the final size ahead of insertion. + public void AddRange (ExposedList list) { + CheckCollection(list); + + int collectionCount = list.Count; + if (collectionCount == 0) + return; + + GrowIfNeeded(collectionCount); + list.CopyTo(Items, Count); + Count += collectionCount; + + version++; + } + + public void AddRange (IEnumerable collection) { + CheckCollection(collection); + + ICollection c = collection as ICollection; + if (c != null) + AddCollection(c); + else + AddEnumerable(collection); + version++; + } + + public int BinarySearch (T item) { + return Array.BinarySearch(Items, 0, Count, item); + } + + public int BinarySearch (T item, IComparer comparer) { + return Array.BinarySearch(Items, 0, Count, item, comparer); + } + + public int BinarySearch (int index, int count, T item, IComparer comparer) { + CheckRange(index, count); + return Array.BinarySearch(Items, index, count, item, comparer); + } + + public void Clear (bool clearArray = true) { + if (clearArray) + Array.Clear(Items, 0, Items.Length); + + Count = 0; + version++; + } + + public bool Contains (T item) { + return Array.IndexOf(Items, item, 0, Count) != -1; + } + + public ExposedList ConvertAll (Converter converter) { + if (converter == null) + throw new ArgumentNullException("converter"); + ExposedList u = new ExposedList(Count); + for (int i = 0; i < Count; i++) + u.Items[i] = converter(Items[i]); + + u.Count = Count; + return u; + } + + public void CopyTo (T[] array) { + Array.Copy(Items, 0, array, 0, Count); + } + + public void CopyTo (T[] array, int arrayIndex) { + Array.Copy(Items, 0, array, arrayIndex, Count); + } + + public void CopyTo (int index, T[] array, int arrayIndex, int count) { + CheckRange(index, count); + Array.Copy(Items, index, array, arrayIndex, count); + } + + + + public bool Exists (Predicate match) { + CheckMatch(match); + return GetIndex(0, Count, match) != -1; + } + + public T Find (Predicate match) { + CheckMatch(match); + int i = GetIndex(0, Count, match); + return (i != -1) ? Items[i] : default(T); + } + + private static void CheckMatch (Predicate match) { + if (match == null) + throw new ArgumentNullException("match"); + } + + public ExposedList FindAll (Predicate match) { + CheckMatch(match); + return FindAllList(match); + } + + private ExposedList FindAllList (Predicate match) { + ExposedList results = new ExposedList(); + for (int i = 0; i < Count; i++) + if (match(Items[i])) + results.Add(Items[i]); + + return results; + } + + public int FindIndex (Predicate match) { + CheckMatch(match); + return GetIndex(0, Count, match); + } + + public int FindIndex (int startIndex, Predicate match) { + CheckMatch(match); + CheckIndex(startIndex); + return GetIndex(startIndex, Count - startIndex, match); + } + + public int FindIndex (int startIndex, int count, Predicate match) { + CheckMatch(match); + CheckRange(startIndex, count); + return GetIndex(startIndex, count, match); + } + + private int GetIndex (int startIndex, int count, Predicate match) { + int end = startIndex + count; + for (int i = startIndex; i < end; i++) + if (match(Items[i])) + return i; + + return -1; + } + + public T FindLast (Predicate match) { + CheckMatch(match); + int i = GetLastIndex(0, Count, match); + return i == -1 ? default(T) : Items[i]; + } + + public int FindLastIndex (Predicate match) { + CheckMatch(match); + return GetLastIndex(0, Count, match); + } + + public int FindLastIndex (int startIndex, Predicate match) { + CheckMatch(match); + CheckIndex(startIndex); + return GetLastIndex(0, startIndex + 1, match); + } + + public int FindLastIndex (int startIndex, int count, Predicate match) { + CheckMatch(match); + int start = startIndex - count + 1; + CheckRange(start, count); + return GetLastIndex(start, count, match); + } + + private int GetLastIndex (int startIndex, int count, Predicate match) { + // unlike FindLastIndex, takes regular params for search range + for (int i = startIndex + count; i != startIndex; ) + if (match(Items[--i])) + return i; + return -1; + } + + public void ForEach (Action action) { + if (action == null) + throw new ArgumentNullException("action"); + for (int i = 0; i < Count; i++) + action(Items[i]); + } + + public Enumerator GetEnumerator () { + return new Enumerator(this); + } + + public ExposedList GetRange (int index, int count) { + CheckRange(index, count); + T[] tmpArray = new T[count]; + Array.Copy(Items, index, tmpArray, 0, count); + return new ExposedList(tmpArray, count); + } + + public int IndexOf (T item) { + return Array.IndexOf(Items, item, 0, Count); + } + + public int IndexOf (T item, int index) { + CheckIndex(index); + return Array.IndexOf(Items, item, index, Count - index); + } + + public int IndexOf (T item, int index, int count) { + if (index < 0) + throw new ArgumentOutOfRangeException("index"); + + if (count < 0) + throw new ArgumentOutOfRangeException("count"); + + if ((uint)index + (uint)count > (uint)Count) + throw new ArgumentOutOfRangeException("index and count exceed length of list"); + + return Array.IndexOf(Items, item, index, count); + } + + private void Shift (int start, int delta) { + if (delta < 0) + start -= delta; + + if (start < Count) + Array.Copy(Items, start, Items, start + delta, Count - start); + + Count += delta; + + if (delta < 0) + Array.Clear(Items, Count, -delta); + } + + private void CheckIndex (int index) { + if (index < 0 || (uint)index > (uint)Count) + throw new ArgumentOutOfRangeException("index"); + } + + public void Insert (int index, T item) { + CheckIndex(index); + if (Count == Items.Length) + GrowIfNeeded(1); + Shift(index, 1); + Items[index] = item; + version++; + } + + private void CheckCollection (IEnumerable collection) { + if (collection == null) + throw new ArgumentNullException("collection"); + } + + public void InsertRange (int index, IEnumerable collection) { + CheckCollection(collection); + CheckIndex(index); + if (collection == this) { + T[] buffer = new T[Count]; + CopyTo(buffer, 0); + GrowIfNeeded(Count); + Shift(index, buffer.Length); + Array.Copy(buffer, 0, Items, index, buffer.Length); + } else { + ICollection c = collection as ICollection; + if (c != null) + InsertCollection(index, c); + else + InsertEnumeration(index, collection); + } + version++; + } + + private void InsertCollection (int index, ICollection collection) { + int collectionCount = collection.Count; + GrowIfNeeded(collectionCount); + + Shift(index, collectionCount); + collection.CopyTo(Items, index); + } + + private void InsertEnumeration (int index, IEnumerable enumerable) { + foreach (T t in enumerable) + Insert(index++, t); + } + + public int LastIndexOf (T item) { + return Array.LastIndexOf(Items, item, Count - 1, Count); + } + + public int LastIndexOf (T item, int index) { + CheckIndex(index); + return Array.LastIndexOf(Items, item, index, index + 1); + } + + public int LastIndexOf (T item, int index, int count) { + if (index < 0) + throw new ArgumentOutOfRangeException("index", index, "index is negative"); + + if (count < 0) + throw new ArgumentOutOfRangeException("count", count, "count is negative"); + + if (index - count + 1 < 0) + throw new ArgumentOutOfRangeException("count", count, "count is too large"); + + return Array.LastIndexOf(Items, item, index, count); + } + + public bool Remove (T item) { + int loc = IndexOf(item); + if (loc != -1) + RemoveAt(loc); + + return loc != -1; + } + + public int RemoveAll (Predicate match) { + CheckMatch(match); + int i = 0; + int j = 0; + + // Find the first item to remove + for (i = 0; i < Count; i++) + if (match(Items[i])) + break; + + if (i == Count) + return 0; + + version++; + + // Remove any additional items + for (j = i + 1; j < Count; j++) { + if (!match(Items[j])) + Items[i++] = Items[j]; + } + if (j - i > 0) + Array.Clear(Items, i, j - i); + + Count = i; + return (j - i); + } + + public void RemoveAt (int index) { + if (index < 0 || (uint)index >= (uint)Count) + throw new ArgumentOutOfRangeException("index"); + Shift(index, -1); + Array.Clear(Items, Count, 1); + version++; + } + + // Spine Added Method + // Based on Stack.Pop(); https://referencesource.microsoft.com/#mscorlib/system/collections/stack.cs + /// Pops the last item of the list. If the list is empty, Pop throws an InvalidOperationException. + public T Pop () { + if (Count == 0) + throw new InvalidOperationException("List is empty. Nothing to pop."); + + int i = Count - 1; + T item = Items[i]; + Items[i] = default(T); + Count--; + version++; + return item; + } + + public void RemoveRange (int index, int count) { + CheckRange(index, count); + if (count > 0) { + Shift(index, -count); + Array.Clear(Items, Count, count); + version++; + } + } + + public void Reverse () { + Array.Reverse(Items, 0, Count); + version++; + } + + public void Reverse (int index, int count) { + CheckRange(index, count); + Array.Reverse(Items, index, count); + version++; + } + + public void Sort () { + Array.Sort(Items, 0, Count, Comparer.Default); + version++; + } + + public void Sort (IComparer comparer) { + Array.Sort(Items, 0, Count, comparer); + version++; + } + + public void Sort (Comparison comparison) { + Array.Sort(Items, comparison); + version++; + } + + public void Sort (int index, int count, IComparer comparer) { + CheckRange(index, count); + Array.Sort(Items, index, count, comparer); + version++; + } + + public T[] ToArray () { + T[] t = new T[Count]; + Array.Copy(Items, t, Count); + + return t; + } + + public void TrimExcess () { + Capacity = Count; + } + + public bool TrueForAll (Predicate match) { + CheckMatch(match); + + for (int i = 0; i < Count; i++) + if (!match(Items[i])) + return false; + + return true; + } + + public int Capacity { + get { + return Items.Length; + } + set { + if ((uint)value < (uint)Count) + throw new ArgumentOutOfRangeException(); + + Array.Resize(ref Items, value); + } + } + + #region Interface implementations. + + IEnumerator IEnumerable.GetEnumerator () { + return GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator () { + return GetEnumerator(); + } + + #endregion + + public struct Enumerator : IEnumerator, IDisposable { + private ExposedList l; + private int next; + private int ver; + private T current; + + internal Enumerator (ExposedList l) + : this() { + this.l = l; + ver = l.version; + } + + public void Dispose () { + l = null; + } + + private void VerifyState () { + if (l == null) + throw new ObjectDisposedException(GetType().FullName); + if (ver != l.version) + throw new InvalidOperationException( + "Collection was modified; enumeration operation may not execute."); + } + + public bool MoveNext () { + VerifyState(); + + if (next < 0) + return false; + + if (next < l.Count) { + current = l.Items[next++]; + return true; + } + + next = -1; + return false; + } + + public T Current { + get { + return current; + } + } + + void IEnumerator.Reset () { + VerifyState(); + next = 0; + } + + object IEnumerator.Current { + get { + VerifyState(); + if (next <= 0) + throw new InvalidOperationException(); + return current; + } + } + } + } +} diff --git a/box1/Assets/Spine/Runtime/spine-csharp/ExposedList.cs.meta b/box1/Assets/Spine/Runtime/spine-csharp/ExposedList.cs.meta new file mode 100644 index 00000000..c51394b4 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-csharp/ExposedList.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 89690af94a880744989712505f2957b1 +timeCreated: 1456265154 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-csharp/IUpdatable.cs b/box1/Assets/Spine/Runtime/spine-csharp/IUpdatable.cs new file mode 100644 index 00000000..aa380adf --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-csharp/IUpdatable.cs @@ -0,0 +1,42 @@ +/****************************************************************************** + * 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. + *****************************************************************************/ + +namespace Spine { + + ///The interface for items updated by . + public interface IUpdatable { + void Update (); + + ///Returns false when this item has not been updated because a skin is required and the active + /// skin does not contain this item. + /// + /// + bool Active { get; } + } +} diff --git a/box1/Assets/Spine/Runtime/spine-csharp/IUpdatable.cs.meta b/box1/Assets/Spine/Runtime/spine-csharp/IUpdatable.cs.meta new file mode 100644 index 00000000..d1c948fa --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-csharp/IUpdatable.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 44a51df5672fe4249b6763960587a017 +timeCreated: 1456265154 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-csharp/IkConstraint.cs b/box1/Assets/Spine/Runtime/spine-csharp/IkConstraint.cs new file mode 100644 index 00000000..1d88c4a6 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-csharp/IkConstraint.cs @@ -0,0 +1,365 @@ +/****************************************************************************** + * 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; + +namespace Spine { + /// + /// + /// Stores the current pose for an IK constraint. An IK constraint adjusts the rotation of 1 or 2 constrained bones so the tip of + /// the last bone is as close to the target bone as possible. + /// + /// See IK constraints in the Spine User Guide. + /// + public class IkConstraint : IUpdatable { + internal IkConstraintData data; + internal ExposedList bones = new ExposedList(); + internal Bone target; + internal int bendDirection; + internal bool compress, stretch; + internal float mix = 1, softness; + + internal bool active; + + public IkConstraint (IkConstraintData data, Skeleton skeleton) { + if (data == null) throw new ArgumentNullException("data", "data cannot be null."); + if (skeleton == null) throw new ArgumentNullException("skeleton", "skeleton cannot be null."); + this.data = data; + mix = data.mix; + softness = data.softness; + bendDirection = data.bendDirection; + compress = data.compress; + stretch = data.stretch; + + bones = new ExposedList(data.bones.Count); + foreach (BoneData boneData in data.bones) + bones.Add(skeleton.FindBone(boneData.name)); + target = skeleton.FindBone(data.target.name); + } + + /// Copy constructor. + public IkConstraint (IkConstraint constraint, Skeleton skeleton) { + if (constraint == null) throw new ArgumentNullException("constraint cannot be null."); + if (skeleton == null) throw new ArgumentNullException("skeleton cannot be null."); + data = constraint.data; + bones = new ExposedList(constraint.Bones.Count); + foreach (Bone bone in constraint.Bones) + bones.Add(skeleton.Bones.Items[bone.data.index]); + target = skeleton.Bones.Items[constraint.target.data.index]; + mix = constraint.mix; + softness = constraint.softness; + bendDirection = constraint.bendDirection; + compress = constraint.compress; + stretch = constraint.stretch; + } + + /// Applies the constraint to the constrained bones. + public void Apply () { + Update(); + } + + public void Update () { + Bone target = this.target; + ExposedList bones = this.bones; + switch (bones.Count) { + case 1: + Apply(bones.Items[0], target.worldX, target.worldY, compress, stretch, data.uniform, mix); + break; + case 2: + Apply(bones.Items[0], bones.Items[1], target.worldX, target.worldY, bendDirection, stretch, softness, mix); + break; + } + } + + /// The bones that will be modified by this IK constraint. + public ExposedList Bones { + get { return bones; } + } + + /// The bone that is the IK target. + public Bone Target { + get { return target; } + set { target = value; } + } + + /// A percentage (0-1) that controls the mix between the constrained and unconstrained rotations. + public float Mix { + get { return mix; } + set { mix = value; } + } + + ///For two bone IK, the distance from the maximum reach of the bones that rotation will slow. + public float Softness { + get { return softness; } + set { softness = value; } + } + + /// Controls the bend direction of the IK bones, either 1 or -1. + public int BendDirection { + get { return bendDirection; } + set { bendDirection = value; } + } + + /// + /// When true and only a single bone is being constrained, if the target is too close, the bone is scaled to reach it. + public bool Compress { + get { return compress; } + set { compress = value; } + } + + /// + /// When true, if the target is out of range, the parent bone is scaled to reach it. If more than one bone is being constrained + /// and the parent bone has local nonuniform scale, stretch is not applied. + public bool Stretch { + get { return stretch; } + set { stretch = value; } + } + + public bool Active { + get { return active; } + } + + /// The IK constraint's setup pose data. + public IkConstraintData Data { + get { return data; } + } + + override public string ToString () { + return data.name; + } + + /// Applies 1 bone IK. The target is specified in the world coordinate system. + static public void Apply (Bone bone, float targetX, float targetY, bool compress, bool stretch, bool uniform, + float alpha) { + if (!bone.appliedValid) bone.UpdateAppliedTransform(); + Bone p = bone.parent; + + float pa = p.a, pb = p.b, pc = p.c, pd = p.d; + float rotationIK = -bone.ashearX - bone.arotation; + float tx = 0, ty = 0; + + switch(bone.data.transformMode) { + case TransformMode.OnlyTranslation: + tx = targetX - bone.worldX; + ty = targetY - bone.worldY; + break; + case TransformMode.NoRotationOrReflection: { + float s = Math.Abs(pa * pd - pb * pc) / (pa * pa + pc * pc); + float sa = pa / bone.skeleton.ScaleX; + float sc = pc / bone.skeleton.ScaleY; + pb = -sc * s * bone.skeleton.ScaleX; + pd = sa * s * bone.skeleton.ScaleY; + rotationIK += (float)Math.Atan2(pc, pa) * MathUtils.RadDeg; + goto default; // Fall through. + } + default: { + float x = targetX - p.worldX, y = targetY - p.worldY; + float d = pa * pd - pb * pc; + tx = (x * pd - y * pb) / d - bone.ax; + ty = (y * pa - x * pc) / d - bone.ay; + break; + } + } + + rotationIK += (float)Math.Atan2(ty, tx) * MathUtils.RadDeg; + if (bone.ascaleX < 0) rotationIK += 180; + if (rotationIK > 180) + rotationIK -= 360; + else if (rotationIK < -180) // + rotationIK += 360; + + float sx = bone.ascaleX, sy = bone.ascaleY; + if (compress || stretch) { + switch (bone.data.transformMode) { + case TransformMode.NoScale: + tx = targetX - bone.worldX; + ty = targetY - bone.worldY; + break; + case TransformMode.NoScaleOrReflection: + tx = targetX - bone.worldX; + ty = targetY - bone.worldY; + break; + } + float b = bone.data.length * sx, dd = (float)Math.Sqrt(tx * tx + ty * ty); + if ((compress && dd < b) || (stretch && dd > b) && b > 0.0001f) { + float s = (dd / b - 1) * alpha + 1; + sx *= s; + if (uniform) sy *= s; + } + } + bone.UpdateWorldTransform(bone.ax, bone.ay, bone.arotation + rotationIK * alpha, sx, sy, bone.ashearX, bone.ashearY); + } + + /// Applies 2 bone IK. The target is specified in the world coordinate system. + /// A direct descendant of the parent bone. + static public void Apply (Bone parent, Bone child, float targetX, float targetY, int bendDir, bool stretch, float softness, + float alpha) { + if (alpha == 0) { + child.UpdateWorldTransform(); + return; + } + if (!parent.appliedValid) parent.UpdateAppliedTransform(); + if (!child.appliedValid) child.UpdateAppliedTransform(); + float px = parent.ax, py = parent.ay, psx = parent.ascaleX, sx = psx, psy = parent.ascaleY, csx = child.ascaleX; + int os1, os2, s2; + if (psx < 0) { + psx = -psx; + os1 = 180; + s2 = -1; + } else { + os1 = 0; + s2 = 1; + } + if (psy < 0) { + psy = -psy; + s2 = -s2; + } + if (csx < 0) { + csx = -csx; + os2 = 180; + } else + os2 = 0; + float cx = child.ax, cy, cwx, cwy, a = parent.a, b = parent.b, c = parent.c, d = parent.d; + bool u = Math.Abs(psx - psy) <= 0.0001f; + if (!u) { + cy = 0; + cwx = a * cx + parent.worldX; + cwy = c * cx + parent.worldY; + } else { + cy = child.ay; + cwx = a * cx + b * cy + parent.worldX; + cwy = c * cx + d * cy + parent.worldY; + } + Bone pp = parent.parent; + a = pp.a; + b = pp.b; + c = pp.c; + d = pp.d; + float id = 1 / (a * d - b * c), x = cwx - pp.worldX, y = cwy - pp.worldY; + float dx = (x * d - y * b) * id - px, dy = (y * a - x * c) * id - py; + float l1 = (float)Math.Sqrt(dx * dx + dy * dy), l2 = child.data.length * csx, a1, a2; + if (l1 < 0.0001f) { + Apply(parent, targetX, targetY, false, stretch, false, alpha); + child.UpdateWorldTransform(cx, cy, 0, child.ascaleX, child.ascaleY, child.ashearX, child.ashearY); + return; + } + x = targetX - pp.worldX; + y = targetY - pp.worldY; + float tx = (x * d - y * b) * id - px, ty = (y * a - x * c) * id - py; + float dd = tx * tx + ty * ty; + if (softness != 0) { + softness *= psx * (csx + 1) / 2; + float td = (float)Math.Sqrt(dd), sd = td - l1 - l2 * psx + softness; + if (sd > 0) { + float p = Math.Min(1, sd / (softness * 2)) - 1; + p = (sd - softness * (1 - p * p)) / td; + tx -= p * tx; + ty -= p * ty; + dd = tx * tx + ty * ty; + } + } + if (u) { + l2 *= psx; + float cos = (dd - l1 * l1 - l2 * l2) / (2 * l1 * l2); + if (cos < -1) + cos = -1; + else if (cos > 1) { + cos = 1; + if (stretch) sx *= ((float)Math.Sqrt(dd) / (l1 + l2) - 1) * alpha + 1; + } + a2 = (float)Math.Acos(cos) * bendDir; + a = l1 + l2 * cos; + b = l2 * (float)Math.Sin(a2); + a1 = (float)Math.Atan2(ty * a - tx * b, tx * a + ty * b); + } else { + a = psx * l2; + b = psy * l2; + float aa = a * a, bb = b * b, ta = (float)Math.Atan2(ty, tx); + c = bb * l1 * l1 + aa * dd - aa * bb; + float c1 = -2 * bb * l1, c2 = bb - aa; + d = c1 * c1 - 4 * c2 * c; + if (d >= 0) { + float q = (float)Math.Sqrt(d); + if (c1 < 0) q = -q; + q = -(c1 + q) / 2; + float r0 = q / c2, r1 = c / q; + float r = Math.Abs(r0) < Math.Abs(r1) ? r0 : r1; + if (r * r <= dd) { + y = (float)Math.Sqrt(dd - r * r) * bendDir; + a1 = ta - (float)Math.Atan2(y, r); + a2 = (float)Math.Atan2(y / psy, (r - l1) / psx); + goto break_outer; // break outer; + } + } + float minAngle = MathUtils.PI, minX = l1 - a, minDist = minX * minX, minY = 0; + float maxAngle = 0, maxX = l1 + a, maxDist = maxX * maxX, maxY = 0; + c = -a * l1 / (aa - bb); + if (c >= -1 && c <= 1) { + c = (float)Math.Acos(c); + x = a * (float)Math.Cos(c) + l1; + y = b * (float)Math.Sin(c); + d = x * x + y * y; + if (d < minDist) { + minAngle = c; + minDist = d; + minX = x; + minY = y; + } + if (d > maxDist) { + maxAngle = c; + maxDist = d; + maxX = x; + maxY = y; + } + } + if (dd <= (minDist + maxDist) / 2) { + a1 = ta - (float)Math.Atan2(minY * bendDir, minX); + a2 = minAngle * bendDir; + } else { + a1 = ta - (float)Math.Atan2(maxY * bendDir, maxX); + a2 = maxAngle * bendDir; + } + } + break_outer: + float os = (float)Math.Atan2(cy, cx) * s2; + float rotation = parent.arotation; + a1 = (a1 - os) * MathUtils.RadDeg + os1 - rotation; + if (a1 > 180) + a1 -= 360; + else if (a1 < -180) a1 += 360; + parent.UpdateWorldTransform(px, py, rotation + a1 * alpha, sx, parent.ascaleY, 0, 0); + rotation = child.arotation; + a2 = ((a2 + os) * MathUtils.RadDeg - child.ashearX) * s2 + os2 - rotation; + if (a2 > 180) + a2 -= 360; + else if (a2 < -180) a2 += 360; + child.UpdateWorldTransform(cx, cy, rotation + a2 * alpha, child.ascaleX, child.ascaleY, child.ashearX, child.ashearY); + } + } +} diff --git a/box1/Assets/Spine/Runtime/spine-csharp/IkConstraint.cs.meta b/box1/Assets/Spine/Runtime/spine-csharp/IkConstraint.cs.meta new file mode 100644 index 00000000..bffcd556 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-csharp/IkConstraint.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 916f8e6534860cc40824adfc2916baa7 +timeCreated: 1456265155 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-csharp/IkConstraintData.cs b/box1/Assets/Spine/Runtime/spine-csharp/IkConstraintData.cs new file mode 100644 index 00000000..bc6a1c76 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-csharp/IkConstraintData.cs @@ -0,0 +1,99 @@ +/****************************************************************************** + * 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; + +namespace Spine { + /// Stores the setup pose for an IkConstraint. + public class IkConstraintData : ConstraintData { + internal ExposedList bones = new ExposedList(); + internal BoneData target; + internal int bendDirection = 1; + internal bool compress, stretch, uniform; + internal float mix = 1, softness; + + public IkConstraintData (string name) : base(name) { + } + + /// The bones that are constrained by this IK Constraint. + public ExposedList Bones { + get { return bones; } + } + + /// The bone that is the IK target. + public BoneData Target { + get { return target; } + set { target = value; } + } + + /// + /// A percentage (0-1) that controls the mix between the constraint and unconstrained rotations. + public float Mix { + get { return mix; } + set { mix = value; } + } + + ///For two bone IK, the distance from the maximum reach of the bones that rotation will slow. + public float Softness { + get { return softness; } + set { softness = value; } + } + + /// Controls the bend direction of the IK bones, either 1 or -1. + public int BendDirection { + get { return bendDirection; } + set { bendDirection = value; } + } + + /// + /// When true, and only a single bone is being constrained, + /// if the target is too close, the bone is scaled to reach it. + public bool Compress { + get { return compress; } + set { compress = value; } + } + + /// + /// When true, if the target is out of range, the parent bone is scaled on the X axis to reach it. + /// If the bone has local nonuniform scale, stretching is not applied. + public bool Stretch { + get { return stretch; } + set { stretch = value; } + } + + /// + /// When true, only a single bone is being constrained and Compress or Stretch is used, + /// the bone is scaled both on the X and Y axes. + public bool Uniform { + get { return uniform; } + set { uniform = value; } + } + } +} diff --git a/box1/Assets/Spine/Runtime/spine-csharp/IkConstraintData.cs.meta b/box1/Assets/Spine/Runtime/spine-csharp/IkConstraintData.cs.meta new file mode 100644 index 00000000..4825594e --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-csharp/IkConstraintData.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 94ad1e9256073264785f806086a000ba +timeCreated: 1456265155 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-csharp/Json.cs b/box1/Assets/Spine/Runtime/spine-csharp/Json.cs new file mode 100644 index 00000000..aa790f42 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-csharp/Json.cs @@ -0,0 +1,531 @@ +/****************************************************************************** + * 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.IO; +using System.Text; +using System.Collections; +using System.Globalization; +using System.Collections.Generic; + +namespace Spine { + public static class Json { + public static object Deserialize (TextReader text) { + var parser = new SharpJson.JsonDecoder(); + parser.parseNumbersAsFloat = true; + return parser.Decode(text.ReadToEnd()); + } + } +} + +/** + * Copyright (c) 2016 Adriano Tinoco d'Oliveira Rezende + * + * Based on the JSON parser by Patrick van Bergen + * http://techblog.procurios.nl/k/news/view/14605/14863/how-do-i-write-my-own-parser-(for-json).html + * + * Changes made: + * + * - Optimized parser speed (deserialize roughly near 3x faster than original) + * - Added support to handle lexer/parser error messages with line numbers + * - Added more fine grained control over type conversions during the parsing + * - Refactory API (Separate Lexer code from Parser code and the Encoder from Decoder) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software + * and associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * The above copyright notice and this permission notice shall be included in all copies or substantial + * portions of the Software. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +namespace SharpJson +{ + class Lexer + { + public enum Token { + None, + Null, + True, + False, + Colon, + Comma, + String, + Number, + CurlyOpen, + CurlyClose, + SquaredOpen, + SquaredClose, + }; + + public bool hasError { + get { + return !success; + } + } + + public int lineNumber { + get; + private set; + } + + public bool parseNumbersAsFloat { + get; + set; + } + + char[] json; + int index = 0; + bool success = true; + char[] stringBuffer = new char[4096]; + + public Lexer(string text) + { + Reset(); + + json = text.ToCharArray(); + parseNumbersAsFloat = false; + } + + public void Reset() + { + index = 0; + lineNumber = 1; + success = true; + } + + public string ParseString() + { + int idx = 0; + StringBuilder builder = null; + + SkipWhiteSpaces(); + + // " + char c = json[index++]; + + bool failed = false; + bool complete = false; + + while (!complete && !failed) { + if (index == json.Length) + break; + + c = json[index++]; + if (c == '"') { + complete = true; + break; + } else if (c == '\\') { + if (index == json.Length) + break; + + c = json[index++]; + + switch (c) { + case '"': + stringBuffer[idx++] = '"'; + break; + case '\\': + stringBuffer[idx++] = '\\'; + break; + case '/': + stringBuffer[idx++] = '/'; + break; + case 'b': + stringBuffer[idx++] = '\b'; + break; + case'f': + stringBuffer[idx++] = '\f'; + break; + case 'n': + stringBuffer[idx++] = '\n'; + break; + case 'r': + stringBuffer[idx++] = '\r'; + break; + case 't': + stringBuffer[idx++] = '\t'; + break; + case 'u': + int remainingLength = json.Length - index; + if (remainingLength >= 4) { + var hex = new string(json, index, 4); + + // XXX: handle UTF + stringBuffer[idx++] = (char) Convert.ToInt32(hex, 16); + + // skip 4 chars + index += 4; + } else { + failed = true; + } + break; + } + } else { + stringBuffer[idx++] = c; + } + + if (idx >= stringBuffer.Length) { + if (builder == null) + builder = new StringBuilder(); + + builder.Append(stringBuffer, 0, idx); + idx = 0; + } + } + + if (!complete) { + success = false; + return null; + } + + if (builder != null) + return builder.ToString (); + else + return new string (stringBuffer, 0, idx); + } + + string GetNumberString() + { + SkipWhiteSpaces(); + + int lastIndex = GetLastIndexOfNumber(index); + int charLength = (lastIndex - index) + 1; + + var result = new string (json, index, charLength); + + index = lastIndex + 1; + + return result; + } + + public float ParseFloatNumber() + { + float number; + var str = GetNumberString (); + + if (!float.TryParse (str, NumberStyles.Float, CultureInfo.InvariantCulture, out number)) + return 0; + + return number; + } + + public double ParseDoubleNumber() + { + double number; + var str = GetNumberString (); + + if (!double.TryParse(str, NumberStyles.Any, CultureInfo.InvariantCulture, out number)) + return 0; + + return number; + } + + int GetLastIndexOfNumber(int index) + { + int lastIndex; + + for (lastIndex = index; lastIndex < json.Length; lastIndex++) { + char ch = json[lastIndex]; + + if ((ch < '0' || ch > '9') && ch != '+' && ch != '-' + && ch != '.' && ch != 'e' && ch != 'E') + break; + } + + return lastIndex - 1; + } + + void SkipWhiteSpaces() + { + for (; index < json.Length; index++) { + char ch = json[index]; + + if (ch == '\n') + lineNumber++; + + if (!char.IsWhiteSpace(json[index])) + break; + } + } + + public Token LookAhead() + { + SkipWhiteSpaces(); + + int savedIndex = index; + return NextToken(json, ref savedIndex); + } + + public Token NextToken() + { + SkipWhiteSpaces(); + return NextToken(json, ref index); + } + + static Token NextToken(char[] json, ref int index) + { + if (index == json.Length) + return Token.None; + + char c = json[index++]; + + switch (c) { + case '{': + return Token.CurlyOpen; + case '}': + return Token.CurlyClose; + case '[': + return Token.SquaredOpen; + case ']': + return Token.SquaredClose; + case ',': + return Token.Comma; + case '"': + return Token.String; + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + case '-': + return Token.Number; + case ':': + return Token.Colon; + } + + index--; + + int remainingLength = json.Length - index; + + // false + if (remainingLength >= 5) { + if (json[index] == 'f' && + json[index + 1] == 'a' && + json[index + 2] == 'l' && + json[index + 3] == 's' && + json[index + 4] == 'e') { + index += 5; + return Token.False; + } + } + + // true + if (remainingLength >= 4) { + if (json[index] == 't' && + json[index + 1] == 'r' && + json[index + 2] == 'u' && + json[index + 3] == 'e') { + index += 4; + return Token.True; + } + } + + // null + if (remainingLength >= 4) { + if (json[index] == 'n' && + json[index + 1] == 'u' && + json[index + 2] == 'l' && + json[index + 3] == 'l') { + index += 4; + return Token.Null; + } + } + + return Token.None; + } + } + + public class JsonDecoder + { + public string errorMessage { + get; + private set; + } + + public bool parseNumbersAsFloat { + get; + set; + } + + Lexer lexer; + + public JsonDecoder() + { + errorMessage = null; + parseNumbersAsFloat = false; + } + + public object Decode(string text) + { + errorMessage = null; + + lexer = new Lexer(text); + lexer.parseNumbersAsFloat = parseNumbersAsFloat; + + return ParseValue(); + } + + public static object DecodeText(string text) + { + var builder = new JsonDecoder(); + return builder.Decode(text); + } + + IDictionary ParseObject() + { + var table = new Dictionary(); + + // { + lexer.NextToken(); + + while (true) { + var token = lexer.LookAhead(); + + switch (token) { + case Lexer.Token.None: + TriggerError("Invalid token"); + return null; + case Lexer.Token.Comma: + lexer.NextToken(); + break; + case Lexer.Token.CurlyClose: + lexer.NextToken(); + return table; + default: + // name + string name = EvalLexer(lexer.ParseString()); + + if (errorMessage != null) + return null; + + // : + token = lexer.NextToken(); + + if (token != Lexer.Token.Colon) { + TriggerError("Invalid token; expected ':'"); + return null; + } + + // value + object value = ParseValue(); + + if (errorMessage != null) + return null; + + table[name] = value; + break; + } + } + + //return null; // Unreachable code + } + + IList ParseArray() + { + var array = new List(); + + // [ + lexer.NextToken(); + + while (true) { + var token = lexer.LookAhead(); + + switch (token) { + case Lexer.Token.None: + TriggerError("Invalid token"); + return null; + case Lexer.Token.Comma: + lexer.NextToken(); + break; + case Lexer.Token.SquaredClose: + lexer.NextToken(); + return array; + default: + object value = ParseValue(); + + if (errorMessage != null) + return null; + + array.Add(value); + break; + } + } + + //return null; // Unreachable code + } + + object ParseValue() + { + switch (lexer.LookAhead()) { + case Lexer.Token.String: + return EvalLexer(lexer.ParseString()); + case Lexer.Token.Number: + if (parseNumbersAsFloat) + return EvalLexer(lexer.ParseFloatNumber()); + else + return EvalLexer(lexer.ParseDoubleNumber()); + case Lexer.Token.CurlyOpen: + return ParseObject(); + case Lexer.Token.SquaredOpen: + return ParseArray(); + case Lexer.Token.True: + lexer.NextToken(); + return true; + case Lexer.Token.False: + lexer.NextToken(); + return false; + case Lexer.Token.Null: + lexer.NextToken(); + return null; + case Lexer.Token.None: + break; + } + + TriggerError("Unable to parse value"); + return null; + } + + void TriggerError(string message) + { + errorMessage = string.Format("Error: '{0}' at line {1}", + message, lexer.lineNumber); + } + + T EvalLexer(T value) + { + if (lexer.hasError) + TriggerError("Lexical error ocurred"); + + return value; + } + } +} diff --git a/box1/Assets/Spine/Runtime/spine-csharp/Json.cs.meta b/box1/Assets/Spine/Runtime/spine-csharp/Json.cs.meta new file mode 100644 index 00000000..ca4d3248 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-csharp/Json.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 371f40ecc08b2eb4cbec49585d41e2c3 +timeCreated: 1456265153 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-csharp/MathUtils.cs b/box1/Assets/Spine/Runtime/spine-csharp/MathUtils.cs new file mode 100644 index 00000000..ad10ec21 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-csharp/MathUtils.cs @@ -0,0 +1,173 @@ +/****************************************************************************** + * 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. + *****************************************************************************/ + +//#define USE_FAST_SIN_COS_ATAN2_APPROXIMATIONS + +using System; + +namespace Spine { + public static class MathUtils { + public const float PI = 3.1415927f; + public const float PI2 = PI * 2; + public const float RadDeg = 180f / PI; + public const float DegRad = PI / 180; + + static Random random = new Random(); + + #if USE_FAST_SIN_COS_ATAN2_APPROXIMATIONS + const int SIN_BITS = 14; // 16KB. Adjust for accuracy. + const int SIN_MASK = ~(-1 << SIN_BITS); + const int SIN_COUNT = SIN_MASK + 1; + const float RadFull = PI * 2; + const float DegFull = 360; + const float RadToIndex = SIN_COUNT / RadFull; + const float DegToIndex = SIN_COUNT / DegFull; + static float[] sin = new float[SIN_COUNT]; + + static MathUtils () { + for (int i = 0; i < SIN_COUNT; i++) + sin[i] = (float)Math.Sin((i + 0.5f) / SIN_COUNT * RadFull); + for (int i = 0; i < 360; i += 90) + sin[(int)(i * DegToIndex) & SIN_MASK] = (float)Math.Sin(i * DegRad); + } + + /// Returns the sine of a given angle in radians from a lookup table. + static public float Sin (float radians) { + return sin[(int)(radians * RadToIndex) & SIN_MASK]; + } + + /// Returns the cosine of a given angle in radians from a lookup table. + static public float Cos (float radians) { + return sin[(int)((radians + PI / 2) * RadToIndex) & SIN_MASK]; + } + + /// Returns the sine of a given angle in degrees from a lookup table. + static public float SinDeg (float degrees) { + return sin[(int)(degrees * DegToIndex) & SIN_MASK]; + } + + /// Returns the cosine of a given angle in degrees from a lookup table. + static public float CosDeg (float degrees) { + return sin[(int)((degrees + 90) * DegToIndex) & SIN_MASK]; + } + + /// Returns atan2 in radians, faster but less accurate than Math.Atan2. Average error of 0.00231 radians (0.1323 + /// degrees), largest error of 0.00488 radians (0.2796 degrees). + static public float Atan2 (float y, float x) { + if (x == 0f) { + if (y > 0f) return PI / 2; + if (y == 0f) return 0f; + return -PI / 2; + } + float atan, z = y / x; + if (Math.Abs(z) < 1f) { + atan = z / (1f + 0.28f * z * z); + if (x < 0f) return atan + (y < 0f ? -PI : PI); + return atan; + } + atan = PI / 2 - z / (z * z + 0.28f); + return y < 0f ? atan - PI : atan; + } + #else + /// Returns the sine of a given angle in radians. + static public float Sin (float radians) { + return (float)Math.Sin(radians); + } + + /// Returns the cosine of a given angle in radians. + static public float Cos (float radians) { + return (float)Math.Cos(radians); + } + + /// Returns the sine of a given angle in degrees. + static public float SinDeg (float degrees) { + return (float)Math.Sin(degrees * DegRad); + } + + /// Returns the cosine of a given angle in degrees. + static public float CosDeg (float degrees) { + return (float)Math.Cos(degrees * DegRad); + } + + /// Returns the atan2 using Math.Atan2. + static public float Atan2 (float y, float x) { + return (float)Math.Atan2(y, x); + } + #endif + static public float Clamp (float value, float min, float max) { + if (value < min) return min; + if (value > max) return max; + return value; + } + + static public float RandomTriangle(float min, float max) { + return RandomTriangle(min, max, (min + max) * 0.5f); + } + + static public float RandomTriangle(float min, float max, float mode) { + float u = (float)random.NextDouble(); + float d = max - min; + if (u <= (mode - min) / d) return min + (float)Math.Sqrt(u * d * (mode - min)); + return max - (float)Math.Sqrt((1 - u) * d * (max - mode)); + } + } + + public abstract class IInterpolation { + public static IInterpolation Pow2 = new Pow(2); + public static IInterpolation Pow2Out = new PowOut(2); + + protected abstract float Apply(float a); + + public float Apply(float start, float end, float a) { + return start + (end - start) * Apply(a); + } + } + + public class Pow: IInterpolation { + public float Power { get; set; } + + public Pow(float power) { + Power = power; + } + + protected override float Apply(float a) { + if (a <= 0.5f) return (float)Math.Pow(a * 2, Power) / 2; + return (float)Math.Pow((a - 1) * 2, Power) / (Power % 2 == 0 ? -2 : 2) + 1; + } + } + + public class PowOut : Pow { + public PowOut(float power) : base(power) { + } + + protected override float Apply(float a) { + return (float)Math.Pow(a - 1, Power) * (Power % 2 == 0 ? -1 : 1) + 1; + } + } +} diff --git a/box1/Assets/Spine/Runtime/spine-csharp/MathUtils.cs.meta b/box1/Assets/Spine/Runtime/spine-csharp/MathUtils.cs.meta new file mode 100644 index 00000000..00c7de32 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-csharp/MathUtils.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 03b653e54c5403b4191f5003d64c6e18 +timeCreated: 1456265153 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-csharp/PathConstraint.cs b/box1/Assets/Spine/Runtime/spine-csharp/PathConstraint.cs new file mode 100644 index 00000000..c8fef419 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-csharp/PathConstraint.cs @@ -0,0 +1,467 @@ +/****************************************************************************** + * 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; + +namespace Spine { + + /// + /// + /// Stores the current pose for a path constraint. A path constraint adjusts the rotation, translation, and scale of the + /// constrained bones so they follow a {@link PathAttachment}. + /// + /// See Path constraints in the Spine User Guide. + /// + public class PathConstraint : IUpdatable { + const int NONE = -1, BEFORE = -2, AFTER = -3; + const float Epsilon = 0.00001f; + + internal PathConstraintData data; + internal ExposedList bones; + internal Slot target; + internal float position, spacing, rotateMix, translateMix; + + internal bool active; + + internal ExposedList spaces = new ExposedList(), positions = new ExposedList(); + internal ExposedList world = new ExposedList(), curves = new ExposedList(), lengths = new ExposedList(); + internal float[] segments = new float[10]; + + public PathConstraint (PathConstraintData data, Skeleton skeleton) { + if (data == null) throw new ArgumentNullException("data", "data cannot be null."); + if (skeleton == null) throw new ArgumentNullException("skeleton", "skeleton cannot be null."); + this.data = data; + bones = new ExposedList(data.Bones.Count); + foreach (BoneData boneData in data.bones) + bones.Add(skeleton.FindBone(boneData.name)); + target = skeleton.FindSlot(data.target.name); + position = data.position; + spacing = data.spacing; + rotateMix = data.rotateMix; + translateMix = data.translateMix; + } + + /// Copy constructor. + public PathConstraint (PathConstraint constraint, Skeleton skeleton) { + if (constraint == null) throw new ArgumentNullException("constraint cannot be null."); + if (skeleton == null) throw new ArgumentNullException("skeleton cannot be null."); + data = constraint.data; + bones = new ExposedList(constraint.Bones.Count); + foreach (Bone bone in constraint.Bones) + bones.Add(skeleton.Bones.Items[bone.data.index]); + target = skeleton.slots.Items[constraint.target.data.index]; + position = constraint.position; + spacing = constraint.spacing; + rotateMix = constraint.rotateMix; + translateMix = constraint.translateMix; + } + + /// Applies the constraint to the constrained bones. + public void Apply () { + Update(); + } + + public void Update () { + PathAttachment attachment = target.Attachment as PathAttachment; + if (attachment == null) return; + + float rotateMix = this.rotateMix, translateMix = this.translateMix; + bool translate = translateMix > 0, rotate = rotateMix > 0; + if (!translate && !rotate) return; + + PathConstraintData data = this.data; + bool percentSpacing = data.spacingMode == SpacingMode.Percent; + RotateMode rotateMode = data.rotateMode; + bool tangents = rotateMode == RotateMode.Tangent, scale = rotateMode == RotateMode.ChainScale; + int boneCount = this.bones.Count, spacesCount = tangents ? boneCount : boneCount + 1; + Bone[] bonesItems = this.bones.Items; + ExposedList spaces = this.spaces.Resize(spacesCount), lengths = null; + float spacing = this.spacing; + if (scale || !percentSpacing) { + if (scale) lengths = this.lengths.Resize(boneCount); + bool lengthSpacing = data.spacingMode == SpacingMode.Length; + for (int i = 0, n = spacesCount - 1; i < n;) { + Bone bone = bonesItems[i]; + float setupLength = bone.data.length; + if (setupLength < PathConstraint.Epsilon) { + if (scale) lengths.Items[i] = 0; + spaces.Items[++i] = 0; + } else if (percentSpacing) { + if (scale) { + float x = setupLength * bone.a, y = setupLength * bone.c; + float length = (float)Math.Sqrt(x * x + y * y); + lengths.Items[i] = length; + } + spaces.Items[++i] = spacing; + } else { + float x = setupLength * bone.a, y = setupLength * bone.c; + float length = (float)Math.Sqrt(x * x + y * y); + if (scale) lengths.Items[i] = length; + spaces.Items[++i] = (lengthSpacing ? setupLength + spacing : spacing) * length / setupLength; + } + } + } else { + for (int i = 1; i < spacesCount; i++) + spaces.Items[i] = spacing; + } + + float[] positions = ComputeWorldPositions(attachment, spacesCount, tangents, + data.positionMode == PositionMode.Percent, percentSpacing); + float boneX = positions[0], boneY = positions[1], offsetRotation = data.offsetRotation; + bool tip; + if (offsetRotation == 0) { + tip = rotateMode == RotateMode.Chain; + } else { + tip = false; + Bone p = target.bone; + offsetRotation *= p.a * p.d - p.b * p.c > 0 ? MathUtils.DegRad : -MathUtils.DegRad; + } + for (int i = 0, p = 3; i < boneCount; i++, p += 3) { + Bone bone = bonesItems[i]; + bone.worldX += (boneX - bone.worldX) * translateMix; + bone.worldY += (boneY - bone.worldY) * translateMix; + float x = positions[p], y = positions[p + 1], dx = x - boneX, dy = y - boneY; + if (scale) { + float length = lengths.Items[i]; + if (length >= PathConstraint.Epsilon) { + float s = ((float)Math.Sqrt(dx * dx + dy * dy) / length - 1) * rotateMix + 1; + bone.a *= s; + bone.c *= s; + } + } + boneX = x; + boneY = y; + if (rotate) { + float a = bone.a, b = bone.b, c = bone.c, d = bone.d, r, cos, sin; + if (tangents) + r = positions[p - 1]; + else if (spaces.Items[i + 1] < PathConstraint.Epsilon) + r = positions[p + 2]; + else + r = MathUtils.Atan2(dy, dx); + r -= MathUtils.Atan2(c, a); + if (tip) { + cos = MathUtils.Cos(r); + sin = MathUtils.Sin(r); + float length = bone.data.length; + boneX += (length * (cos * a - sin * c) - dx) * rotateMix; + boneY += (length * (sin * a + cos * c) - dy) * rotateMix; + } else + r += offsetRotation; + if (r > MathUtils.PI) + r -= MathUtils.PI2; + else if (r < -MathUtils.PI) // + r += MathUtils.PI2; + r *= rotateMix; + cos = MathUtils.Cos(r); + sin = MathUtils.Sin(r); + bone.a = cos * a - sin * c; + bone.b = cos * b - sin * d; + bone.c = sin * a + cos * c; + bone.d = sin * b + cos * d; + } + bone.appliedValid = false; + } + } + + float[] ComputeWorldPositions (PathAttachment path, int spacesCount, bool tangents, bool percentPosition, + bool percentSpacing) { + + Slot target = this.target; + float position = this.position; + float[] spacesItems = this.spaces.Items, output = this.positions.Resize(spacesCount * 3 + 2).Items, world; + bool closed = path.Closed; + int verticesLength = path.WorldVerticesLength, curveCount = verticesLength / 6, prevCurve = NONE; + float pathLength = 0; + + if (!path.ConstantSpeed) { + float[] lengths = path.Lengths; + curveCount -= closed ? 1 : 2; + pathLength = lengths[curveCount]; + if (percentPosition) position *= pathLength; + if (percentSpacing) { + for (int i = 1; i < spacesCount; i++) + spacesItems[i] *= pathLength; + } + world = this.world.Resize(8).Items; + for (int i = 0, o = 0, curve = 0; i < spacesCount; i++, o += 3) { + float space = spacesItems[i]; + position += space; + float p = position; + + if (closed) { + p %= pathLength; + if (p < 0) p += pathLength; + curve = 0; + } else if (p < 0) { + if (prevCurve != BEFORE) { + prevCurve = BEFORE; + path.ComputeWorldVertices(target, 2, 4, world, 0, 2); + } + AddBeforePosition(p, world, 0, output, o); + continue; + } else if (p > pathLength) { + if (prevCurve != AFTER) { + prevCurve = AFTER; + path.ComputeWorldVertices(target, verticesLength - 6, 4, world, 0, 2); + } + AddAfterPosition(p - pathLength, world, 0, output, o); + continue; + } + + // Determine curve containing position. + for (;; curve++) { + float length = lengths[curve]; + if (p > length) continue; + if (curve == 0) + p /= length; + else { + float prev = lengths[curve - 1]; + p = (p - prev) / (length - prev); + } + break; + } + if (curve != prevCurve) { + prevCurve = curve; + if (closed && curve == curveCount) { + path.ComputeWorldVertices(target, verticesLength - 4, 4, world, 0, 2); + path.ComputeWorldVertices(target, 0, 4, world, 4, 2); + } else + path.ComputeWorldVertices(target, curve * 6 + 2, 8, world, 0, 2); + } + AddCurvePosition(p, world[0], world[1], world[2], world[3], world[4], world[5], world[6], world[7], output, o, + tangents || (i > 0 && space < PathConstraint.Epsilon)); + } + return output; + } + + // World vertices. + if (closed) { + verticesLength += 2; + world = this.world.Resize(verticesLength).Items; + path.ComputeWorldVertices(target, 2, verticesLength - 4, world, 0, 2); + path.ComputeWorldVertices(target, 0, 2, world, verticesLength - 4, 2); + world[verticesLength - 2] = world[0]; + world[verticesLength - 1] = world[1]; + } else { + curveCount--; + verticesLength -= 4; + world = this.world.Resize(verticesLength).Items; + path.ComputeWorldVertices(target, 2, verticesLength, world, 0, 2); + } + + // Curve lengths. + float[] curves = this.curves.Resize(curveCount).Items; + pathLength = 0; + float x1 = world[0], y1 = world[1], cx1 = 0, cy1 = 0, cx2 = 0, cy2 = 0, x2 = 0, y2 = 0; + float tmpx, tmpy, dddfx, dddfy, ddfx, ddfy, dfx, dfy; + for (int i = 0, w = 2; i < curveCount; i++, w += 6) { + cx1 = world[w]; + cy1 = world[w + 1]; + cx2 = world[w + 2]; + cy2 = world[w + 3]; + x2 = world[w + 4]; + y2 = world[w + 5]; + tmpx = (x1 - cx1 * 2 + cx2) * 0.1875f; + tmpy = (y1 - cy1 * 2 + cy2) * 0.1875f; + dddfx = ((cx1 - cx2) * 3 - x1 + x2) * 0.09375f; + dddfy = ((cy1 - cy2) * 3 - y1 + y2) * 0.09375f; + ddfx = tmpx * 2 + dddfx; + ddfy = tmpy * 2 + dddfy; + dfx = (cx1 - x1) * 0.75f + tmpx + dddfx * 0.16666667f; + dfy = (cy1 - y1) * 0.75f + tmpy + dddfy * 0.16666667f; + pathLength += (float)Math.Sqrt(dfx * dfx + dfy * dfy); + dfx += ddfx; + dfy += ddfy; + ddfx += dddfx; + ddfy += dddfy; + pathLength += (float)Math.Sqrt(dfx * dfx + dfy * dfy); + dfx += ddfx; + dfy += ddfy; + pathLength += (float)Math.Sqrt(dfx * dfx + dfy * dfy); + dfx += ddfx + dddfx; + dfy += ddfy + dddfy; + pathLength += (float)Math.Sqrt(dfx * dfx + dfy * dfy); + curves[i] = pathLength; + x1 = x2; + y1 = y2; + } + if (percentPosition) + position *= pathLength; + else + position *= pathLength / path.lengths[curveCount - 1]; + + if (percentSpacing) { + for (int i = 1; i < spacesCount; i++) + spacesItems[i] *= pathLength; + } + + float[] segments = this.segments; + float curveLength = 0; + for (int i = 0, o = 0, curve = 0, segment = 0; i < spacesCount; i++, o += 3) { + float space = spacesItems[i]; + position += space; + float p = position; + + if (closed) { + p %= pathLength; + if (p < 0) p += pathLength; + curve = 0; + } else if (p < 0) { + AddBeforePosition(p, world, 0, output, o); + continue; + } else if (p > pathLength) { + AddAfterPosition(p - pathLength, world, verticesLength - 4, output, o); + continue; + } + + // Determine curve containing position. + for (;; curve++) { + float length = curves[curve]; + if (p > length) continue; + if (curve == 0) + p /= length; + else { + float prev = curves[curve - 1]; + p = (p - prev) / (length - prev); + } + break; + } + + // Curve segment lengths. + if (curve != prevCurve) { + prevCurve = curve; + int ii = curve * 6; + x1 = world[ii]; + y1 = world[ii + 1]; + cx1 = world[ii + 2]; + cy1 = world[ii + 3]; + cx2 = world[ii + 4]; + cy2 = world[ii + 5]; + x2 = world[ii + 6]; + y2 = world[ii + 7]; + tmpx = (x1 - cx1 * 2 + cx2) * 0.03f; + tmpy = (y1 - cy1 * 2 + cy2) * 0.03f; + dddfx = ((cx1 - cx2) * 3 - x1 + x2) * 0.006f; + dddfy = ((cy1 - cy2) * 3 - y1 + y2) * 0.006f; + ddfx = tmpx * 2 + dddfx; + ddfy = tmpy * 2 + dddfy; + dfx = (cx1 - x1) * 0.3f + tmpx + dddfx * 0.16666667f; + dfy = (cy1 - y1) * 0.3f + tmpy + dddfy * 0.16666667f; + curveLength = (float)Math.Sqrt(dfx * dfx + dfy * dfy); + segments[0] = curveLength; + for (ii = 1; ii < 8; ii++) { + dfx += ddfx; + dfy += ddfy; + ddfx += dddfx; + ddfy += dddfy; + curveLength += (float)Math.Sqrt(dfx * dfx + dfy * dfy); + segments[ii] = curveLength; + } + dfx += ddfx; + dfy += ddfy; + curveLength += (float)Math.Sqrt(dfx * dfx + dfy * dfy); + segments[8] = curveLength; + dfx += ddfx + dddfx; + dfy += ddfy + dddfy; + curveLength += (float)Math.Sqrt(dfx * dfx + dfy * dfy); + segments[9] = curveLength; + segment = 0; + } + + // Weight by segment length. + p *= curveLength; + for (;; segment++) { + float length = segments[segment]; + if (p > length) continue; + if (segment == 0) + p /= length; + else { + float prev = segments[segment - 1]; + p = segment + (p - prev) / (length - prev); + } + break; + } + AddCurvePosition(p * 0.1f, x1, y1, cx1, cy1, cx2, cy2, x2, y2, output, o, tangents || (i > 0 && space < PathConstraint.Epsilon)); + } + return output; + } + + static void AddBeforePosition (float p, float[] temp, int i, float[] output, int o) { + float x1 = temp[i], y1 = temp[i + 1], dx = temp[i + 2] - x1, dy = temp[i + 3] - y1, r = MathUtils.Atan2(dy, dx); + output[o] = x1 + p * MathUtils.Cos(r); + output[o + 1] = y1 + p * MathUtils.Sin(r); + output[o + 2] = r; + } + + static void AddAfterPosition (float p, float[] temp, int i, float[] output, int o) { + float x1 = temp[i + 2], y1 = temp[i + 3], dx = x1 - temp[i], dy = y1 - temp[i + 1], r = MathUtils.Atan2(dy, dx); + output[o] = x1 + p * MathUtils.Cos(r); + output[o + 1] = y1 + p * MathUtils.Sin(r); + output[o + 2] = r; + } + + static void AddCurvePosition (float p, float x1, float y1, float cx1, float cy1, float cx2, float cy2, float x2, float y2, + float[] output, int o, bool tangents) { + if (p < PathConstraint.Epsilon || float.IsNaN(p)) { + output[o] = x1; + output[o + 1] = y1; + output[o + 2] = (float)Math.Atan2(cy1 - y1, cx1 - x1); + return; + } + float tt = p * p, ttt = tt * p, u = 1 - p, uu = u * u, uuu = uu * u; + float ut = u * p, ut3 = ut * 3, uut3 = u * ut3, utt3 = ut3 * p; + float x = x1 * uuu + cx1 * uut3 + cx2 * utt3 + x2 * ttt, y = y1 * uuu + cy1 * uut3 + cy2 * utt3 + y2 * ttt; + output[o] = x; + output[o + 1] = y; + if (tangents) { + if (p < 0.001f) + output[o + 2] = (float)Math.Atan2(cy1 - y1, cx1 - x1); + else + output[o + 2] = (float)Math.Atan2(y - (y1 * uu + cy1 * ut * 2 + cy2 * tt), x - (x1 * uu + cx1 * ut * 2 + cx2 * tt)); + } + } + + /// The position along the path. + public float Position { get { return position; } set { position = value; } } + /// The spacing between bones. + public float Spacing { get { return spacing; } set { spacing = value; } } + /// A percentage (0-1) that controls the mix between the constrained and unconstrained rotations. + public float RotateMix { get { return rotateMix; } set { rotateMix = value; } } + /// A percentage (0-1) that controls the mix between the constrained and unconstrained translations. + public float TranslateMix { get { return translateMix; } set { translateMix = value; } } + /// The bones that will be modified by this path constraint. + public ExposedList Bones { get { return bones; } } + /// The slot whose path attachment will be used to constrained the bones. + public Slot Target { get { return target; } set { target = value; } } + public bool Active { get { return active; } } + /// The path constraint's setup pose data. + public PathConstraintData Data { get { return data; } } + } +} diff --git a/box1/Assets/Spine/Runtime/spine-csharp/PathConstraint.cs.meta b/box1/Assets/Spine/Runtime/spine-csharp/PathConstraint.cs.meta new file mode 100644 index 00000000..3ee81222 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-csharp/PathConstraint.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 731d05fbc2874c74984813ce4c5bb8df +timeCreated: 1467213650 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-csharp/PathConstraintData.cs b/box1/Assets/Spine/Runtime/spine-csharp/PathConstraintData.cs new file mode 100644 index 00000000..fa6e71fd --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-csharp/PathConstraintData.cs @@ -0,0 +1,68 @@ +/****************************************************************************** + * 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; + +namespace Spine { + public class PathConstraintData : ConstraintData { + internal ExposedList bones = new ExposedList(); + internal SlotData target; + internal PositionMode positionMode; + internal SpacingMode spacingMode; + internal RotateMode rotateMode; + internal float offsetRotation; + internal float position, spacing, rotateMix, translateMix; + + public PathConstraintData (string name) : base(name) { + } + + public ExposedList Bones { get { return bones; } } + public SlotData Target { get { return target; } set { target = value; } } + public PositionMode PositionMode { get { return positionMode; } set { positionMode = value; } } + public SpacingMode SpacingMode { get { return spacingMode; } set { spacingMode = value; } } + public RotateMode RotateMode { get { return rotateMode; } set { rotateMode = value; } } + public float OffsetRotation { get { return offsetRotation; } set { offsetRotation = value; } } + public float Position { get { return position; } set { position = value; } } + public float Spacing { get { return spacing; } set { spacing = value; } } + public float RotateMix { get { return rotateMix; } set { rotateMix = value; } } + public float TranslateMix { get { return translateMix; } set { translateMix = value; } } + } + + public enum PositionMode { + Fixed, Percent + } + + public enum SpacingMode { + Length, Fixed, Percent + } + + public enum RotateMode { + Tangent, Chain, ChainScale + } +} diff --git a/box1/Assets/Spine/Runtime/spine-csharp/PathConstraintData.cs.meta b/box1/Assets/Spine/Runtime/spine-csharp/PathConstraintData.cs.meta new file mode 100644 index 00000000..65062769 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-csharp/PathConstraintData.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 9d836858269be96428428fb6764dfc3a +timeCreated: 1467213651 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-csharp/Skeleton.cs b/box1/Assets/Spine/Runtime/spine-csharp/Skeleton.cs new file mode 100644 index 00000000..1bd50172 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-csharp/Skeleton.cs @@ -0,0 +1,635 @@ +/****************************************************************************** + * 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; + +namespace Spine { + public class Skeleton { + internal SkeletonData data; + internal ExposedList bones; + internal ExposedList slots; + internal ExposedList drawOrder; + internal ExposedList ikConstraints; + internal ExposedList transformConstraints; + internal ExposedList pathConstraints; + internal ExposedList updateCache = new ExposedList(); + internal ExposedList updateCacheReset = new ExposedList(); + internal Skin skin; + internal float r = 1, g = 1, b = 1, a = 1; + internal float time; + private float scaleX = 1, scaleY = 1; + internal float x, y; + + public SkeletonData Data { get { return data; } } + public ExposedList Bones { get { return bones; } } + public ExposedList UpdateCacheList { get { return updateCache; } } + public ExposedList Slots { get { return slots; } } + public ExposedList DrawOrder { get { return drawOrder; } } + public ExposedList IkConstraints { get { return ikConstraints; } } + public ExposedList PathConstraints { get { return pathConstraints; } } + public ExposedList TransformConstraints { get { return transformConstraints; } } + public Skin Skin { get { return skin; } set { SetSkin(value); } } + public float R { get { return r; } set { r = value; } } + public float G { get { return g; } set { g = value; } } + public float B { get { return b; } set { b = value; } } + public float A { get { return a; } set { a = value; } } + public float Time { get { return time; } set { time = value; } } + public float X { get { return x; } set { x = value; } } + public float Y { get { return y; } set { y = value; } } + public float ScaleX { get { return scaleX; } set { scaleX = value; } } + public float ScaleY { get { return scaleY * (Bone.yDown ? -1 : 1); } set { scaleY = value; } } + + [Obsolete("Use ScaleX instead. FlipX is when ScaleX is negative.")] + public bool FlipX { get { return scaleX < 0; } set { scaleX = value ? -1f : 1f; } } + + [Obsolete("Use ScaleY instead. FlipY is when ScaleY is negative.")] + public bool FlipY { get { return scaleY < 0; } set { scaleY = value ? -1f : 1f; } } + + public Bone RootBone { + get { return bones.Count == 0 ? null : bones.Items[0]; } + } + + public Skeleton (SkeletonData data) { + if (data == null) throw new ArgumentNullException("data", "data cannot be null."); + this.data = data; + + bones = new ExposedList(data.bones.Count); + foreach (BoneData boneData in data.bones) { + Bone bone; + if (boneData.parent == null) { + bone = new Bone(boneData, this, null); + } else { + Bone parent = bones.Items[boneData.parent.index]; + bone = new Bone(boneData, this, parent); + parent.children.Add(bone); + } + bones.Add(bone); + } + + slots = new ExposedList(data.slots.Count); + drawOrder = new ExposedList(data.slots.Count); + foreach (SlotData slotData in data.slots) { + Bone bone = bones.Items[slotData.boneData.index]; + Slot slot = new Slot(slotData, bone); + slots.Add(slot); + drawOrder.Add(slot); + } + + ikConstraints = new ExposedList(data.ikConstraints.Count); + foreach (IkConstraintData ikConstraintData in data.ikConstraints) + ikConstraints.Add(new IkConstraint(ikConstraintData, this)); + + transformConstraints = new ExposedList(data.transformConstraints.Count); + foreach (TransformConstraintData transformConstraintData in data.transformConstraints) + transformConstraints.Add(new TransformConstraint(transformConstraintData, this)); + + pathConstraints = new ExposedList (data.pathConstraints.Count); + foreach (PathConstraintData pathConstraintData in data.pathConstraints) + pathConstraints.Add(new PathConstraint(pathConstraintData, this)); + + UpdateCache(); + UpdateWorldTransform(); + } + + /// Caches information about bones and constraints. Must be called if the is modified or if bones, constraints, or + /// constraints, or weighted path attachments are added or removed. + public void UpdateCache () { + var updateCache = this.updateCache; + updateCache.Clear(); + this.updateCacheReset.Clear(); + + int boneCount = this.bones.Items.Length; + var bones = this.bones; + for (int i = 0; i < boneCount; i++) { + Bone bone = bones.Items[i]; + bone.sorted = bone.data.skinRequired; + bone.active = !bone.sorted; + } + if (skin != null) { + Object[] skinBones = skin.bones.Items; + for (int i = 0, n = skin.bones.Count; i < n; i++) { + Bone bone = (Bone)bones.Items[((BoneData)skinBones[i]).index]; + do { + bone.sorted = false; + bone.active = true; + bone = bone.parent; + } while (bone != null); + } + } + + int ikCount = this.ikConstraints.Count, transformCount = this.transformConstraints.Count, pathCount = this.pathConstraints.Count; + var ikConstraints = this.ikConstraints; + var transformConstraints = this.transformConstraints; + var pathConstraints = this.pathConstraints; + int constraintCount = ikCount + transformCount + pathCount; + //outer: + for (int i = 0; i < constraintCount; i++) { + for (int ii = 0; ii < ikCount; ii++) { + IkConstraint constraint = ikConstraints.Items[ii]; + if (constraint.data.order == i) { + SortIkConstraint(constraint); + goto continue_outer; //continue outer; + } + } + for (int ii = 0; ii < transformCount; ii++) { + TransformConstraint constraint = transformConstraints.Items[ii]; + if (constraint.data.order == i) { + SortTransformConstraint(constraint); + goto continue_outer; //continue outer; + } + } + for (int ii = 0; ii < pathCount; ii++) { + PathConstraint constraint = pathConstraints.Items[ii]; + if (constraint.data.order == i) { + SortPathConstraint(constraint); + goto continue_outer; //continue outer; + } + } + continue_outer: {} + } + + for (int i = 0; i < boneCount; i++) + SortBone(bones.Items[i]); + } + + private void SortIkConstraint (IkConstraint constraint) { + constraint.active = constraint.target.active + && (!constraint.data.skinRequired || (skin != null && skin.constraints.Contains(constraint.data))); + if (!constraint.active) return; + + Bone target = constraint.target; + SortBone(target); + + var constrained = constraint.bones; + Bone parent = constrained.Items[0]; + SortBone(parent); + + if (constrained.Count > 1) { + Bone child = constrained.Items[constrained.Count - 1]; + if (!updateCache.Contains(child)) + updateCacheReset.Add(child); + } + + updateCache.Add(constraint); + + SortReset(parent.children); + constrained.Items[constrained.Count - 1].sorted = true; + } + + private void SortPathConstraint (PathConstraint constraint) { + constraint.active = constraint.target.bone.active + && (!constraint.data.skinRequired || (skin != null && skin.constraints.Contains(constraint.data))); + if (!constraint.active) return; + + Slot slot = constraint.target; + int slotIndex = slot.data.index; + Bone slotBone = slot.bone; + if (skin != null) SortPathConstraintAttachment(skin, slotIndex, slotBone); + if (data.defaultSkin != null && data.defaultSkin != skin) + SortPathConstraintAttachment(data.defaultSkin, slotIndex, slotBone); + + Attachment attachment = slot.attachment; + if (attachment is PathAttachment) SortPathConstraintAttachment(attachment, slotBone); + + var constrained = constraint.bones; + int boneCount = constrained.Count; + for (int i = 0; i < boneCount; i++) + SortBone(constrained.Items[i]); + + updateCache.Add(constraint); + + for (int i = 0; i < boneCount; i++) + SortReset(constrained.Items[i].children); + for (int i = 0; i < boneCount; i++) + constrained.Items[i].sorted = true; + } + + private void SortTransformConstraint (TransformConstraint constraint) { + constraint.active = constraint.target.active + && (!constraint.data.skinRequired || (skin != null && skin.constraints.Contains(constraint.data))); + if (!constraint.active) return; + + SortBone(constraint.target); + + var constrained = constraint.bones; + int boneCount = constrained.Count; + if (constraint.data.local) { + for (int i = 0; i < boneCount; i++) { + Bone child = constrained.Items[i]; + SortBone(child.parent); + if (!updateCache.Contains(child)) updateCacheReset.Add(child); + } + } else { + for (int i = 0; i < boneCount; i++) + SortBone(constrained.Items[i]); + } + + updateCache.Add(constraint); + + for (int i = 0; i < boneCount; i++) + SortReset(constrained.Items[i].children); + for (int i = 0; i < boneCount; i++) + constrained.Items[i].sorted = true; + } + + private void SortPathConstraintAttachment (Skin skin, int slotIndex, Bone slotBone) { + foreach (var entryObj in skin.Attachments.Keys) { + var entry = (Skin.SkinEntry)entryObj; + if (entry.SlotIndex == slotIndex) SortPathConstraintAttachment(entry.Attachment, slotBone); + } + } + + private void SortPathConstraintAttachment (Attachment attachment, Bone slotBone) { + if (!(attachment is PathAttachment)) return; + int[] pathBones = ((PathAttachment)attachment).bones; + if (pathBones == null) + SortBone(slotBone); + else { + var bones = this.bones; + for (int i = 0, n = pathBones.Length; i < n;) { + int nn = pathBones[i++]; + nn += i; + while (i < nn) + SortBone(bones.Items[pathBones[i++]]); + } + } + } + + private void SortBone (Bone bone) { + if (bone.sorted) return; + Bone parent = bone.parent; + if (parent != null) SortBone(parent); + bone.sorted = true; + updateCache.Add(bone); + } + + private static void SortReset (ExposedList bones) { + var bonesItems = bones.Items; + for (int i = 0, n = bones.Count; i < n; i++) { + Bone bone = bonesItems[i]; + if (!bone.active) continue; + if (bone.sorted) SortReset(bone.children); + bone.sorted = false; + } + } + + /// Updates the world transform for each bone and applies constraints. + public void UpdateWorldTransform () { + var updateCacheReset = this.updateCacheReset; + var updateCacheResetItems = updateCacheReset.Items; + for (int i = 0, n = updateCacheReset.Count; i < n; i++) { + Bone bone = updateCacheResetItems[i]; + bone.ax = bone.x; + bone.ay = bone.y; + bone.arotation = bone.rotation; + bone.ascaleX = bone.scaleX; + bone.ascaleY = bone.scaleY; + bone.ashearX = bone.shearX; + bone.ashearY = bone.shearY; + bone.appliedValid = true; + } + var updateItems = this.updateCache.Items; + for (int i = 0, n = updateCache.Count; i < n; i++) + updateItems[i].Update(); + } + + /// + /// Temporarily sets the root bone as a child of the specified bone, then updates the world transform for each bone and applies + /// all constraints. + /// + public void UpdateWorldTransform (Bone parent) { + // This partial update avoids computing the world transform for constrained bones when 1) the bone is not updated + // before the constraint, 2) the constraint only needs to access the applied local transform, and 3) the constraint calls + // updateWorldTransform. + var updateCacheReset = this.updateCacheReset; + var updateCacheResetItems = updateCacheReset.Items; + for (int i = 0, n = updateCacheReset.Count; i < n; i++) { + Bone bone = updateCacheResetItems[i]; + bone.ax = bone.x; + bone.ay = bone.y; + bone.arotation = bone.rotation; + bone.ascaleX = bone.scaleX; + bone.ascaleY = bone.scaleY; + bone.ashearX = bone.shearX; + bone.ashearY = bone.shearY; + bone.appliedValid = true; + } + + // Apply the parent bone transform to the root bone. The root bone always inherits scale, rotation and reflection. + Bone rootBone = this.RootBone; + float pa = parent.a, pb = parent.b, pc = parent.c, pd = parent.d; + rootBone.worldX = pa * x + pb * y + parent.worldX; + rootBone.worldY = pc * x + pd * y + parent.worldY; + + float rotationY = rootBone.rotation + 90 + rootBone.shearY; + float la = MathUtils.CosDeg(rootBone.rotation + rootBone.shearX) * rootBone.scaleX; + float lb = MathUtils.CosDeg(rotationY) * rootBone.scaleY; + float lc = MathUtils.SinDeg(rootBone.rotation + rootBone.shearX) * rootBone.scaleX; + float ld = MathUtils.SinDeg(rotationY) * rootBone.scaleY; + rootBone.a = (pa * la + pb * lc) * scaleX; + rootBone.b = (pa * lb + pb * ld) * scaleX; + rootBone.c = (pc * la + pd * lc) * scaleY; + rootBone.d = (pc * lb + pd * ld) * scaleY; + + // Update everything except root bone. + var updateCache = this.updateCache; + var updateCacheItems = updateCache.Items; + for (int i = 0, n = updateCache.Count; i < n; i++) { + var updatable = updateCacheItems[i]; + if (updatable != rootBone) + updatable.Update(); + } + } + + /// Sets the bones, constraints, and slots to their setup pose values. + public void SetToSetupPose () { + SetBonesToSetupPose(); + SetSlotsToSetupPose(); + } + + /// Sets the bones and constraints to their setup pose values. + public void SetBonesToSetupPose () { + var bonesItems = this.bones.Items; + for (int i = 0, n = bones.Count; i < n; i++) + bonesItems[i].SetToSetupPose(); + + var ikConstraintsItems = this.ikConstraints.Items; + for (int i = 0, n = ikConstraints.Count; i < n; i++) { + IkConstraint constraint = ikConstraintsItems[i]; + constraint.mix = constraint.data.mix; + constraint.softness = constraint.data.softness; + constraint.bendDirection = constraint.data.bendDirection; + constraint.compress = constraint.data.compress; + constraint.stretch = constraint.data.stretch; + } + + var transformConstraintsItems = this.transformConstraints.Items; + for (int i = 0, n = transformConstraints.Count; i < n; i++) { + TransformConstraint constraint = transformConstraintsItems[i]; + TransformConstraintData constraintData = constraint.data; + constraint.rotateMix = constraintData.rotateMix; + constraint.translateMix = constraintData.translateMix; + constraint.scaleMix = constraintData.scaleMix; + constraint.shearMix = constraintData.shearMix; + } + + var pathConstraintItems = this.pathConstraints.Items; + for (int i = 0, n = pathConstraints.Count; i < n; i++) { + PathConstraint constraint = pathConstraintItems[i]; + PathConstraintData constraintData = constraint.data; + constraint.position = constraintData.position; + constraint.spacing = constraintData.spacing; + constraint.rotateMix = constraintData.rotateMix; + constraint.translateMix = constraintData.translateMix; + } + } + + public void SetSlotsToSetupPose () { + var slots = this.slots; + var slotsItems = slots.Items; + drawOrder.Clear(); + for (int i = 0, n = slots.Count; i < n; i++) + drawOrder.Add(slotsItems[i]); + + for (int i = 0, n = slots.Count; i < n; i++) + slotsItems[i].SetToSetupPose(); + } + + /// May be null. + public Bone FindBone (string boneName) { + if (boneName == null) throw new ArgumentNullException("boneName", "boneName cannot be null."); + var bones = this.bones; + var bonesItems = bones.Items; + for (int i = 0, n = bones.Count; i < n; i++) { + Bone bone = bonesItems[i]; + if (bone.data.name == boneName) return bone; + } + return null; + } + + /// -1 if the bone was not found. + public int FindBoneIndex (string boneName) { + if (boneName == null) throw new ArgumentNullException("boneName", "boneName cannot be null."); + var bones = this.bones; + var bonesItems = bones.Items; + for (int i = 0, n = bones.Count; i < n; i++) + if (bonesItems[i].data.name == boneName) return i; + return -1; + } + + /// May be null. + public Slot FindSlot (string slotName) { + if (slotName == null) throw new ArgumentNullException("slotName", "slotName cannot be null."); + var slots = this.slots; + var slotsItems = slots.Items; + for (int i = 0, n = slots.Count; i < n; i++) { + Slot slot = slotsItems[i]; + if (slot.data.name == slotName) return slot; + } + return null; + } + + /// -1 if the bone was not found. + public int FindSlotIndex (string slotName) { + if (slotName == null) throw new ArgumentNullException("slotName", "slotName cannot be null."); + var slots = this.slots; + var slotsItems = slots.Items; + for (int i = 0, n = slots.Count; i < n; i++) + if (slotsItems[i].data.name.Equals(slotName)) return i; + return -1; + } + + /// Sets a skin by name (see SetSkin). + public void SetSkin (string skinName) { + Skin foundSkin = data.FindSkin(skinName); + if (foundSkin == null) throw new ArgumentException("Skin not found: " + skinName, "skinName"); + SetSkin(foundSkin); + } + + /// + /// Sets the skin used to look up attachments before looking in the . If the + /// skin is changed, is called. + /// + /// Attachments from the new skin are attached if the corresponding attachment from the old skin was attached. + /// If there was no old skin, each slot's setup mode attachment is attached from the new skin. + /// + /// After changing the skin, the visible attachments can be reset to those attached in the setup pose by calling + /// . + /// Also, often is called before the next time the + /// skeleton is rendered to allow any attachment keys in the current animation(s) to hide or show attachments from the new skin. + /// + /// May be null. + public void SetSkin (Skin newSkin) { + if (newSkin == skin) return; + if (newSkin != null) { + if (skin != null) + newSkin.AttachAll(this, skin); + else { + ExposedList slots = this.slots; + for (int i = 0, n = slots.Count; i < n; i++) { + Slot slot = slots.Items[i]; + string name = slot.data.attachmentName; + if (name != null) { + Attachment attachment = newSkin.GetAttachment(i, name); + if (attachment != null) slot.Attachment = attachment; + } + } + } + } + skin = newSkin; + UpdateCache(); + } + + /// Finds an attachment by looking in the {@link #skin} and {@link SkeletonData#defaultSkin} using the slot name and attachment name. + /// May be null. + public Attachment GetAttachment (string slotName, string attachmentName) { + return GetAttachment(data.FindSlotIndex(slotName), attachmentName); + } + + /// Finds an attachment by looking in the skin and skeletonData.defaultSkin using the slot index and attachment name.First the skin is checked and if the attachment was not found, the default skin is checked. + /// May be null. + public Attachment GetAttachment (int slotIndex, string attachmentName) { + if (attachmentName == null) throw new ArgumentNullException("attachmentName", "attachmentName cannot be null."); + if (skin != null) { + Attachment attachment = skin.GetAttachment(slotIndex, attachmentName); + if (attachment != null) return attachment; + } + return data.defaultSkin != null ? data.defaultSkin.GetAttachment(slotIndex, attachmentName) : null; + } + + /// A convenience method to set an attachment by finding the slot with FindSlot, finding the attachment with GetAttachment, then setting the slot's slot.Attachment. + /// May be null to clear the slot's attachment. + public void SetAttachment (string slotName, string attachmentName) { + if (slotName == null) throw new ArgumentNullException("slotName", "slotName cannot be null."); + ExposedList slots = this.slots; + for (int i = 0, n = slots.Count; i < n; i++) { + Slot slot = slots.Items[i]; + if (slot.data.name == slotName) { + Attachment attachment = null; + if (attachmentName != null) { + attachment = GetAttachment(i, attachmentName); + if (attachment == null) throw new Exception("Attachment not found: " + attachmentName + ", for slot: " + slotName); + } + slot.Attachment = attachment; + return; + } + } + throw new Exception("Slot not found: " + slotName); + } + + /// May be null. + public IkConstraint FindIkConstraint (string constraintName) { + if (constraintName == null) throw new ArgumentNullException("constraintName", "constraintName cannot be null."); + ExposedList ikConstraints = this.ikConstraints; + for (int i = 0, n = ikConstraints.Count; i < n; i++) { + IkConstraint ikConstraint = ikConstraints.Items[i]; + if (ikConstraint.data.name == constraintName) return ikConstraint; + } + return null; + } + + /// May be null. + public TransformConstraint FindTransformConstraint (string constraintName) { + if (constraintName == null) throw new ArgumentNullException("constraintName", "constraintName cannot be null."); + ExposedList transformConstraints = this.transformConstraints; + for (int i = 0, n = transformConstraints.Count; i < n; i++) { + TransformConstraint transformConstraint = transformConstraints.Items[i]; + if (transformConstraint.data.Name == constraintName) return transformConstraint; + } + return null; + } + + /// May be null. + public PathConstraint FindPathConstraint (string constraintName) { + if (constraintName == null) throw new ArgumentNullException("constraintName", "constraintName cannot be null."); + ExposedList pathConstraints = this.pathConstraints; + for (int i = 0, n = pathConstraints.Count; i < n; i++) { + PathConstraint constraint = pathConstraints.Items[i]; + if (constraint.data.Name.Equals(constraintName)) return constraint; + } + return null; + } + + public void Update (float delta) { + time += delta; + } + + /// Returns the axis aligned bounding box (AABB) of the region and mesh attachments for the current pose. + /// The horizontal distance between the skeleton origin and the left side of the AABB. + /// The vertical distance between the skeleton origin and the bottom side of the AABB. + /// The width of the AABB + /// The height of the AABB. + /// Reference to hold a float[]. May be a null reference. This method will assign it a new float[] with the appropriate size as needed. + public void GetBounds (out float x, out float y, out float width, out float height, ref float[] vertexBuffer) { + float[] temp = vertexBuffer; + temp = temp ?? new float[8]; + var drawOrderItems = this.drawOrder.Items; + float minX = int.MaxValue, minY = int.MaxValue, maxX = int.MinValue, maxY = int.MinValue; + for (int i = 0, n = drawOrderItems.Length; i < n; i++) { + Slot slot = drawOrderItems[i]; + if (!slot.bone.active) continue; + int verticesLength = 0; + float[] vertices = null; + Attachment attachment = slot.attachment; + var regionAttachment = attachment as RegionAttachment; + if (regionAttachment != null) { + verticesLength = 8; + vertices = temp; + if (vertices.Length < 8) vertices = temp = new float[8]; + regionAttachment.ComputeWorldVertices(slot.bone, temp, 0); + } else { + var meshAttachment = attachment as MeshAttachment; + if (meshAttachment != null) { + MeshAttachment mesh = meshAttachment; + verticesLength = mesh.WorldVerticesLength; + vertices = temp; + if (vertices.Length < verticesLength) vertices = temp = new float[verticesLength]; + mesh.ComputeWorldVertices(slot, 0, verticesLength, temp, 0); + } + } + + if (vertices != null) { + for (int ii = 0; ii < verticesLength; ii += 2) { + float vx = vertices[ii], vy = vertices[ii + 1]; + minX = Math.Min(minX, vx); + minY = Math.Min(minY, vy); + maxX = Math.Max(maxX, vx); + maxY = Math.Max(maxY, vy); + } + } + } + x = minX; + y = minY; + width = maxX - minX; + height = maxY - minY; + vertexBuffer = temp; + } + } +} diff --git a/box1/Assets/Spine/Runtime/spine-csharp/Skeleton.cs.meta b/box1/Assets/Spine/Runtime/spine-csharp/Skeleton.cs.meta new file mode 100644 index 00000000..619d2ccb --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-csharp/Skeleton.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 12ac3c1c7546be24fb9625d3c850619d +timeCreated: 1456265153 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-csharp/SkeletonBinary.cs b/box1/Assets/Spine/Runtime/spine-csharp/SkeletonBinary.cs new file mode 100644 index 00000000..810c22b7 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-csharp/SkeletonBinary.cs @@ -0,0 +1,997 @@ +/****************************************************************************** + * 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_5 || UNITY_5_3_OR_NEWER || UNITY_WSA || UNITY_WP8 || UNITY_WP8_1) +#define IS_UNITY +#endif + +using System; +using System.IO; +using System.Collections.Generic; + +#if WINDOWS_STOREAPP +using System.Threading.Tasks; +using Windows.Storage; +#endif + +namespace Spine { + public class SkeletonBinary { + public const int BONE_ROTATE = 0; + public const int BONE_TRANSLATE = 1; + public const int BONE_SCALE = 2; + public const int BONE_SHEAR = 3; + + public const int SLOT_ATTACHMENT = 0; + public const int SLOT_COLOR = 1; + public const int SLOT_TWO_COLOR = 2; + + public const int PATH_POSITION = 0; + public const int PATH_SPACING = 1; + public const int PATH_MIX = 2; + + public const int CURVE_LINEAR = 0; + public const int CURVE_STEPPED = 1; + public const int CURVE_BEZIER = 2; + + public float Scale { get; set; } + + private AttachmentLoader attachmentLoader; + private List linkedMeshes = new List(); + + public SkeletonBinary (params Atlas[] atlasArray) + : this(new AtlasAttachmentLoader(atlasArray)) { + } + + public SkeletonBinary (AttachmentLoader attachmentLoader) { + if (attachmentLoader == null) throw new ArgumentNullException("attachmentLoader"); + this.attachmentLoader = attachmentLoader; + Scale = 1; + } + + #if !ISUNITY && WINDOWS_STOREAPP + private async Task ReadFile(string path) { + var folder = Windows.ApplicationModel.Package.Current.InstalledLocation; + using (var input = new BufferedStream(await folder.GetFileAsync(path).AsTask().ConfigureAwait(false))) { + SkeletonData skeletonData = ReadSkeletonData(input); + skeletonData.Name = Path.GetFileNameWithoutExtension(path); + return skeletonData; + } + } + + public SkeletonData ReadSkeletonData (String path) { + return this.ReadFile(path).Result; + } + #else + public SkeletonData ReadSkeletonData (String path) { + #if WINDOWS_PHONE + using (var input = new BufferedStream(Microsoft.Xna.Framework.TitleContainer.OpenStream(path))) { + #else + using (var input = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read)) { + #endif + SkeletonData skeletonData = ReadSkeletonData(input); + skeletonData.name = Path.GetFileNameWithoutExtension(path); + return skeletonData; + } + } + #endif // WINDOWS_STOREAPP + + public static readonly TransformMode[] TransformModeValues = { + TransformMode.Normal, + TransformMode.OnlyTranslation, + TransformMode.NoRotationOrReflection, + TransformMode.NoScale, + TransformMode.NoScaleOrReflection + }; + + /// Returns the version string of binary skeleton data. + public static string GetVersionString (Stream file) { + if (file == null) throw new ArgumentNullException("file"); + + SkeletonInput input = new SkeletonInput(file); + return input.GetVersionString(); + } + + public SkeletonData ReadSkeletonData (Stream file) { + if (file == null) throw new ArgumentNullException("file"); + float scale = Scale; + + var skeletonData = new SkeletonData(); + SkeletonInput input = new SkeletonInput(file); + + skeletonData.hash = input.ReadString(); + if (skeletonData.hash.Length == 0) skeletonData.hash = null; + skeletonData.version = input.ReadString(); + if (skeletonData.version.Length == 0) skeletonData.version = null; + if ("3.8.75" == skeletonData.version) + throw new Exception("Unsupported skeleton data, please export with a newer version of Spine."); + skeletonData.x = input.ReadFloat(); + skeletonData.y = input.ReadFloat(); + skeletonData.width = input.ReadFloat(); + skeletonData.height = input.ReadFloat(); + + bool nonessential = input.ReadBoolean(); + + if (nonessential) { + skeletonData.fps = input.ReadFloat(); + + skeletonData.imagesPath = input.ReadString(); + if (string.IsNullOrEmpty(skeletonData.imagesPath)) skeletonData.imagesPath = null; + + skeletonData.audioPath = input.ReadString(); + if (string.IsNullOrEmpty(skeletonData.audioPath)) skeletonData.audioPath = null; + } + + int n; + Object[] o; + + // Strings. + input.strings = new ExposedList(n = input.ReadInt(true)); + o = input.strings.Resize(n).Items; + for (int i = 0; i < n; i++) + o[i] = input.ReadString(); + + // Bones. + o = skeletonData.bones.Resize(n = input.ReadInt(true)).Items; + for (int i = 0; i < n; i++) { + String name = input.ReadString(); + BoneData parent = i == 0 ? null : skeletonData.bones.Items[input.ReadInt(true)]; + BoneData data = new BoneData(i, name, parent); + data.rotation = input.ReadFloat(); + data.x = input.ReadFloat() * scale; + data.y = input.ReadFloat() * scale; + data.scaleX = input.ReadFloat(); + data.scaleY = input.ReadFloat(); + data.shearX = input.ReadFloat(); + data.shearY = input.ReadFloat(); + data.length = input.ReadFloat() * scale; + data.transformMode = TransformModeValues[input.ReadInt(true)]; + data.skinRequired = input.ReadBoolean(); + if (nonessential) input.ReadInt(); // Skip bone color. + o[i] = data; + } + + // Slots. + o = skeletonData.slots.Resize(n = input.ReadInt(true)).Items; + for (int i = 0; i < n; i++) { + String slotName = input.ReadString(); + BoneData boneData = skeletonData.bones.Items[input.ReadInt(true)]; + SlotData slotData = new SlotData(i, slotName, boneData); + int color = input.ReadInt(); + slotData.r = ((color & 0xff000000) >> 24) / 255f; + slotData.g = ((color & 0x00ff0000) >> 16) / 255f; + slotData.b = ((color & 0x0000ff00) >> 8) / 255f; + slotData.a = ((color & 0x000000ff)) / 255f; + + int darkColor = input.ReadInt(); // 0x00rrggbb + if (darkColor != -1) { + slotData.hasSecondColor = true; + slotData.r2 = ((darkColor & 0x00ff0000) >> 16) / 255f; + slotData.g2 = ((darkColor & 0x0000ff00) >> 8) / 255f; + slotData.b2 = ((darkColor & 0x000000ff)) / 255f; + } + + slotData.attachmentName = input.ReadStringRef(); + slotData.blendMode = (BlendMode)input.ReadInt(true); + o[i] = slotData; + } + + // IK constraints. + o = skeletonData.ikConstraints.Resize(n = input.ReadInt(true)).Items; + for (int i = 0, nn; i < n; i++) { + IkConstraintData data = new IkConstraintData(input.ReadString()); + data.order = input.ReadInt(true); + data.skinRequired = input.ReadBoolean(); + Object[] bones = data.bones.Resize(nn = input.ReadInt(true)).Items; + for (int ii = 0; ii < nn; ii++) + bones[ii] = skeletonData.bones.Items[input.ReadInt(true)]; + data.target = skeletonData.bones.Items[input.ReadInt(true)]; + data.mix = input.ReadFloat(); + data.softness = input.ReadFloat() * scale; + data.bendDirection = input.ReadSByte(); + data.compress = input.ReadBoolean(); + data.stretch = input.ReadBoolean(); + data.uniform = input.ReadBoolean(); + o[i] = data; + } + + // Transform constraints. + o = skeletonData.transformConstraints.Resize(n = input.ReadInt(true)).Items; + for (int i = 0, nn; i < n; i++) { + TransformConstraintData data = new TransformConstraintData(input.ReadString()); + data.order = input.ReadInt(true); + data.skinRequired = input.ReadBoolean(); + Object[] bones = data.bones.Resize(nn = input.ReadInt(true)).Items; + for (int ii = 0; ii < nn; ii++) + bones[ii] = skeletonData.bones.Items[input.ReadInt(true)]; + data.target = skeletonData.bones.Items[input.ReadInt(true)]; + data.local = input.ReadBoolean(); + data.relative = input.ReadBoolean(); + data.offsetRotation = input.ReadFloat(); + data.offsetX = input.ReadFloat() * scale; + data.offsetY = input.ReadFloat() * scale; + data.offsetScaleX = input.ReadFloat(); + data.offsetScaleY = input.ReadFloat(); + data.offsetShearY = input.ReadFloat(); + data.rotateMix = input.ReadFloat(); + data.translateMix = input.ReadFloat(); + data.scaleMix = input.ReadFloat(); + data.shearMix = input.ReadFloat(); + o[i] = data; + } + + // Path constraints + o = skeletonData.pathConstraints.Resize(n = input.ReadInt(true)).Items; + for (int i = 0, nn; i < n; i++) { + PathConstraintData data = new PathConstraintData(input.ReadString()); + data.order = input.ReadInt(true); + data.skinRequired = input.ReadBoolean(); + Object[] bones = data.bones.Resize(nn = input.ReadInt(true)).Items; + for (int ii = 0; ii < nn; ii++) + bones[ii] = skeletonData.bones.Items[input.ReadInt(true)]; + data.target = skeletonData.slots.Items[input.ReadInt(true)]; + data.positionMode = (PositionMode)Enum.GetValues(typeof(PositionMode)).GetValue(input.ReadInt(true)); + data.spacingMode = (SpacingMode)Enum.GetValues(typeof(SpacingMode)).GetValue(input.ReadInt(true)); + data.rotateMode = (RotateMode)Enum.GetValues(typeof(RotateMode)).GetValue(input.ReadInt(true)); + data.offsetRotation = input.ReadFloat(); + data.position = input.ReadFloat(); + if (data.positionMode == PositionMode.Fixed) data.position *= scale; + data.spacing = input.ReadFloat(); + if (data.spacingMode == SpacingMode.Length || data.spacingMode == SpacingMode.Fixed) data.spacing *= scale; + data.rotateMix = input.ReadFloat(); + data.translateMix = input.ReadFloat(); + o[i] = data; + } + + // Default skin. + Skin defaultSkin = ReadSkin(input, skeletonData, true, nonessential); + if (defaultSkin != null) { + skeletonData.defaultSkin = defaultSkin; + skeletonData.skins.Add(defaultSkin); + } + + // Skins. + { + int i = skeletonData.skins.Count; + o = skeletonData.skins.Resize(n = i + input.ReadInt(true)).Items; + for (; i < n; i++) + o[i] = ReadSkin(input, skeletonData, false, nonessential); + } + + // Linked meshes. + n = linkedMeshes.Count; + for (int i = 0; i < n; i++) { + SkeletonJson.LinkedMesh linkedMesh = linkedMeshes[i]; + Skin skin = linkedMesh.skin == null ? skeletonData.DefaultSkin : skeletonData.FindSkin(linkedMesh.skin); + if (skin == null) throw new Exception("Skin not found: " + linkedMesh.skin); + Attachment parent = skin.GetAttachment(linkedMesh.slotIndex, linkedMesh.parent); + if (parent == null) throw new Exception("Parent mesh not found: " + linkedMesh.parent); + linkedMesh.mesh.DeformAttachment = linkedMesh.inheritDeform ? (VertexAttachment)parent : linkedMesh.mesh; + linkedMesh.mesh.ParentMesh = (MeshAttachment)parent; + linkedMesh.mesh.UpdateUVs(); + } + linkedMeshes.Clear(); + + // Events. + o = skeletonData.events.Resize(n = input.ReadInt(true)).Items; + for (int i = 0; i < n; i++) { + EventData data = new EventData(input.ReadStringRef()); + data.Int = input.ReadInt(false); + data.Float = input.ReadFloat(); + data.String = input.ReadString(); + data.AudioPath = input.ReadString(); + if (data.AudioPath != null) { + data.Volume = input.ReadFloat(); + data.Balance = input.ReadFloat(); + } + o[i] = data; + } + + // Animations. + o = skeletonData.animations.Resize(n = input.ReadInt(true)).Items; + for (int i = 0; i < n; i++) + o[i] = ReadAnimation(input.ReadString(), input, skeletonData); + + return skeletonData; + } + + + /// May be null. + private Skin ReadSkin (SkeletonInput input, SkeletonData skeletonData, bool defaultSkin, bool nonessential) { + + Skin skin; + int slotCount; + + if (defaultSkin) { + slotCount = input.ReadInt(true); + if (slotCount == 0) return null; + skin = new Skin("default"); + } else { + skin = new Skin(input.ReadStringRef()); + Object[] bones = skin.bones.Resize(input.ReadInt(true)).Items; + for (int i = 0, n = skin.bones.Count; i < n; i++) + bones[i] = skeletonData.bones.Items[input.ReadInt(true)]; + + for (int i = 0, n = input.ReadInt(true); i < n; i++) + skin.constraints.Add(skeletonData.ikConstraints.Items[input.ReadInt(true)]); + for (int i = 0, n = input.ReadInt(true); i < n; i++) + skin.constraints.Add(skeletonData.transformConstraints.Items[input.ReadInt(true)]); + for (int i = 0, n = input.ReadInt(true); i < n; i++) + skin.constraints.Add(skeletonData.pathConstraints.Items[input.ReadInt(true)]); + skin.constraints.TrimExcess(); + slotCount = input.ReadInt(true); + } + for (int i = 0; i < slotCount; i++) { + int slotIndex = input.ReadInt(true); + for (int ii = 0, nn = input.ReadInt(true); ii < nn; ii++) { + String name = input.ReadStringRef(); + Attachment attachment = ReadAttachment(input, skeletonData, skin, slotIndex, name, nonessential); + if (attachment != null) skin.SetAttachment(slotIndex, name, attachment); + } + } + return skin; + } + + private Attachment ReadAttachment (SkeletonInput input, SkeletonData skeletonData, Skin skin, int slotIndex, + String attachmentName, bool nonessential) { + + float scale = Scale; + + String name = input.ReadStringRef(); + if (name == null) name = attachmentName; + + AttachmentType type = (AttachmentType)input.ReadByte(); + switch (type) { + case AttachmentType.Region: { + String path = input.ReadStringRef(); + float rotation = input.ReadFloat(); + float x = input.ReadFloat(); + float y = input.ReadFloat(); + float scaleX = input.ReadFloat(); + float scaleY = input.ReadFloat(); + float width = input.ReadFloat(); + float height = input.ReadFloat(); + int color = input.ReadInt(); + + if (path == null) path = name; + RegionAttachment region = attachmentLoader.NewRegionAttachment(skin, name, path); + if (region == null) return null; + region.Path = path; + region.x = x * scale; + region.y = y * scale; + region.scaleX = scaleX; + region.scaleY = scaleY; + region.rotation = rotation; + region.width = width * scale; + region.height = height * scale; + region.r = ((color & 0xff000000) >> 24) / 255f; + region.g = ((color & 0x00ff0000) >> 16) / 255f; + region.b = ((color & 0x0000ff00) >> 8) / 255f; + region.a = ((color & 0x000000ff)) / 255f; + region.UpdateOffset(); + return region; + } + case AttachmentType.Boundingbox: { + int vertexCount = input.ReadInt(true); + Vertices vertices = ReadVertices(input, vertexCount); + if (nonessential) input.ReadInt(); //int color = nonessential ? input.ReadInt() : 0; // Avoid unused local warning. + + BoundingBoxAttachment box = attachmentLoader.NewBoundingBoxAttachment(skin, name); + if (box == null) return null; + box.worldVerticesLength = vertexCount << 1; + box.vertices = vertices.vertices; + box.bones = vertices.bones; + // skipped porting: if (nonessential) Color.rgba8888ToColor(box.getColor(), color); + return box; + } + case AttachmentType.Mesh: { + String path = input.ReadStringRef(); + int color = input.ReadInt(); + int vertexCount = input.ReadInt(true); + float[] uvs = ReadFloatArray(input, vertexCount << 1, 1); + int[] triangles = ReadShortArray(input); + Vertices vertices = ReadVertices(input, vertexCount); + int hullLength = input.ReadInt(true); + int[] edges = null; + float width = 0, height = 0; + if (nonessential) { + edges = ReadShortArray(input); + width = input.ReadFloat(); + height = input.ReadFloat(); + } + + if (path == null) path = name; + MeshAttachment mesh = attachmentLoader.NewMeshAttachment(skin, name, path); + if (mesh == null) return null; + mesh.Path = path; + mesh.r = ((color & 0xff000000) >> 24) / 255f; + mesh.g = ((color & 0x00ff0000) >> 16) / 255f; + mesh.b = ((color & 0x0000ff00) >> 8) / 255f; + mesh.a = ((color & 0x000000ff)) / 255f; + mesh.bones = vertices.bones; + mesh.vertices = vertices.vertices; + mesh.WorldVerticesLength = vertexCount << 1; + mesh.triangles = triangles; + mesh.regionUVs = uvs; + mesh.UpdateUVs(); + mesh.HullLength = hullLength << 1; + if (nonessential) { + mesh.Edges = edges; + mesh.Width = width * scale; + mesh.Height = height * scale; + } + return mesh; + } + case AttachmentType.Linkedmesh: { + String path = input.ReadStringRef(); + int color = input.ReadInt(); + String skinName = input.ReadStringRef(); + String parent = input.ReadStringRef(); + bool inheritDeform = input.ReadBoolean(); + float width = 0, height = 0; + if (nonessential) { + width = input.ReadFloat(); + height = input.ReadFloat(); + } + + if (path == null) path = name; + MeshAttachment mesh = attachmentLoader.NewMeshAttachment(skin, name, path); + if (mesh == null) return null; + mesh.Path = path; + mesh.r = ((color & 0xff000000) >> 24) / 255f; + mesh.g = ((color & 0x00ff0000) >> 16) / 255f; + mesh.b = ((color & 0x0000ff00) >> 8) / 255f; + mesh.a = ((color & 0x000000ff)) / 255f; + if (nonessential) { + mesh.Width = width * scale; + mesh.Height = height * scale; + } + linkedMeshes.Add(new SkeletonJson.LinkedMesh(mesh, skinName, slotIndex, parent, inheritDeform)); + return mesh; + } + case AttachmentType.Path: { + bool closed = input.ReadBoolean(); + bool constantSpeed = input.ReadBoolean(); + int vertexCount = input.ReadInt(true); + Vertices vertices = ReadVertices(input, vertexCount); + float[] lengths = new float[vertexCount / 3]; + for (int i = 0, n = lengths.Length; i < n; i++) + lengths[i] = input.ReadFloat() * scale; + if (nonessential) input.ReadInt(); //int color = nonessential ? input.ReadInt() : 0; + + PathAttachment path = attachmentLoader.NewPathAttachment(skin, name); + if (path == null) return null; + path.closed = closed; + path.constantSpeed = constantSpeed; + path.worldVerticesLength = vertexCount << 1; + path.vertices = vertices.vertices; + path.bones = vertices.bones; + path.lengths = lengths; + // skipped porting: if (nonessential) Color.rgba8888ToColor(path.getColor(), color); + return path; + } + case AttachmentType.Point: { + float rotation = input.ReadFloat(); + float x = input.ReadFloat(); + float y = input.ReadFloat(); + if (nonessential) input.ReadInt(); //int color = nonessential ? input.ReadInt() : 0; + + PointAttachment point = attachmentLoader.NewPointAttachment(skin, name); + if (point == null) return null; + point.x = x * scale; + point.y = y * scale; + point.rotation = rotation; + // skipped porting: if (nonessential) point.color = color; + return point; + } + case AttachmentType.Clipping: { + int endSlotIndex = input.ReadInt(true); + int vertexCount = input.ReadInt(true); + Vertices vertices = ReadVertices(input, vertexCount); + if (nonessential) input.ReadInt(); + + ClippingAttachment clip = attachmentLoader.NewClippingAttachment(skin, name); + if (clip == null) return null; + clip.EndSlot = skeletonData.slots.Items[endSlotIndex]; + clip.worldVerticesLength = vertexCount << 1; + clip.vertices = vertices.vertices; + clip.bones = vertices.bones; + // skipped porting: if (nonessential) Color.rgba8888ToColor(clip.getColor(), color); + return clip; + } + } + return null; + } + + private Vertices ReadVertices (SkeletonInput input, int vertexCount) { + float scale = Scale; + int verticesLength = vertexCount << 1; + Vertices vertices = new Vertices(); + if(!input.ReadBoolean()) { + vertices.vertices = ReadFloatArray(input, verticesLength, scale); + return vertices; + } + var weights = new ExposedList(verticesLength * 3 * 3); + var bonesArray = new ExposedList(verticesLength * 3); + for (int i = 0; i < vertexCount; i++) { + int boneCount = input.ReadInt(true); + bonesArray.Add(boneCount); + for (int ii = 0; ii < boneCount; ii++) { + bonesArray.Add(input.ReadInt(true)); + weights.Add(input.ReadFloat() * scale); + weights.Add(input.ReadFloat() * scale); + weights.Add(input.ReadFloat()); + } + } + + vertices.vertices = weights.ToArray(); + vertices.bones = bonesArray.ToArray(); + return vertices; + } + + private float[] ReadFloatArray (SkeletonInput input, int n, float scale) { + float[] array = new float[n]; + if (scale == 1) { + for (int i = 0; i < n; i++) + array[i] = input.ReadFloat(); + } else { + for (int i = 0; i < n; i++) + array[i] = input.ReadFloat() * scale; + } + return array; + } + + private int[] ReadShortArray (SkeletonInput input) { + int n = input.ReadInt(true); + int[] array = new int[n]; + for (int i = 0; i < n; i++) + array[i] = (input.ReadByte() << 8) | input.ReadByte(); + return array; + } + + private Animation ReadAnimation (String name, SkeletonInput input, SkeletonData skeletonData) { + var timelines = new ExposedList(32); + float scale = Scale; + float duration = 0; + + // Slot timelines. + for (int i = 0, n = input.ReadInt(true); i < n; i++) { + int slotIndex = input.ReadInt(true); + for (int ii = 0, nn = input.ReadInt(true); ii < nn; ii++) { + int timelineType = input.ReadByte(); + int frameCount = input.ReadInt(true); + switch (timelineType) { + case SLOT_ATTACHMENT: { + AttachmentTimeline timeline = new AttachmentTimeline(frameCount); + timeline.slotIndex = slotIndex; + for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) + timeline.SetFrame(frameIndex, input.ReadFloat(), input.ReadStringRef()); + timelines.Add(timeline); + duration = Math.Max(duration, timeline.frames[frameCount - 1]); + break; + } + case SLOT_COLOR: { + ColorTimeline timeline = new ColorTimeline(frameCount); + timeline.slotIndex = slotIndex; + for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) { + float time = input.ReadFloat(); + int color = input.ReadInt(); + float r = ((color & 0xff000000) >> 24) / 255f; + float g = ((color & 0x00ff0000) >> 16) / 255f; + float b = ((color & 0x0000ff00) >> 8) / 255f; + float a = ((color & 0x000000ff)) / 255f; + timeline.SetFrame(frameIndex, time, r, g, b, a); + if (frameIndex < frameCount - 1) ReadCurve(input, frameIndex, timeline); + } + timelines.Add(timeline); + duration = Math.Max(duration, timeline.frames[(frameCount - 1) * ColorTimeline.ENTRIES]); + break; + } + case SLOT_TWO_COLOR: { + TwoColorTimeline timeline = new TwoColorTimeline(frameCount); + timeline.slotIndex = slotIndex; + for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) { + float time = input.ReadFloat(); + int color = input.ReadInt(); + float r = ((color & 0xff000000) >> 24) / 255f; + float g = ((color & 0x00ff0000) >> 16) / 255f; + float b = ((color & 0x0000ff00) >> 8) / 255f; + float a = ((color & 0x000000ff)) / 255f; + int color2 = input.ReadInt(); // 0x00rrggbb + float r2 = ((color2 & 0x00ff0000) >> 16) / 255f; + float g2 = ((color2 & 0x0000ff00) >> 8) / 255f; + float b2 = ((color2 & 0x000000ff)) / 255f; + + timeline.SetFrame(frameIndex, time, r, g, b, a, r2, g2, b2); + if (frameIndex < frameCount - 1) ReadCurve(input, frameIndex, timeline); + } + timelines.Add(timeline); + duration = Math.Max(duration, timeline.frames[(frameCount - 1) * TwoColorTimeline.ENTRIES]); + break; + } + } + } + } + + // Bone timelines. + for (int i = 0, n = input.ReadInt(true); i < n; i++) { + int boneIndex = input.ReadInt(true); + for (int ii = 0, nn = input.ReadInt(true); ii < nn; ii++) { + int timelineType = input.ReadByte(); + int frameCount = input.ReadInt(true); + switch (timelineType) { + case BONE_ROTATE: { + RotateTimeline timeline = new RotateTimeline(frameCount); + timeline.boneIndex = boneIndex; + for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) { + timeline.SetFrame(frameIndex, input.ReadFloat(), input.ReadFloat()); + if (frameIndex < frameCount - 1) ReadCurve(input, frameIndex, timeline); + } + timelines.Add(timeline); + duration = Math.Max(duration, timeline.frames[(frameCount - 1) * RotateTimeline.ENTRIES]); + break; + } + case BONE_TRANSLATE: + case BONE_SCALE: + case BONE_SHEAR: { + TranslateTimeline timeline; + float timelineScale = 1; + if (timelineType == BONE_SCALE) + timeline = new ScaleTimeline(frameCount); + else if (timelineType == BONE_SHEAR) + timeline = new ShearTimeline(frameCount); + else { + timeline = new TranslateTimeline(frameCount); + timelineScale = scale; + } + timeline.boneIndex = boneIndex; + for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) { + timeline.SetFrame(frameIndex, input.ReadFloat(), input.ReadFloat() * timelineScale, + input.ReadFloat() * timelineScale); + if (frameIndex < frameCount - 1) ReadCurve(input, frameIndex, timeline); + } + timelines.Add(timeline); + duration = Math.Max(duration, timeline.frames[(frameCount - 1) * TranslateTimeline.ENTRIES]); + break; + } + } + } + } + + // IK constraint timelines. + for (int i = 0, n = input.ReadInt(true); i < n; i++) { + int index = input.ReadInt(true); + int frameCount = input.ReadInt(true); + IkConstraintTimeline timeline = new IkConstraintTimeline(frameCount) { + ikConstraintIndex = index + }; + for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) { + timeline.SetFrame(frameIndex, input.ReadFloat(), input.ReadFloat(), input.ReadFloat() * scale, input.ReadSByte(), input.ReadBoolean(), + input.ReadBoolean()); + if (frameIndex < frameCount - 1) ReadCurve(input, frameIndex, timeline); + } + timelines.Add(timeline); + duration = Math.Max(duration, timeline.frames[(frameCount - 1) * IkConstraintTimeline.ENTRIES]); + } + + // Transform constraint timelines. + for (int i = 0, n = input.ReadInt(true); i < n; i++) { + int index = input.ReadInt(true); + int frameCount = input.ReadInt(true); + TransformConstraintTimeline timeline = new TransformConstraintTimeline(frameCount); + timeline.transformConstraintIndex = index; + for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) { + timeline.SetFrame(frameIndex, input.ReadFloat(), input.ReadFloat(), input.ReadFloat(), input.ReadFloat(), + input.ReadFloat()); + if (frameIndex < frameCount - 1) ReadCurve(input, frameIndex, timeline); + } + timelines.Add(timeline); + duration = Math.Max(duration, timeline.frames[(frameCount - 1) * TransformConstraintTimeline.ENTRIES]); + } + + // Path constraint timelines. + for (int i = 0, n = input.ReadInt(true); i < n; i++) { + int index = input.ReadInt(true); + PathConstraintData data = skeletonData.pathConstraints.Items[index]; + for (int ii = 0, nn = input.ReadInt(true); ii < nn; ii++) { + int timelineType = input.ReadSByte(); + int frameCount = input.ReadInt(true); + switch(timelineType) { + case PATH_POSITION: + case PATH_SPACING: { + PathConstraintPositionTimeline timeline; + float timelineScale = 1; + if (timelineType == PATH_SPACING) { + timeline = new PathConstraintSpacingTimeline(frameCount); + if (data.spacingMode == SpacingMode.Length || data.spacingMode == SpacingMode.Fixed) timelineScale = scale; + } else { + timeline = new PathConstraintPositionTimeline(frameCount); + if (data.positionMode == PositionMode.Fixed) timelineScale = scale; + } + timeline.pathConstraintIndex = index; + for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) { + timeline.SetFrame(frameIndex, input.ReadFloat(), input.ReadFloat() * timelineScale); + if (frameIndex < frameCount - 1) ReadCurve(input, frameIndex, timeline); + } + timelines.Add(timeline); + duration = Math.Max(duration, timeline.frames[(frameCount - 1) * PathConstraintPositionTimeline.ENTRIES]); + break; + } + case PATH_MIX: { + PathConstraintMixTimeline timeline = new PathConstraintMixTimeline(frameCount); + timeline.pathConstraintIndex = index; + for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) { + timeline.SetFrame(frameIndex, input.ReadFloat(), input.ReadFloat(), input.ReadFloat()); + if (frameIndex < frameCount - 1) ReadCurve(input, frameIndex, timeline); + } + timelines.Add(timeline); + duration = Math.Max(duration, timeline.frames[(frameCount - 1) * PathConstraintMixTimeline.ENTRIES]); + break; + } + } + } + } + + // Deform timelines. + for (int i = 0, n = input.ReadInt(true); i < n; i++) { + Skin skin = skeletonData.skins.Items[input.ReadInt(true)]; + for (int ii = 0, nn = input.ReadInt(true); ii < nn; ii++) { + int slotIndex = input.ReadInt(true); + for (int iii = 0, nnn = input.ReadInt(true); iii < nnn; iii++) { + VertexAttachment attachment = (VertexAttachment)skin.GetAttachment(slotIndex, input.ReadStringRef()); + bool weighted = attachment.bones != null; + float[] vertices = attachment.vertices; + int deformLength = weighted ? vertices.Length / 3 * 2 : vertices.Length; + + int frameCount = input.ReadInt(true); + DeformTimeline timeline = new DeformTimeline(frameCount); + timeline.slotIndex = slotIndex; + timeline.attachment = attachment; + + for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) { + float time = input.ReadFloat(); + float[] deform; + int end = input.ReadInt(true); + if (end == 0) + deform = weighted ? new float[deformLength] : vertices; + else { + deform = new float[deformLength]; + int start = input.ReadInt(true); + end += start; + if (scale == 1) { + for (int v = start; v < end; v++) + deform[v] = input.ReadFloat(); + } else { + for (int v = start; v < end; v++) + deform[v] = input.ReadFloat() * scale; + } + if (!weighted) { + for (int v = 0, vn = deform.Length; v < vn; v++) + deform[v] += vertices[v]; + } + } + + timeline.SetFrame(frameIndex, time, deform); + if (frameIndex < frameCount - 1) ReadCurve(input, frameIndex, timeline); + } + timelines.Add(timeline); + duration = Math.Max(duration, timeline.frames[frameCount - 1]); + } + } + } + + // Draw order timeline. + int drawOrderCount = input.ReadInt(true); + if (drawOrderCount > 0) { + DrawOrderTimeline timeline = new DrawOrderTimeline(drawOrderCount); + int slotCount = skeletonData.slots.Count; + for (int i = 0; i < drawOrderCount; i++) { + float time = input.ReadFloat(); + int offsetCount = input.ReadInt(true); + int[] drawOrder = new int[slotCount]; + for (int ii = slotCount - 1; ii >= 0; ii--) + drawOrder[ii] = -1; + int[] unchanged = new int[slotCount - offsetCount]; + int originalIndex = 0, unchangedIndex = 0; + for (int ii = 0; ii < offsetCount; ii++) { + int slotIndex = input.ReadInt(true); + // Collect unchanged items. + while (originalIndex != slotIndex) + unchanged[unchangedIndex++] = originalIndex++; + // Set changed items. + drawOrder[originalIndex + input.ReadInt(true)] = originalIndex++; + } + // Collect remaining unchanged items. + while (originalIndex < slotCount) + unchanged[unchangedIndex++] = originalIndex++; + // Fill in unchanged items. + for (int ii = slotCount - 1; ii >= 0; ii--) + if (drawOrder[ii] == -1) drawOrder[ii] = unchanged[--unchangedIndex]; + timeline.SetFrame(i, time, drawOrder); + } + timelines.Add(timeline); + duration = Math.Max(duration, timeline.frames[drawOrderCount - 1]); + } + + // Event timeline. + int eventCount = input.ReadInt(true); + if (eventCount > 0) { + EventTimeline timeline = new EventTimeline(eventCount); + for (int i = 0; i < eventCount; i++) { + float time = input.ReadFloat(); + EventData eventData = skeletonData.events.Items[input.ReadInt(true)]; + Event e = new Event(time, eventData) { + Int = input.ReadInt(false), + Float = input.ReadFloat(), + String = input.ReadBoolean() ? input.ReadString() : eventData.String + }; + if (e.data.AudioPath != null) { + e.volume = input.ReadFloat(); + e.balance = input.ReadFloat(); + } + timeline.SetFrame(i, e); + } + timelines.Add(timeline); + duration = Math.Max(duration, timeline.frames[eventCount - 1]); + } + + timelines.TrimExcess(); + return new Animation(name, timelines, duration); + } + + private void ReadCurve (SkeletonInput input, int frameIndex, CurveTimeline timeline) { + switch (input.ReadByte()) { + case CURVE_STEPPED: + timeline.SetStepped(frameIndex); + break; + case CURVE_BEZIER: + timeline.SetCurve(frameIndex, input.ReadFloat(), input.ReadFloat(), input.ReadFloat(), input.ReadFloat()); + break; + } + } + + internal class Vertices + { + public int[] bones; + public float[] vertices; + } + + internal class SkeletonInput { + private byte[] chars = new byte[32]; + private byte[] bytesBigEndian = new byte[4]; + internal ExposedList strings; + Stream input; + + public SkeletonInput (Stream input) { + this.input = input; + } + + public byte ReadByte () { + return (byte)input.ReadByte(); + } + + public sbyte ReadSByte () { + int value = input.ReadByte(); + if (value == -1) throw new EndOfStreamException(); + return (sbyte)value; + } + + public bool ReadBoolean () { + return input.ReadByte() != 0; + } + + public float ReadFloat () { + input.Read(bytesBigEndian, 0, 4); + chars[3] = bytesBigEndian[0]; + chars[2] = bytesBigEndian[1]; + chars[1] = bytesBigEndian[2]; + chars[0] = bytesBigEndian[3]; + return BitConverter.ToSingle(chars, 0); + } + + public int ReadInt () { + input.Read(bytesBigEndian, 0, 4); + return (bytesBigEndian[0] << 24) + + (bytesBigEndian[1] << 16) + + (bytesBigEndian[2] << 8) + + bytesBigEndian[3]; + } + + public int ReadInt (bool optimizePositive) { + int b = input.ReadByte(); + int result = b & 0x7F; + if ((b & 0x80) != 0) { + b = input.ReadByte(); + result |= (b & 0x7F) << 7; + if ((b & 0x80) != 0) { + b = input.ReadByte(); + result |= (b & 0x7F) << 14; + if ((b & 0x80) != 0) { + b = input.ReadByte(); + result |= (b & 0x7F) << 21; + if ((b & 0x80) != 0) result |= (input.ReadByte() & 0x7F) << 28; + } + } + } + return optimizePositive ? result : ((result >> 1) ^ -(result & 1)); + } + + public string ReadString () { + int byteCount = ReadInt(true); + switch (byteCount) { + case 0: + return null; + case 1: + return ""; + } + byteCount--; + byte[] buffer = this.chars; + if (buffer.Length < byteCount) buffer = new byte[byteCount]; + ReadFully(buffer, 0, byteCount); + return System.Text.Encoding.UTF8.GetString(buffer, 0, byteCount); + } + + ///May be null. + public String ReadStringRef () { + int index = ReadInt(true); + return index == 0 ? null : strings.Items[index - 1]; + } + + public void ReadFully (byte[] buffer, int offset, int length) { + while (length > 0) { + int count = input.Read(buffer, offset, length); + if (count <= 0) throw new EndOfStreamException(); + offset += count; + length -= count; + } + } + + /// Returns the version string of binary skeleton data. + public string GetVersionString () { + try { + // Hash. + int byteCount = ReadInt(true); + if (byteCount > 1) input.Position += byteCount - 1; + + // Version. + byteCount = ReadInt(true); + if (byteCount > 1) { + byteCount--; + var buffer = new byte[byteCount]; + ReadFully(buffer, 0, byteCount); + return System.Text.Encoding.UTF8.GetString(buffer, 0, byteCount); + } + + throw new ArgumentException("Stream does not contain a valid binary Skeleton Data.", "input"); + } catch (Exception e) { + throw new ArgumentException("Stream does not contain a valid binary Skeleton Data.\n" + e, "input"); + } + } + } + } +} diff --git a/box1/Assets/Spine/Runtime/spine-csharp/SkeletonBinary.cs.meta b/box1/Assets/Spine/Runtime/spine-csharp/SkeletonBinary.cs.meta new file mode 100644 index 00000000..fd3aabcd --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-csharp/SkeletonBinary.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 40d8a8f15082f3844a5c9c8c3ef2047f +timeCreated: 1456265154 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-csharp/SkeletonBounds.cs b/box1/Assets/Spine/Runtime/spine-csharp/SkeletonBounds.cs new file mode 100644 index 00000000..fe247364 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-csharp/SkeletonBounds.cs @@ -0,0 +1,234 @@ +/****************************************************************************** + * 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; + +namespace Spine { + + /// + /// Collects each BoundingBoxAttachment that is visible and computes the world vertices for its polygon. + /// The polygon vertices are provided along with convenience methods for doing hit detection. + /// + public class SkeletonBounds { + private ExposedList polygonPool = new ExposedList(); + private float minX, minY, maxX, maxY; + + public ExposedList BoundingBoxes { get; private set; } + public ExposedList Polygons { get; private set; } + public float MinX { get { return minX; } set { minX = value; } } + public float MinY { get { return minY; } set { minY = value; } } + public float MaxX { get { return maxX; } set { maxX = value; } } + public float MaxY { get { return maxY; } set { maxY = value; } } + public float Width { get { return maxX - minX; } } + public float Height { get { return maxY - minY; } } + + public SkeletonBounds () { + BoundingBoxes = new ExposedList(); + Polygons = new ExposedList(); + } + + /// + /// Clears any previous polygons, finds all visible bounding box attachments, + /// and computes the world vertices for each bounding box's polygon. + /// The skeleton. + /// + /// If true, the axis aligned bounding box containing all the polygons is computed. + /// If false, the SkeletonBounds AABB methods will always return true. + /// + public void Update (Skeleton skeleton, bool updateAabb) { + ExposedList boundingBoxes = BoundingBoxes; + ExposedList polygons = Polygons; + ExposedList slots = skeleton.slots; + int slotCount = slots.Count; + + boundingBoxes.Clear(); + for (int i = 0, n = polygons.Count; i < n; i++) + polygonPool.Add(polygons.Items[i]); + polygons.Clear(); + + for (int i = 0; i < slotCount; i++) { + Slot slot = slots.Items[i]; + if (!slot.bone.active) continue; + BoundingBoxAttachment boundingBox = slot.attachment as BoundingBoxAttachment; + if (boundingBox == null) continue; + boundingBoxes.Add(boundingBox); + + Polygon polygon = null; + int poolCount = polygonPool.Count; + if (poolCount > 0) { + polygon = polygonPool.Items[poolCount - 1]; + polygonPool.RemoveAt(poolCount - 1); + } else + polygon = new Polygon(); + polygons.Add(polygon); + + int count = boundingBox.worldVerticesLength; + polygon.Count = count; + if (polygon.Vertices.Length < count) polygon.Vertices = new float[count]; + boundingBox.ComputeWorldVertices(slot, polygon.Vertices); + } + + if (updateAabb) { + AabbCompute(); + } else { + minX = int.MinValue; + minY = int.MinValue; + maxX = int.MaxValue; + maxY = int.MaxValue; + } + } + + private void AabbCompute () { + float minX = int.MaxValue, minY = int.MaxValue, maxX = int.MinValue, maxY = int.MinValue; + ExposedList polygons = Polygons; + for (int i = 0, n = polygons.Count; i < n; i++) { + Polygon polygon = polygons.Items[i]; + float[] vertices = polygon.Vertices; + for (int ii = 0, nn = polygon.Count; ii < nn; ii += 2) { + float x = vertices[ii]; + float y = vertices[ii + 1]; + minX = Math.Min(minX, x); + minY = Math.Min(minY, y); + maxX = Math.Max(maxX, x); + maxY = Math.Max(maxY, y); + } + } + this.minX = minX; + this.minY = minY; + this.maxX = maxX; + this.maxY = maxY; + } + + + /// Returns true if the axis aligned bounding box contains the point. + public bool AabbContainsPoint (float x, float y) { + return x >= minX && x <= maxX && y >= minY && y <= maxY; + } + + /// Returns true if the axis aligned bounding box intersects the line segment. + public bool AabbIntersectsSegment (float x1, float y1, float x2, float y2) { + float minX = this.minX; + float minY = this.minY; + float maxX = this.maxX; + float maxY = this.maxY; + if ((x1 <= minX && x2 <= minX) || (y1 <= minY && y2 <= minY) || (x1 >= maxX && x2 >= maxX) || (y1 >= maxY && y2 >= maxY)) + return false; + float m = (y2 - y1) / (x2 - x1); + float y = m * (minX - x1) + y1; + if (y > minY && y < maxY) return true; + y = m * (maxX - x1) + y1; + if (y > minY && y < maxY) return true; + float x = (minY - y1) / m + x1; + if (x > minX && x < maxX) return true; + x = (maxY - y1) / m + x1; + if (x > minX && x < maxX) return true; + return false; + } + + /// Returns true if the axis aligned bounding box intersects the axis aligned bounding box of the specified bounds. + public bool AabbIntersectsSkeleton (SkeletonBounds bounds) { + return minX < bounds.maxX && maxX > bounds.minX && minY < bounds.maxY && maxY > bounds.minY; + } + + /// Returns true if the polygon contains the point. + public bool ContainsPoint (Polygon polygon, float x, float y) { + float[] vertices = polygon.Vertices; + int nn = polygon.Count; + + int prevIndex = nn - 2; + bool inside = false; + for (int ii = 0; ii < nn; ii += 2) { + float vertexY = vertices[ii + 1]; + float prevY = vertices[prevIndex + 1]; + if ((vertexY < y && prevY >= y) || (prevY < y && vertexY >= y)) { + float vertexX = vertices[ii]; + if (vertexX + (y - vertexY) / (prevY - vertexY) * (vertices[prevIndex] - vertexX) < x) inside = !inside; + } + prevIndex = ii; + } + return inside; + } + + /// Returns the first bounding box attachment that contains the point, or null. When doing many checks, it is usually more + /// efficient to only call this method if {@link #aabbContainsPoint(float, float)} returns true. + public BoundingBoxAttachment ContainsPoint (float x, float y) { + ExposedList polygons = Polygons; + for (int i = 0, n = polygons.Count; i < n; i++) + if (ContainsPoint(polygons.Items[i], x, y)) return BoundingBoxes.Items[i]; + return null; + } + + /// Returns the first bounding box attachment that contains the line segment, or null. When doing many checks, it is usually + /// more efficient to only call this method if {@link #aabbIntersectsSegment(float, float, float, float)} returns true. + public BoundingBoxAttachment IntersectsSegment (float x1, float y1, float x2, float y2) { + ExposedList polygons = Polygons; + for (int i = 0, n = polygons.Count; i < n; i++) + if (IntersectsSegment(polygons.Items[i], x1, y1, x2, y2)) return BoundingBoxes.Items[i]; + return null; + } + + /// Returns true if the polygon contains the line segment. + public bool IntersectsSegment (Polygon polygon, float x1, float y1, float x2, float y2) { + float[] vertices = polygon.Vertices; + int nn = polygon.Count; + + float width12 = x1 - x2, height12 = y1 - y2; + float det1 = x1 * y2 - y1 * x2; + float x3 = vertices[nn - 2], y3 = vertices[nn - 1]; + for (int ii = 0; ii < nn; ii += 2) { + float x4 = vertices[ii], y4 = vertices[ii + 1]; + float det2 = x3 * y4 - y3 * x4; + float width34 = x3 - x4, height34 = y3 - y4; + float det3 = width12 * height34 - height12 * width34; + float x = (det1 * width34 - width12 * det2) / det3; + if (((x >= x3 && x <= x4) || (x >= x4 && x <= x3)) && ((x >= x1 && x <= x2) || (x >= x2 && x <= x1))) { + float y = (det1 * height34 - height12 * det2) / det3; + if (((y >= y3 && y <= y4) || (y >= y4 && y <= y3)) && ((y >= y1 && y <= y2) || (y >= y2 && y <= y1))) return true; + } + x3 = x4; + y3 = y4; + } + return false; + } + + public Polygon GetPolygon (BoundingBoxAttachment attachment) { + int index = BoundingBoxes.IndexOf(attachment); + return index == -1 ? null : Polygons.Items[index]; + } + } + + public class Polygon { + public float[] Vertices { get; set; } + public int Count { get; set; } + + public Polygon () { + Vertices = new float[16]; + } + } +} diff --git a/box1/Assets/Spine/Runtime/spine-csharp/SkeletonBounds.cs.meta b/box1/Assets/Spine/Runtime/spine-csharp/SkeletonBounds.cs.meta new file mode 100644 index 00000000..db6a2d1a --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-csharp/SkeletonBounds.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 087b328a58c93b149bb977eee3a17258 +timeCreated: 1456265153 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-csharp/SkeletonClipping.cs b/box1/Assets/Spine/Runtime/spine-csharp/SkeletonClipping.cs new file mode 100644 index 00000000..40b6036a --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-csharp/SkeletonClipping.cs @@ -0,0 +1,296 @@ +/****************************************************************************** + * 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; + +namespace Spine { + public class SkeletonClipping { + internal readonly Triangulator triangulator = new Triangulator(); + internal readonly ExposedList clippingPolygon = new ExposedList(); + internal readonly ExposedList clipOutput = new ExposedList(128); + internal readonly ExposedList clippedVertices = new ExposedList(128); + internal readonly ExposedList clippedTriangles = new ExposedList(128); + internal readonly ExposedList clippedUVs = new ExposedList(128); + internal readonly ExposedList scratch = new ExposedList(); + + internal ClippingAttachment clipAttachment; + internal ExposedList> clippingPolygons; + + public ExposedList ClippedVertices { get { return clippedVertices; } } + public ExposedList ClippedTriangles { get { return clippedTriangles; } } + public ExposedList ClippedUVs { get { return clippedUVs; } } + + public bool IsClipping { get { return clipAttachment != null; } } + + public int ClipStart (Slot slot, ClippingAttachment clip) { + if (clipAttachment != null) return 0; + clipAttachment = clip; + + int n = clip.worldVerticesLength; + float[] vertices = clippingPolygon.Resize(n).Items; + clip.ComputeWorldVertices(slot, 0, n, vertices, 0, 2); + MakeClockwise(clippingPolygon); + clippingPolygons = triangulator.Decompose(clippingPolygon, triangulator.Triangulate(clippingPolygon)); + foreach (var polygon in clippingPolygons) { + MakeClockwise(polygon); + polygon.Add(polygon.Items[0]); + polygon.Add(polygon.Items[1]); + } + return clippingPolygons.Count; + } + + public void ClipEnd (Slot slot) { + if (clipAttachment != null && clipAttachment.endSlot == slot.data) ClipEnd(); + } + + public void ClipEnd () { + if (clipAttachment == null) return; + clipAttachment = null; + clippingPolygons = null; + clippedVertices.Clear(); + clippedTriangles.Clear(); + clippingPolygon.Clear(); + } + + public void ClipTriangles (float[] vertices, int verticesLength, int[] triangles, int trianglesLength, float[] uvs) { + ExposedList clipOutput = this.clipOutput, clippedVertices = this.clippedVertices; + var clippedTriangles = this.clippedTriangles; + var polygons = clippingPolygons.Items; + int polygonsCount = clippingPolygons.Count; + + int index = 0; + clippedVertices.Clear(); + clippedUVs.Clear(); + clippedTriangles.Clear(); + //outer: + for (int i = 0; i < trianglesLength; i += 3) { + int vertexOffset = triangles[i] << 1; + float x1 = vertices[vertexOffset], y1 = vertices[vertexOffset + 1]; + float u1 = uvs[vertexOffset], v1 = uvs[vertexOffset + 1]; + + vertexOffset = triangles[i + 1] << 1; + float x2 = vertices[vertexOffset], y2 = vertices[vertexOffset + 1]; + float u2 = uvs[vertexOffset], v2 = uvs[vertexOffset + 1]; + + vertexOffset = triangles[i + 2] << 1; + float x3 = vertices[vertexOffset], y3 = vertices[vertexOffset + 1]; + float u3 = uvs[vertexOffset], v3 = uvs[vertexOffset + 1]; + + for (int p = 0; p < polygonsCount; p++) { + int s = clippedVertices.Count; + if (Clip(x1, y1, x2, y2, x3, y3, polygons[p], clipOutput)) { + int clipOutputLength = clipOutput.Count; + if (clipOutputLength == 0) continue; + float d0 = y2 - y3, d1 = x3 - x2, d2 = x1 - x3, d4 = y3 - y1; + float d = 1 / (d0 * d2 + d1 * (y1 - y3)); + + int clipOutputCount = clipOutputLength >> 1; + float[] clipOutputItems = clipOutput.Items; + float[] clippedVerticesItems = clippedVertices.Resize(s + clipOutputCount * 2).Items; + float[] clippedUVsItems = clippedUVs.Resize(s + clipOutputCount * 2).Items; + for (int ii = 0; ii < clipOutputLength; ii += 2) { + float x = clipOutputItems[ii], y = clipOutputItems[ii + 1]; + clippedVerticesItems[s] = x; + clippedVerticesItems[s + 1] = y; + float c0 = x - x3, c1 = y - y3; + float a = (d0 * c0 + d1 * c1) * d; + float b = (d4 * c0 + d2 * c1) * d; + float c = 1 - a - b; + clippedUVsItems[s] = u1 * a + u2 * b + u3 * c; + clippedUVsItems[s + 1] = v1 * a + v2 * b + v3 * c; + s += 2; + } + + s = clippedTriangles.Count; + int[] clippedTrianglesItems = clippedTriangles.Resize(s + 3 * (clipOutputCount - 2)).Items; + clipOutputCount--; + for (int ii = 1; ii < clipOutputCount; ii++) { + clippedTrianglesItems[s] = index; + clippedTrianglesItems[s + 1] = index + ii; + clippedTrianglesItems[s + 2] = index + ii + 1; + s += 3; + } + index += clipOutputCount + 1; + } + else { + float[] clippedVerticesItems = clippedVertices.Resize(s + 3 * 2).Items; + float[] clippedUVsItems = clippedUVs.Resize(s + 3 * 2).Items; + clippedVerticesItems[s] = x1; + clippedVerticesItems[s + 1] = y1; + clippedVerticesItems[s + 2] = x2; + clippedVerticesItems[s + 3] = y2; + clippedVerticesItems[s + 4] = x3; + clippedVerticesItems[s + 5] = y3; + + clippedUVsItems[s] = u1; + clippedUVsItems[s + 1] = v1; + clippedUVsItems[s + 2] = u2; + clippedUVsItems[s + 3] = v2; + clippedUVsItems[s + 4] = u3; + clippedUVsItems[s + 5] = v3; + + s = clippedTriangles.Count; + int[] clippedTrianglesItems = clippedTriangles.Resize(s + 3).Items; + clippedTrianglesItems[s] = index; + clippedTrianglesItems[s + 1] = index + 1; + clippedTrianglesItems[s + 2] = index + 2; + index += 3; + break; //continue outer; + } + } + } + + } + + /** Clips the input triangle against the convex, clockwise clipping area. If the triangle lies entirely within the clipping + * area, false is returned. The clipping area must duplicate the first vertex at the end of the vertices list. */ + internal bool Clip (float x1, float y1, float x2, float y2, float x3, float y3, ExposedList clippingArea, ExposedList output) { + var originalOutput = output; + var clipped = false; + + // Avoid copy at the end. + ExposedList input = null; + if (clippingArea.Count % 4 >= 2) { + input = output; + output = scratch; + } else { + input = scratch; + } + + input.Clear(); + input.Add(x1); + input.Add(y1); + input.Add(x2); + input.Add(y2); + input.Add(x3); + input.Add(y3); + input.Add(x1); + input.Add(y1); + output.Clear(); + + float[] clippingVertices = clippingArea.Items; + int clippingVerticesLast = clippingArea.Count - 4; + for (int i = 0; ; i += 2) { + float edgeX = clippingVertices[i], edgeY = clippingVertices[i + 1]; + float edgeX2 = clippingVertices[i + 2], edgeY2 = clippingVertices[i + 3]; + float deltaX = edgeX - edgeX2, deltaY = edgeY - edgeY2; + + float[] inputVertices = input.Items; + int inputVerticesLength = input.Count - 2, outputStart = output.Count; + for (int ii = 0; ii < inputVerticesLength; ii += 2) { + float inputX = inputVertices[ii], inputY = inputVertices[ii + 1]; + float inputX2 = inputVertices[ii + 2], inputY2 = inputVertices[ii + 3]; + bool side2 = deltaX * (inputY2 - edgeY2) - deltaY * (inputX2 - edgeX2) > 0; + if (deltaX * (inputY - edgeY2) - deltaY * (inputX - edgeX2) > 0) { + if (side2) { // v1 inside, v2 inside + output.Add(inputX2); + output.Add(inputY2); + continue; + } + // v1 inside, v2 outside + float c0 = inputY2 - inputY, c2 = inputX2 - inputX; + float s = c0 * (edgeX2 - edgeX) - c2 * (edgeY2 - edgeY); + if (Math.Abs(s) > 0.000001f) { + float ua = (c2 * (edgeY - inputY) - c0 * (edgeX - inputX)) / s; + output.Add(edgeX + (edgeX2 - edgeX) * ua); + output.Add(edgeY + (edgeY2 - edgeY) * ua); + } else { + output.Add(edgeX); + output.Add(edgeY); + } + } + else if (side2) { // v1 outside, v2 inside + float c0 = inputY2 - inputY, c2 = inputX2 - inputX; + float s = c0 * (edgeX2 - edgeX) - c2 * (edgeY2 - edgeY); + if (Math.Abs(s) > 0.000001f) { + float ua = (c2 * (edgeY - inputY) - c0 * (edgeX - inputX)) / s; + output.Add(edgeX + (edgeX2 - edgeX) * ua); + output.Add(edgeY + (edgeY2 - edgeY) * ua); + } else { + output.Add(edgeX); + output.Add(edgeY); + } + output.Add(inputX2); + output.Add(inputY2); + } + clipped = true; + } + + if (outputStart == output.Count) { // All edges outside. + originalOutput.Clear(); + return true; + } + + output.Add(output.Items[0]); + output.Add(output.Items[1]); + + if (i == clippingVerticesLast) break; + var temp = output; + output = input; + output.Clear(); + input = temp; + } + + if (originalOutput != output) { + originalOutput.Clear(); + for (int i = 0, n = output.Count - 2; i < n; i++) { + originalOutput.Add(output.Items[i]); + } + } else { + originalOutput.Resize(originalOutput.Count - 2); + } + + return clipped; + } + + public static void MakeClockwise (ExposedList polygon) { + float[] vertices = polygon.Items; + int verticeslength = polygon.Count; + + float area = vertices[verticeslength - 2] * vertices[1] - vertices[0] * vertices[verticeslength - 1], p1x, p1y, p2x, p2y; + for (int i = 0, n = verticeslength - 3; i < n; i += 2) { + p1x = vertices[i]; + p1y = vertices[i + 1]; + p2x = vertices[i + 2]; + p2y = vertices[i + 3]; + area += p1x * p2y - p2x * p1y; + } + if (area < 0) return; + + for (int i = 0, lastX = verticeslength - 2, n = verticeslength >> 1; i < n; i += 2) { + float x = vertices[i], y = vertices[i + 1]; + int other = lastX - i; + vertices[i] = vertices[other]; + vertices[i + 1] = vertices[other + 1]; + vertices[other] = x; + vertices[other + 1] = y; + } + } + } +} diff --git a/box1/Assets/Spine/Runtime/spine-csharp/SkeletonClipping.cs.meta b/box1/Assets/Spine/Runtime/spine-csharp/SkeletonClipping.cs.meta new file mode 100644 index 00000000..73ecd0d5 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-csharp/SkeletonClipping.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 7db809d277afd0e4a8e8c6b703002ee0 +timeCreated: 1492744746 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-csharp/SkeletonData.cs b/box1/Assets/Spine/Runtime/spine-csharp/SkeletonData.cs new file mode 100644 index 00000000..05ec2722 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-csharp/SkeletonData.cs @@ -0,0 +1,230 @@ +/****************************************************************************** + * 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; + +namespace Spine { + + /// Stores the setup pose and all of the stateless data for a skeleton. + public class SkeletonData { + internal string name; + internal ExposedList bones = new ExposedList(); // Ordered parents first + internal ExposedList slots = new ExposedList(); // Setup pose draw order. + internal ExposedList skins = new ExposedList(); + internal Skin defaultSkin; + internal ExposedList events = new ExposedList(); + internal ExposedList animations = new ExposedList(); + internal ExposedList ikConstraints = new ExposedList(); + internal ExposedList transformConstraints = new ExposedList(); + internal ExposedList pathConstraints = new ExposedList(); + internal float x , y, width, height; + internal string version, hash; + + // Nonessential. + internal float fps; + internal string imagesPath, audioPath; + + public string Name { get { return name; } set { name = value; } } + + /// The skeleton's bones, sorted parent first. The root bone is always the first bone. + public ExposedList Bones { get { return bones; } } + + public ExposedList Slots { get { return slots; } } + + /// All skins, including the default skin. + public ExposedList Skins { get { return skins; } set { skins = value; } } + + /// + /// The skeleton's default skin. + /// By default this skin contains all attachments that were not in a skin in Spine. + /// + /// May be null. + public Skin DefaultSkin { get { return defaultSkin; } set { defaultSkin = value; } } + + public ExposedList Events { get { return events; } set { events = value; } } + public ExposedList Animations { get { return animations; } set { animations = value; } } + public ExposedList IkConstraints { get { return ikConstraints; } set { ikConstraints = value; } } + public ExposedList TransformConstraints { get { return transformConstraints; } set { transformConstraints = value; } } + public ExposedList PathConstraints { get { return pathConstraints; } set { pathConstraints = value; } } + + public float X { get { return x; } set { x = value; } } + public float Y { get { return y; } set { y = value; } } + public float Width { get { return width; } set { width = value; } } + public float Height { get { return height; } set { height = value; } } + /// The Spine version used to export this data, or null. + public string Version { get { return version; } set { version = value; } } + public string Hash { get { return hash; } set { hash = value; } } + + /// The path to the images directory as defined in Spine. Available only when nonessential data was exported. May be null + public string ImagesPath { get { return imagesPath; } set { imagesPath = value; } } + + /// The path to the audio directory defined in Spine. Available only when nonessential data was exported. May be null. + public string AudioPath { get { return audioPath; } set { audioPath = value; } } + + /// + /// The dopesheet FPS in Spine. Available only when nonessential data was exported. + public float Fps { get { return fps; } set { fps = value; } } + + // --- Bones. + + /// + /// Finds a bone by comparing each bone's name. + /// It is more efficient to cache the results of this method than to call it multiple times. + /// May be null. + public BoneData FindBone (string boneName) { + if (boneName == null) throw new ArgumentNullException("boneName", "boneName cannot be null."); + var bones = this.bones; + var bonesItems = bones.Items; + for (int i = 0, n = bones.Count; i < n; i++) { + BoneData bone = bonesItems[i]; + if (bone.name == boneName) return bone; + } + return null; + } + + /// -1 if the bone was not found. + public int FindBoneIndex (string boneName) { + if (boneName == null) throw new ArgumentNullException("boneName", "boneName cannot be null."); + var bones = this.bones; + var bonesItems = bones.Items; + for (int i = 0, n = bones.Count; i < n; i++) + if (bonesItems[i].name == boneName) return i; + return -1; + } + + // --- Slots. + + /// May be null. + public SlotData FindSlot (string slotName) { + if (slotName == null) throw new ArgumentNullException("slotName", "slotName cannot be null."); + ExposedList slots = this.slots; + for (int i = 0, n = slots.Count; i < n; i++) { + SlotData slot = slots.Items[i]; + if (slot.name == slotName) return slot; + } + return null; + } + + /// -1 if the slot was not found. + public int FindSlotIndex (string slotName) { + if (slotName == null) throw new ArgumentNullException("slotName", "slotName cannot be null."); + ExposedList slots = this.slots; + for (int i = 0, n = slots.Count; i < n; i++) + if (slots.Items[i].name == slotName) return i; + return -1; + } + + // --- Skins. + + /// May be null. + public Skin FindSkin (string skinName) { + if (skinName == null) throw new ArgumentNullException("skinName", "skinName cannot be null."); + foreach (Skin skin in skins) + if (skin.name == skinName) return skin; + return null; + } + + // --- Events. + + /// May be null. + public EventData FindEvent (string eventDataName) { + if (eventDataName == null) throw new ArgumentNullException("eventDataName", "eventDataName cannot be null."); + foreach (EventData eventData in events) + if (eventData.name == eventDataName) return eventData; + return null; + } + + // --- Animations. + + /// May be null. + public Animation FindAnimation (string animationName) { + if (animationName == null) throw new ArgumentNullException("animationName", "animationName cannot be null."); + ExposedList animations = this.animations; + for (int i = 0, n = animations.Count; i < n; i++) { + Animation animation = animations.Items[i]; + if (animation.name == animationName) return animation; + } + return null; + } + + // --- IK constraints. + + /// May be null. + public IkConstraintData FindIkConstraint (string constraintName) { + if (constraintName == null) throw new ArgumentNullException("constraintName", "constraintName cannot be null."); + ExposedList ikConstraints = this.ikConstraints; + for (int i = 0, n = ikConstraints.Count; i < n; i++) { + IkConstraintData ikConstraint = ikConstraints.Items[i]; + if (ikConstraint.name == constraintName) return ikConstraint; + } + return null; + } + + // --- Transform constraints. + + /// May be null. + public TransformConstraintData FindTransformConstraint (string constraintName) { + if (constraintName == null) throw new ArgumentNullException("constraintName", "constraintName cannot be null."); + ExposedList transformConstraints = this.transformConstraints; + for (int i = 0, n = transformConstraints.Count; i < n; i++) { + TransformConstraintData transformConstraint = transformConstraints.Items[i]; + if (transformConstraint.name == constraintName) return transformConstraint; + } + return null; + } + + // --- Path constraints. + + /// May be null. + public PathConstraintData FindPathConstraint (string constraintName) { + if (constraintName == null) throw new ArgumentNullException("constraintName", "constraintName cannot be null."); + ExposedList pathConstraints = this.pathConstraints; + for (int i = 0, n = pathConstraints.Count; i < n; i++) { + PathConstraintData constraint = pathConstraints.Items[i]; + if (constraint.name.Equals(constraintName)) return constraint; + } + return null; + } + + /// -1 if the path constraint was not found. + public int FindPathConstraintIndex (string pathConstraintName) { + if (pathConstraintName == null) throw new ArgumentNullException("pathConstraintName", "pathConstraintName cannot be null."); + ExposedList pathConstraints = this.pathConstraints; + for (int i = 0, n = pathConstraints.Count; i < n; i++) + if (pathConstraints.Items[i].name.Equals(pathConstraintName)) return i; + return -1; + } + + // --- + + override public string ToString () { + return name ?? base.ToString(); + } + } +} diff --git a/box1/Assets/Spine/Runtime/spine-csharp/SkeletonData.cs.meta b/box1/Assets/Spine/Runtime/spine-csharp/SkeletonData.cs.meta new file mode 100644 index 00000000..579186e3 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-csharp/SkeletonData.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 2b813f63abbb6d94a80a5c050590a0be +timeCreated: 1456265153 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-csharp/SkeletonJson.cs b/box1/Assets/Spine/Runtime/spine-csharp/SkeletonJson.cs new file mode 100644 index 00000000..de7f2367 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-csharp/SkeletonJson.cs @@ -0,0 +1,918 @@ +/****************************************************************************** + * 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_5 || UNITY_5_3_OR_NEWER || UNITY_WSA || UNITY_WP8 || UNITY_WP8_1) +#define IS_UNITY +#endif + +using System; +using System.IO; +using System.Collections.Generic; + +#if WINDOWS_STOREAPP +using System.Threading.Tasks; +using Windows.Storage; +#endif + +namespace Spine { + public class SkeletonJson { + public float Scale { get; set; } + + private AttachmentLoader attachmentLoader; + private List linkedMeshes = new List(); + + public SkeletonJson (params Atlas[] atlasArray) + : this(new AtlasAttachmentLoader(atlasArray)) { + } + + public SkeletonJson (AttachmentLoader attachmentLoader) { + if (attachmentLoader == null) throw new ArgumentNullException("attachmentLoader", "attachmentLoader cannot be null."); + this.attachmentLoader = attachmentLoader; + Scale = 1; + } + + #if !IS_UNITY && WINDOWS_STOREAPP + private async Task ReadFile(string path) { + var folder = Windows.ApplicationModel.Package.Current.InstalledLocation; + var file = await folder.GetFileAsync(path).AsTask().ConfigureAwait(false); + using (var reader = new StreamReader(await file.OpenStreamForReadAsync().ConfigureAwait(false))) { + SkeletonData skeletonData = ReadSkeletonData(reader); + skeletonData.Name = Path.GetFileNameWithoutExtension(path); + return skeletonData; + } + } + + public SkeletonData ReadSkeletonData (string path) { + return this.ReadFile(path).Result; + } + #else + public SkeletonData ReadSkeletonData (string path) { + #if WINDOWS_PHONE + using (var reader = new StreamReader(Microsoft.Xna.Framework.TitleContainer.OpenStream(path))) { + #else + using (var reader = new StreamReader(new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read))) { + #endif + SkeletonData skeletonData = ReadSkeletonData(reader); + skeletonData.name = Path.GetFileNameWithoutExtension(path); + return skeletonData; + } + } + #endif + + public SkeletonData ReadSkeletonData (TextReader reader) { + if (reader == null) throw new ArgumentNullException("reader", "reader cannot be null."); + + float scale = this.Scale; + var skeletonData = new SkeletonData(); + + var root = Json.Deserialize(reader) as Dictionary; + if (root == null) throw new Exception("Invalid JSON."); + + // Skeleton. + if (root.ContainsKey("skeleton")) { + var skeletonMap = (Dictionary)root["skeleton"]; + skeletonData.hash = (string)skeletonMap["hash"]; + skeletonData.version = (string)skeletonMap["spine"]; + if ("3.8.75" == skeletonData.version) + throw new Exception("Unsupported skeleton data, please export with a newer version of Spine."); + skeletonData.x = GetFloat(skeletonMap, "x", 0); + skeletonData.y = GetFloat(skeletonMap, "y", 0); + skeletonData.width = GetFloat(skeletonMap, "width", 0); + skeletonData.height = GetFloat(skeletonMap, "height", 0); + skeletonData.fps = GetFloat(skeletonMap, "fps", 30); + skeletonData.imagesPath = GetString(skeletonMap, "images", null); + skeletonData.audioPath = GetString(skeletonMap, "audio", null); + } + + // Bones. + if (root.ContainsKey("bones")) { + foreach (Dictionary boneMap in (List)root["bones"]) { + BoneData parent = null; + if (boneMap.ContainsKey("parent")) { + parent = skeletonData.FindBone((string)boneMap["parent"]); + if (parent == null) + throw new Exception("Parent bone not found: " + boneMap["parent"]); + } + var data = new BoneData(skeletonData.Bones.Count, (string)boneMap["name"], parent); + data.length = GetFloat(boneMap, "length", 0) * scale; + data.x = GetFloat(boneMap, "x", 0) * scale; + data.y = GetFloat(boneMap, "y", 0) * scale; + data.rotation = GetFloat(boneMap, "rotation", 0); + data.scaleX = GetFloat(boneMap, "scaleX", 1); + data.scaleY = GetFloat(boneMap, "scaleY", 1); + data.shearX = GetFloat(boneMap, "shearX", 0); + data.shearY = GetFloat(boneMap, "shearY", 0); + + string tm = GetString(boneMap, "transform", TransformMode.Normal.ToString()); + data.transformMode = (TransformMode)Enum.Parse(typeof(TransformMode), tm, true); + data.skinRequired = GetBoolean(boneMap, "skin", false); + + skeletonData.bones.Add(data); + } + } + + // Slots. + if (root.ContainsKey("slots")) { + foreach (Dictionary slotMap in (List)root["slots"]) { + var slotName = (string)slotMap["name"]; + var boneName = (string)slotMap["bone"]; + BoneData boneData = skeletonData.FindBone(boneName); + if (boneData == null) throw new Exception("Slot bone not found: " + boneName); + var data = new SlotData(skeletonData.Slots.Count, slotName, boneData); + + if (slotMap.ContainsKey("color")) { + string color = (string)slotMap["color"]; + data.r = ToColor(color, 0); + data.g = ToColor(color, 1); + data.b = ToColor(color, 2); + data.a = ToColor(color, 3); + } + + if (slotMap.ContainsKey("dark")) { + var color2 = (string)slotMap["dark"]; + data.r2 = ToColor(color2, 0, 6); // expectedLength = 6. ie. "RRGGBB" + data.g2 = ToColor(color2, 1, 6); + data.b2 = ToColor(color2, 2, 6); + data.hasSecondColor = true; + } + + data.attachmentName = GetString(slotMap, "attachment", null); + if (slotMap.ContainsKey("blend")) + data.blendMode = (BlendMode)Enum.Parse(typeof(BlendMode), (string)slotMap["blend"], true); + else + data.blendMode = BlendMode.Normal; + skeletonData.slots.Add(data); + } + } + + // IK constraints. + if (root.ContainsKey("ik")) { + foreach (Dictionary constraintMap in (List)root["ik"]) { + IkConstraintData data = new IkConstraintData((string)constraintMap["name"]); + data.order = GetInt(constraintMap, "order", 0); + data.skinRequired = GetBoolean(constraintMap,"skin", false); + + if (constraintMap.ContainsKey("bones")) { + foreach (string boneName in (List)constraintMap["bones"]) { + BoneData bone = skeletonData.FindBone(boneName); + if (bone == null) throw new Exception("IK bone not found: " + boneName); + data.bones.Add(bone); + } + } + + string targetName = (string)constraintMap["target"]; + data.target = skeletonData.FindBone(targetName); + if (data.target == null) throw new Exception("IK target bone not found: " + targetName); + data.mix = GetFloat(constraintMap, "mix", 1); + data.softness = GetFloat(constraintMap, "softness", 0) * scale; + data.bendDirection = GetBoolean(constraintMap, "bendPositive", true) ? 1 : -1; + data.compress = GetBoolean(constraintMap, "compress", false); + data.stretch = GetBoolean(constraintMap, "stretch", false); + data.uniform = GetBoolean(constraintMap, "uniform", false); + + skeletonData.ikConstraints.Add(data); + } + } + + // Transform constraints. + if (root.ContainsKey("transform")) { + foreach (Dictionary constraintMap in (List)root["transform"]) { + TransformConstraintData data = new TransformConstraintData((string)constraintMap["name"]); + data.order = GetInt(constraintMap, "order", 0); + data.skinRequired = GetBoolean(constraintMap,"skin", false); + + if (constraintMap.ContainsKey("bones")) { + foreach (string boneName in (List)constraintMap["bones"]) { + BoneData bone = skeletonData.FindBone(boneName); + if (bone == null) throw new Exception("Transform constraint bone not found: " + boneName); + data.bones.Add(bone); + } + } + + string targetName = (string)constraintMap["target"]; + data.target = skeletonData.FindBone(targetName); + if (data.target == null) throw new Exception("Transform constraint target bone not found: " + targetName); + + data.local = GetBoolean(constraintMap, "local", false); + data.relative = GetBoolean(constraintMap, "relative", false); + + data.offsetRotation = GetFloat(constraintMap, "rotation", 0); + data.offsetX = GetFloat(constraintMap, "x", 0) * scale; + data.offsetY = GetFloat(constraintMap, "y", 0) * scale; + data.offsetScaleX = GetFloat(constraintMap, "scaleX", 0); + data.offsetScaleY = GetFloat(constraintMap, "scaleY", 0); + data.offsetShearY = GetFloat(constraintMap, "shearY", 0); + + data.rotateMix = GetFloat(constraintMap, "rotateMix", 1); + data.translateMix = GetFloat(constraintMap, "translateMix", 1); + data.scaleMix = GetFloat(constraintMap, "scaleMix", 1); + data.shearMix = GetFloat(constraintMap, "shearMix", 1); + + skeletonData.transformConstraints.Add(data); + } + } + + // Path constraints. + if(root.ContainsKey("path")) { + foreach (Dictionary constraintMap in (List)root["path"]) { + PathConstraintData data = new PathConstraintData((string)constraintMap["name"]); + data.order = GetInt(constraintMap, "order", 0); + data.skinRequired = GetBoolean(constraintMap,"skin", false); + + if (constraintMap.ContainsKey("bones")) { + foreach (string boneName in (List)constraintMap["bones"]) { + BoneData bone = skeletonData.FindBone(boneName); + if (bone == null) throw new Exception("Path bone not found: " + boneName); + data.bones.Add(bone); + } + } + + string targetName = (string)constraintMap["target"]; + data.target = skeletonData.FindSlot(targetName); + if (data.target == null) throw new Exception("Path target slot not found: " + targetName); + + data.positionMode = (PositionMode)Enum.Parse(typeof(PositionMode), GetString(constraintMap, "positionMode", "percent"), true); + data.spacingMode = (SpacingMode)Enum.Parse(typeof(SpacingMode), GetString(constraintMap, "spacingMode", "length"), true); + data.rotateMode = (RotateMode)Enum.Parse(typeof(RotateMode), GetString(constraintMap, "rotateMode", "tangent"), true); + data.offsetRotation = GetFloat(constraintMap, "rotation", 0); + data.position = GetFloat(constraintMap, "position", 0); + if (data.positionMode == PositionMode.Fixed) data.position *= scale; + data.spacing = GetFloat(constraintMap, "spacing", 0); + if (data.spacingMode == SpacingMode.Length || data.spacingMode == SpacingMode.Fixed) data.spacing *= scale; + data.rotateMix = GetFloat(constraintMap, "rotateMix", 1); + data.translateMix = GetFloat(constraintMap, "translateMix", 1); + + skeletonData.pathConstraints.Add(data); + } + } + + // Skins. + if (root.ContainsKey("skins")) { + foreach (Dictionary skinMap in (List)root["skins"]) { + Skin skin = new Skin((string)skinMap["name"]); + if (skinMap.ContainsKey("bones")) { + foreach (string entryName in (List)skinMap["bones"]) { + BoneData bone = skeletonData.FindBone(entryName); + if (bone == null) throw new Exception("Skin bone not found: " + entryName); + skin.bones.Add(bone); + } + } + if (skinMap.ContainsKey("ik")) { + foreach (string entryName in (List)skinMap["ik"]) { + IkConstraintData constraint = skeletonData.FindIkConstraint(entryName); + if (constraint == null) throw new Exception("Skin IK constraint not found: " + entryName); + skin.constraints.Add(constraint); + } + } + if (skinMap.ContainsKey("transform")) { + foreach (string entryName in (List)skinMap["transform"]) { + TransformConstraintData constraint = skeletonData.FindTransformConstraint(entryName); + if (constraint == null) throw new Exception("Skin transform constraint not found: " + entryName); + skin.constraints.Add(constraint); + } + } + if (skinMap.ContainsKey("path")) { + foreach (string entryName in (List)skinMap["path"]) { + PathConstraintData constraint = skeletonData.FindPathConstraint(entryName); + if (constraint == null) throw new Exception("Skin path constraint not found: " + entryName); + skin.constraints.Add(constraint); + } + } + if (skinMap.ContainsKey("attachments")) { + foreach (KeyValuePair slotEntry in (Dictionary)skinMap["attachments"]) { + int slotIndex = skeletonData.FindSlotIndex(slotEntry.Key); + foreach (KeyValuePair entry in ((Dictionary)slotEntry.Value)) { + try { + Attachment attachment = ReadAttachment((Dictionary)entry.Value, skin, slotIndex, entry.Key, skeletonData); + if (attachment != null) skin.SetAttachment(slotIndex, entry.Key, attachment); + } catch (Exception e) { + throw new Exception("Error reading attachment: " + entry.Key + ", skin: " + skin, e); + } + } + } + } + skeletonData.skins.Add(skin); + if (skin.name == "default") skeletonData.defaultSkin = skin; + } + } + + // Linked meshes. + for (int i = 0, n = linkedMeshes.Count; i < n; i++) { + LinkedMesh linkedMesh = linkedMeshes[i]; + Skin skin = linkedMesh.skin == null ? skeletonData.defaultSkin : skeletonData.FindSkin(linkedMesh.skin); + if (skin == null) throw new Exception("Slot not found: " + linkedMesh.skin); + Attachment parent = skin.GetAttachment(linkedMesh.slotIndex, linkedMesh.parent); + if (parent == null) throw new Exception("Parent mesh not found: " + linkedMesh.parent); + linkedMesh.mesh.DeformAttachment = linkedMesh.inheritDeform ? (VertexAttachment)parent : linkedMesh.mesh; + linkedMesh.mesh.ParentMesh = (MeshAttachment)parent; + linkedMesh.mesh.UpdateUVs(); + } + linkedMeshes.Clear(); + + // Events. + if (root.ContainsKey("events")) { + foreach (KeyValuePair entry in (Dictionary)root["events"]) { + var entryMap = (Dictionary)entry.Value; + var data = new EventData(entry.Key); + data.Int = GetInt(entryMap, "int", 0); + data.Float = GetFloat(entryMap, "float", 0); + data.String = GetString(entryMap, "string", string.Empty); + data.AudioPath = GetString(entryMap, "audio", null); + if (data.AudioPath != null) { + data.Volume = GetFloat(entryMap, "volume", 1); + data.Balance = GetFloat(entryMap, "balance", 0); + } + skeletonData.events.Add(data); + } + } + + // Animations. + if (root.ContainsKey("animations")) { + foreach (KeyValuePair entry in (Dictionary)root["animations"]) { + try { + ReadAnimation((Dictionary)entry.Value, entry.Key, skeletonData); + } catch (Exception e) { + throw new Exception("Error reading animation: " + entry.Key, e); + } + } + } + + skeletonData.bones.TrimExcess(); + skeletonData.slots.TrimExcess(); + skeletonData.skins.TrimExcess(); + skeletonData.events.TrimExcess(); + skeletonData.animations.TrimExcess(); + skeletonData.ikConstraints.TrimExcess(); + return skeletonData; + } + + private Attachment ReadAttachment (Dictionary map, Skin skin, int slotIndex, string name, SkeletonData skeletonData) { + float scale = this.Scale; + name = GetString(map, "name", name); + + var typeName = GetString(map, "type", "region"); + var type = (AttachmentType)Enum.Parse(typeof(AttachmentType), typeName, true); + + string path = GetString(map, "path", name); + + switch (type) { + case AttachmentType.Region: + RegionAttachment region = attachmentLoader.NewRegionAttachment(skin, name, path); + if (region == null) return null; + region.Path = path; + region.x = GetFloat(map, "x", 0) * scale; + region.y = GetFloat(map, "y", 0) * scale; + region.scaleX = GetFloat(map, "scaleX", 1); + region.scaleY = GetFloat(map, "scaleY", 1); + region.rotation = GetFloat(map, "rotation", 0); + region.width = GetFloat(map, "width", 32) * scale; + region.height = GetFloat(map, "height", 32) * scale; + + if (map.ContainsKey("color")) { + var color = (string)map["color"]; + region.r = ToColor(color, 0); + region.g = ToColor(color, 1); + region.b = ToColor(color, 2); + region.a = ToColor(color, 3); + } + + region.UpdateOffset(); + return region; + case AttachmentType.Boundingbox: + BoundingBoxAttachment box = attachmentLoader.NewBoundingBoxAttachment(skin, name); + if (box == null) return null; + ReadVertices(map, box, GetInt(map, "vertexCount", 0) << 1); + return box; + case AttachmentType.Mesh: + case AttachmentType.Linkedmesh: { + MeshAttachment mesh = attachmentLoader.NewMeshAttachment(skin, name, path); + if (mesh == null) return null; + mesh.Path = path; + + if (map.ContainsKey("color")) { + var color = (string)map["color"]; + mesh.r = ToColor(color, 0); + mesh.g = ToColor(color, 1); + mesh.b = ToColor(color, 2); + mesh.a = ToColor(color, 3); + } + + mesh.Width = GetFloat(map, "width", 0) * scale; + mesh.Height = GetFloat(map, "height", 0) * scale; + + string parent = GetString(map, "parent", null); + if (parent != null) { + linkedMeshes.Add(new LinkedMesh(mesh, GetString(map, "skin", null), slotIndex, parent, GetBoolean(map, "deform", true))); + return mesh; + } + + float[] uvs = GetFloatArray(map, "uvs", 1); + ReadVertices(map, mesh, uvs.Length); + mesh.triangles = GetIntArray(map, "triangles"); + mesh.regionUVs = uvs; + mesh.UpdateUVs(); + + if (map.ContainsKey("hull")) mesh.HullLength = GetInt(map, "hull", 0) * 2; + if (map.ContainsKey("edges")) mesh.Edges = GetIntArray(map, "edges"); + return mesh; + } + case AttachmentType.Path: { + PathAttachment pathAttachment = attachmentLoader.NewPathAttachment(skin, name); + if (pathAttachment == null) return null; + pathAttachment.closed = GetBoolean(map, "closed", false); + pathAttachment.constantSpeed = GetBoolean(map, "constantSpeed", true); + + int vertexCount = GetInt(map, "vertexCount", 0); + ReadVertices(map, pathAttachment, vertexCount << 1); + + // potential BOZO see Java impl + pathAttachment.lengths = GetFloatArray(map, "lengths", scale); + return pathAttachment; + } + case AttachmentType.Point: { + PointAttachment point = attachmentLoader.NewPointAttachment(skin, name); + if (point == null) return null; + point.x = GetFloat(map, "x", 0) * scale; + point.y = GetFloat(map, "y", 0) * scale; + point.rotation = GetFloat(map, "rotation", 0); + + //string color = GetString(map, "color", null); + //if (color != null) point.color = color; + return point; + } + case AttachmentType.Clipping: { + ClippingAttachment clip = attachmentLoader.NewClippingAttachment(skin, name); + if (clip == null) return null; + + string end = GetString(map, "end", null); + if (end != null) { + SlotData slot = skeletonData.FindSlot(end); + if (slot == null) throw new Exception("Clipping end slot not found: " + end); + clip.EndSlot = slot; + } + + ReadVertices(map, clip, GetInt(map, "vertexCount", 0) << 1); + + //string color = GetString(map, "color", null); + // if (color != null) clip.color = color; + return clip; + } + } + return null; + } + + private void ReadVertices (Dictionary map, VertexAttachment attachment, int verticesLength) { + attachment.WorldVerticesLength = verticesLength; + float[] vertices = GetFloatArray(map, "vertices", 1); + float scale = Scale; + if (verticesLength == vertices.Length) { + if (scale != 1) { + for (int i = 0; i < vertices.Length; i++) { + vertices[i] *= scale; + } + } + attachment.vertices = vertices; + return; + } + ExposedList weights = new ExposedList(verticesLength * 3 * 3); + ExposedList bones = new ExposedList(verticesLength * 3); + for (int i = 0, n = vertices.Length; i < n;) { + int boneCount = (int)vertices[i++]; + bones.Add(boneCount); + for (int nn = i + boneCount * 4; i < nn; i += 4) { + bones.Add((int)vertices[i]); + weights.Add(vertices[i + 1] * this.Scale); + weights.Add(vertices[i + 2] * this.Scale); + weights.Add(vertices[i + 3]); + } + } + attachment.bones = bones.ToArray(); + attachment.vertices = weights.ToArray(); + } + + private void ReadAnimation (Dictionary map, string name, SkeletonData skeletonData) { + var scale = this.Scale; + var timelines = new ExposedList(); + float duration = 0; + + // Slot timelines. + if (map.ContainsKey("slots")) { + foreach (KeyValuePair entry in (Dictionary)map["slots"]) { + string slotName = entry.Key; + int slotIndex = skeletonData.FindSlotIndex(slotName); + var timelineMap = (Dictionary)entry.Value; + foreach (KeyValuePair timelineEntry in timelineMap) { + var values = (List)timelineEntry.Value; + var timelineName = (string)timelineEntry.Key; + if (timelineName == "attachment") { + var timeline = new AttachmentTimeline(values.Count); + timeline.slotIndex = slotIndex; + + int frameIndex = 0; + foreach (Dictionary valueMap in values) { + float time = GetFloat(valueMap, "time", 0); + timeline.SetFrame(frameIndex++, time, (string)valueMap["name"]); + } + timelines.Add(timeline); + duration = Math.Max(duration, timeline.frames[timeline.FrameCount - 1]); + + } else if (timelineName == "color") { + var timeline = new ColorTimeline(values.Count); + timeline.slotIndex = slotIndex; + + int frameIndex = 0; + foreach (Dictionary valueMap in values) { + float time = GetFloat(valueMap, "time", 0); + string c = (string)valueMap["color"]; + timeline.SetFrame(frameIndex, time, ToColor(c, 0), ToColor(c, 1), ToColor(c, 2), ToColor(c, 3)); + ReadCurve(valueMap, timeline, frameIndex); + frameIndex++; + } + timelines.Add(timeline); + duration = Math.Max(duration, timeline.frames[(timeline.FrameCount - 1) * ColorTimeline.ENTRIES]); + + } else if (timelineName == "twoColor") { + var timeline = new TwoColorTimeline(values.Count); + timeline.slotIndex = slotIndex; + + int frameIndex = 0; + foreach (Dictionary valueMap in values) { + float time = GetFloat(valueMap, "time", 0); + string light = (string)valueMap["light"]; + string dark = (string)valueMap["dark"]; + timeline.SetFrame(frameIndex, time, ToColor(light, 0), ToColor(light, 1), ToColor(light, 2), ToColor(light, 3), + ToColor(dark, 0, 6), ToColor(dark, 1, 6), ToColor(dark, 2, 6)); + ReadCurve(valueMap, timeline, frameIndex); + frameIndex++; + } + timelines.Add(timeline); + duration = Math.Max(duration, timeline.frames[(timeline.FrameCount - 1) * TwoColorTimeline.ENTRIES]); + + } else + throw new Exception("Invalid timeline type for a slot: " + timelineName + " (" + slotName + ")"); + } + } + } + + // Bone timelines. + if (map.ContainsKey("bones")) { + foreach (KeyValuePair entry in (Dictionary)map["bones"]) { + string boneName = entry.Key; + int boneIndex = skeletonData.FindBoneIndex(boneName); + if (boneIndex == -1) throw new Exception("Bone not found: " + boneName); + var timelineMap = (Dictionary)entry.Value; + foreach (KeyValuePair timelineEntry in timelineMap) { + var values = (List)timelineEntry.Value; + var timelineName = (string)timelineEntry.Key; + if (timelineName == "rotate") { + var timeline = new RotateTimeline(values.Count); + timeline.boneIndex = boneIndex; + + int frameIndex = 0; + foreach (Dictionary valueMap in values) { + timeline.SetFrame(frameIndex, GetFloat(valueMap, "time", 0), GetFloat(valueMap, "angle", 0)); + ReadCurve(valueMap, timeline, frameIndex); + frameIndex++; + } + timelines.Add(timeline); + duration = Math.Max(duration, timeline.frames[(timeline.FrameCount - 1) * RotateTimeline.ENTRIES]); + + } else if (timelineName == "translate" || timelineName == "scale" || timelineName == "shear") { + TranslateTimeline timeline; + float timelineScale = 1, defaultValue = 0; + if (timelineName == "scale") { + timeline = new ScaleTimeline(values.Count); + defaultValue = 1; + } + else if (timelineName == "shear") + timeline = new ShearTimeline(values.Count); + else { + timeline = new TranslateTimeline(values.Count); + timelineScale = scale; + } + timeline.boneIndex = boneIndex; + + int frameIndex = 0; + foreach (Dictionary valueMap in values) { + float time = GetFloat(valueMap, "time", 0); + float x = GetFloat(valueMap, "x", defaultValue); + float y = GetFloat(valueMap, "y", defaultValue); + timeline.SetFrame(frameIndex, time, x * timelineScale, y * timelineScale); + ReadCurve(valueMap, timeline, frameIndex); + frameIndex++; + } + timelines.Add(timeline); + duration = Math.Max(duration, timeline.frames[(timeline.FrameCount - 1) * TranslateTimeline.ENTRIES]); + + } else + throw new Exception("Invalid timeline type for a bone: " + timelineName + " (" + boneName + ")"); + } + } + } + + // IK constraint timelines. + if (map.ContainsKey("ik")) { + foreach (KeyValuePair constraintMap in (Dictionary)map["ik"]) { + IkConstraintData constraint = skeletonData.FindIkConstraint(constraintMap.Key); + var values = (List)constraintMap.Value; + var timeline = new IkConstraintTimeline(values.Count); + timeline.ikConstraintIndex = skeletonData.ikConstraints.IndexOf(constraint); + int frameIndex = 0; + foreach (Dictionary valueMap in values) { + timeline.SetFrame(frameIndex, GetFloat(valueMap, "time", 0), GetFloat(valueMap, "mix", 1), + GetFloat(valueMap, "softness", 0) * scale, GetBoolean(valueMap, "bendPositive", true) ? 1 : -1, + GetBoolean(valueMap, "compress", false), GetBoolean(valueMap, "stretch", false)); + ReadCurve(valueMap, timeline, frameIndex); + frameIndex++; + } + timelines.Add(timeline); + duration = Math.Max(duration, timeline.frames[(timeline.FrameCount - 1) * IkConstraintTimeline.ENTRIES]); + } + } + + // Transform constraint timelines. + if (map.ContainsKey("transform")) { + foreach (KeyValuePair constraintMap in (Dictionary)map["transform"]) { + TransformConstraintData constraint = skeletonData.FindTransformConstraint(constraintMap.Key); + var values = (List)constraintMap.Value; + var timeline = new TransformConstraintTimeline(values.Count); + timeline.transformConstraintIndex = skeletonData.transformConstraints.IndexOf(constraint); + int frameIndex = 0; + foreach (Dictionary valueMap in values) { + timeline.SetFrame(frameIndex, GetFloat(valueMap, "time", 0), GetFloat(valueMap, "rotateMix", 1), + GetFloat(valueMap, "translateMix", 1), GetFloat(valueMap, "scaleMix", 1), GetFloat(valueMap, "shearMix", 1)); + ReadCurve(valueMap, timeline, frameIndex); + frameIndex++; + } + timelines.Add(timeline); + duration = Math.Max(duration, timeline.frames[(timeline.FrameCount - 1) * TransformConstraintTimeline.ENTRIES]); + } + } + + // Path constraint timelines. + if (map.ContainsKey("path")) { + foreach (KeyValuePair constraintMap in (Dictionary)map["path"]) { + int index = skeletonData.FindPathConstraintIndex(constraintMap.Key); + if (index == -1) throw new Exception("Path constraint not found: " + constraintMap.Key); + PathConstraintData data = skeletonData.pathConstraints.Items[index]; + var timelineMap = (Dictionary)constraintMap.Value; + foreach (KeyValuePair timelineEntry in timelineMap) { + var values = (List)timelineEntry.Value; + var timelineName = (string)timelineEntry.Key; + if (timelineName == "position" || timelineName == "spacing") { + PathConstraintPositionTimeline timeline; + float timelineScale = 1; + if (timelineName == "spacing") { + timeline = new PathConstraintSpacingTimeline(values.Count); + if (data.spacingMode == SpacingMode.Length || data.spacingMode == SpacingMode.Fixed) timelineScale = scale; + } + else { + timeline = new PathConstraintPositionTimeline(values.Count); + if (data.positionMode == PositionMode.Fixed) timelineScale = scale; + } + timeline.pathConstraintIndex = index; + int frameIndex = 0; + foreach (Dictionary valueMap in values) { + timeline.SetFrame(frameIndex, GetFloat(valueMap, "time", 0), GetFloat(valueMap, timelineName, 0) * timelineScale); + ReadCurve(valueMap, timeline, frameIndex); + frameIndex++; + } + timelines.Add(timeline); + duration = Math.Max(duration, timeline.frames[(timeline.FrameCount - 1) * PathConstraintPositionTimeline.ENTRIES]); + } + else if (timelineName == "mix") { + PathConstraintMixTimeline timeline = new PathConstraintMixTimeline(values.Count); + timeline.pathConstraintIndex = index; + int frameIndex = 0; + foreach (Dictionary valueMap in values) { + timeline.SetFrame(frameIndex, GetFloat(valueMap, "time", 0), GetFloat(valueMap, "rotateMix", 1), + GetFloat(valueMap, "translateMix", 1)); + ReadCurve(valueMap, timeline, frameIndex); + frameIndex++; + } + timelines.Add(timeline); + duration = Math.Max(duration, timeline.frames[(timeline.FrameCount - 1) * PathConstraintMixTimeline.ENTRIES]); + } + } + } + } + + // Deform timelines. + if (map.ContainsKey("deform")) { + foreach (KeyValuePair deformMap in (Dictionary)map["deform"]) { + Skin skin = skeletonData.FindSkin(deformMap.Key); + foreach (KeyValuePair slotMap in (Dictionary)deformMap.Value) { + int slotIndex = skeletonData.FindSlotIndex(slotMap.Key); + if (slotIndex == -1) throw new Exception("Slot not found: " + slotMap.Key); + foreach (KeyValuePair timelineMap in (Dictionary)slotMap.Value) { + var values = (List)timelineMap.Value; + VertexAttachment attachment = (VertexAttachment)skin.GetAttachment(slotIndex, timelineMap.Key); + if (attachment == null) throw new Exception("Deform attachment not found: " + timelineMap.Key); + bool weighted = attachment.bones != null; + float[] vertices = attachment.vertices; + int deformLength = weighted ? vertices.Length / 3 * 2 : vertices.Length; + + var timeline = new DeformTimeline(values.Count); + timeline.slotIndex = slotIndex; + timeline.attachment = attachment; + + int frameIndex = 0; + foreach (Dictionary valueMap in values) { + float[] deform; + if (!valueMap.ContainsKey("vertices")) { + deform = weighted ? new float[deformLength] : vertices; + } else { + deform = new float[deformLength]; + int start = GetInt(valueMap, "offset", 0); + float[] verticesValue = GetFloatArray(valueMap, "vertices", 1); + Array.Copy(verticesValue, 0, deform, start, verticesValue.Length); + if (scale != 1) { + for (int i = start, n = i + verticesValue.Length; i < n; i++) + deform[i] *= scale; + } + + if (!weighted) { + for (int i = 0; i < deformLength; i++) + deform[i] += vertices[i]; + } + } + + timeline.SetFrame(frameIndex, GetFloat(valueMap, "time", 0), deform); + ReadCurve(valueMap, timeline, frameIndex); + frameIndex++; + } + timelines.Add(timeline); + duration = Math.Max(duration, timeline.frames[timeline.FrameCount - 1]); + } + } + } + } + + // Draw order timeline. + if (map.ContainsKey("drawOrder") || map.ContainsKey("draworder")) { + var values = (List)map[map.ContainsKey("drawOrder") ? "drawOrder" : "draworder"]; + var timeline = new DrawOrderTimeline(values.Count); + int slotCount = skeletonData.slots.Count; + int frameIndex = 0; + foreach (Dictionary drawOrderMap in values) { + int[] drawOrder = null; + if (drawOrderMap.ContainsKey("offsets")) { + drawOrder = new int[slotCount]; + for (int i = slotCount - 1; i >= 0; i--) + drawOrder[i] = -1; + var offsets = (List)drawOrderMap["offsets"]; + int[] unchanged = new int[slotCount - offsets.Count]; + int originalIndex = 0, unchangedIndex = 0; + foreach (Dictionary offsetMap in offsets) { + int slotIndex = skeletonData.FindSlotIndex((string)offsetMap["slot"]); + if (slotIndex == -1) throw new Exception("Slot not found: " + offsetMap["slot"]); + // Collect unchanged items. + while (originalIndex != slotIndex) + unchanged[unchangedIndex++] = originalIndex++; + // Set changed items. + int index = originalIndex + (int)(float)offsetMap["offset"]; + drawOrder[index] = originalIndex++; + } + // Collect remaining unchanged items. + while (originalIndex < slotCount) + unchanged[unchangedIndex++] = originalIndex++; + // Fill in unchanged items. + for (int i = slotCount - 1; i >= 0; i--) + if (drawOrder[i] == -1) drawOrder[i] = unchanged[--unchangedIndex]; + } + timeline.SetFrame(frameIndex++, GetFloat(drawOrderMap, "time", 0), drawOrder); + } + timelines.Add(timeline); + duration = Math.Max(duration, timeline.frames[timeline.FrameCount - 1]); + } + + // Event timeline. + if (map.ContainsKey("events")) { + var eventsMap = (List)map["events"]; + var timeline = new EventTimeline(eventsMap.Count); + int frameIndex = 0; + foreach (Dictionary eventMap in eventsMap) { + EventData eventData = skeletonData.FindEvent((string)eventMap["name"]); + if (eventData == null) throw new Exception("Event not found: " + eventMap["name"]); + var e = new Event(GetFloat(eventMap, "time", 0), eventData) { + intValue = GetInt(eventMap, "int", eventData.Int), + floatValue = GetFloat(eventMap, "float", eventData.Float), + stringValue = GetString(eventMap, "string", eventData.String) + }; + if (e.data.AudioPath != null) { + e.volume = GetFloat(eventMap, "volume", eventData.Volume); + e.balance = GetFloat(eventMap, "balance", eventData.Balance); + } + timeline.SetFrame(frameIndex++, e); + } + timelines.Add(timeline); + duration = Math.Max(duration, timeline.frames[timeline.FrameCount - 1]); + } + + timelines.TrimExcess(); + skeletonData.animations.Add(new Animation(name, timelines, duration)); + } + + static void ReadCurve (Dictionary valueMap, CurveTimeline timeline, int frameIndex) { + if (!valueMap.ContainsKey("curve")) + return; + Object curveObject = valueMap["curve"]; + if (curveObject is string) + timeline.SetStepped(frameIndex); + else + timeline.SetCurve(frameIndex, (float)curveObject, GetFloat(valueMap, "c2", 0), GetFloat(valueMap, "c3", 1), GetFloat(valueMap, "c4", 1)); + } + + internal class LinkedMesh { + internal string parent, skin; + internal int slotIndex; + internal MeshAttachment mesh; + internal bool inheritDeform; + + public LinkedMesh (MeshAttachment mesh, string skin, int slotIndex, string parent, bool inheritDeform) { + this.mesh = mesh; + this.skin = skin; + this.slotIndex = slotIndex; + this.parent = parent; + this.inheritDeform = inheritDeform; + } + } + + static float[] GetFloatArray(Dictionary map, string name, float scale) { + var list = (List)map[name]; + var values = new float[list.Count]; + if (scale == 1) { + for (int i = 0, n = list.Count; i < n; i++) + values[i] = (float)list[i]; + } else { + for (int i = 0, n = list.Count; i < n; i++) + values[i] = (float)list[i] * scale; + } + return values; + } + + static int[] GetIntArray(Dictionary map, string name) { + var list = (List)map[name]; + var values = new int[list.Count]; + for (int i = 0, n = list.Count; i < n; i++) + values[i] = (int)(float)list[i]; + return values; + } + + static float GetFloat(Dictionary map, string name, float defaultValue) { + if (!map.ContainsKey(name)) + return defaultValue; + return (float)map[name]; + } + + static int GetInt(Dictionary map, string name, int defaultValue) { + if (!map.ContainsKey(name)) + return defaultValue; + return (int)(float)map[name]; + } + + static bool GetBoolean(Dictionary map, string name, bool defaultValue) { + if (!map.ContainsKey(name)) + return defaultValue; + return (bool)map[name]; + } + + static string GetString(Dictionary map, string name, string defaultValue) { + if (!map.ContainsKey(name)) + return defaultValue; + return (string)map[name]; + } + + static float ToColor(string hexString, int colorIndex, int expectedLength = 8) { + if (hexString.Length != expectedLength) + throw new ArgumentException("Color hexidecimal length must be " + expectedLength + ", recieved: " + hexString, "hexString"); + return Convert.ToInt32(hexString.Substring(colorIndex * 2, 2), 16) / (float)255; + } + } +} diff --git a/box1/Assets/Spine/Runtime/spine-csharp/SkeletonJson.cs.meta b/box1/Assets/Spine/Runtime/spine-csharp/SkeletonJson.cs.meta new file mode 100644 index 00000000..9188b238 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-csharp/SkeletonJson.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 6c4ab7992894bdb44a480981b1953f76 +timeCreated: 1456265154 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-csharp/Skin.cs b/box1/Assets/Spine/Runtime/spine-csharp/Skin.cs new file mode 100644 index 00000000..de26ad1b --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-csharp/Skin.cs @@ -0,0 +1,193 @@ +/****************************************************************************** + * 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; +using System.Collections.Generic; +using Spine.Collections; + +namespace Spine { + /// Stores attachments by slot index and attachment name. + /// See SkeletonData , Skeleton , and + /// Runtime skins in the Spine Runtimes Guide. + /// + public class Skin { + internal string name; + private OrderedDictionary attachments = new OrderedDictionary(SkinEntryComparer.Instance); + internal readonly ExposedList bones = new ExposedList(); + internal readonly ExposedList constraints = new ExposedList(); + + public string Name { get { return name; } } + public OrderedDictionary Attachments { get { return attachments; } } + public ExposedList Bones { get { return bones; } } + public ExposedList Constraints { get { return constraints; } } + + public Skin (string name) { + if (name == null) throw new ArgumentNullException("name", "name cannot be null."); + this.name = name; + } + + /// Adds an attachment to the skin for the specified slot index and name. + /// If the name already exists for the slot, the previous value is replaced. + public void SetAttachment (int slotIndex, string name, Attachment attachment) { + if (attachment == null) throw new ArgumentNullException("attachment", "attachment cannot be null."); + if (slotIndex < 0) throw new ArgumentNullException("slotIndex", "slotIndex must be >= 0."); + attachments[new SkinEntry(slotIndex, name, attachment)] = attachment; + } + + ///Adds all attachments, bones, and constraints from the specified skin to this skin. + public void AddSkin (Skin skin) { + foreach (BoneData data in skin.bones) + if (!bones.Contains(data)) bones.Add(data); + + foreach (ConstraintData data in skin.constraints) + if (!constraints.Contains(data)) constraints.Add(data); + + foreach (SkinEntry entry in skin.attachments.Keys) + SetAttachment(entry.SlotIndex, entry.Name, entry.Attachment); + } + + ///Adds all attachments from the specified skin to this skin. Attachments are deep copied. + public void CopySkin (Skin skin) { + foreach (BoneData data in skin.bones) + if (!bones.Contains(data)) bones.Add(data); + + foreach (ConstraintData data in skin.constraints) + if (!constraints.Contains(data)) constraints.Add(data); + + foreach (SkinEntry entry in skin.attachments.Keys) { + if (entry.Attachment is MeshAttachment) + SetAttachment(entry.SlotIndex, entry.Name, + entry.Attachment != null ? ((MeshAttachment)entry.Attachment).NewLinkedMesh() : null); + else + SetAttachment(entry.SlotIndex, entry.Name, entry.Attachment != null ? entry.Attachment.Copy() : null); + } + } + + /// Returns the attachment for the specified slot index and name, or null. + /// May be null. + public Attachment GetAttachment (int slotIndex, string name) { + var lookup = new SkinEntry(slotIndex, name, null); + Attachment attachment = null; + bool containsKey = attachments.TryGetValue(lookup, out attachment); + return containsKey ? attachment : null; + } + + /// Removes the attachment in the skin for the specified slot index and name, if any. + public void RemoveAttachment (int slotIndex, string name) { + if (slotIndex < 0) throw new ArgumentOutOfRangeException("slotIndex", "slotIndex must be >= 0"); + var lookup = new SkinEntry(slotIndex, name, null); + attachments.Remove(lookup); + } + + ///Returns all attachments contained in this skin. + public ICollection GetAttachments () { + return this.attachments.Keys; + } + + /// Returns all attachments in this skin for the specified slot index. + /// The target slotIndex. To find the slot index, use or + public void GetAttachments (int slotIndex, List attachments) { + foreach (SkinEntry entry in this.attachments.Keys) + if (entry.SlotIndex == slotIndex) attachments.Add(entry); + } + + ///Clears all attachments, bones, and constraints. + public void Clear () { + attachments.Clear(); + bones.Clear(); + constraints.Clear(); + } + + override public string ToString () { + return name; + } + + /// Attach all attachments from this skin if the corresponding attachment from the old skin is currently attached. + internal void AttachAll (Skeleton skeleton, Skin oldSkin) { + foreach (SkinEntry entry in oldSkin.attachments.Keys) { + int slotIndex = entry.SlotIndex; + Slot slot = skeleton.slots.Items[slotIndex]; + if (slot.Attachment == entry.Attachment) { + Attachment attachment = GetAttachment(slotIndex, entry.Name); + if (attachment != null) slot.Attachment = attachment; + } + } + } + + /// Stores an entry in the skin consisting of the slot index, name, and attachment. + public struct SkinEntry { + private readonly int slotIndex; + private readonly string name; + private readonly Attachment attachment; + internal readonly int hashCode; + + public SkinEntry (int slotIndex, string name, Attachment attachment) { + this.slotIndex = slotIndex; + this.name = name; + this.attachment = attachment; + this.hashCode = this.name.GetHashCode() + this.slotIndex * 37; + } + + public int SlotIndex { + get { + return slotIndex; + } + } + + /// The name the attachment is associated with, equivalent to the skin placeholder name in the Spine editor. + public String Name { + get { + return name; + } + } + + public Attachment Attachment { + get { + return attachment; + } + } + } + + // Avoids boxing in the dictionary and is necessary to omit entry.attachment in the comparison. + class SkinEntryComparer : IEqualityComparer { + internal static readonly SkinEntryComparer Instance = new SkinEntryComparer(); + + bool IEqualityComparer.Equals (SkinEntry e1, SkinEntry e2) { + if (e1.SlotIndex != e2.SlotIndex) return false; + if (!string.Equals(e1.Name, e2.Name, StringComparison.Ordinal)) return false; + return true; + } + + int IEqualityComparer.GetHashCode (SkinEntry e) { + return e.Name.GetHashCode() + e.SlotIndex * 37; + } + } + } +} diff --git a/box1/Assets/Spine/Runtime/spine-csharp/Skin.cs.meta b/box1/Assets/Spine/Runtime/spine-csharp/Skin.cs.meta new file mode 100644 index 00000000..1e9f87e7 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-csharp/Skin.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 7df8caa3a771f464e803316a6b18c909 +timeCreated: 1456265154 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-csharp/Slot.cs b/box1/Assets/Spine/Runtime/spine-csharp/Slot.cs new file mode 100644 index 00000000..c7e45a88 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-csharp/Slot.cs @@ -0,0 +1,196 @@ +/****************************************************************************** + * 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; + +namespace Spine { + + /// + /// Stores a slot's current pose. Slots organize attachments for {@link Skeleton#drawOrder} purposes and provide a place to store + /// state for an attachment.State cannot be stored in an attachment itself because attachments are stateless and may be shared + /// across multiple skeletons. + /// + public class Slot { + internal SlotData data; + internal Bone bone; + internal float r, g, b, a; + internal float r2, g2, b2; + internal bool hasSecondColor; + internal Attachment attachment; + internal float attachmentTime; + internal ExposedList deform = new ExposedList(); + internal int attachmentState; + + public Slot (SlotData data, Bone bone) { + if (data == null) throw new ArgumentNullException("data", "data cannot be null."); + if (bone == null) throw new ArgumentNullException("bone", "bone cannot be null."); + this.data = data; + this.bone = bone; + + // darkColor = data.darkColor == null ? null : new Color(); + if (data.hasSecondColor) { + r2 = g2 = b2 = 0; + } + + SetToSetupPose(); + } + + /// Copy constructor. + public Slot(Slot slot, Bone bone) { + if (slot == null) throw new ArgumentNullException("slot", "slot cannot be null."); + if (bone == null) throw new ArgumentNullException("bone", "bone cannot be null."); + data = slot.data; + this.bone = bone; + r = slot.r; + g = slot.g; + b = slot.b; + a = slot.a; + + // darkColor = slot.darkColor == null ? null : new Color(slot.darkColor); + if (slot.hasSecondColor) { + r2 = slot.r2; + g2 = slot.g2; + b2 = slot.b2; + } else { + r2 = g2 = b2 = 0; + } + hasSecondColor = slot.hasSecondColor; + + attachment = slot.attachment; + attachmentTime = slot.attachmentTime; + deform.AddRange(slot.deform); + } + + /// The slot's setup pose data. + public SlotData Data { get { return data; } } + /// The bone this slot belongs to. + public Bone Bone { get { return bone; } } + /// The skeleton this slot belongs to. + public Skeleton Skeleton { get { return bone.skeleton; } } + /// The color used to tint the slot's attachment. If is set, this is used as the light color for two + /// color tinting. + public float R { get { return r; } set { r = value; } } + /// The color used to tint the slot's attachment. If is set, this is used as the light color for two + /// color tinting. + public float G { get { return g; } set { g = value; } } + /// The color used to tint the slot's attachment. If is set, this is used as the light color for two + /// color tinting. + public float B { get { return b; } set { b = value; } } + /// The color used to tint the slot's attachment. If is set, this is used as the light color for two + /// color tinting. + public float A { get { return a; } set { a = value; } } + + public void ClampColor() { + r = MathUtils.Clamp(r, 0, 1); + g = MathUtils.Clamp(g, 0, 1); + b = MathUtils.Clamp(b, 0, 1); + a = MathUtils.Clamp(a, 0, 1); + } + + /// The dark color used to tint the slot's attachment for two color tinting, ignored if two color tinting is not used. + /// + public float R2 { get { return r2; } set { r2 = value; } } + /// The dark color used to tint the slot's attachment for two color tinting, ignored if two color tinting is not used. + /// + public float G2 { get { return g2; } set { g2 = value; } } + /// The dark color used to tint the slot's attachment for two color tinting, ignored if two color tinting is not used. + /// + public float B2 { get { return b2; } set { b2 = value; } } + /// Whether R2 G2 B2 are used to tint the slot's attachment for two color tinting. False if two color tinting is not used. + public bool HasSecondColor { get { return data.hasSecondColor; } set { data.hasSecondColor = value; } } + + public void ClampSecondColor () { + r2 = MathUtils.Clamp(r2, 0, 1); + g2 = MathUtils.Clamp(g2, 0, 1); + b2 = MathUtils.Clamp(b2, 0, 1); + } + + public Attachment Attachment { + /// The current attachment for the slot, or null if the slot has no attachment. + get { return attachment; } + /// + /// Sets the slot's attachment and, if the attachment changed, resets and clears + /// . + /// May be null. + set { + if (attachment == value) return; + attachment = value; + attachmentTime = bone.skeleton.time; + deform.Clear(false); + } + } + + /// The time that has elapsed since the last time the attachment was set or cleared. Relies on Skeleton + /// + public float AttachmentTime { + get { return bone.skeleton.time - attachmentTime; } + set { attachmentTime = bone.skeleton.time - value; } + } + + /// Vertices to deform the slot's attachment. For an unweighted mesh, the entries are local positions for each vertex. For a + /// weighted mesh, the entries are an offset for each vertex which will be added to the mesh's local vertex positions. + /// + /// See and . + public ExposedList Deform { + get { + return deform; + } + set { + if (deform == null) throw new ArgumentNullException("deform", "deform cannot be null."); + deform = value; + } + } + + /// Sets this slot to the setup pose. + public void SetToSetupPose () { + r = data.r; + g = data.g; + b = data.b; + a = data.a; + + // if (darkColor != null) darkColor.set(data.darkColor); + if (HasSecondColor) { + r2 = data.r2; + g2 = data.g2; + b2 = data.b2; + } + + if (data.attachmentName == null) + Attachment = null; + else { + attachment = null; + Attachment = bone.skeleton.GetAttachment(data.index, data.attachmentName); + } + } + + override public string ToString () { + return data.name; + } + } +} diff --git a/box1/Assets/Spine/Runtime/spine-csharp/Slot.cs.meta b/box1/Assets/Spine/Runtime/spine-csharp/Slot.cs.meta new file mode 100644 index 00000000..4bc86f43 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-csharp/Slot.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 6974c4b5c87687140a2417201ea43066 +timeCreated: 1456265154 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-csharp/SlotData.cs b/box1/Assets/Spine/Runtime/spine-csharp/SlotData.cs new file mode 100644 index 00000000..a51b2949 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-csharp/SlotData.cs @@ -0,0 +1,77 @@ +/****************************************************************************** + * 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; + +namespace Spine { + public class SlotData { + internal int index; + internal string name; + internal BoneData boneData; + internal float r = 1, g = 1, b = 1, a = 1; + internal float r2 = 0, g2 = 0, b2 = 0; + internal bool hasSecondColor = false; + internal string attachmentName; + internal BlendMode blendMode; + + /// The index of the slot in . + public int Index { get { return index; } } + /// The name of the slot, which is unique across all slots in the skeleton. + public string Name { get { return name; } } + /// The bone this slot belongs to. + public BoneData BoneData { get { return boneData; } } + public float R { get { return r; } set { r = value; } } + public float G { get { return g; } set { g = value; } } + public float B { get { return b; } set { b = value; } } + public float A { get { return a; } set { a = value; } } + + public float R2 { get { return r2; } set { r2 = value; } } + public float G2 { get { return g2; } set { g2 = value; } } + public float B2 { get { return b2; } set { b2 = value; } } + public bool HasSecondColor { get { return hasSecondColor; } set { hasSecondColor = value; } } + + /// The name of the attachment that is visible for this slot in the setup pose, or null if no attachment is visible. + public String AttachmentName { get { return attachmentName; } set { attachmentName = value; } } + /// The blend mode for drawing the slot's attachment. + public BlendMode BlendMode { get { return blendMode; } set { blendMode = value; } } + + public SlotData (int index, String name, BoneData boneData) { + if (index < 0) throw new ArgumentException ("index must be >= 0.", "index"); + if (name == null) throw new ArgumentNullException("name", "name cannot be null."); + if (boneData == null) throw new ArgumentNullException("boneData", "boneData cannot be null."); + this.index = index; + this.name = name; + this.boneData = boneData; + } + + override public string ToString () { + return name; + } + } +} diff --git a/box1/Assets/Spine/Runtime/spine-csharp/SlotData.cs.meta b/box1/Assets/Spine/Runtime/spine-csharp/SlotData.cs.meta new file mode 100644 index 00000000..d203ba70 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-csharp/SlotData.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: f28cb47bc1e8b434c85e6f69b2c9e15e +timeCreated: 1456265156 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-csharp/TransformConstraint.cs b/box1/Assets/Spine/Runtime/spine-csharp/TransformConstraint.cs new file mode 100644 index 00000000..25761029 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-csharp/TransformConstraint.cs @@ -0,0 +1,313 @@ +/****************************************************************************** + * 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; + +namespace Spine { + /// + /// + /// Stores the current pose for a transform constraint. A transform constraint adjusts the world transform of the constrained + /// bones to match that of the target bone. + /// + /// See Transform constraints in the Spine User Guide. + /// + public class TransformConstraint : IUpdatable { + internal TransformConstraintData data; + internal ExposedList bones; + internal Bone target; + internal float rotateMix, translateMix, scaleMix, shearMix; + + internal bool active; + + public TransformConstraint (TransformConstraintData data, Skeleton skeleton) { + if (data == null) throw new ArgumentNullException("data", "data cannot be null."); + if (skeleton == null) throw new ArgumentNullException("skeleton", "skeleton cannot be null."); + this.data = data; + rotateMix = data.rotateMix; + translateMix = data.translateMix; + scaleMix = data.scaleMix; + shearMix = data.shearMix; + + bones = new ExposedList(); + foreach (BoneData boneData in data.bones) + bones.Add (skeleton.FindBone(boneData.name)); + + target = skeleton.FindBone(data.target.name); + } + + /// Copy constructor. + public TransformConstraint (TransformConstraint constraint, Skeleton skeleton) { + if (constraint == null) throw new ArgumentNullException("constraint cannot be null."); + if (skeleton == null) throw new ArgumentNullException("skeleton cannot be null."); + data = constraint.data; + bones = new ExposedList(constraint.Bones.Count); + foreach (Bone bone in constraint.Bones) + bones.Add(skeleton.Bones.Items[bone.data.index]); + target = skeleton.Bones.Items[constraint.target.data.index]; + rotateMix = constraint.rotateMix; + translateMix = constraint.translateMix; + scaleMix = constraint.scaleMix; + shearMix = constraint.shearMix; + } + + /// Applies the constraint to the constrained bones. + public void Apply () { + Update(); + } + + public void Update () { + if (data.local) { + if (data.relative) + ApplyRelativeLocal(); + else + ApplyAbsoluteLocal(); + } else { + if (data.relative) + ApplyRelativeWorld(); + else + ApplyAbsoluteWorld(); + } + } + + void ApplyAbsoluteWorld () { + float rotateMix = this.rotateMix, translateMix = this.translateMix, scaleMix = this.scaleMix, shearMix = this.shearMix; + Bone target = this.target; + float ta = target.a, tb = target.b, tc = target.c, td = target.d; + float degRadReflect = ta * td - tb * tc > 0 ? MathUtils.DegRad : -MathUtils.DegRad; + float offsetRotation = data.offsetRotation * degRadReflect, offsetShearY = data.offsetShearY * degRadReflect; + var bones = this.bones; + for (int i = 0, n = bones.Count; i < n; i++) { + Bone bone = bones.Items[i]; + bool modified = false; + + if (rotateMix != 0) { + float a = bone.a, b = bone.b, c = bone.c, d = bone.d; + float r = MathUtils.Atan2(tc, ta) - MathUtils.Atan2(c, a) + offsetRotation; + if (r > MathUtils.PI) + r -= MathUtils.PI2; + else if (r < -MathUtils.PI) r += MathUtils.PI2; + r *= rotateMix; + float cos = MathUtils.Cos(r), sin = MathUtils.Sin(r); + bone.a = cos * a - sin * c; + bone.b = cos * b - sin * d; + bone.c = sin * a + cos * c; + bone.d = sin * b + cos * d; + modified = true; + } + + if (translateMix != 0) { + float tx, ty; //Vector2 temp = this.temp; + target.LocalToWorld(data.offsetX, data.offsetY, out tx, out ty); //target.localToWorld(temp.set(data.offsetX, data.offsetY)); + bone.worldX += (tx - bone.worldX) * translateMix; + bone.worldY += (ty - bone.worldY) * translateMix; + modified = true; + } + + if (scaleMix > 0) { + float s = (float)Math.Sqrt(bone.a * bone.a + bone.c * bone.c); + if (s != 0) s = (s + ((float)Math.Sqrt(ta * ta + tc * tc) - s + data.offsetScaleX) * scaleMix) / s; + bone.a *= s; + bone.c *= s; + s = (float)Math.Sqrt(bone.b * bone.b + bone.d * bone.d); + if (s != 0) s = (s + ((float)Math.Sqrt(tb * tb + td * td) - s + data.offsetScaleY) * scaleMix) / s; + bone.b *= s; + bone.d *= s; + modified = true; + } + + if (shearMix > 0) { + float b = bone.b, d = bone.d; + float by = MathUtils.Atan2(d, b); + float r = MathUtils.Atan2(td, tb) - MathUtils.Atan2(tc, ta) - (by - MathUtils.Atan2(bone.c, bone.a)); + if (r > MathUtils.PI) + r -= MathUtils.PI2; + else if (r < -MathUtils.PI) r += MathUtils.PI2; + r = by + (r + offsetShearY) * shearMix; + float s = (float)Math.Sqrt(b * b + d * d); + bone.b = MathUtils.Cos(r) * s; + bone.d = MathUtils.Sin(r) * s; + modified = true; + } + + if (modified) bone.appliedValid = false; + } + } + + void ApplyRelativeWorld () { + float rotateMix = this.rotateMix, translateMix = this.translateMix, scaleMix = this.scaleMix, shearMix = this.shearMix; + Bone target = this.target; + float ta = target.a, tb = target.b, tc = target.c, td = target.d; + float degRadReflect = ta * td - tb * tc > 0 ? MathUtils.DegRad : -MathUtils.DegRad; + float offsetRotation = data.offsetRotation * degRadReflect, offsetShearY = data.offsetShearY * degRadReflect; + var bones = this.bones; + for (int i = 0, n = bones.Count; i < n; i++) { + Bone bone = bones.Items[i]; + bool modified = false; + + if (rotateMix != 0) { + float a = bone.a, b = bone.b, c = bone.c, d = bone.d; + float r = MathUtils.Atan2(tc, ta) + offsetRotation; + if (r > MathUtils.PI) + r -= MathUtils.PI2; + else if (r < -MathUtils.PI) r += MathUtils.PI2; + r *= rotateMix; + float cos = MathUtils.Cos(r), sin = MathUtils.Sin(r); + bone.a = cos * a - sin * c; + bone.b = cos * b - sin * d; + bone.c = sin * a + cos * c; + bone.d = sin * b + cos * d; + modified = true; + } + + if (translateMix != 0) { + float tx, ty; //Vector2 temp = this.temp; + target.LocalToWorld(data.offsetX, data.offsetY, out tx, out ty); //target.localToWorld(temp.set(data.offsetX, data.offsetY)); + bone.worldX += tx * translateMix; + bone.worldY += ty * translateMix; + modified = true; + } + + if (scaleMix > 0) { + float s = ((float)Math.Sqrt(ta * ta + tc * tc) - 1 + data.offsetScaleX) * scaleMix + 1; + bone.a *= s; + bone.c *= s; + s = ((float)Math.Sqrt(tb * tb + td * td) - 1 + data.offsetScaleY) * scaleMix + 1; + bone.b *= s; + bone.d *= s; + modified = true; + } + + if (shearMix > 0) { + float r = MathUtils.Atan2(td, tb) - MathUtils.Atan2(tc, ta); + if (r > MathUtils.PI) + r -= MathUtils.PI2; + else if (r < -MathUtils.PI) r += MathUtils.PI2; + float b = bone.b, d = bone.d; + r = MathUtils.Atan2(d, b) + (r - MathUtils.PI / 2 + offsetShearY) * shearMix; + float s = (float)Math.Sqrt(b * b + d * d); + bone.b = MathUtils.Cos(r) * s; + bone.d = MathUtils.Sin(r) * s; + modified = true; + } + + if (modified) bone.appliedValid = false; + } + } + + void ApplyAbsoluteLocal () { + float rotateMix = this.rotateMix, translateMix = this.translateMix, scaleMix = this.scaleMix, shearMix = this.shearMix; + Bone target = this.target; + if (!target.appliedValid) target.UpdateAppliedTransform(); + var bonesItems = this.bones.Items; + for (int i = 0, n = this.bones.Count; i < n; i++) { + Bone bone = bonesItems[i]; + if (!bone.appliedValid) bone.UpdateAppliedTransform(); + + float rotation = bone.arotation; + if (rotateMix != 0) { + float r = target.arotation - rotation + data.offsetRotation; + r -= (16384 - (int)(16384.499999999996 - r / 360)) * 360; + rotation += r * rotateMix; + } + + float x = bone.ax, y = bone.ay; + if (translateMix != 0) { + x += (target.ax - x + data.offsetX) * translateMix; + y += (target.ay - y + data.offsetY) * translateMix; + } + + float scaleX = bone.ascaleX, scaleY = bone.ascaleY; + if (scaleMix != 0) { + if (scaleX != 0) scaleX = (scaleX + (target.ascaleX - scaleX + data.offsetScaleX) * scaleMix) / scaleX; + if (scaleY != 0) scaleY = (scaleY + (target.ascaleY - scaleY + data.offsetScaleY) * scaleMix) / scaleY; + } + + float shearY = bone.ashearY; + if (shearMix != 0) { + float r = target.ashearY - shearY + data.offsetShearY; + r -= (16384 - (int)(16384.499999999996 - r / 360)) * 360; + shearY += r * shearMix; + } + + bone.UpdateWorldTransform(x, y, rotation, scaleX, scaleY, bone.ashearX, shearY); + } + } + + void ApplyRelativeLocal () { + float rotateMix = this.rotateMix, translateMix = this.translateMix, scaleMix = this.scaleMix, shearMix = this.shearMix; + Bone target = this.target; + if (!target.appliedValid) target.UpdateAppliedTransform(); + var bonesItems = this.bones.Items; + for (int i = 0, n = this.bones.Count; i < n; i++) { + Bone bone = bonesItems[i]; + if (!bone.appliedValid) bone.UpdateAppliedTransform(); + + float rotation = bone.arotation; + if (rotateMix != 0) rotation += (target.arotation + data.offsetRotation) * rotateMix; + + float x = bone.ax, y = bone.ay; + if (translateMix != 0) { + x += (target.ax + data.offsetX) * translateMix; + y += (target.ay + data.offsetY) * translateMix; + } + + float scaleX = bone.ascaleX, scaleY = bone.ascaleY; + if (scaleMix != 0) { + scaleX *= ((target.ascaleX - 1 + data.offsetScaleX) * scaleMix) + 1; + scaleY *= ((target.ascaleY - 1 + data.offsetScaleY) * scaleMix) + 1; + } + + float shearY = bone.ashearY; + if (shearMix != 0) shearY += (target.ashearY + data.offsetShearY) * shearMix; + + bone.UpdateWorldTransform(x, y, rotation, scaleX, scaleY, bone.ashearX, shearY); + } + } + + /// The bones that will be modified by this transform constraint. + public ExposedList Bones { get { return bones; } } + /// The target bone whose world transform will be copied to the constrained bones. + public Bone Target { get { return target; } set { target = value; } } + /// A percentage (0-1) that controls the mix between the constrained and unconstrained rotations. + public float RotateMix { get { return rotateMix; } set { rotateMix = value; } } + /// A percentage (0-1) that controls the mix between the constrained and unconstrained translations. + public float TranslateMix { get { return translateMix; } set { translateMix = value; } } + /// A percentage (0-1) that controls the mix between the constrained and unconstrained scales. + public float ScaleMix { get { return scaleMix; } set { scaleMix = value; } } + /// A percentage (0-1) that controls the mix between the constrained and unconstrained scales. + public float ShearMix { get { return shearMix; } set { shearMix = value; } } + public bool Active { get { return active; } } + /// The transform constraint's setup pose data. + public TransformConstraintData Data { get { return data; } } + + override public string ToString () { + return data.name; + } + } +} diff --git a/box1/Assets/Spine/Runtime/spine-csharp/TransformConstraint.cs.meta b/box1/Assets/Spine/Runtime/spine-csharp/TransformConstraint.cs.meta new file mode 100644 index 00000000..b3e7adad --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-csharp/TransformConstraint.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 2e30316a9733f8a4b8b6c362c06dfa11 +timeCreated: 1456265153 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-csharp/TransformConstraintData.cs b/box1/Assets/Spine/Runtime/spine-csharp/TransformConstraintData.cs new file mode 100644 index 00000000..f3da4d6a --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-csharp/TransformConstraintData.cs @@ -0,0 +1,60 @@ +/****************************************************************************** + * 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; + +namespace Spine { + public class TransformConstraintData : ConstraintData { + internal ExposedList bones = new ExposedList(); + internal BoneData target; + internal float rotateMix, translateMix, scaleMix, shearMix; + internal float offsetRotation, offsetX, offsetY, offsetScaleX, offsetScaleY, offsetShearY; + internal bool relative, local; + + public ExposedList Bones { get { return bones; } } + public BoneData Target { get { return target; } set { target = value; } } + public float RotateMix { get { return rotateMix; } set { rotateMix = value; } } + public float TranslateMix { get { return translateMix; } set { translateMix = value; } } + public float ScaleMix { get { return scaleMix; } set { scaleMix = value; } } + public float ShearMix { get { return shearMix; } set { shearMix = value; } } + + public float OffsetRotation { get { return offsetRotation; } set { offsetRotation = value; } } + public float OffsetX { get { return offsetX; } set { offsetX = value; } } + public float OffsetY { get { return offsetY; } set { offsetY = value; } } + public float OffsetScaleX { get { return offsetScaleX; } set { offsetScaleX = value; } } + public float OffsetScaleY { get { return offsetScaleY; } set { offsetScaleY = value; } } + public float OffsetShearY { get { return offsetShearY; } set { offsetShearY = value; } } + + public bool Relative { get { return relative; } set { relative = value; } } + public bool Local { get { return local; } set { local = value; } } + + public TransformConstraintData (string name) : base(name) { + } + } +} diff --git a/box1/Assets/Spine/Runtime/spine-csharp/TransformConstraintData.cs.meta b/box1/Assets/Spine/Runtime/spine-csharp/TransformConstraintData.cs.meta new file mode 100644 index 00000000..d8b3f279 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-csharp/TransformConstraintData.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: b7edeecc9bd7dd44faabf24f29b119a0 +timeCreated: 1456265155 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-csharp/Triangulator.cs b/box1/Assets/Spine/Runtime/spine-csharp/Triangulator.cs new file mode 100644 index 00000000..f0cc8dc5 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-csharp/Triangulator.cs @@ -0,0 +1,277 @@ +/****************************************************************************** + * 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; + +namespace Spine { + public class Triangulator { + private readonly ExposedList> convexPolygons = new ExposedList>(); + private readonly ExposedList> convexPolygonsIndices = new ExposedList>(); + + private readonly ExposedList indicesArray = new ExposedList(); + private readonly ExposedList isConcaveArray = new ExposedList(); + private readonly ExposedList triangles = new ExposedList(); + + private readonly Pool> polygonPool = new Pool>(); + private readonly Pool> polygonIndicesPool = new Pool>(); + + public ExposedList Triangulate (ExposedList verticesArray) { + var vertices = verticesArray.Items; + int vertexCount = verticesArray.Count >> 1; + + var indicesArray = this.indicesArray; + indicesArray.Clear(); + int[] indices = indicesArray.Resize(vertexCount).Items; + for (int i = 0; i < vertexCount; i++) + indices[i] = i; + + var isConcaveArray = this.isConcaveArray; + bool[] isConcave = isConcaveArray.Resize(vertexCount).Items; + for (int i = 0, n = vertexCount; i < n; ++i) + isConcave[i] = IsConcave(i, vertexCount, vertices, indices); + + var triangles = this.triangles; + triangles.Clear(); + triangles.EnsureCapacity(Math.Max(0, vertexCount - 2) << 2); + + while (vertexCount > 3) { + // Find ear tip. + int previous = vertexCount - 1, i = 0, next = 1; + + // outer: + while (true) { + if (!isConcave[i]) { + int p1 = indices[previous] << 1, p2 = indices[i] << 1, p3 = indices[next] << 1; + float p1x = vertices[p1], p1y = vertices[p1 + 1]; + float p2x = vertices[p2], p2y = vertices[p2 + 1]; + float p3x = vertices[p3], p3y = vertices[p3 + 1]; + for (int ii = (next + 1) % vertexCount; ii != previous; ii = (ii + 1) % vertexCount) { + if (!isConcave[ii]) continue; + int v = indices[ii] << 1; + float vx = vertices[v], vy = vertices[v + 1]; + if (PositiveArea(p3x, p3y, p1x, p1y, vx, vy)) { + if (PositiveArea(p1x, p1y, p2x, p2y, vx, vy)) { + if (PositiveArea(p2x, p2y, p3x, p3y, vx, vy)) goto break_outer; // break outer; + } + } + } + break; + } + break_outer: + + if (next == 0) { + do { + if (!isConcave[i]) break; + i--; + } while (i > 0); + break; + } + + previous = i; + i = next; + next = (next + 1) % vertexCount; + } + + // Cut ear tip. + triangles.Add(indices[(vertexCount + i - 1) % vertexCount]); + triangles.Add(indices[i]); + triangles.Add(indices[(i + 1) % vertexCount]); + indicesArray.RemoveAt(i); + isConcaveArray.RemoveAt(i); + vertexCount--; + + int previousIndex = (vertexCount + i - 1) % vertexCount; + int nextIndex = i == vertexCount ? 0 : i; + isConcave[previousIndex] = IsConcave(previousIndex, vertexCount, vertices, indices); + isConcave[nextIndex] = IsConcave(nextIndex, vertexCount, vertices, indices); + } + + if (vertexCount == 3) { + triangles.Add(indices[2]); + triangles.Add(indices[0]); + triangles.Add(indices[1]); + } + + return triangles; + } + + public ExposedList> Decompose (ExposedList verticesArray, ExposedList triangles) { + var vertices = verticesArray.Items; + var convexPolygons = this.convexPolygons; + for (int i = 0, n = convexPolygons.Count; i < n; i++) { + polygonPool.Free(convexPolygons.Items[i]); + } + convexPolygons.Clear(); + + var convexPolygonsIndices = this.convexPolygonsIndices; + for (int i = 0, n = convexPolygonsIndices.Count; i < n; i++) { + polygonIndicesPool.Free(convexPolygonsIndices.Items[i]); + } + convexPolygonsIndices.Clear(); + + var polygonIndices = polygonIndicesPool.Obtain(); + polygonIndices.Clear(); + + var polygon = polygonPool.Obtain(); + polygon.Clear(); + + // Merge subsequent triangles if they form a triangle fan. + int fanBaseIndex = -1, lastWinding = 0; + int[] trianglesItems = triangles.Items; + for (int i = 0, n = triangles.Count; i < n; i += 3) { + int t1 = trianglesItems[i] << 1, t2 = trianglesItems[i + 1] << 1, t3 = trianglesItems[i + 2] << 1; + float x1 = vertices[t1], y1 = vertices[t1 + 1]; + float x2 = vertices[t2], y2 = vertices[t2 + 1]; + float x3 = vertices[t3], y3 = vertices[t3 + 1]; + + // If the base of the last triangle is the same as this triangle, check if they form a convex polygon (triangle fan). + var merged = false; + if (fanBaseIndex == t1) { + int o = polygon.Count - 4; + float[] p = polygon.Items; + int winding1 = Winding(p[o], p[o + 1], p[o + 2], p[o + 3], x3, y3); + int winding2 = Winding(x3, y3, p[0], p[1], p[2], p[3]); + if (winding1 == lastWinding && winding2 == lastWinding) { + polygon.Add(x3); + polygon.Add(y3); + polygonIndices.Add(t3); + merged = true; + } + } + + // Otherwise make this triangle the new base. + if (!merged) { + if (polygon.Count > 0) { + convexPolygons.Add(polygon); + convexPolygonsIndices.Add(polygonIndices); + } else { + polygonPool.Free(polygon); + polygonIndicesPool.Free(polygonIndices); + } + polygon = polygonPool.Obtain(); + polygon.Clear(); + polygon.Add(x1); + polygon.Add(y1); + polygon.Add(x2); + polygon.Add(y2); + polygon.Add(x3); + polygon.Add(y3); + polygonIndices = polygonIndicesPool.Obtain(); + polygonIndices.Clear(); + polygonIndices.Add(t1); + polygonIndices.Add(t2); + polygonIndices.Add(t3); + lastWinding = Winding(x1, y1, x2, y2, x3, y3); + fanBaseIndex = t1; + } + } + + if (polygon.Count > 0) { + convexPolygons.Add(polygon); + convexPolygonsIndices.Add(polygonIndices); + } + + // Go through the list of polygons and try to merge the remaining triangles with the found triangle fans. + for (int i = 0, n = convexPolygons.Count; i < n; i++) { + polygonIndices = convexPolygonsIndices.Items[i]; + if (polygonIndices.Count == 0) continue; + int firstIndex = polygonIndices.Items[0]; + int lastIndex = polygonIndices.Items[polygonIndices.Count - 1]; + + polygon = convexPolygons.Items[i]; + int o = polygon.Count - 4; + float[] p = polygon.Items; + float prevPrevX = p[o], prevPrevY = p[o + 1]; + float prevX = p[o + 2], prevY = p[o + 3]; + float firstX = p[0], firstY = p[1]; + float secondX = p[2], secondY = p[3]; + int winding = Winding(prevPrevX, prevPrevY, prevX, prevY, firstX, firstY); + + for (int ii = 0; ii < n; ii++) { + if (ii == i) continue; + var otherIndices = convexPolygonsIndices.Items[ii]; + if (otherIndices.Count != 3) continue; + int otherFirstIndex = otherIndices.Items[0]; + int otherSecondIndex = otherIndices.Items[1]; + int otherLastIndex = otherIndices.Items[2]; + + var otherPoly = convexPolygons.Items[ii]; + float x3 = otherPoly.Items[otherPoly.Count - 2], y3 = otherPoly.Items[otherPoly.Count - 1]; + + if (otherFirstIndex != firstIndex || otherSecondIndex != lastIndex) continue; + int winding1 = Winding(prevPrevX, prevPrevY, prevX, prevY, x3, y3); + int winding2 = Winding(x3, y3, firstX, firstY, secondX, secondY); + if (winding1 == winding && winding2 == winding) { + otherPoly.Clear(); + otherIndices.Clear(); + polygon.Add(x3); + polygon.Add(y3); + polygonIndices.Add(otherLastIndex); + prevPrevX = prevX; + prevPrevY = prevY; + prevX = x3; + prevY = y3; + ii = 0; + } + } + } + + // Remove empty polygons that resulted from the merge step above. + for (int i = convexPolygons.Count - 1; i >= 0; i--) { + polygon = convexPolygons.Items[i]; + if (polygon.Count == 0) { + convexPolygons.RemoveAt(i); + polygonPool.Free(polygon); + polygonIndices = convexPolygonsIndices.Items[i]; + convexPolygonsIndices.RemoveAt(i); + polygonIndicesPool.Free(polygonIndices); + } + } + + return convexPolygons; + } + + static private bool IsConcave (int index, int vertexCount, float[] vertices, int[] indices) { + int previous = indices[(vertexCount + index - 1) % vertexCount] << 1; + int current = indices[index] << 1; + int next = indices[(index + 1) % vertexCount] << 1; + return !PositiveArea(vertices[previous], vertices[previous + 1], vertices[current], vertices[current + 1], vertices[next], + vertices[next + 1]); + } + + static private bool PositiveArea (float p1x, float p1y, float p2x, float p2y, float p3x, float p3y) { + return p1x * (p3y - p2y) + p2x * (p1y - p3y) + p3x * (p2y - p1y) >= 0; + } + + static private int Winding (float p1x, float p1y, float p2x, float p2y, float p3x, float p3y) { + float px = p2x - p1x, py = p2y - p1y; + return p3x * py - p3y * px + px * p1y - p1x * py >= 0 ? 1 : -1; + } + } +} diff --git a/box1/Assets/Spine/Runtime/spine-csharp/Triangulator.cs.meta b/box1/Assets/Spine/Runtime/spine-csharp/Triangulator.cs.meta new file mode 100644 index 00000000..cdabaebe --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-csharp/Triangulator.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 90a8832a1f3c5f846b8773dc0e1c3238 +timeCreated: 1493126637 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity.asmdef b/box1/Assets/Spine/Runtime/spine-unity.asmdef new file mode 100644 index 00000000..cabce6f9 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity.asmdef @@ -0,0 +1,4 @@ +{ + "name": "spine-unity", + "references": [] +} diff --git a/box1/Assets/Spine/Runtime/spine-unity.asmdef.meta b/box1/Assets/Spine/Runtime/spine-unity.asmdef.meta new file mode 100644 index 00000000..549f3cb7 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 68765d262e2128e4ab49c983f3411946 +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity.meta b/box1/Assets/Spine/Runtime/spine-unity.meta new file mode 100644 index 00000000..f89227fa --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity.meta @@ -0,0 +1,5 @@ +fileFormatVersion: 2 +guid: 29a3535756b284a428d35dcd4327185e +folderAsset: yes +DefaultImporter: + userData: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Asset Types.meta b/box1/Assets/Spine/Runtime/spine-unity/Asset Types.meta new file mode 100644 index 00000000..ade58c0b --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Asset Types.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 1dc4b7c23385e8c43ad19d01cbed78ce +folderAsset: yes +timeCreated: 1455489521 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Asset Types/AnimationReferenceAsset.cs b/box1/Assets/Spine/Runtime/spine-unity/Asset Types/AnimationReferenceAsset.cs new file mode 100644 index 00000000..494ce23e --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Asset Types/AnimationReferenceAsset.cs @@ -0,0 +1,66 @@ +/****************************************************************************** + * 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. + *****************************************************************************/ + +#define AUTOINIT_SPINEREFERENCE + +using UnityEngine; + +namespace Spine.Unity { + [CreateAssetMenu(menuName = "Spine/Animation Reference Asset", order = 100)] + public class AnimationReferenceAsset : ScriptableObject, IHasSkeletonDataAsset { + const bool QuietSkeletonData = true; + + [SerializeField] protected SkeletonDataAsset skeletonDataAsset; + [SerializeField, SpineAnimation] protected string animationName; + private Animation animation; + + public SkeletonDataAsset SkeletonDataAsset { get { return skeletonDataAsset; } } + + public Animation Animation { + get { + #if AUTOINIT_SPINEREFERENCE + if (animation == null) + Initialize(); + #endif + + return animation; + } + } + + public void Initialize () { + if (skeletonDataAsset == null) return; + this.animation = skeletonDataAsset.GetSkeletonData(AnimationReferenceAsset.QuietSkeletonData).FindAnimation(animationName); + if (this.animation == null) Debug.LogWarningFormat("Animation '{0}' not found in SkeletonData : {1}.", animationName, skeletonDataAsset.name); + } + + public static implicit operator Animation (AnimationReferenceAsset asset) { + return asset.Animation; + } + } +} diff --git a/box1/Assets/Spine/Runtime/spine-unity/Asset Types/AnimationReferenceAsset.cs.meta b/box1/Assets/Spine/Runtime/spine-unity/Asset Types/AnimationReferenceAsset.cs.meta new file mode 100644 index 00000000..dbfadcdb --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Asset Types/AnimationReferenceAsset.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 6e3e95a05e4c9774397eeeb7bdee8ccb +timeCreated: 1523328498 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {fileID: 2800000, guid: 52b12ec801461494185a4d3dc66f3d1d, type: 3} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Asset Types/AtlasAssetBase.cs b/box1/Assets/Spine/Runtime/spine-unity/Asset Types/AtlasAssetBase.cs new file mode 100644 index 00000000..a987b54f --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Asset Types/AtlasAssetBase.cs @@ -0,0 +1,44 @@ +/****************************************************************************** + * 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.Collections; +using System.Collections.Generic; +using UnityEngine; + +namespace Spine.Unity { + public abstract class AtlasAssetBase : ScriptableObject { + public abstract Material PrimaryMaterial { get; } + public abstract IEnumerable Materials { get; } + public abstract int MaterialCount { get; } + + public abstract bool IsLoaded { get; } + public abstract void Clear (); + public abstract Atlas GetAtlas (); + } +} diff --git a/box1/Assets/Spine/Runtime/spine-unity/Asset Types/AtlasAssetBase.cs.meta b/box1/Assets/Spine/Runtime/spine-unity/Asset Types/AtlasAssetBase.cs.meta new file mode 100644 index 00000000..5469af61 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Asset Types/AtlasAssetBase.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 787a36933c1c6e14db2104c01ed92dcb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Asset Types/EventDataReferenceAsset.cs b/box1/Assets/Spine/Runtime/spine-unity/Asset Types/EventDataReferenceAsset.cs new file mode 100644 index 00000000..38e41dfe --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Asset Types/EventDataReferenceAsset.cs @@ -0,0 +1,65 @@ +/****************************************************************************** + * 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. + *****************************************************************************/ + +#define AUTOINIT_SPINEREFERENCE + +using UnityEngine; + +namespace Spine.Unity { + [CreateAssetMenu(menuName = "Spine/EventData Reference Asset", order = 100)] + public class EventDataReferenceAsset : ScriptableObject { + const bool QuietSkeletonData = true; + + [SerializeField] protected SkeletonDataAsset skeletonDataAsset; + [SerializeField, SpineEvent(dataField: "skeletonDataAsset")] protected string eventName; + + EventData eventData; + public EventData EventData { + get { + #if AUTOINIT_SPINEREFERENCE + if (eventData == null) + Initialize(); + #endif + return eventData; + } + } + + public void Initialize () { + if (skeletonDataAsset == null) + return; + this.eventData = skeletonDataAsset.GetSkeletonData(EventDataReferenceAsset.QuietSkeletonData).FindEvent(eventName); + if (this.eventData == null) + Debug.LogWarningFormat("Event Data '{0}' not found in SkeletonData : {1}.", eventName, skeletonDataAsset.name); + } + + public static implicit operator EventData (EventDataReferenceAsset asset) { + return asset.EventData; + } + } +} diff --git a/box1/Assets/Spine/Runtime/spine-unity/Asset Types/EventDataReferenceAsset.cs.meta b/box1/Assets/Spine/Runtime/spine-unity/Asset Types/EventDataReferenceAsset.cs.meta new file mode 100644 index 00000000..cb261305 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Asset Types/EventDataReferenceAsset.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 8e60be42c1473144db0fd3337c25b500 +timeCreated: 1523330891 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {fileID: 2800000, guid: d226a80acc775714aa78b85e16a00e9b, type: 3} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Asset Types/RegionlessAttachmentLoader.cs b/box1/Assets/Spine/Runtime/spine-unity/Asset Types/RegionlessAttachmentLoader.cs new file mode 100644 index 00000000..37e7eaa2 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Asset Types/RegionlessAttachmentLoader.cs @@ -0,0 +1,83 @@ +/****************************************************************************** + * 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 UnityEngine; + +namespace Spine.Unity { + + public class RegionlessAttachmentLoader : AttachmentLoader { + + static AtlasRegion emptyRegion; + static AtlasRegion EmptyRegion { + get { + if (emptyRegion == null) { + emptyRegion = new AtlasRegion { + name = "Empty AtlasRegion", + page = new AtlasPage { + name = "Empty AtlasPage", + rendererObject = new Material(Shader.Find("Spine/Special/HiddenPass")) { name = "NoRender Material" } + } + }; + } + return emptyRegion; + } + } + + public RegionAttachment NewRegionAttachment (Skin skin, string name, string path) { + RegionAttachment attachment = new RegionAttachment(name) { + RendererObject = EmptyRegion + }; + return attachment; + } + + public MeshAttachment NewMeshAttachment (Skin skin, string name, string path) { + MeshAttachment attachment = new MeshAttachment(name) { + RendererObject = EmptyRegion + }; + return attachment; + } + + public BoundingBoxAttachment NewBoundingBoxAttachment (Skin skin, string name) { + return new BoundingBoxAttachment(name); + } + + public PathAttachment NewPathAttachment (Skin skin, string name) { + return new PathAttachment(name); + } + + public PointAttachment NewPointAttachment (Skin skin, string name) { + return new PointAttachment(name); + } + + public ClippingAttachment NewClippingAttachment (Skin skin, string name) { + return new ClippingAttachment(name); + } + } +} diff --git a/box1/Assets/Spine/Runtime/spine-unity/Asset Types/RegionlessAttachmentLoader.cs.meta b/box1/Assets/Spine/Runtime/spine-unity/Asset Types/RegionlessAttachmentLoader.cs.meta new file mode 100644 index 00000000..5d7a368b --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Asset Types/RegionlessAttachmentLoader.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 15f0f78b87720c047a320c5e0e3f91b7 +timeCreated: 1520505662 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Asset Types/SkeletonDataAsset.cs b/box1/Assets/Spine/Runtime/spine-unity/Asset Types/SkeletonDataAsset.cs new file mode 100644 index 00000000..f642b10a --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Asset Types/SkeletonDataAsset.cs @@ -0,0 +1,249 @@ +/****************************************************************************** + * 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.IO; +using UnityEngine; + +using CompatibilityProblemInfo = Spine.Unity.SkeletonDataCompatibility.CompatibilityProblemInfo; + +namespace Spine.Unity { + + [CreateAssetMenu(fileName = "New SkeletonDataAsset", menuName = "Spine/SkeletonData Asset")] + public class SkeletonDataAsset : ScriptableObject { + #region Inspector + public AtlasAssetBase[] atlasAssets = new AtlasAssetBase[0]; + + #if SPINE_TK2D + public tk2dSpriteCollectionData spriteCollection; + public float scale = 1f; + #else + public float scale = 0.01f; + #endif + public TextAsset skeletonJSON; + + [Tooltip("Use SkeletonDataModifierAssets to apply changes to the SkeletonData after being loaded, such as apply blend mode Materials to Attachments under slots with special blend modes.")] + public List skeletonDataModifiers = new List(); + + [SpineAnimation(includeNone: false)] + public string[] fromAnimation = new string[0]; + [SpineAnimation(includeNone: false)] + public string[] toAnimation = new string[0]; + public float[] duration = new float[0]; + public float defaultMix; + public RuntimeAnimatorController controller; + + public bool IsLoaded { get { return this.skeletonData != null; } } + + void Reset () { + Clear(); + } + #endregion + + SkeletonData skeletonData; + AnimationStateData stateData; + + #region Runtime Instantiation + /// + /// Creates a runtime SkeletonDataAsset. + public static SkeletonDataAsset CreateRuntimeInstance (TextAsset skeletonDataFile, AtlasAssetBase atlasAsset, bool initialize, float scale = 0.01f) { + return CreateRuntimeInstance(skeletonDataFile, new [] {atlasAsset}, initialize, scale); + } + + /// + /// Creates a runtime SkeletonDataAsset. + public static SkeletonDataAsset CreateRuntimeInstance (TextAsset skeletonDataFile, AtlasAssetBase[] atlasAssets, bool initialize, float scale = 0.01f) { + SkeletonDataAsset skeletonDataAsset = ScriptableObject.CreateInstance(); + skeletonDataAsset.Clear(); + skeletonDataAsset.skeletonJSON = skeletonDataFile; + skeletonDataAsset.atlasAssets = atlasAssets; + skeletonDataAsset.scale = scale; + + if (initialize) + skeletonDataAsset.GetSkeletonData(true); + + return skeletonDataAsset; + } + #endregion + + /// Clears the loaded SkeletonData and AnimationStateData. Use this to force a reload for the next time GetSkeletonData is called. + public void Clear () { + skeletonData = null; + stateData = null; + } + + public AnimationStateData GetAnimationStateData () { + if (stateData != null) + return stateData; + GetSkeletonData(false); + return stateData; + } + + /// Loads, caches and returns the SkeletonData from the skeleton data file. Returns the cached SkeletonData after the first time it is called. Pass false to prevent direct errors from being logged. + public SkeletonData GetSkeletonData (bool quiet) { + if (skeletonJSON == null) { + if (!quiet) + Debug.LogError("Skeleton JSON file not set for SkeletonData asset: " + name, this); + Clear(); + return null; + } + + // Disabled to support attachmentless/skinless SkeletonData. + // if (atlasAssets == null) { + // atlasAssets = new AtlasAsset[0]; + // if (!quiet) + // Debug.LogError("Atlas not set for SkeletonData asset: " + name, this); + // Clear(); + // return null; + // } + // #if !SPINE_TK2D + // if (atlasAssets.Length == 0) { + // Clear(); + // return null; + // } + // #else + // if (atlasAssets.Length == 0 && spriteCollection == null) { + // Clear(); + // return null; + // } + // #endif + + if (skeletonData != null) + return skeletonData; + + AttachmentLoader attachmentLoader; + float skeletonDataScale; + Atlas[] atlasArray = this.GetAtlasArray(); + + #if !SPINE_TK2D + attachmentLoader = (atlasArray.Length == 0) ? (AttachmentLoader)new RegionlessAttachmentLoader() : (AttachmentLoader)new AtlasAttachmentLoader(atlasArray); + skeletonDataScale = scale; + #else + if (spriteCollection != null) { + attachmentLoader = new Spine.Unity.TK2D.SpriteCollectionAttachmentLoader(spriteCollection); + skeletonDataScale = (1.0f / (spriteCollection.invOrthoSize * spriteCollection.halfTargetHeight) * scale); + } else { + if (atlasArray.Length == 0) { + Reset(); + if (!quiet) Debug.LogError("Atlas not set for SkeletonData asset: " + name, this); + return null; + } + attachmentLoader = new AtlasAttachmentLoader(atlasArray); + skeletonDataScale = scale; + } + #endif + + bool isBinary = skeletonJSON.name.ToLower().Contains(".skel"); + SkeletonData loadedSkeletonData = null; + + try { + if (isBinary) + loadedSkeletonData = SkeletonDataAsset.ReadSkeletonData(skeletonJSON.bytes, attachmentLoader, skeletonDataScale); + else + loadedSkeletonData = SkeletonDataAsset.ReadSkeletonData(skeletonJSON.text, attachmentLoader, skeletonDataScale); + } catch (Exception ex) { + if (!quiet) + Debug.LogError("Error reading skeleton JSON file for SkeletonData asset: " + name + "\n" + ex.Message + "\n" + ex.StackTrace, this); + } + + #if UNITY_EDITOR + if (loadedSkeletonData == null && !quiet && skeletonJSON != null) { + SkeletonDataCompatibility.VersionInfo fileVersion = SkeletonDataCompatibility.GetVersionInfo(skeletonJSON); + CompatibilityProblemInfo compatibilityProblemInfo = SkeletonDataCompatibility.GetCompatibilityProblemInfo(fileVersion); + if (compatibilityProblemInfo != null) { + SkeletonDataCompatibility.DisplayCompatibilityProblem(compatibilityProblemInfo.DescriptionString(), skeletonJSON); + return null; + } + } + #endif + if (loadedSkeletonData == null) + return null; + + if (skeletonDataModifiers != null) { + foreach (var m in skeletonDataModifiers) { + if (m != null) m.Apply(loadedSkeletonData); + } + } + + this.InitializeWithData(loadedSkeletonData); + + return skeletonData; + } + + internal void InitializeWithData (SkeletonData sd) { + this.skeletonData = sd; + this.stateData = new AnimationStateData(skeletonData); + FillStateData(); + } + + public void FillStateData () { + if (stateData != null) { + stateData.defaultMix = defaultMix; + + for (int i = 0, n = fromAnimation.Length; i < n; i++) { + if (fromAnimation[i].Length == 0 || toAnimation[i].Length == 0) + continue; + stateData.SetMix(fromAnimation[i], toAnimation[i], duration[i]); + } + } + } + + internal Atlas[] GetAtlasArray () { + var returnList = new System.Collections.Generic.List(atlasAssets.Length); + for (int i = 0; i < atlasAssets.Length; i++) { + var aa = atlasAssets[i]; + if (aa == null) continue; + var a = aa.GetAtlas(); + if (a == null) continue; + returnList.Add(a); + } + return returnList.ToArray(); + } + + internal static SkeletonData ReadSkeletonData (byte[] bytes, AttachmentLoader attachmentLoader, float scale) { + using (var input = new MemoryStream(bytes)) { + var binary = new SkeletonBinary(attachmentLoader) { + Scale = scale + }; + return binary.ReadSkeletonData(input); + } + } + + internal static SkeletonData ReadSkeletonData (string text, AttachmentLoader attachmentLoader, float scale) { + var input = new StringReader(text); + var json = new SkeletonJson(attachmentLoader) { + Scale = scale + }; + return json.ReadSkeletonData(input); + } + + } + +} diff --git a/box1/Assets/Spine/Runtime/spine-unity/Asset Types/SkeletonDataAsset.cs.meta b/box1/Assets/Spine/Runtime/spine-unity/Asset Types/SkeletonDataAsset.cs.meta new file mode 100644 index 00000000..941ef0f6 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Asset Types/SkeletonDataAsset.cs.meta @@ -0,0 +1,20 @@ +fileFormatVersion: 2 +guid: f1b3b4b945939a54ea0b23d3396115fb +timeCreated: 1536403985 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: + - multiplyMaterialTemplate: {fileID: 2100000, guid: 53bf0ab317d032d418cf1252d68f51df, + type: 2} + - screenMaterialTemplate: {fileID: 2100000, guid: 73f0f46d3177c614baf0fa48d646a9be, + type: 2} + - additiveMaterialTemplate: {fileID: 2100000, guid: 4deba332d47209e4780b3c5fcf0e3745, + type: 2} + - skeletonJSON: {instanceID: 0} + - controller: {instanceID: 0} + executionOrder: 0 + icon: {fileID: 2800000, guid: 68defdbc95b30a74a9ad396bfc9a2277, type: 3} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Asset Types/SkeletonDataCompatibility.cs b/box1/Assets/Spine/Runtime/spine-unity/Asset Types/SkeletonDataCompatibility.cs new file mode 100644 index 00000000..d072a31c --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Asset Types/SkeletonDataCompatibility.cs @@ -0,0 +1,171 @@ +/****************************************************************************** + * 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.Collections.Generic; +using System.IO; +using UnityEngine; +#if UNITY_EDITOR +using System.Globalization; +using System.Text.RegularExpressions; +#endif + +namespace Spine.Unity { + + public static class SkeletonDataCompatibility { + + #if UNITY_EDITOR + static readonly int[][] compatibleBinaryVersions = { new[] { 3, 8, 0 } }; + static readonly int[][] compatibleJsonVersions = { new[] { 3, 8, 0 } }; + + static bool wasVersionDialogShown = false; + static readonly Regex jsonVersionRegex = new Regex(@"""spine""\s*:\s*""([^""]+)""", RegexOptions.CultureInvariant); + #endif + + public enum SourceType { + Json, + Binary + } + + [System.Serializable] + public class VersionInfo { + public string rawVersion = null; + public int[] version = null; + public SourceType sourceType; + } + + [System.Serializable] + public class CompatibilityProblemInfo { + public VersionInfo actualVersion; + public int[][] compatibleVersions; + + public string DescriptionString () { + string compatibleVersionString = ""; + string optionalOr = null; + foreach (int[] version in compatibleVersions) { + compatibleVersionString += string.Format("{0}{1}.{2}", optionalOr, version[0], version[1]); + optionalOr = " or "; + } + return string.Format("Skeleton data could not be loaded. Data version: {0}. Required version: {1}.\nPlease re-export skeleton data with Spine {1} or change runtime to version {2}.{3}.", + actualVersion.rawVersion, compatibleVersionString, actualVersion.version[0], actualVersion.version[1]); + } + } + + #if UNITY_EDITOR + public static VersionInfo GetVersionInfo (TextAsset asset) { + if (asset == null) + return null; + + VersionInfo fileVersion = new VersionInfo(); + fileVersion.sourceType = asset.name.Contains(".skel") ? SourceType.Binary : SourceType.Json; + + if (fileVersion.sourceType == SourceType.Binary) { + try { + using (var memStream = new MemoryStream(asset.bytes)) { + fileVersion.rawVersion = SkeletonBinary.GetVersionString(memStream); + } + } + catch (System.Exception e) { + Debug.LogErrorFormat("Failed to read '{0}'. It is likely not a binary Spine SkeletonData file.\n{1}", asset.name, e); + return null; + } + } + else { + Match match = jsonVersionRegex.Match(asset.text); + if (match != null) { + fileVersion.rawVersion = match.Groups[1].Value; + } + else { + object obj = Json.Deserialize(new StringReader(asset.text)); + if (obj == null) { + Debug.LogErrorFormat("'{0}' is not valid JSON.", asset.name); + return null; + } + + var root = obj as Dictionary; + if (root == null) { + Debug.LogErrorFormat("'{0}' is not compatible JSON. Parser returned an incorrect type while parsing version info.", asset.name); + return null; + } + + if (root.ContainsKey("skeleton")) { + var skeletonInfo = (Dictionary)root["skeleton"]; + object jv; + skeletonInfo.TryGetValue("spine", out jv); + fileVersion.rawVersion = jv as string; + } + } + } + + if (string.IsNullOrEmpty(fileVersion.rawVersion)) { + // very likely not a Spine skeleton json file at all. + return null; + } + + var versionSplit = fileVersion.rawVersion.Split('.'); + try { + fileVersion.version = new[]{ int.Parse(versionSplit[0], CultureInfo.InvariantCulture), + int.Parse(versionSplit[1], CultureInfo.InvariantCulture) }; + } + catch (System.Exception e) { + Debug.LogErrorFormat("Failed to read version info at skeleton '{0}'. It is likely not a valid Spine SkeletonData file.\n{1}", asset.name, e); + return null; + } + return fileVersion; + } + + public static CompatibilityProblemInfo GetCompatibilityProblemInfo (VersionInfo fileVersion) { + if (fileVersion == null) + return null; + + CompatibilityProblemInfo info = new CompatibilityProblemInfo(); + info.actualVersion = fileVersion; + info.compatibleVersions = (fileVersion.sourceType == SourceType.Binary) ? compatibleBinaryVersions + : compatibleJsonVersions; + + foreach (var compatibleVersion in info.compatibleVersions) { + bool majorMatch = fileVersion.version[0] == compatibleVersion[0]; + bool minorMatch = fileVersion.version[1] == compatibleVersion[1]; + if (majorMatch && minorMatch) { + return null; // is compatible, thus no problem info returned + } + } + return info; + } + + public static void DisplayCompatibilityProblem (string descriptionString, TextAsset spineJson) { + if (!wasVersionDialogShown) { + wasVersionDialogShown = true; + UnityEditor.EditorUtility.DisplayDialog("Version mismatch!", descriptionString, "OK"); + } + Debug.LogError(string.Format("Error importing skeleton '{0}': {1}", + spineJson.name, descriptionString), spineJson); + } + #endif // UNITY_EDITOR + } +} diff --git a/box1/Assets/Spine/Runtime/spine-unity/Asset Types/SkeletonDataCompatibility.cs.meta b/box1/Assets/Spine/Runtime/spine-unity/Asset Types/SkeletonDataCompatibility.cs.meta new file mode 100644 index 00000000..1df7111a --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Asset Types/SkeletonDataCompatibility.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 4224df6e20549f0449154531ae080201 +timeCreated: 1567002861 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Asset Types/SkeletonDataModifierAsset.cs b/box1/Assets/Spine/Runtime/spine-unity/Asset Types/SkeletonDataModifierAsset.cs new file mode 100644 index 00000000..34fef4fa --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Asset Types/SkeletonDataModifierAsset.cs @@ -0,0 +1,39 @@ +/****************************************************************************** + * 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.Collections; +using System.Collections.Generic; +using UnityEngine; + +namespace Spine.Unity { + /// Can be stored by SkeletonDataAsset to automatically apply modifications to loaded SkeletonData. + public abstract class SkeletonDataModifierAsset : ScriptableObject { + public abstract void Apply (SkeletonData skeletonData); + } +} diff --git a/box1/Assets/Spine/Runtime/spine-unity/Asset Types/SkeletonDataModifierAsset.cs.meta b/box1/Assets/Spine/Runtime/spine-unity/Asset Types/SkeletonDataModifierAsset.cs.meta new file mode 100644 index 00000000..ffcc5f17 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Asset Types/SkeletonDataModifierAsset.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 79a44aba1f342f440965874280b4c318 +timeCreated: 1536412736 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Asset Types/SpineAtlasAsset.cs b/box1/Assets/Spine/Runtime/spine-unity/Asset Types/SpineAtlasAsset.cs new file mode 100644 index 00000000..55aba23d --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Asset Types/SpineAtlasAsset.cs @@ -0,0 +1,245 @@ +/****************************************************************************** + * 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.IO; +using UnityEngine; +using Spine; + +namespace Spine.Unity { + /// Loads and stores a Spine atlas and list of materials. + [CreateAssetMenu(fileName = "New Spine Atlas Asset", menuName = "Spine/Spine Atlas Asset")] + public class SpineAtlasAsset : AtlasAssetBase { + public TextAsset atlasFile; + public Material[] materials; + protected Atlas atlas; + + public override bool IsLoaded { get { return this.atlas != null; } } + + public override IEnumerable Materials { get { return materials; } } + public override int MaterialCount { get { return materials == null ? 0 : materials.Length; } } + public override Material PrimaryMaterial { get { return materials[0]; } } + + #region Runtime Instantiation + /// + /// Creates a runtime AtlasAsset + public static SpineAtlasAsset CreateRuntimeInstance (TextAsset atlasText, Material[] materials, bool initialize) { + SpineAtlasAsset atlasAsset = ScriptableObject.CreateInstance(); + atlasAsset.Reset(); + atlasAsset.atlasFile = atlasText; + atlasAsset.materials = materials; + + if (initialize) + atlasAsset.GetAtlas(); + + return atlasAsset; + } + + /// + /// Creates a runtime AtlasAsset. Only providing the textures is slower because it has to search for atlas page matches. + public static SpineAtlasAsset CreateRuntimeInstance (TextAsset atlasText, Texture2D[] textures, Material materialPropertySource, bool initialize) { + // Get atlas page names. + string atlasString = atlasText.text; + atlasString = atlasString.Replace("\r", ""); + string[] atlasLines = atlasString.Split('\n'); + var pages = new List(); + for (int i = 0; i < atlasLines.Length - 1; i++) { + if (atlasLines[i].Trim().Length == 0) + pages.Add(atlasLines[i + 1].Trim().Replace(".png", "")); + } + + // Populate Materials[] by matching texture names with page names. + var materials = new Material[pages.Count]; + for (int i = 0, n = pages.Count; i < n; i++) { + Material mat = null; + + // Search for a match. + string pageName = pages[i]; + for (int j = 0, m = textures.Length; j < m; j++) { + if (string.Equals(pageName, textures[j].name, System.StringComparison.OrdinalIgnoreCase)) { + // Match found. + mat = new Material(materialPropertySource); + mat.mainTexture = textures[j]; + break; + } + } + + if (mat != null) + materials[i] = mat; + else + throw new ArgumentException("Could not find matching atlas page in the texture array."); + } + + // Create AtlasAsset normally + return CreateRuntimeInstance(atlasText, materials, initialize); + } + + /// + /// Creates a runtime AtlasAsset. Only providing the textures is slower because it has to search for atlas page matches. + public static SpineAtlasAsset CreateRuntimeInstance (TextAsset atlasText, Texture2D[] textures, Shader shader, bool initialize) { + if (shader == null) + shader = Shader.Find("Spine/Skeleton"); + + Material materialProperySource = new Material(shader); + var oa = CreateRuntimeInstance(atlasText, textures, materialProperySource, initialize); + + return oa; + } + #endregion + + void Reset () { + Clear(); + } + + public override void Clear () { + atlas = null; + } + + /// The atlas or null if it could not be loaded. + public override Atlas GetAtlas () { + if (atlasFile == null) { + Debug.LogError("Atlas file not set for atlas asset: " + name, this); + Clear(); + return null; + } + + if (materials == null || materials.Length == 0) { + Debug.LogError("Materials not set for atlas asset: " + name, this); + Clear(); + return null; + } + + if (atlas != null) return atlas; + + try { + atlas = new Atlas(new StringReader(atlasFile.text), "", new MaterialsTextureLoader(this)); + atlas.FlipV(); + return atlas; + } catch (Exception ex) { + Debug.LogError("Error reading atlas file for atlas asset: " + name + "\n" + ex.Message + "\n" + ex.StackTrace, this); + return null; + } + } + + public Mesh GenerateMesh (string name, Mesh mesh, out Material material, float scale = 0.01f) { + AtlasRegion region = atlas.FindRegion(name); + material = null; + if (region != null) { + if (mesh == null) { + mesh = new Mesh(); + mesh.name = name; + } + + Vector3[] verts = new Vector3[4]; + Vector2[] uvs = new Vector2[4]; + Color[] colors = { Color.white, Color.white, Color.white, Color.white }; + int[] triangles = { 0, 1, 2, 2, 3, 0 }; + + float left, right, top, bottom; + left = region.width / -2f; + right = left * -1f; + top = region.height / 2f; + bottom = top * -1; + + verts[0] = new Vector3(left, bottom, 0) * scale; + verts[1] = new Vector3(left, top, 0) * scale; + verts[2] = new Vector3(right, top, 0) * scale; + verts[3] = new Vector3(right, bottom, 0) * scale; + float u, v, u2, v2; + u = region.u; + v = region.v; + u2 = region.u2; + v2 = region.v2; + + if (!region.rotate) { + uvs[0] = new Vector2(u, v2); + uvs[1] = new Vector2(u, v); + uvs[2] = new Vector2(u2, v); + uvs[3] = new Vector2(u2, v2); + } else { + uvs[0] = new Vector2(u2, v2); + uvs[1] = new Vector2(u, v2); + uvs[2] = new Vector2(u, v); + uvs[3] = new Vector2(u2, v); + } + + mesh.triangles = new int[0]; + mesh.vertices = verts; + mesh.uv = uvs; + mesh.colors = colors; + mesh.triangles = triangles; + mesh.RecalculateNormals(); + mesh.RecalculateBounds(); + + material = (Material)region.page.rendererObject; + } else { + mesh = null; + } + + return mesh; + } + } + + public class MaterialsTextureLoader : TextureLoader { + SpineAtlasAsset atlasAsset; + + public MaterialsTextureLoader (SpineAtlasAsset atlasAsset) { + this.atlasAsset = atlasAsset; + } + + public void Load (AtlasPage page, string path) { + String name = Path.GetFileNameWithoutExtension(path); + Material material = null; + foreach (Material other in atlasAsset.materials) { + if (other.mainTexture == null) { + Debug.LogError("Material is missing texture: " + other.name, other); + return; + } + if (other.mainTexture.name == name) { + material = other; + break; + } + } + if (material == null) { + Debug.LogError("Material with texture name \"" + name + "\" not found for atlas asset: " + atlasAsset.name, atlasAsset); + return; + } + page.rendererObject = material; + + // Very old atlas files expected the texture's actual size to be used at runtime. + if (page.width == 0 || page.height == 0) { + page.width = material.mainTexture.width; + page.height = material.mainTexture.height; + } + } + + public void Unload (object texture) { } + } +} diff --git a/box1/Assets/Spine/Runtime/spine-unity/Asset Types/SpineAtlasAsset.cs.meta b/box1/Assets/Spine/Runtime/spine-unity/Asset Types/SpineAtlasAsset.cs.meta new file mode 100644 index 00000000..e6a49205 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Asset Types/SpineAtlasAsset.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: a6b194f808b1af6499c93410e504af42 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {fileID: 2800000, guid: 3fc714a0dc1cf6b4b959e073fff2844e, type: 3} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Asset Types/SpineSpriteAtlasAsset.cs b/box1/Assets/Spine/Runtime/spine-unity/Asset Types/SpineSpriteAtlasAsset.cs new file mode 100644 index 00000000..12b1a700 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Asset Types/SpineSpriteAtlasAsset.cs @@ -0,0 +1,397 @@ +/****************************************************************************** + * 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_2_OR_NEWER +#define EXPOSES_SPRITE_ATLAS_UTILITIES +#endif + +using System; +using System.Collections.Generic; +using System.IO; +using UnityEngine; +using Spine; +using UnityEngine.U2D; + +#if UNITY_EDITOR +using UnityEditor; +using System.Reflection; +#endif + +namespace Spine.Unity { + /// Loads and stores a Spine atlas and list of materials. + [CreateAssetMenu(fileName = "New Spine SpriteAtlas Asset", menuName = "Spine/Spine SpriteAtlas Asset")] + public class SpineSpriteAtlasAsset : AtlasAssetBase { + public SpriteAtlas spriteAtlasFile; + public Material[] materials; + protected Atlas atlas; + public bool updateRegionsInPlayMode; + + [System.Serializable] + protected class SavedRegionInfo { + public float x, y, width, height; + public SpritePackingRotation packingRotation; + } + [SerializeField] protected SavedRegionInfo[] savedRegions; + + public override bool IsLoaded { get { return this.atlas != null; } } + + public override IEnumerable Materials { get { return materials; } } + public override int MaterialCount { get { return materials == null ? 0 : materials.Length; } } + public override Material PrimaryMaterial { get { return materials[0]; } } + + #if UNITY_EDITOR + static MethodInfo GetPackedSpritesMethod, GetPreviewTexturesMethod; + #if !EXPOSES_SPRITE_ATLAS_UTILITIES + static MethodInfo PackAtlasesMethod; + #endif + #endif + + #region Runtime Instantiation + /// + /// Creates a runtime AtlasAsset + public static SpineSpriteAtlasAsset CreateRuntimeInstance (SpriteAtlas spriteAtlasFile, Material[] materials, bool initialize) { + SpineSpriteAtlasAsset atlasAsset = ScriptableObject.CreateInstance(); + atlasAsset.Reset(); + atlasAsset.spriteAtlasFile = spriteAtlasFile; + atlasAsset.materials = materials; + + if (initialize) + atlasAsset.GetAtlas(); + + return atlasAsset; + } + #endregion + + void Reset () { + Clear(); + } + + public override void Clear () { + atlas = null; + } + + /// The atlas or null if it could not be loaded. + public override Atlas GetAtlas () { + if (spriteAtlasFile == null) { + Debug.LogError("SpriteAtlas file not set for SpineSpriteAtlasAsset: " + name, this); + Clear(); + return null; + } + + if (materials == null || materials.Length == 0) { + Debug.LogError("Materials not set for SpineSpriteAtlasAsset: " + name, this); + Clear(); + return null; + } + + if (atlas != null) return atlas; + + try { + atlas = LoadAtlas(spriteAtlasFile); + return atlas; + } catch (Exception ex) { + Debug.LogError("Error analyzing SpriteAtlas for SpineSpriteAtlasAsset: " + name + "\n" + ex.Message + "\n" + ex.StackTrace, this); + return null; + } + } + + protected void AssignRegionsFromSavedRegions (Sprite[] sprites, Atlas usedAtlas) { + + if (savedRegions == null || savedRegions.Length != sprites.Length) + return; + + int i = 0; + foreach (var region in usedAtlas) { + var savedRegion = savedRegions[i]; + var page = region.page; + + region.degrees = savedRegion.packingRotation == SpritePackingRotation.None ? 0 : 90; + region.rotate = region.degrees != 0; + + float x = savedRegion.x; + float y = savedRegion.y; + float width = savedRegion.width; + float height = savedRegion.height; + + region.u = x / (float)page.width; + region.v = y / (float)page.height; + if (region.rotate) { + region.u2 = (x + height) / (float)page.width; + region.v2 = (y + width) / (float)page.height; + } + else { + region.u2 = (x + width) / (float)page.width; + region.v2 = (y + height) / (float)page.height; + } + region.x = (int)x; + region.y = (int)y; + region.width = Math.Abs((int)width); + region.height = Math.Abs((int)height); + + // flip upside down + var temp = region.v; + region.v = region.v2; + region.v2 = temp; + + region.originalWidth = (int)width; + region.originalHeight = (int)height; + + // note: currently sprite pivot offsets are ignored. + // var sprite = sprites[i]; + region.offsetX = 0;//sprite.pivot.x; + region.offsetY = 0;//sprite.pivot.y; + + ++i; + } + } + + private Atlas LoadAtlas (UnityEngine.U2D.SpriteAtlas spriteAtlas) { + + List pages = new List(); + List regions = new List(); + + Sprite[] sprites = new UnityEngine.Sprite[spriteAtlas.spriteCount]; + spriteAtlas.GetSprites(sprites); + if (sprites.Length == 0) + return new Atlas(pages, regions); + + Texture2D texture = null; + #if UNITY_EDITOR + if (!Application.isPlaying) + texture = AccessPackedTextureEditor(spriteAtlas); + else + #endif + texture = AccessPackedTexture(sprites); + + Material material = materials[0]; + #if !UNITY_EDITOR + material.mainTexture = texture; + #endif + + Spine.AtlasPage page = new AtlasPage(); + page.name = spriteAtlas.name; + page.width = texture.width; + page.height = texture.height; + page.format = Spine.Format.RGBA8888; + + page.minFilter = TextureFilter.Linear; + page.magFilter = TextureFilter.Linear; + page.uWrap = TextureWrap.ClampToEdge; + page.vWrap = TextureWrap.ClampToEdge; + page.rendererObject = material; + pages.Add(page); + + sprites = AccessPackedSprites(spriteAtlas); + + int i = 0; + for ( ; i < sprites.Length; ++i) { + var sprite = sprites[i]; + AtlasRegion region = new AtlasRegion(); + region.name = sprite.name.Replace("(Clone)", ""); + region.page = page; + region.degrees = sprite.packingRotation == SpritePackingRotation.None ? 0 : 90; + region.rotate = region.degrees != 0; + + region.u2 = 1; + region.v2 = 1; + region.width = page.width; + region.height = page.height; + region.originalWidth = page.width; + region.originalHeight = page.height; + + region.index = i; + regions.Add(region); + } + + var atlas = new Atlas(pages, regions); + AssignRegionsFromSavedRegions(sprites, atlas); + + return atlas; + } + +#if UNITY_EDITOR + public static void UpdateByStartingEditorPlayMode () { + EditorApplication.isPlaying = true; + } + + public static bool AnySpriteAtlasNeedsRegionsLoaded () { + string[] guids = UnityEditor.AssetDatabase.FindAssets("t:SpineSpriteAtlasAsset"); + foreach (var guid in guids) { + string path = UnityEditor.AssetDatabase.GUIDToAssetPath(guid); + if (!string.IsNullOrEmpty(path)) { + var atlasAsset = UnityEditor.AssetDatabase.LoadAssetAtPath(path); + if (atlasAsset) { + if (atlasAsset.RegionsNeedLoading) + return true; + } + } + } + return false; + } + + public static void UpdateWhenEditorPlayModeStarted () { + if (!EditorApplication.isPlaying) + return; + + EditorApplication.update -= UpdateWhenEditorPlayModeStarted; + string[] guids = UnityEditor.AssetDatabase.FindAssets("t:SpineSpriteAtlasAsset"); + if (guids.Length == 0) + return; + + Debug.Log("Updating SpineSpriteAtlasAssets"); + foreach (var guid in guids) { + string path = UnityEditor.AssetDatabase.GUIDToAssetPath(guid); + if (!string.IsNullOrEmpty(path)) { + var atlasAsset = UnityEditor.AssetDatabase.LoadAssetAtPath(path); + if (atlasAsset) { + atlasAsset.atlas = atlasAsset.LoadAtlas(atlasAsset.spriteAtlasFile); + atlasAsset.LoadRegionsInEditorPlayMode(); + Debug.Log(string.Format("Updated regions of '{0}'", atlasAsset.name), atlasAsset); + } + } + } + + EditorApplication.isPlaying = false; + } + + public bool RegionsNeedLoading { + get { return savedRegions == null || savedRegions.Length == 0 || updateRegionsInPlayMode; } + } + + public void LoadRegionsInEditorPlayMode () { + + Sprite[] sprites = null; + System.Type T = Type.GetType("UnityEditor.U2D.SpriteAtlasExtensions,UnityEditor"); + var method = T.GetMethod("GetPackedSprites", BindingFlags.NonPublic | BindingFlags.Static); + if (method != null) { + object retval = method.Invoke(null, new object[] { spriteAtlasFile }); + var spritesArray = retval as Sprite[]; + if (spritesArray != null && spritesArray.Length > 0) { + sprites = spritesArray; + } + } + if (sprites == null) { + sprites = new UnityEngine.Sprite[spriteAtlasFile.spriteCount]; + spriteAtlasFile.GetSprites(sprites); + } + if (sprites.Length == 0) { + Debug.LogWarning(string.Format("SpriteAtlas '{0}' contains no sprites. Please make sure all assigned images are set to import type 'Sprite'.", spriteAtlasFile.name), spriteAtlasFile); + return; + } + else if (sprites[0].packingMode == SpritePackingMode.Tight) { + Debug.LogError(string.Format("SpriteAtlas '{0}': Tight packing is not supported. Please disable 'Tight Packing' in the SpriteAtlas Inspector.", spriteAtlasFile.name), spriteAtlasFile); + return; + } + + if (savedRegions == null || savedRegions.Length != sprites.Length) + savedRegions = new SavedRegionInfo[sprites.Length]; + + int i = 0; + foreach (var region in atlas) { + var sprite = sprites[i]; + var rect = sprite.textureRect; + float x = rect.min.x; + float y = rect.min.y; + float width = rect.width; + float height = rect.height; + + var savedRegion = new SavedRegionInfo(); + savedRegion.x = x; + savedRegion.y = y; + savedRegion.width = width; + savedRegion.height = height; + savedRegion.packingRotation = sprite.packingRotation; + savedRegions[i] = savedRegion; + + ++i; + } + updateRegionsInPlayMode = false; + AssignRegionsFromSavedRegions(sprites, atlas); + EditorUtility.SetDirty(this); + AssetDatabase.SaveAssets(); + } + + public static Texture2D AccessPackedTextureEditor (SpriteAtlas spriteAtlas) { + #if EXPOSES_SPRITE_ATLAS_UTILITIES + UnityEditor.U2D.SpriteAtlasUtility.PackAtlases(new SpriteAtlas[] { spriteAtlas }, EditorUserBuildSettings.activeBuildTarget); + #else + /*if (PackAtlasesMethod == null) { + System.Type T = Type.GetType("UnityEditor.U2D.SpriteAtlasUtility,UnityEditor"); + PackAtlasesMethod = T.GetMethod("PackAtlases", BindingFlags.NonPublic | BindingFlags.Static); + } + if (PackAtlasesMethod != null) { + PackAtlasesMethod.Invoke(null, new object[] { new SpriteAtlas[] { spriteAtlas }, EditorUserBuildSettings.activeBuildTarget }); + }*/ + #endif + if (GetPreviewTexturesMethod == null) { + System.Type T = Type.GetType("UnityEditor.U2D.SpriteAtlasExtensions,UnityEditor"); + GetPreviewTexturesMethod = T.GetMethod("GetPreviewTextures", BindingFlags.NonPublic | BindingFlags.Static); + } + if (GetPreviewTexturesMethod != null) { + object retval = GetPreviewTexturesMethod.Invoke(null, new object[] { spriteAtlas }); + var textures = retval as Texture2D[]; + if (textures.Length > 0) + return textures[0]; + } + return null; + } +#endif + public static Texture2D AccessPackedTexture (Sprite[] sprites) { + return sprites[0].texture; + } + + + public static Sprite[] AccessPackedSprites (UnityEngine.U2D.SpriteAtlas spriteAtlas) { + Sprite[] sprites = null; +#if UNITY_EDITOR + if (!Application.isPlaying) { + + if (GetPackedSpritesMethod == null) { + System.Type T = Type.GetType("UnityEditor.U2D.SpriteAtlasExtensions,UnityEditor"); + GetPackedSpritesMethod = T.GetMethod("GetPackedSprites", BindingFlags.NonPublic | BindingFlags.Static); + } + if (GetPackedSpritesMethod != null) { + object retval = GetPackedSpritesMethod.Invoke(null, new object[] { spriteAtlas }); + var spritesArray = retval as Sprite[]; + if (spritesArray != null && spritesArray.Length > 0) { + sprites = spritesArray; + } + } + } +#endif + if (sprites == null) { + sprites = new UnityEngine.Sprite[spriteAtlas.spriteCount]; + spriteAtlas.GetSprites(sprites); + if (sprites.Length == 0) + return null; + } + return sprites; + } + } +} diff --git a/box1/Assets/Spine/Runtime/spine-unity/Asset Types/SpineSpriteAtlasAsset.cs.meta b/box1/Assets/Spine/Runtime/spine-unity/Asset Types/SpineSpriteAtlasAsset.cs.meta new file mode 100644 index 00000000..e61e24e0 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Asset Types/SpineSpriteAtlasAsset.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ce59897dd7e6cbc4690a05ebaf975dff +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Components.meta b/box1/Assets/Spine/Runtime/spine-unity/Components.meta new file mode 100644 index 00000000..c8b46595 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Components.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 954179821df28404683b8289f05d0c6f +folderAsset: yes +timeCreated: 1518344191 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Components/Following.meta b/box1/Assets/Spine/Runtime/spine-unity/Components/Following.meta new file mode 100644 index 00000000..39fdc6c3 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Components/Following.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: b0fd98019ca00c74f929c6d1f7ee3544 +folderAsset: yes +timeCreated: 1563290418 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Components/Following/BoneFollower.cs b/box1/Assets/Spine/Runtime/spine-unity/Components/Following/BoneFollower.cs new file mode 100644 index 00000000..4938e15f --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Components/Following/BoneFollower.cs @@ -0,0 +1,193 @@ +/****************************************************************************** + * 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 UnityEngine; + +namespace Spine.Unity { + + /// Sets a GameObject's transform to match a bone on a Spine skeleton. + #if NEW_PREFAB_SYSTEM + [ExecuteAlways] + #else + [ExecuteInEditMode] + #endif + [AddComponentMenu("Spine/BoneFollower")] + [HelpURL("http://esotericsoftware.com/spine-unity#BoneFollower")] + public class BoneFollower : MonoBehaviour { + + #region Inspector + public SkeletonRenderer skeletonRenderer; + public SkeletonRenderer SkeletonRenderer { + get { return skeletonRenderer; } + set { + skeletonRenderer = value; + Initialize(); + } + } + + /// If a bone isn't set in code, boneName is used to find the bone at the beginning. For runtime switching by name, use SetBoneByName. You can also set the BoneFollower.bone field directly. + [SpineBone(dataField: "skeletonRenderer")] + public string boneName; + + public bool followXYPosition = true; + public bool followZPosition = true; + public bool followBoneRotation = true; + + [Tooltip("Follows the skeleton's flip state by controlling this Transform's local scale.")] + public bool followSkeletonFlip = true; + + [Tooltip("Follows the target bone's local scale. BoneFollower cannot inherit world/skewed scale because of UnityEngine.Transform property limitations.")] + public bool followLocalScale = false; + + [UnityEngine.Serialization.FormerlySerializedAs("resetOnAwake")] + public bool initializeOnAwake = true; + #endregion + + [NonSerialized] public bool valid; + [NonSerialized] public Bone bone; + + Transform skeletonTransform; + bool skeletonTransformIsParent; + + /// + /// Sets the target bone by its bone name. Returns false if no bone was found. To set the bone by reference, use BoneFollower.bone directly. + public bool SetBone (string name) { + bone = skeletonRenderer.skeleton.FindBone(name); + if (bone == null) { + Debug.LogError("Bone not found: " + name, this); + return false; + } + boneName = name; + return true; + } + + public void Awake () { + if (initializeOnAwake) Initialize(); + } + + public void HandleRebuildRenderer (SkeletonRenderer skeletonRenderer) { + Initialize(); + } + + public void Initialize () { + bone = null; + valid = skeletonRenderer != null && skeletonRenderer.valid; + if (!valid) return; + + skeletonTransform = skeletonRenderer.transform; + skeletonRenderer.OnRebuild -= HandleRebuildRenderer; + skeletonRenderer.OnRebuild += HandleRebuildRenderer; + skeletonTransformIsParent = Transform.ReferenceEquals(skeletonTransform, transform.parent); + + if (!string.IsNullOrEmpty(boneName)) + bone = skeletonRenderer.skeleton.FindBone(boneName); + + #if UNITY_EDITOR + if (Application.isEditor) + LateUpdate(); + #endif + } + + void OnDestroy () { + if (skeletonRenderer != null) + skeletonRenderer.OnRebuild -= HandleRebuildRenderer; + } + + public void LateUpdate () { + if (!valid) { + Initialize(); + return; + } + + #if UNITY_EDITOR + if (!Application.isPlaying) + skeletonTransformIsParent = Transform.ReferenceEquals(skeletonTransform, transform.parent); + #endif + + if (bone == null) { + if (string.IsNullOrEmpty(boneName)) return; + bone = skeletonRenderer.skeleton.FindBone(boneName); + if (!SetBone(boneName)) return; + } + + Transform thisTransform = this.transform; + if (skeletonTransformIsParent) { + // Recommended setup: Use local transform properties if Spine GameObject is the immediate parent + thisTransform.localPosition = new Vector3(followXYPosition ? bone.worldX : thisTransform.localPosition.x, + followXYPosition ? bone.worldY : thisTransform.localPosition.y, + followZPosition ? 0f : thisTransform.localPosition.z); + if (followBoneRotation) { + float halfRotation = Mathf.Atan2(bone.c, bone.a) * 0.5f; + if (followLocalScale && bone.scaleX < 0) // Negate rotation from negative scaleX. Don't use negative determinant. local scaleY doesn't factor into used rotation. + halfRotation += Mathf.PI * 0.5f; + + var q = default(Quaternion); + q.z = Mathf.Sin(halfRotation); + q.w = Mathf.Cos(halfRotation); + thisTransform.localRotation = q; + } + } else { + // For special cases: Use transform world properties if transform relationship is complicated + Vector3 targetWorldPosition = skeletonTransform.TransformPoint(new Vector3(bone.worldX, bone.worldY, 0f)); + if (!followZPosition) targetWorldPosition.z = thisTransform.position.z; + if (!followXYPosition) { + targetWorldPosition.x = thisTransform.position.x; + targetWorldPosition.y = thisTransform.position.y; + } + + float boneWorldRotation = bone.WorldRotationX; + + Transform transformParent = thisTransform.parent; + if (transformParent != null) { + Matrix4x4 m = transformParent.localToWorldMatrix; + if (m.m00 * m.m11 - m.m01 * m.m10 < 0) // Determinant2D is negative + boneWorldRotation = -boneWorldRotation; + } + + if (followBoneRotation) { + Vector3 worldRotation = skeletonTransform.rotation.eulerAngles; + if (followLocalScale && bone.scaleX < 0) boneWorldRotation += 180f; + thisTransform.SetPositionAndRotation(targetWorldPosition, Quaternion.Euler(worldRotation.x, worldRotation.y, worldRotation.z + boneWorldRotation)); + } else { + thisTransform.position = targetWorldPosition; + } + } + + Vector3 localScale = followLocalScale ? new Vector3(bone.scaleX, bone.scaleY, 1f) : new Vector3(1f, 1f, 1f); + if (followSkeletonFlip) localScale.y *= Mathf.Sign(bone.skeleton.ScaleX * bone.skeleton.ScaleY); + thisTransform.localScale = localScale; + } + } + +} diff --git a/box1/Assets/Spine/Runtime/spine-unity/Components/Following/BoneFollower.cs.meta b/box1/Assets/Spine/Runtime/spine-unity/Components/Following/BoneFollower.cs.meta new file mode 100644 index 00000000..c5bb78cf --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Components/Following/BoneFollower.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: a1fd8daaed7b64148a34acb96ba14ce1 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Components/Following/BoneFollowerGraphic.cs b/box1/Assets/Spine/Runtime/spine-unity/Components/Following/BoneFollowerGraphic.cs new file mode 100644 index 00000000..b8336cbf --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Components/Following/BoneFollowerGraphic.cs @@ -0,0 +1,175 @@ +/****************************************************************************** + * 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 UnityEngine; + +namespace Spine.Unity { + + #if NEW_PREFAB_SYSTEM + [ExecuteAlways] + #else + [ExecuteInEditMode] + #endif + [DisallowMultipleComponent] + [AddComponentMenu("Spine/UI/BoneFollowerGraphic")] + [HelpURL("http://esotericsoftware.com/spine-unity#BoneFollowerGraphic")] + public class BoneFollowerGraphic : MonoBehaviour { + public SkeletonGraphic skeletonGraphic; + public SkeletonGraphic SkeletonGraphic { + get { return skeletonGraphic; } + set { + skeletonGraphic = value; + Initialize(); + } + } + + public bool initializeOnAwake = true; + + /// If a bone isn't set in code, boneName is used to find the bone at the beginning. For runtime switching by name, use SetBoneByName. You can also set the BoneFollower.bone field directly. + [SpineBone(dataField: "skeletonGraphic")] + public string boneName; + + public bool followBoneRotation = true; + [Tooltip("Follows the skeleton's flip state by controlling this Transform's local scale.")] + public bool followSkeletonFlip = true; + [Tooltip("Follows the target bone's local scale. BoneFollower cannot inherit world/skewed scale because of UnityEngine.Transform property limitations.")] + public bool followLocalScale = false; + public bool followXYPosition = true; + public bool followZPosition = true; + + [System.NonSerialized] public Bone bone; + + Transform skeletonTransform; + bool skeletonTransformIsParent; + + [System.NonSerialized] public bool valid; + + /// + /// Sets the target bone by its bone name. Returns false if no bone was found. + public bool SetBone (string name) { + bone = skeletonGraphic.Skeleton.FindBone(name); + if (bone == null) { + Debug.LogError("Bone not found: " + name, this); + return false; + } + boneName = name; + return true; + } + + public void Awake () { + if (initializeOnAwake) Initialize(); + } + + public void Initialize () { + bone = null; + valid = skeletonGraphic != null && skeletonGraphic.IsValid; + if (!valid) return; + + skeletonTransform = skeletonGraphic.transform; +// skeletonGraphic.OnRebuild -= HandleRebuildRenderer; +// skeletonGraphic.OnRebuild += HandleRebuildRenderer; + skeletonTransformIsParent = Transform.ReferenceEquals(skeletonTransform, transform.parent); + + if (!string.IsNullOrEmpty(boneName)) + bone = skeletonGraphic.Skeleton.FindBone(boneName); + + #if UNITY_EDITOR + if (Application.isEditor) { + LateUpdate(); + } + #endif + } + + public void LateUpdate () { + if (!valid) { + Initialize(); + return; + } + + #if UNITY_EDITOR + if (!Application.isPlaying) + skeletonTransformIsParent = Transform.ReferenceEquals(skeletonTransform, transform.parent); + #endif + + if (bone == null) { + if (string.IsNullOrEmpty(boneName)) return; + bone = skeletonGraphic.Skeleton.FindBone(boneName); + if (!SetBone(boneName)) return; + } + + var thisTransform = this.transform as RectTransform; + if (thisTransform == null) return; + + var canvas = skeletonGraphic.canvas; + if (canvas == null) canvas = skeletonGraphic.GetComponentInParent(); + float scale = canvas != null ? canvas.referencePixelsPerUnit : 100.0f; + + if (skeletonTransformIsParent) { + // Recommended setup: Use local transform properties if Spine GameObject is the immediate parent + thisTransform.localPosition = new Vector3(followXYPosition ? bone.worldX * scale : thisTransform.localPosition.x, + followXYPosition ? bone.worldY * scale : thisTransform.localPosition.y, + followZPosition ? 0f : thisTransform.localPosition.z); + if (followBoneRotation) thisTransform.localRotation = bone.GetQuaternion(); + } else { + // For special cases: Use transform world properties if transform relationship is complicated + Vector3 targetWorldPosition = skeletonTransform.TransformPoint(new Vector3(bone.worldX * scale, bone.worldY * scale, 0f)); + if (!followZPosition) targetWorldPosition.z = thisTransform.position.z; + if (!followXYPosition) { + targetWorldPosition.x = thisTransform.position.x; + targetWorldPosition.y = thisTransform.position.y; + } + + float boneWorldRotation = bone.WorldRotationX; + + Transform transformParent = thisTransform.parent; + if (transformParent != null) { + Matrix4x4 m = transformParent.localToWorldMatrix; + if (m.m00 * m.m11 - m.m01 * m.m10 < 0) // Determinant2D is negative + boneWorldRotation = -boneWorldRotation; + } + + if (followBoneRotation) { + Vector3 worldRotation = skeletonTransform.rotation.eulerAngles; + thisTransform.SetPositionAndRotation(targetWorldPosition, Quaternion.Euler(worldRotation.x, worldRotation.y, skeletonTransform.rotation.eulerAngles.z + boneWorldRotation)); + } else { + thisTransform.position = targetWorldPosition; + } + } + + Vector3 localScale = followLocalScale ? new Vector3(bone.scaleX, bone.scaleY, 1f) : new Vector3(1f, 1f, 1f); + if (followSkeletonFlip) localScale.y *= Mathf.Sign(bone.skeleton.ScaleX * bone.skeleton.ScaleY); + thisTransform.localScale = localScale; + } + + } +} diff --git a/box1/Assets/Spine/Runtime/spine-unity/Components/Following/BoneFollowerGraphic.cs.meta b/box1/Assets/Spine/Runtime/spine-unity/Components/Following/BoneFollowerGraphic.cs.meta new file mode 100644 index 00000000..b2279663 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Components/Following/BoneFollowerGraphic.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: b42a195b47491d34b9bcbc40898bcb29 +timeCreated: 1499211965 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Components/Following/BoundingBoxFollower.cs b/box1/Assets/Spine/Runtime/spine-unity/Components/Following/BoundingBoxFollower.cs new file mode 100644 index 00000000..82aae46d --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Components/Following/BoundingBoxFollower.cs @@ -0,0 +1,251 @@ +/****************************************************************************** + * 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 UnityEngine; +using System.Collections.Generic; + +namespace Spine.Unity { + + #if NEW_PREFAB_SYSTEM + [ExecuteAlways] + #else + [ExecuteInEditMode] + #endif + [HelpURL("http://esotericsoftware.com/spine-unity#BoundingBoxFollower")] + public class BoundingBoxFollower : MonoBehaviour { + internal static bool DebugMessages = true; + + #region Inspector + public SkeletonRenderer skeletonRenderer; + [SpineSlot(dataField: "skeletonRenderer", containsBoundingBoxes: true)] + public string slotName; + public bool isTrigger; + public bool clearStateOnDisable = true; + #endregion + + Slot slot; + BoundingBoxAttachment currentAttachment; + string currentAttachmentName; + PolygonCollider2D currentCollider; + + public readonly Dictionary colliderTable = new Dictionary(); + public readonly Dictionary nameTable = new Dictionary(); + + public Slot Slot { get { return slot; } } + public BoundingBoxAttachment CurrentAttachment { get { return currentAttachment; } } + public string CurrentAttachmentName { get { return currentAttachmentName; } } + public PolygonCollider2D CurrentCollider { get { return currentCollider; } } + public bool IsTrigger { get { return isTrigger; } } + + void Start () { + Initialize(); + } + + void OnEnable () { + if (skeletonRenderer != null) { + skeletonRenderer.OnRebuild -= HandleRebuild; + skeletonRenderer.OnRebuild += HandleRebuild; + } + + Initialize(); + } + + void HandleRebuild (SkeletonRenderer sr) { + //if (BoundingBoxFollower.DebugMessages) Debug.Log("Skeleton was rebuilt. Repopulating BoundingBoxFollower."); + Initialize(); + } + + /// + /// Initialize and instantiate the BoundingBoxFollower colliders. This is method checks if the BoundingBoxFollower has already been initialized for the skeleton instance and slotName and prevents overwriting unless it detects a new setup. + public void Initialize (bool overwrite = false) { + if (skeletonRenderer == null) + return; + + skeletonRenderer.Initialize(false); + + if (string.IsNullOrEmpty(slotName)) + return; + + // Don't reinitialize if the setup did not change. + if (!overwrite + && + colliderTable.Count > 0 && slot != null // Slot is set and colliders already populated. + && + skeletonRenderer.skeleton == slot.Skeleton // Skeleton object did not change. + && + slotName == slot.data.name // Slot object did not change. + ) + return; + + slot = null; + currentAttachment = null; + currentAttachmentName = null; + currentCollider = null; + colliderTable.Clear(); + nameTable.Clear(); + + var skeleton = skeletonRenderer.skeleton; + slot = skeleton.FindSlot(slotName); + int slotIndex = skeleton.FindSlotIndex(slotName); + + if (slot == null) { + if (BoundingBoxFollower.DebugMessages) + Debug.LogWarning(string.Format("Slot '{0}' not found for BoundingBoxFollower on '{1}'. (Previous colliders were disposed.)", slotName, this.gameObject.name)); + return; + } + + int requiredCollidersCount = 0; + var colliders = GetComponents(); + if (this.gameObject.activeInHierarchy) { + foreach (var skin in skeleton.Data.Skins) + AddCollidersForSkin(skin, slotIndex, colliders, ref requiredCollidersCount); + + if (skeleton.skin != null) + AddCollidersForSkin(skeleton.skin, slotIndex, colliders, ref requiredCollidersCount); + } + DisposeExcessCollidersAfter(requiredCollidersCount); + + if (BoundingBoxFollower.DebugMessages) { + bool valid = colliderTable.Count != 0; + if (!valid) { + if (this.gameObject.activeInHierarchy) + Debug.LogWarning("Bounding Box Follower not valid! Slot [" + slotName + "] does not contain any Bounding Box Attachments!"); + else + Debug.LogWarning("Bounding Box Follower tried to rebuild as a prefab."); + } + } + } + + void AddCollidersForSkin (Skin skin, int slotIndex, PolygonCollider2D[] previousColliders, ref int collidersCount) { + if (skin == null) return; + var skinEntries = new List(); + skin.GetAttachments(slotIndex, skinEntries); + + foreach (var entry in skinEntries) { + var attachment = skin.GetAttachment(slotIndex, entry.Name); + var boundingBoxAttachment = attachment as BoundingBoxAttachment; + + if (BoundingBoxFollower.DebugMessages && attachment != null && boundingBoxAttachment == null) + Debug.Log("BoundingBoxFollower tried to follow a slot that contains non-boundingbox attachments: " + slotName); + + if (boundingBoxAttachment != null) { + if (!colliderTable.ContainsKey(boundingBoxAttachment)) { + var bbCollider = collidersCount < previousColliders.Length ? + previousColliders[collidersCount] : gameObject.AddComponent(); + ++collidersCount; + SkeletonUtility.SetColliderPointsLocal(bbCollider, slot, boundingBoxAttachment); + bbCollider.isTrigger = isTrigger; + bbCollider.enabled = false; + bbCollider.hideFlags = HideFlags.NotEditable; + bbCollider.isTrigger = IsTrigger; + colliderTable.Add(boundingBoxAttachment, bbCollider); + nameTable.Add(boundingBoxAttachment, entry.Name); + } + } + } + } + + void OnDisable () { + if (clearStateOnDisable) + ClearState(); + + if (skeletonRenderer != null) + skeletonRenderer.OnRebuild -= HandleRebuild; + } + + public void ClearState () { + if (colliderTable != null) + foreach (var col in colliderTable.Values) + col.enabled = false; + + currentAttachment = null; + currentAttachmentName = null; + currentCollider = null; + } + + void DisposeExcessCollidersAfter (int requiredCount) { + var colliders = GetComponents(); + if (colliders.Length == 0) return; + + for (int i = requiredCount; i < colliders.Length; ++i) { + var collider = colliders[i]; + if (collider != null) { +#if UNITY_EDITOR + if (Application.isEditor && !Application.isPlaying) + DestroyImmediate(collider); + else +#endif + Destroy(collider); + } + } + } + + void LateUpdate () { + if (slot != null && slot.Attachment != currentAttachment) + MatchAttachment(slot.Attachment); + } + + /// Sets the current collider to match attachment. + /// If the attachment is not a bounding box, it will be treated as null. + void MatchAttachment (Attachment attachment) { + var bbAttachment = attachment as BoundingBoxAttachment; + + if (BoundingBoxFollower.DebugMessages && attachment != null && bbAttachment == null) + Debug.LogWarning("BoundingBoxFollower tried to match a non-boundingbox attachment. It will treat it as null."); + + if (currentCollider != null) + currentCollider.enabled = false; + + if (bbAttachment == null) { + currentCollider = null; + currentAttachment = null; + currentAttachmentName = null; + } else { + PolygonCollider2D foundCollider; + colliderTable.TryGetValue(bbAttachment, out foundCollider); + if (foundCollider != null) { + currentCollider = foundCollider; + currentCollider.enabled = true; + currentAttachment = bbAttachment; + currentAttachmentName = nameTable[bbAttachment]; + } else { + currentCollider = null; + currentAttachment = bbAttachment; + currentAttachmentName = null; + if (BoundingBoxFollower.DebugMessages) Debug.LogFormat("Collider for BoundingBoxAttachment named '{0}' was not initialized. It is possibly from a new skin. currentAttachmentName will be null. You may need to call BoundingBoxFollower.Initialize(overwrite: true);", bbAttachment.Name); + } + } + } + } + +} diff --git a/box1/Assets/Spine/Runtime/spine-unity/Components/Following/BoundingBoxFollower.cs.meta b/box1/Assets/Spine/Runtime/spine-unity/Components/Following/BoundingBoxFollower.cs.meta new file mode 100644 index 00000000..d81fd14a --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Components/Following/BoundingBoxFollower.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 0317ee9ba6e1b1e49a030268e026d372 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Components/Following/PointFollower.cs b/box1/Assets/Spine/Runtime/spine-unity/Components/Following/PointFollower.cs new file mode 100644 index 00000000..25aa203f --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Components/Following/PointFollower.cs @@ -0,0 +1,164 @@ +/****************************************************************************** + * 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 UnityEngine; + +namespace Spine.Unity { + + #if NEW_PREFAB_SYSTEM + [ExecuteAlways] + #else + [ExecuteInEditMode] + #endif + [AddComponentMenu("Spine/Point Follower")] + [HelpURL("http://esotericsoftware.com/spine-unity#PointFollower")] + public class PointFollower : MonoBehaviour, IHasSkeletonRenderer, IHasSkeletonComponent { + + public SkeletonRenderer skeletonRenderer; + public SkeletonRenderer SkeletonRenderer { get { return this.skeletonRenderer; } } + public ISkeletonComponent SkeletonComponent { get { return skeletonRenderer as ISkeletonComponent; } } + + [SpineSlot(dataField:"skeletonRenderer", includeNone: true)] + public string slotName; + + [SpineAttachment(slotField:"slotName", dataField: "skeletonRenderer", fallbackToTextField:true, includeNone: true)] + public string pointAttachmentName; + + public bool followRotation = true; + public bool followSkeletonFlip = true; + public bool followSkeletonZPosition = false; + + Transform skeletonTransform; + bool skeletonTransformIsParent; + PointAttachment point; + Bone bone; + bool valid; + public bool IsValid { get { return valid; } } + + public void Initialize () { + valid = skeletonRenderer != null && skeletonRenderer.valid; + if (!valid) + return; + + UpdateReferences(); + + #if UNITY_EDITOR + if (Application.isEditor) LateUpdate(); + #endif + } + + private void HandleRebuildRenderer (SkeletonRenderer skeletonRenderer) { + Initialize(); + } + + void UpdateReferences () { + skeletonTransform = skeletonRenderer.transform; + skeletonRenderer.OnRebuild -= HandleRebuildRenderer; + skeletonRenderer.OnRebuild += HandleRebuildRenderer; + skeletonTransformIsParent = Transform.ReferenceEquals(skeletonTransform, transform.parent); + + bone = null; + point = null; + if (!string.IsNullOrEmpty(pointAttachmentName)) { + var skeleton = skeletonRenderer.Skeleton; + + int slotIndex = skeleton.FindSlotIndex(slotName); + if (slotIndex >= 0) { + var slot = skeleton.slots.Items[slotIndex]; + bone = slot.bone; + point = skeleton.GetAttachment(slotIndex, pointAttachmentName) as PointAttachment; + } + } + } + + void OnDestroy () { + if (skeletonRenderer != null) + skeletonRenderer.OnRebuild -= HandleRebuildRenderer; + } + + public void LateUpdate () { + #if UNITY_EDITOR + if (!Application.isPlaying) skeletonTransformIsParent = Transform.ReferenceEquals(skeletonTransform, transform.parent); + #endif + + if (point == null) { + if (string.IsNullOrEmpty(pointAttachmentName)) return; + UpdateReferences(); + if (point == null) return; + } + + Vector2 worldPos; + point.ComputeWorldPosition(bone, out worldPos.x, out worldPos.y); + float rotation = point.ComputeWorldRotation(bone); + + Transform thisTransform = this.transform; + if (skeletonTransformIsParent) { + // Recommended setup: Use local transform properties if Spine GameObject is the immediate parent + thisTransform.localPosition = new Vector3(worldPos.x, worldPos.y, followSkeletonZPosition ? 0f : thisTransform.localPosition.z); + if (followRotation) { + float halfRotation = rotation * 0.5f * Mathf.Deg2Rad; + + var q = default(Quaternion); + q.z = Mathf.Sin(halfRotation); + q.w = Mathf.Cos(halfRotation); + thisTransform.localRotation = q; + } + } else { + // For special cases: Use transform world properties if transform relationship is complicated + Vector3 targetWorldPosition = skeletonTransform.TransformPoint(new Vector3(worldPos.x, worldPos.y, 0f)); + if (!followSkeletonZPosition) + targetWorldPosition.z = thisTransform.position.z; + + Transform transformParent = thisTransform.parent; + if (transformParent != null) { + Matrix4x4 m = transformParent.localToWorldMatrix; + if (m.m00 * m.m11 - m.m01 * m.m10 < 0) // Determinant2D is negative + rotation = -rotation; + } + + if (followRotation) { + Vector3 transformWorldRotation = skeletonTransform.rotation.eulerAngles; + thisTransform.SetPositionAndRotation(targetWorldPosition, Quaternion.Euler(transformWorldRotation.x, transformWorldRotation.y, transformWorldRotation.z + rotation)); + } else { + thisTransform.position = targetWorldPosition; + } + } + + if (followSkeletonFlip) { + Vector3 localScale = thisTransform.localScale; + localScale.y = Mathf.Abs(localScale.y) * Mathf.Sign(bone.skeleton.ScaleX * bone.skeleton.ScaleY); + thisTransform.localScale = localScale; + } + } + } +} diff --git a/box1/Assets/Spine/Runtime/spine-unity/Components/Following/PointFollower.cs.meta b/box1/Assets/Spine/Runtime/spine-unity/Components/Following/PointFollower.cs.meta new file mode 100644 index 00000000..1af3893c --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Components/Following/PointFollower.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: daf461e4341180341a648c07e1899528 +timeCreated: 1518094986 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Components/RootMotion.meta b/box1/Assets/Spine/Runtime/spine-unity/Components/RootMotion.meta new file mode 100644 index 00000000..d8d3bd38 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Components/RootMotion.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 2b957aa69dae9f948bacdeec549d28ea +folderAsset: yes +timeCreated: 1593173800 +licenseType: Pro +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Components/RootMotion/SkeletonMecanimRootMotion.cs b/box1/Assets/Spine/Runtime/spine-unity/Components/RootMotion/SkeletonMecanimRootMotion.cs new file mode 100644 index 00000000..e42e8ec2 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Components/RootMotion/SkeletonMecanimRootMotion.cs @@ -0,0 +1,112 @@ +/****************************************************************************** + * 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.Generic; +using Spine.Unity.AnimationTools; + +namespace Spine.Unity { + + /// + /// Add this component to a SkeletonMecanim GameObject + /// to turn motion of a selected root bone into Transform or RigidBody motion. + /// Local bone translation movement is used as motion. + /// All top-level bones of the skeleton are moved to compensate the root + /// motion bone location, keeping the distance relationship between bones intact. + /// + /// + /// Only compatible with SkeletonMecanim. + /// For SkeletonAnimation or SkeletonGraphic please use + /// SkeletonRootMotion instead. + /// + [HelpURL("http://esotericsoftware.com/spine-unity#SkeletonMecanimRootMotion")] + public class SkeletonMecanimRootMotion : SkeletonRootMotionBase { + #region Inspector + const int DefaultMecanimLayerFlags = -1; + public int mecanimLayerFlags = DefaultMecanimLayerFlags; + #endregion + + protected Vector2 movementDelta; + + SkeletonMecanim skeletonMecanim; + public SkeletonMecanim SkeletonMecanim { + get { + return skeletonMecanim ? skeletonMecanim : skeletonMecanim = GetComponent(); + } + } + + public override Vector2 GetRemainingRootMotion (int layerIndex) { + var pair = skeletonMecanim.Translator.GetActiveAnimationAndTime(layerIndex); + var animation = pair.Key; + var time = pair.Value; + if (animation == null) + return Vector2.zero; + + float start = time; + float end = animation.duration; + return GetAnimationRootMotion(start, end, animation); + } + + protected override void Reset () { + base.Reset(); + mecanimLayerFlags = DefaultMecanimLayerFlags; + } + + protected override void Start () { + base.Start(); + skeletonMecanim = GetComponent(); + if (skeletonMecanim) { + skeletonMecanim.Translator.OnClipApplied -= OnClipApplied; + skeletonMecanim.Translator.OnClipApplied += OnClipApplied; + } + } + + void OnClipApplied(Spine.Animation animation, int layerIndex, float weight, + float time, float lastTime, bool playsBackward) { + + if (((mecanimLayerFlags & 1< + /// Add this component to a SkeletonAnimation or SkeletonGraphic GameObject + /// to turn motion of a selected root bone into Transform or RigidBody motion. + /// Local bone translation movement is used as motion. + /// All top-level bones of the skeleton are moved to compensate the root + /// motion bone location, keeping the distance relationship between bones intact. + /// + /// + /// Only compatible with SkeletonAnimation (or other components that implement + /// ISkeletonComponent, ISkeletonAnimation and IAnimationStateComponent). + /// For SkeletonMecanim please use + /// SkeletonMecanimRootMotion instead. + /// + [HelpURL("http://esotericsoftware.com/spine-unity#SkeletonRootMotion")] + public class SkeletonRootMotion : SkeletonRootMotionBase { + #region Inspector + const int DefaultAnimationTrackFlags = -1; + public int animationTrackFlags = DefaultAnimationTrackFlags; + #endregion + + AnimationState animationState; + Canvas canvas; + + public override Vector2 GetRemainingRootMotion (int trackIndex) { + TrackEntry track = animationState.GetCurrent(trackIndex); + if (track == null) + return Vector2.zero; + + var animation = track.Animation; + float start = track.AnimationTime; + float end = animation.duration; + return GetAnimationRootMotion(start, end, animation); + } + + protected override float AdditionalScale { + get { + return canvas ? canvas.referencePixelsPerUnit: 1.0f; + } + } + + protected override void Reset () { + base.Reset(); + animationTrackFlags = DefaultAnimationTrackFlags; + } + + protected override void Start () { + base.Start(); + var animstateComponent = skeletonComponent as IAnimationStateComponent; + this.animationState = (animstateComponent != null) ? animstateComponent.AnimationState : null; + + if (this.GetComponent() != null) { + canvas = this.GetComponentInParent(); + } + } + + protected override Vector2 CalculateAnimationsMovementDelta () { + Vector2 localDelta = Vector2.zero; + int trackCount = animationState.Tracks.Count; + + for (int trackIndex = 0; trackIndex < trackCount; ++trackIndex) { + // note: animationTrackFlags != -1 below covers trackIndex >= 32, + // with -1 corresponding to entry "everything" of the dropdown list. + if (animationTrackFlags != -1 && (animationTrackFlags & 1 << trackIndex) == 0) + continue; + + TrackEntry track = animationState.GetCurrent(trackIndex); + TrackEntry next = null; + while (track != null) { + var animation = track.Animation; + float start = track.animationLast; + float end = track.AnimationTime; + var currentDelta = GetAnimationRootMotion(start, end, animation); + if (currentDelta != Vector2.zero) { + ApplyMixAlphaToDelta(ref currentDelta, next, track); + localDelta += currentDelta; + } + + // Traverse mixingFrom chain. + next = track; + track = track.mixingFrom; + } + } + return localDelta; + } + + void ApplyMixAlphaToDelta (ref Vector2 currentDelta, TrackEntry next, TrackEntry track) { + // Apply mix alpha to the delta position (based on AnimationState.cs). + float mix; + if (next != null) { + if (next.mixDuration == 0) { // Single frame mix to undo mixingFrom changes. + mix = 1; + } + else { + mix = next.mixTime / next.mixDuration; + if (mix > 1) mix = 1; + } + float mixAndAlpha = track.alpha * next.interruptAlpha * (1 - mix); + currentDelta *= mixAndAlpha; + } + else { + if (track.mixDuration == 0) { + mix = 1; + } + else { + mix = track.alpha * (track.mixTime / track.mixDuration); + if (mix > 1) mix = 1; + } + currentDelta *= mix; + } + } + } +} diff --git a/box1/Assets/Spine/Runtime/spine-unity/Components/RootMotion/SkeletonRootMotion.cs.meta b/box1/Assets/Spine/Runtime/spine-unity/Components/RootMotion/SkeletonRootMotion.cs.meta new file mode 100644 index 00000000..bef9e2e4 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Components/RootMotion/SkeletonRootMotion.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: f21c9538588898a45a3da22bf4779ab3 +timeCreated: 1591121072 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Components/RootMotion/SkeletonRootMotionBase.cs b/box1/Assets/Spine/Runtime/spine-unity/Components/RootMotion/SkeletonRootMotionBase.cs new file mode 100644 index 00000000..9f7defcd --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Components/RootMotion/SkeletonRootMotionBase.cs @@ -0,0 +1,214 @@ +/****************************************************************************** + * 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.Generic; +using Spine.Unity.AnimationTools; + +namespace Spine.Unity { + + /// + /// Base class for skeleton root motion components. + /// + abstract public class SkeletonRootMotionBase : MonoBehaviour { + + #region Inspector + [SpineBone] + [SerializeField] + protected string rootMotionBoneName = "root"; + public bool transformPositionX = true; + public bool transformPositionY = true; + + public float rootMotionScaleX = 1; + public float rootMotionScaleY = 1; + + [Header("Optional")] + public Rigidbody2D rigidBody2D; + public Rigidbody rigidBody; + + public bool UsesRigidbody { + get { return rigidBody != null || rigidBody2D != null; } + } + #endregion + + protected ISkeletonComponent skeletonComponent; + protected Bone rootMotionBone; + protected int rootMotionBoneIndex; + protected List topLevelBones = new List(); + protected Vector2 rigidbodyDisplacement; + + protected virtual void Reset () { + FindRigidbodyComponent(); + } + + protected virtual void Start () { + skeletonComponent = GetComponent(); + GatherTopLevelBones(); + SetRootMotionBone(rootMotionBoneName); + + var skeletonAnimation = skeletonComponent as ISkeletonAnimation; + if (skeletonAnimation != null) + skeletonAnimation.UpdateLocal += HandleUpdateLocal; + } + + protected virtual void FixedUpdate () { + if (!this.isActiveAndEnabled) + return; // Root motion is only applied when component is enabled. + + if (rigidBody2D != null) { + rigidBody2D.MovePosition(new Vector2(transform.position.x, transform.position.y) + + rigidbodyDisplacement); + } + if (rigidBody != null) { + rigidBody.MovePosition(transform.position + + new Vector3(rigidbodyDisplacement.x, rigidbodyDisplacement.y, 0)); + } + rigidbodyDisplacement = Vector2.zero; + } + + protected virtual void OnDisable () { + rigidbodyDisplacement = Vector2.zero; + } + + protected void FindRigidbodyComponent () { + rigidBody2D = this.GetComponent(); + if (!rigidBody2D) + rigidBody = this.GetComponent(); + + if (!rigidBody2D && !rigidBody) { + rigidBody2D = this.GetComponentInParent(); + if (!rigidBody2D) + rigidBody = this.GetComponentInParent(); + } + } + + protected virtual float AdditionalScale { get { return 1.0f; } } + abstract protected Vector2 CalculateAnimationsMovementDelta (); + abstract public Vector2 GetRemainingRootMotion (int trackIndex = 0); + + public void SetRootMotionBone (string name) { + var skeleton = skeletonComponent.Skeleton; + int index = skeleton.FindBoneIndex(name); + if (index >= 0) { + this.rootMotionBoneIndex = index; + this.rootMotionBone = skeleton.bones.Items[index]; + } + else { + Debug.Log("Bone named \"" + name + "\" could not be found."); + this.rootMotionBoneIndex = 0; + this.rootMotionBone = skeleton.RootBone; + } + } + + public void AdjustRootMotionToDistance (Vector2 distanceToTarget, int trackIndex = 0) { + Vector2 remainingRootMotion = GetRemainingRootMotion(trackIndex); + if (remainingRootMotion.x == 0) + remainingRootMotion.x = 0.0001f; + if (remainingRootMotion.y == 0) + remainingRootMotion.y = 0.0001f; + rootMotionScaleX = distanceToTarget.x / remainingRootMotion.x; + rootMotionScaleY = distanceToTarget.y / remainingRootMotion.y; + } + + public Vector2 GetAnimationRootMotion (Animation animation) { + return GetAnimationRootMotion(0, animation.duration, animation); + } + + public Vector2 GetAnimationRootMotion (float startTime, float endTime, + Animation animation) { + + var timeline = animation.FindTranslateTimelineForBone(rootMotionBoneIndex); + if (timeline != null) { + return GetTimelineMovementDelta(startTime, endTime, timeline, animation); + } + return Vector2.zero; + } + + Vector2 GetTimelineMovementDelta (float startTime, float endTime, + TranslateTimeline timeline, Animation animation) { + + Vector2 currentDelta; + if (startTime > endTime) // Looped + currentDelta = (timeline.Evaluate(animation.duration) - timeline.Evaluate(startTime)) + + (timeline.Evaluate(endTime) - timeline.Evaluate(0)); + else if (startTime != endTime) // Non-looped + currentDelta = timeline.Evaluate(endTime) - timeline.Evaluate(startTime); + else + currentDelta = Vector2.zero; + return currentDelta; + } + + void GatherTopLevelBones () { + topLevelBones.Clear(); + var skeleton = skeletonComponent.Skeleton; + foreach (var bone in skeleton.Bones) { + if (bone.Parent == null) + topLevelBones.Add(bone); + } + } + + void HandleUpdateLocal (ISkeletonAnimation animatedSkeletonComponent) { + if (!this.isActiveAndEnabled) + return; // Root motion is only applied when component is enabled. + + var movementDelta = CalculateAnimationsMovementDelta(); + AdjustMovementDeltaToConfiguration(ref movementDelta, animatedSkeletonComponent.Skeleton); + ApplyRootMotion(movementDelta); + } + + void AdjustMovementDeltaToConfiguration (ref Vector2 localDelta, Skeleton skeleton) { + if (skeleton.ScaleX < 0) localDelta.x = -localDelta.x; + if (skeleton.ScaleY < 0) localDelta.y = -localDelta.y; + if (!transformPositionX) localDelta.x = 0f; + if (!transformPositionY) localDelta.y = 0f; + } + + void ApplyRootMotion (Vector2 localDelta) { + localDelta *= AdditionalScale; + localDelta.x *= rootMotionScaleX; + localDelta.y *= rootMotionScaleY; + + // Apply root motion to Transform or RigidBody; + if (UsesRigidbody) { + rigidbodyDisplacement += (Vector2)transform.TransformVector(localDelta); + // Accumulated displacement is applied on the next Physics update (FixedUpdate) + } + else { + + transform.position += transform.TransformVector(localDelta); + } + + // Move top level bones in opposite direction of the root motion bone + foreach (var topLevelBone in topLevelBones) { + if (transformPositionX) topLevelBone.x -= rootMotionBone.x; + if (transformPositionY) topLevelBone.y -= rootMotionBone.y; + } + } + } +} diff --git a/box1/Assets/Spine/Runtime/spine-unity/Components/RootMotion/SkeletonRootMotionBase.cs.meta b/box1/Assets/Spine/Runtime/spine-unity/Components/RootMotion/SkeletonRootMotionBase.cs.meta new file mode 100644 index 00000000..719fd629 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Components/RootMotion/SkeletonRootMotionBase.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: fc23a4f220b20024ab0592719f92587d +timeCreated: 1592849332 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonAnimation.cs b/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonAnimation.cs new file mode 100644 index 00000000..1011099b --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonAnimation.cs @@ -0,0 +1,230 @@ +/****************************************************************************** + * 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 UnityEngine; + +namespace Spine.Unity { + + #if NEW_PREFAB_SYSTEM + [ExecuteAlways] + #else + [ExecuteInEditMode] + #endif + [AddComponentMenu("Spine/SkeletonAnimation")] + [HelpURL("http://esotericsoftware.com/spine-unity#SkeletonAnimation-Component")] + public class SkeletonAnimation : SkeletonRenderer, ISkeletonAnimation, IAnimationStateComponent { + + #region IAnimationStateComponent + /// + /// This is the Spine.AnimationState object of this SkeletonAnimation. You can control animations through it. + /// Note that this object, like .skeleton, is not guaranteed to exist in Awake. Do all accesses and caching to it in Start + public Spine.AnimationState state; + /// + /// This is the Spine.AnimationState object of this SkeletonAnimation. You can control animations through it. + /// Note that this object, like .skeleton, is not guaranteed to exist in Awake. Do all accesses and caching to it in Start + public Spine.AnimationState AnimationState { get { return this.state; } } + private bool wasUpdatedAfterInit = true; + #endregion + + #region Bone Callbacks ISkeletonAnimation + protected event UpdateBonesDelegate _UpdateLocal; + protected event UpdateBonesDelegate _UpdateWorld; + protected event UpdateBonesDelegate _UpdateComplete; + + /// + /// Occurs after the animations are applied and before world space values are resolved. + /// Use this callback when you want to set bone local values. + /// + public event UpdateBonesDelegate UpdateLocal { add { _UpdateLocal += value; } remove { _UpdateLocal -= value; } } + + /// + /// Occurs after the Skeleton's bone world space values are resolved (including all constraints). + /// Using this callback will cause the world space values to be solved an extra time. + /// Use this callback if want to use bone world space values, and also set bone local values. + public event UpdateBonesDelegate UpdateWorld { add { _UpdateWorld += value; } remove { _UpdateWorld -= value; } } + + /// + /// Occurs after the Skeleton's bone world space values are resolved (including all constraints). + /// Use this callback if you want to use bone world space values, but don't intend to modify bone local values. + /// This callback can also be used when setting world position and the bone matrix. + public event UpdateBonesDelegate UpdateComplete { add { _UpdateComplete += value; } remove { _UpdateComplete -= value; } } + #endregion + + #region Serialized state and Beginner API + [SerializeField] + [SpineAnimation] + private string _animationName; + + /// + /// Setting this property sets the animation of the skeleton. If invalid, it will store the animation name for the next time the skeleton is properly initialized. + /// Getting this property gets the name of the currently playing animation. If invalid, it will return the last stored animation name set through this property. + public string AnimationName { + get { + if (!valid) { + return _animationName; + } else { + TrackEntry entry = state.GetCurrent(0); + return entry == null ? null : entry.Animation.Name; + } + } + set { + if (_animationName == value) { + TrackEntry entry = state.GetCurrent(0); + if (entry != null && entry.loop == loop) + return; + } + _animationName = value; + + if (string.IsNullOrEmpty(value)) { + state.ClearTrack(0); + } else { + var animationObject = skeletonDataAsset.GetSkeletonData(false).FindAnimation(value); + if (animationObject != null) + state.SetAnimation(0, animationObject, loop); + } + } + } + + /// Whether or not should loop. This only applies to the initial animation specified in the inspector, or any subsequent Animations played through .AnimationName. Animations set through state.SetAnimation are unaffected. + public bool loop; + + /// + /// The rate at which animations progress over time. 1 means 100%. 0.5 means 50%. + /// AnimationState and TrackEntry also have their own timeScale. These are combined multiplicatively. + public float timeScale = 1; + #endregion + + #region Runtime Instantiation + /// Adds and prepares a SkeletonAnimation component to a GameObject at runtime. + /// The newly instantiated SkeletonAnimation + public static SkeletonAnimation AddToGameObject (GameObject gameObject, SkeletonDataAsset skeletonDataAsset) { + return SkeletonRenderer.AddSpineComponent(gameObject, skeletonDataAsset); + } + + /// Instantiates a new UnityEngine.GameObject and adds a prepared SkeletonAnimation component to it. + /// The newly instantiated SkeletonAnimation component. + public static SkeletonAnimation NewSkeletonAnimationGameObject (SkeletonDataAsset skeletonDataAsset) { + return SkeletonRenderer.NewSpineGameObject(skeletonDataAsset); + } + #endregion + + /// + /// Clears the previously generated mesh, resets the skeleton's pose, and clears all previously active animations. + public override void ClearState () { + base.ClearState(); + if (state != null) state.ClearTracks(); + } + + /// + /// Initialize this component. Attempts to load the SkeletonData and creates the internal Spine objects and buffers. + /// If set to true, force overwrite an already initialized object. + public override void Initialize (bool overwrite) { + if (valid && !overwrite) + return; + base.Initialize(overwrite); + + if (!valid) + return; + state = new Spine.AnimationState(skeletonDataAsset.GetAnimationStateData()); + wasUpdatedAfterInit = false; + + if (!string.IsNullOrEmpty(_animationName)) { + var animationObject = skeletonDataAsset.GetSkeletonData(false).FindAnimation(_animationName); + if (animationObject != null) { + state.SetAnimation(0, animationObject, loop); + #if UNITY_EDITOR + if (!Application.isPlaying) + Update(0f); + #endif + } + } + } + + void Update () { + #if UNITY_EDITOR + if (!Application.isPlaying) { + Update(0f); + return; + } + #endif + + Update(Time.deltaTime); + } + + /// Progresses the AnimationState according to the given deltaTime, and applies it to the Skeleton. Use Time.deltaTime to update manually. Use deltaTime 0 to update without progressing the time. + public void Update (float deltaTime) { + if (!valid || state == null) + return; + + wasUpdatedAfterInit = true; + if (updateMode < UpdateMode.OnlyAnimationStatus) + return; + UpdateAnimationStatus(deltaTime); + + if (updateMode == UpdateMode.OnlyAnimationStatus) + return; + ApplyAnimation(); + } + + protected void UpdateAnimationStatus (float deltaTime) { + deltaTime *= timeScale; + skeleton.Update(deltaTime); + state.Update(deltaTime); + } + + protected void ApplyAnimation () { + state.Apply(skeleton); + + if (_UpdateLocal != null) + _UpdateLocal(this); + + skeleton.UpdateWorldTransform(); + + if (_UpdateWorld != null) { + _UpdateWorld(this); + skeleton.UpdateWorldTransform(); + } + + if (_UpdateComplete != null) { + _UpdateComplete(this); + } + } + + public override void LateUpdate () { + // instantiation can happen from Update() after this component, leading to a missing Update() call. + if (!wasUpdatedAfterInit) Update(0); + base.LateUpdate(); + } + } + +} diff --git a/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonAnimation.cs.meta b/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonAnimation.cs.meta new file mode 100644 index 00000000..23ede7bd --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonAnimation.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: d247ba06193faa74d9335f5481b2b56c +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonGraphic.cs b/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonGraphic.cs new file mode 100644 index 00000000..ccb83f8d --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonGraphic.cs @@ -0,0 +1,745 @@ +/****************************************************************************** + * 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.Collections.Generic; +using UnityEngine; +using UnityEngine.UI; + +namespace Spine.Unity { + #if NEW_PREFAB_SYSTEM + [ExecuteAlways] + #else + [ExecuteInEditMode] + #endif + [RequireComponent(typeof(CanvasRenderer), typeof(RectTransform)), DisallowMultipleComponent] + [AddComponentMenu("Spine/SkeletonGraphic (Unity UI Canvas)")] + [HelpURL("http://esotericsoftware.com/spine-unity#SkeletonGraphic-Component")] + public class SkeletonGraphic : MaskableGraphic, ISkeletonComponent, IAnimationStateComponent, ISkeletonAnimation, IHasSkeletonDataAsset { + + #region Inspector + public SkeletonDataAsset skeletonDataAsset; + public SkeletonDataAsset SkeletonDataAsset { get { return skeletonDataAsset; } } + + [SpineSkin(dataField:"skeletonDataAsset", defaultAsEmptyString:true)] + public string initialSkinName; + public bool initialFlipX, initialFlipY; + + [SpineAnimation(dataField:"skeletonDataAsset")] + public string startingAnimation; + public bool startingLoop; + public float timeScale = 1f; + public bool freeze; + + /// Update mode to optionally limit updates to e.g. only apply animations but not update the mesh. + public UpdateMode UpdateMode { get { return updateMode; } set { updateMode = value; } } + [SerializeField] protected UpdateMode updateMode = UpdateMode.FullUpdate; + + /// Update mode used when the MeshRenderer becomes invisible + /// (when OnBecameInvisible() is called). Update mode is automatically + /// reset to UpdateMode.FullUpdate when the mesh becomes visible again. + public UpdateMode updateWhenInvisible = UpdateMode.FullUpdate; + + public bool unscaledTime; + public bool allowMultipleCanvasRenderers = false; + public List canvasRenderers = new List(); + + // Submesh Separation + public const string SeparatorPartGameObjectName = "Part"; + /// Slot names used to populate separatorSlots list when the Skeleton is initialized. Changing this after initialization does nothing. + [SerializeField] [SpineSlot] protected string[] separatorSlotNames = new string[0]; + + /// 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. + [System.NonSerialized] public readonly List separatorSlots = new List(); + public bool enableSeparatorSlots = false; + [SerializeField] protected List separatorParts = new List(); + public List SeparatorParts { get { return separatorParts; } } + public bool updateSeparatorPartLocation = true; + + private bool wasUpdatedAfterInit = true; + private Texture baseTexture = null; + + #if UNITY_EDITOR + protected override void OnValidate () { + // This handles Scene View preview. + base.OnValidate (); + if (this.IsValid) { + if (skeletonDataAsset == null) { + Clear(); + } else if (skeletonDataAsset.skeletonJSON == null) { + Clear(); + } else if (skeletonDataAsset.GetSkeletonData(true) != skeleton.data) { + Clear(); + Initialize(true); + 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; + + if (!string.IsNullOrEmpty(initialSkinName)) { + var skin = skeleton.data.FindSkin(initialSkinName); + if (skin != null) { + if (skin == skeleton.data.defaultSkin) + skeleton.SetSkin((Skin)null); + else + skeleton.SetSkin(skin); + } + + } + + // Only provide visual feedback to inspector changes in Unity Editor Edit mode. + if (!Application.isPlaying) { + skeleton.ScaleX = this.initialFlipX ? -1 : 1; + skeleton.ScaleY = this.initialFlipY ? -1 : 1; + + state.ClearTrack(0); + skeleton.SetToSetupPose(); + if (!string.IsNullOrEmpty(startingAnimation)) { + state.SetAnimation(0, startingAnimation, startingLoop); + Update(0f); + } + } + } + } else { + // Under some circumstances (e.g. sometimes on the first import) OnValidate is called + // before SpineEditorUtilities.ImportSpineContent, causing an unnecessary exception. + // The (skeletonDataAsset.skeletonJSON != null) condition serves to prevent this exception. + if (skeletonDataAsset != null && skeletonDataAsset.skeletonJSON != null) + Initialize(true); + } + } + + protected override void Reset () { + + base.Reset(); + if (material == null || material.shader != Shader.Find("Spine/SkeletonGraphic")) + Debug.LogWarning("SkeletonGraphic works best with the SkeletonGraphic material."); + } + #endif + #endregion + + #region Runtime Instantiation + /// Create a new GameObject with a SkeletonGraphic component. + /// Material for the canvas renderer to use. Usually, the default SkeletonGraphic material will work. + public static SkeletonGraphic NewSkeletonGraphicGameObject (SkeletonDataAsset skeletonDataAsset, Transform parent, Material material) { + var sg = SkeletonGraphic.AddSkeletonGraphicComponent(new GameObject("New Spine GameObject"), skeletonDataAsset, material); + if (parent != null) sg.transform.SetParent(parent, false); + return sg; + } + + /// Add a SkeletonGraphic component to a GameObject. + /// Material for the canvas renderer to use. Usually, the default SkeletonGraphic material will work. + public static SkeletonGraphic AddSkeletonGraphicComponent (GameObject gameObject, SkeletonDataAsset skeletonDataAsset, Material material) { + var c = gameObject.AddComponent(); + if (skeletonDataAsset != null) { + c.material = material; + c.skeletonDataAsset = skeletonDataAsset; + c.Initialize(false); + } + return c; + } + #endregion + + #region Overrides + [System.NonSerialized] readonly Dictionary customTextureOverride = new Dictionary(); + /// Use this Dictionary to override a Texture with a different Texture. + public Dictionary CustomTextureOverride { get { return customTextureOverride; } } + + [System.NonSerialized] readonly Dictionary customMaterialOverride = new Dictionary(); + /// Use this Dictionary to override the Material where the Texture was used at the original atlas. + public Dictionary CustomMaterialOverride { get { return customMaterialOverride; } } + + // This is used by the UI system to determine what to put in the MaterialPropertyBlock. + Texture overrideTexture; + public Texture OverrideTexture { + get { return overrideTexture; } + set { + overrideTexture = value; + 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; + return baseTexture; + } + } + + protected override void Awake () { + + base.Awake (); + if (!this.IsValid) { +#if UNITY_EDITOR + // workaround for special import case of open scene where OnValidate and Awake are + // called in wrong order, before setup of Spine assets. + if (!Application.isPlaying) { + if (this.skeletonDataAsset != null && this.skeletonDataAsset.skeletonJSON == null) + return; + } +#endif + Initialize(false); + Rebuild(CanvasUpdate.PreRender); + } + } + + public override void Rebuild (CanvasUpdate update) { + base.Rebuild(update); + if (canvasRenderer.cull) return; + if (update == CanvasUpdate.PreRender) UpdateMesh(); + if (allowMultipleCanvasRenderers) canvasRenderer.Clear(); + } + + protected override void OnDisable () { + base.OnDisable(); + foreach (var canvasRenderer in canvasRenderers) { + canvasRenderer.Clear(); + } + } + + public virtual void Update () { + #if UNITY_EDITOR + if (!Application.isPlaying) { + Update(0f); + return; + } + #endif + + if (freeze) return; + Update(unscaledTime ? Time.unscaledDeltaTime : Time.deltaTime); + } + + public virtual void Update (float deltaTime) { + if (!this.IsValid) return; + + wasUpdatedAfterInit = true; + if (updateMode < UpdateMode.OnlyAnimationStatus) + return; + UpdateAnimationStatus(deltaTime); + + if (updateMode == UpdateMode.OnlyAnimationStatus) + return; + ApplyAnimation(); + } + + protected void UpdateAnimationStatus (float deltaTime) { + deltaTime *= timeScale; + skeleton.Update(deltaTime); + state.Update(deltaTime); + } + + protected void ApplyAnimation () { + state.Apply(skeleton); + + if (UpdateLocal != null) + UpdateLocal(this); + + skeleton.UpdateWorldTransform(); + + if (UpdateWorld != null) { + UpdateWorld(this); + skeleton.UpdateWorldTransform(); + } + + if (UpdateComplete != null) + UpdateComplete(this); + } + + public void LateUpdate () { + // instantiation can happen from Update() after this component, leading to a missing Update() call. + if (!wasUpdatedAfterInit) Update(0); + if (freeze) return; + if (updateMode <= UpdateMode.EverythingExceptMesh) return; + + UpdateMesh(); + } + + public void OnBecameVisible () { + updateMode = UpdateMode.FullUpdate; + } + + public void OnBecameInvisible () { + updateMode = updateWhenInvisible; + } + + 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 + protected Skeleton skeleton; + public Skeleton Skeleton { get { return skeleton; } set { skeleton = value; } } + public SkeletonData SkeletonData { get { return skeleton == null ? null : skeleton.data; } } + public bool IsValid { get { return skeleton != null; } } + + public delegate void SkeletonRendererDelegate (SkeletonGraphic skeletonGraphic); + + /// OnRebuild is raised after the Skeleton is successfully initialized. + public event SkeletonRendererDelegate OnRebuild; + + /// OnMeshAndMaterialsUpdated is at the end of LateUpdate after the Mesh and + /// all materials have been updated. + public event SkeletonRendererDelegate OnMeshAndMaterialsUpdated; + + protected Spine.AnimationState state; + public Spine.AnimationState AnimationState { get { return state; } } + + [SerializeField] protected Spine.Unity.MeshGenerator meshGenerator = new MeshGenerator(); + public Spine.Unity.MeshGenerator MeshGenerator { get { return this.meshGenerator; } } + DoubleBuffered meshBuffers; + SkeletonRendererInstruction currentInstructions = new SkeletonRendererInstruction(); + readonly ExposedList meshes = new ExposedList(); + + public Mesh GetLastMesh () { + return meshBuffers.GetCurrent().mesh; + } + + 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(); + 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) + ); + + this.rectTransform.sizeDelta = size; + this.rectTransform.pivot = p; + } + + public event UpdateBonesDelegate UpdateLocal; + public event UpdateBonesDelegate UpdateWorld; + public event UpdateBonesDelegate UpdateComplete; + + /// Occurs after the vertex data populated every frame, before the vertices are pushed into the mesh. + public event Spine.Unity.MeshGeneratorDelegate OnPostProcessVertices; + + 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(); + 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) { + if (this.IsValid && !overwrite) return; + + // Make sure none of the stuff is null + if (this.skeletonDataAsset == null) return; + var skeletonData = this.skeletonDataAsset.GetSkeletonData(false); + if (skeletonData == null) return; + + if (skeletonDataAsset.atlasAssets.Length <= 0 || skeletonDataAsset.atlasAssets[0].MaterialCount <= 0) return; + + this.state = new Spine.AnimationState(skeletonDataAsset.GetAnimationStateData()); + if (state == null) { + Clear(); + return; + } + + this.skeleton = new Skeleton(skeletonData) { + ScaleX = this.initialFlipX ? -1 : 1, + ScaleY = this.initialFlipY ? -1 : 1 + }; + + InitMeshBuffers(); + baseTexture = skeletonDataAsset.atlasAssets[0].PrimaryMaterial.mainTexture; + canvasRenderer.SetTexture(this.mainTexture); // Needed for overwriting initializations. + + // Set the initial Skin and Animation + 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); + if (animationObject != null) { + state.SetAnimation(0, animationObject, startingLoop); + #if UNITY_EDITOR + if (!Application.isPlaying) + Update(0f); + #endif + } + } + + if (OnRebuild != null) + OnRebuild(this); + } + + public void UpdateMesh () { + if (!this.IsValid) return; + + skeleton.SetColor(this.color); + + 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 InitMeshBuffers () { + if (meshBuffers != null) { + meshBuffers.GetNext().Clear(); + meshBuffers.GetNext().Clear(); + } + else { + meshBuffers = new DoubleBuffered(); + } + } + + 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 { + meshGenerator.BuildMeshWithArrays(currentInstructions, updateTriangles); + } + + if (canvas != null) meshGenerator.ScaleVertexData(canvas.referencePixelsPerUnit); + if (OnPostProcessVertices != null) OnPostProcessVertices.Invoke(this.meshGenerator.Buffers); + + var mesh = smartMesh.mesh; + meshGenerator.FillVertexData(mesh); + if (updateTriangles) meshGenerator.FillTriangles(mesh); + meshGenerator.FillLateVertexData(mesh); + + canvasRenderer.SetMesh(mesh); + smartMesh.instructionUsed.Set(currentInstructions); + + if (currentInstructions.submeshInstructions.Count > 0) { + var material = currentInstructions.submeshInstructions.Items[0].material; + if (material != null && baseTexture != material.mainTexture) { + baseTexture = material.mainTexture; + if (overrideTexture == null) + canvasRenderer.SetTexture(this.mainTexture); + } + } + + //this.UpdateMaterial(); // note: This would allocate memory. + } + + 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(); + 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 + } +} diff --git a/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonGraphic.cs.meta b/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonGraphic.cs.meta new file mode 100644 index 00000000..e44ab782 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonGraphic.cs.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: d85b887af7e6c3f45a2e2d2920d641bc +timeCreated: 1455576193 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: + - m_Material: {fileID: 2100000, guid: b66cf7a186d13054989b33a5c90044e4, type: 2} + - skeletonDataAsset: {instanceID: 0} + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonMecanim.cs b/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonMecanim.cs new file mode 100644 index 00000000..98da35cb --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonMecanim.cs @@ -0,0 +1,647 @@ +/****************************************************************************** + * 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.Generic; + +namespace Spine.Unity { + [RequireComponent(typeof(Animator))] + [HelpURL("http://esotericsoftware.com/spine-unity#SkeletonMecanim-Component")] + public class SkeletonMecanim : SkeletonRenderer, ISkeletonAnimation { + + [SerializeField] protected MecanimTranslator translator; + public MecanimTranslator Translator { get { return translator; } } + private bool wasUpdatedAfterInit = true; + + #region Bone Callbacks (ISkeletonAnimation) + protected event UpdateBonesDelegate _UpdateLocal; + protected event UpdateBonesDelegate _UpdateWorld; + protected event UpdateBonesDelegate _UpdateComplete; + + /// + /// Occurs after the animations are applied and before world space values are resolved. + /// Use this callback when you want to set bone local values. + public event UpdateBonesDelegate UpdateLocal { add { _UpdateLocal += value; } remove { _UpdateLocal -= value; } } + + /// + /// Occurs after the Skeleton's bone world space values are resolved (including all constraints). + /// Using this callback will cause the world space values to be solved an extra time. + /// Use this callback if want to use bone world space values, and also set bone local values. + public event UpdateBonesDelegate UpdateWorld { add { _UpdateWorld += value; } remove { _UpdateWorld -= value; } } + + /// + /// Occurs after the Skeleton's bone world space values are resolved (including all constraints). + /// Use this callback if you want to use bone world space values, but don't intend to modify bone local values. + /// This callback can also be used when setting world position and the bone matrix. + public event UpdateBonesDelegate UpdateComplete { add { _UpdateComplete += value; } remove { _UpdateComplete -= value; } } + #endregion + + public override void Initialize (bool overwrite) { + if (valid && !overwrite) + return; + + base.Initialize(overwrite); + + if (!valid) + return; + + if (translator == null) translator = new MecanimTranslator(); + translator.Initialize(GetComponent(), this.skeletonDataAsset); + wasUpdatedAfterInit = false; + } + + public void Update () { + if (!valid) return; + + wasUpdatedAfterInit = true; + // animation status is kept by Mecanim Animator component + if (updateMode <= UpdateMode.OnlyAnimationStatus) + return; + ApplyAnimation(); + } + + protected void ApplyAnimation () { + #if UNITY_EDITOR + var translatorAnimator = translator.Animator; + if (translatorAnimator != null && !translatorAnimator.isInitialized) + translatorAnimator.Rebind(); + + if (Application.isPlaying) { + translator.Apply(skeleton); + } + else { + if (translatorAnimator != null && translatorAnimator.isInitialized && + translatorAnimator.isActiveAndEnabled && translatorAnimator.runtimeAnimatorController != null) { + // Note: Rebind is required to prevent warning "Animator is not playing an AnimatorController" with prefabs + translatorAnimator.Rebind(); + translator.Apply(skeleton); + } + } + #else + translator.Apply(skeleton); + #endif + + // UpdateWorldTransform and Bone Callbacks + { + if (_UpdateLocal != null) + _UpdateLocal(this); + + skeleton.UpdateWorldTransform(); + + if (_UpdateWorld != null) { + _UpdateWorld(this); + skeleton.UpdateWorldTransform(); + } + + if (_UpdateComplete != null) + _UpdateComplete(this); + } + } + + public override void LateUpdate () { + // instantiation can happen from Update() after this component, leading to a missing Update() call. + if (!wasUpdatedAfterInit) Update(); + base.LateUpdate(); + } + + [System.Serializable] + public class MecanimTranslator { + #region Inspector + public bool autoReset = true; + public bool useCustomMixMode = true; + public MixMode[] layerMixModes = new MixMode[0]; + public MixBlend[] layerBlendModes = new MixBlend[0]; + #endregion + + public delegate void OnClipAppliedDelegate (Spine.Animation clip, int layerIndex, float weight, + float time, float lastTime, bool playsBackward); + protected event OnClipAppliedDelegate _OnClipApplied; + + public event OnClipAppliedDelegate OnClipApplied { add { _OnClipApplied += value; } remove { _OnClipApplied -= value; } } + + public enum MixMode { AlwaysMix, MixNext, Hard } + + readonly Dictionary animationTable = new Dictionary(IntEqualityComparer.Instance); + readonly Dictionary clipNameHashCodeTable = new Dictionary(AnimationClipEqualityComparer.Instance); + readonly List previousAnimations = new List(); + + protected class ClipInfos { + public bool isInterruptionActive = false; + public bool isLastFrameOfInterruption = false; + + public int clipInfoCount = 0; + public int nextClipInfoCount = 0; + public int interruptingClipInfoCount = 0; + public readonly List clipInfos = new List(); + public readonly List nextClipInfos = new List(); + public readonly List interruptingClipInfos = new List(); + + public AnimatorStateInfo stateInfo; + public AnimatorStateInfo nextStateInfo; + public AnimatorStateInfo interruptingStateInfo; + + public float interruptingClipTimeAddition = 0; + } + protected ClipInfos[] layerClipInfos = new ClipInfos[0]; + + Animator animator; + public Animator Animator { get { return this.animator; } } + + public int MecanimLayerCount { + get { + if (!animator) + return 0; + return animator.layerCount; + } + } + + public string[] MecanimLayerNames { + get { + if (!animator) + return new string[0]; + string[] layerNames = new string[animator.layerCount]; + for (int i = 0; i < animator.layerCount; ++i) { + layerNames[i] = animator.GetLayerName(i); + } + return layerNames; + } + } + + public void Initialize(Animator animator, SkeletonDataAsset skeletonDataAsset) { + this.animator = animator; + + previousAnimations.Clear(); + + animationTable.Clear(); + var data = skeletonDataAsset.GetSkeletonData(true); + foreach (var a in data.Animations) + animationTable.Add(a.Name.GetHashCode(), a); + + clipNameHashCodeTable.Clear(); + ClearClipInfosForLayers(); + } + + private bool ApplyAnimation (Skeleton skeleton, AnimatorClipInfo info, AnimatorStateInfo stateInfo, + int layerIndex, float layerWeight, MixBlend layerBlendMode, bool useClipWeight1 = false) { + float weight = info.weight * layerWeight; + if (weight == 0) + return false; + + var clip = GetAnimation(info.clip); + if (clip == null) + return false; + + var time = AnimationTime(stateInfo.normalizedTime, info.clip.length, + info.clip.isLooping, stateInfo.speed < 0); + weight = useClipWeight1 ? layerWeight : weight; + clip.Apply(skeleton, 0, time, info.clip.isLooping, null, + weight, layerBlendMode, MixDirection.In); + if (_OnClipApplied != null) + OnClipAppliedCallback(clip, stateInfo, layerIndex, time, info.clip.isLooping, weight); + return true; + } + + private bool ApplyInterruptionAnimation (Skeleton skeleton, + bool interpolateWeightTo1, AnimatorClipInfo info, AnimatorStateInfo stateInfo, + int layerIndex, float layerWeight, MixBlend layerBlendMode, float interruptingClipTimeAddition, + bool useClipWeight1 = false) { + + float clipWeight = interpolateWeightTo1 ? (info.weight + 1.0f) * 0.5f : info.weight; + float weight = clipWeight * layerWeight; + if (weight == 0) + return false; + + var clip = GetAnimation(info.clip); + if (clip == null) + return false; + + var time = AnimationTime(stateInfo.normalizedTime + interruptingClipTimeAddition, + info.clip.length, stateInfo.speed < 0); + weight = useClipWeight1 ? layerWeight : weight; + clip.Apply(skeleton, 0, time, info.clip.isLooping, null, + weight, layerBlendMode, MixDirection.In); + if (_OnClipApplied != null) { + OnClipAppliedCallback(clip, stateInfo, layerIndex, time, info.clip.isLooping, weight); + } + return true; + } + + private void OnClipAppliedCallback (Spine.Animation clip, AnimatorStateInfo stateInfo, + int layerIndex, float time, bool isLooping, float weight) { + + float speedFactor = stateInfo.speedMultiplier * stateInfo.speed; + float lastTime = time - (Time.deltaTime * speedFactor); + if (isLooping && clip.duration != 0) { + time %= clip.duration; + lastTime %= clip.duration; + } + _OnClipApplied(clip, layerIndex, weight, time, lastTime, speedFactor < 0); + } + + public void Apply (Skeleton skeleton) { + #if UNITY_EDITOR + if (!Application.isPlaying) { + GetLayerBlendModes(); + } + #endif + + if (layerMixModes.Length < animator.layerCount) { + int oldSize = layerMixModes.Length; + System.Array.Resize(ref layerMixModes, animator.layerCount); + for (int layer = oldSize; layer < animator.layerCount; ++layer) { + bool isAdditiveLayer = false; + if (layer < layerBlendModes.Length) + isAdditiveLayer = layerBlendModes[layer] == MixBlend.Add; + layerMixModes[layer] = isAdditiveLayer ? MixMode.AlwaysMix : MixMode.MixNext; + } + } + + InitClipInfosForLayers(); + for (int layer = 0, n = animator.layerCount; layer < n; layer++) { + GetStateUpdatesFromAnimator(layer); + } + + // Clear Previous + if (autoReset) { + var previousAnimations = this.previousAnimations; + for (int i = 0, n = previousAnimations.Count; i < n; i++) + previousAnimations[i].SetKeyedItemsToSetupPose(skeleton); + + previousAnimations.Clear(); + for (int layer = 0, n = animator.layerCount; layer < n; layer++) { + float layerWeight = (layer == 0) ? 1 : animator.GetLayerWeight(layer); // Animator.GetLayerWeight always returns 0 on the first layer. Should be interpreted as 1. + if (layerWeight <= 0) continue; + + AnimatorStateInfo nextStateInfo = animator.GetNextAnimatorStateInfo(layer); + + bool hasNext = nextStateInfo.fullPathHash != 0; + + int clipInfoCount, nextClipInfoCount, interruptingClipInfoCount; + IList clipInfo, nextClipInfo, interruptingClipInfo; + bool isInterruptionActive, shallInterpolateWeightTo1; + GetAnimatorClipInfos(layer, out isInterruptionActive, out clipInfoCount, out nextClipInfoCount, out interruptingClipInfoCount, + out clipInfo, out nextClipInfo, out interruptingClipInfo, out shallInterpolateWeightTo1); + + for (int c = 0; c < clipInfoCount; c++) { + var info = clipInfo[c]; + float weight = info.weight * layerWeight; if (weight == 0) continue; + var clip = GetAnimation(info.clip); + if (clip != null) + previousAnimations.Add(clip); + } + + 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) + previousAnimations.Add(clip); + } + } + + if (isInterruptionActive) { + for (int c = 0; c < interruptingClipInfoCount; c++) + { + var info = interruptingClipInfo[c]; + float clipWeight = shallInterpolateWeightTo1 ? (info.weight + 1.0f) * 0.5f : info.weight; + float weight = clipWeight * layerWeight; if (weight == 0) continue; + var clip = GetAnimation(info.clip); + if (clip != null) + previousAnimations.Add(clip); + } + } + } + } + + // Apply + for (int layer = 0, n = animator.layerCount; layer < n; layer++) { + float layerWeight = (layer == 0) ? 1 : animator.GetLayerWeight(layer); // Animator.GetLayerWeight always returns 0 on the first layer. Should be interpreted as 1. + + bool isInterruptionActive; + AnimatorStateInfo stateInfo; + AnimatorStateInfo nextStateInfo; + AnimatorStateInfo interruptingStateInfo; + float interruptingClipTimeAddition; + GetAnimatorStateInfos(layer, out isInterruptionActive, out stateInfo, out nextStateInfo, out interruptingStateInfo, out interruptingClipTimeAddition); + + bool hasNext = nextStateInfo.fullPathHash != 0; + + int clipInfoCount, nextClipInfoCount, interruptingClipInfoCount; + IList clipInfo, nextClipInfo, interruptingClipInfo; + bool interpolateWeightTo1; + GetAnimatorClipInfos(layer, out isInterruptionActive, out clipInfoCount, out nextClipInfoCount, out interruptingClipInfoCount, + out clipInfo, out nextClipInfo, out interruptingClipInfo, out interpolateWeightTo1); + + MixBlend layerBlendMode = (layer < layerBlendModes.Length) ? layerBlendModes[layer] : MixBlend.Replace; + MixMode mode = GetMixMode(layer, layerBlendMode); + if (mode == MixMode.AlwaysMix) { + // Always use Mix instead of Applying the first non-zero weighted clip. + for (int c = 0; c < clipInfoCount; c++) { + ApplyAnimation(skeleton, clipInfo[c], stateInfo, layer, layerWeight, layerBlendMode); + } + if (hasNext) { + for (int c = 0; c < nextClipInfoCount; c++) { + ApplyAnimation(skeleton, nextClipInfo[c], nextStateInfo, layer, layerWeight, layerBlendMode); + } + } + if (isInterruptionActive) { + for (int c = 0; c < interruptingClipInfoCount; c++) + { + ApplyInterruptionAnimation(skeleton, interpolateWeightTo1, + interruptingClipInfo[c], interruptingStateInfo, + layer, layerWeight, layerBlendMode, interruptingClipTimeAddition); + } + } + } else { // case MixNext || Hard + // Apply first non-zero weighted clip + int c = 0; + for (; c < clipInfoCount; c++) { + if (!ApplyAnimation(skeleton, clipInfo[c], stateInfo, layer, layerWeight, layerBlendMode, useClipWeight1:true)) + continue; + ++c; break; + } + // Mix the rest + for (; c < clipInfoCount; c++) { + ApplyAnimation(skeleton, clipInfo[c], stateInfo, layer, layerWeight, layerBlendMode); + } + + c = 0; + if (hasNext) { + // Apply next clip directly instead of mixing (ie: no crossfade, ignores mecanim transition weights) + if (mode == MixMode.Hard) { + for (; c < nextClipInfoCount; c++) { + if (!ApplyAnimation(skeleton, nextClipInfo[c], nextStateInfo, layer, layerWeight, layerBlendMode, useClipWeight1:true)) + continue; + ++c; break; + } + } + // Mix the rest + for (; c < nextClipInfoCount; c++) { + if (!ApplyAnimation(skeleton, nextClipInfo[c], nextStateInfo, layer, layerWeight, layerBlendMode)) + continue; + } + } + + c = 0; + if (isInterruptionActive) { + // Apply next clip directly instead of mixing (ie: no crossfade, ignores mecanim transition weights) + if (mode == MixMode.Hard) { + for (; c < interruptingClipInfoCount; c++) { + if (ApplyInterruptionAnimation(skeleton, interpolateWeightTo1, + interruptingClipInfo[c], interruptingStateInfo, + layer, layerWeight, layerBlendMode, interruptingClipTimeAddition, useClipWeight1:true)) { + + ++c; break; + } + } + } + // Mix the rest + for (; c < interruptingClipInfoCount; c++) { + ApplyInterruptionAnimation(skeleton, interpolateWeightTo1, + interruptingClipInfo[c], interruptingStateInfo, + layer, layerWeight, layerBlendMode, interruptingClipTimeAddition); + } + } + } + } + } + + public KeyValuePair GetActiveAnimationAndTime (int layer) { + if (layer >= layerClipInfos.Length) + return new KeyValuePair(null, 0); + + var layerInfos = layerClipInfos[layer]; + bool isInterruptionActive = layerInfos.isInterruptionActive; + AnimationClip clip = null; + Spine.Animation animation = null; + AnimatorStateInfo stateInfo; + if (isInterruptionActive && layerInfos.interruptingClipInfoCount > 0) { + clip = layerInfos.interruptingClipInfos[0].clip; + stateInfo = layerInfos.interruptingStateInfo; + } + else { + clip = layerInfos.clipInfos[0].clip; + stateInfo = layerInfos.stateInfo; + } + animation = GetAnimation(clip); + float time = AnimationTime(stateInfo.normalizedTime, clip.length, + clip.isLooping, stateInfo.speed < 0); + return new KeyValuePair(animation, time); + } + + static float AnimationTime (float normalizedTime, float clipLength, bool loop, bool reversed) { + float time = AnimationTime(normalizedTime, clipLength, reversed); + if (loop) return time; + const float EndSnapEpsilon = 1f / 30f; // Workaround for end-duration keys not being applied. + return (clipLength - time < EndSnapEpsilon) ? clipLength : time; // return a time snapped to clipLength; + } + + static float AnimationTime (float normalizedTime, float clipLength, bool reversed) { + if (reversed) + normalizedTime = (1 - normalizedTime + (int)normalizedTime) + (int)normalizedTime; + + return normalizedTime * clipLength; + } + + void InitClipInfosForLayers () { + if (layerClipInfos.Length < animator.layerCount) { + System.Array.Resize(ref layerClipInfos, animator.layerCount); + for (int layer = 0, n = animator.layerCount; layer < n; ++layer) { + if (layerClipInfos[layer] == null) + layerClipInfos[layer] = new ClipInfos(); + } + } + } + + void ClearClipInfosForLayers () { + for (int layer = 0, n = layerClipInfos.Length; layer < n; ++layer) { + if (layerClipInfos[layer] == null) + layerClipInfos[layer] = new ClipInfos(); + else { + layerClipInfos[layer].isInterruptionActive = false; + layerClipInfos[layer].isLastFrameOfInterruption = false; + layerClipInfos[layer].clipInfos.Clear(); + layerClipInfos[layer].nextClipInfos.Clear(); + layerClipInfos[layer].interruptingClipInfos.Clear(); + } + } + } + + private MixMode GetMixMode (int layer, MixBlend layerBlendMode) { + if (useCustomMixMode) { + MixMode mode = layerMixModes[layer]; + // Note: at additive blending it makes no sense to use constant weight 1 at a fadeout anim add1 as + // with override layers, so we use AlwaysMix instead to use the proper weights. + // AlwaysMix leads to the expected result = lower_layer + lerp(add1, add2, transition_weight). + if (layerBlendMode == MixBlend.Add && mode == MixMode.MixNext) { + mode = MixMode.AlwaysMix; + layerMixModes[layer] = mode; + } + return mode; + } + else { + return layerBlendMode == MixBlend.Add ? MixMode.AlwaysMix : MixMode.MixNext; + } + } + +#if UNITY_EDITOR + void GetLayerBlendModes() { + if (layerBlendModes.Length < animator.layerCount) { + System.Array.Resize(ref layerBlendModes, animator.layerCount); + } + for (int layer = 0, n = animator.layerCount; layer < n; ++layer) { + var controller = animator.runtimeAnimatorController as UnityEditor.Animations.AnimatorController; + if (controller != null) { + layerBlendModes[layer] = MixBlend.First; + if (layer > 0) { + layerBlendModes[layer] = controller.layers[layer].blendingMode == UnityEditor.Animations.AnimatorLayerBlendingMode.Additive ? + MixBlend.Add : MixBlend.Replace; + } + } + } + } + #endif + + void GetStateUpdatesFromAnimator (int layer) { + + var layerInfos = layerClipInfos[layer]; + int clipInfoCount = animator.GetCurrentAnimatorClipInfoCount(layer); + int nextClipInfoCount = animator.GetNextAnimatorClipInfoCount(layer); + + var clipInfos = layerInfos.clipInfos; + var nextClipInfos = layerInfos.nextClipInfos; + var interruptingClipInfos = layerInfos.interruptingClipInfos; + + layerInfos.isInterruptionActive = (clipInfoCount == 0 && clipInfos.Count != 0 && + nextClipInfoCount == 0 && nextClipInfos.Count != 0); + + // Note: during interruption, GetCurrentAnimatorClipInfoCount and GetNextAnimatorClipInfoCount + // are returning 0 in calls above. Therefore we keep previous clipInfos and nextClipInfos + // until the interruption is over. + if (layerInfos.isInterruptionActive) { + + // Note: The last frame of a transition interruption + // will have fullPathHash set to 0, therefore we have to use previous + // frame's infos about interruption clips and correct some values + // accordingly (normalizedTime and weight). + var interruptingStateInfo = animator.GetNextAnimatorStateInfo(layer); + layerInfos.isLastFrameOfInterruption = interruptingStateInfo.fullPathHash == 0; + if (!layerInfos.isLastFrameOfInterruption) { + animator.GetNextAnimatorClipInfo(layer, interruptingClipInfos); + layerInfos.interruptingClipInfoCount = interruptingClipInfos.Count; + float oldTime = layerInfos.interruptingStateInfo.normalizedTime; + float newTime = interruptingStateInfo.normalizedTime; + layerInfos.interruptingClipTimeAddition = newTime - oldTime; + layerInfos.interruptingStateInfo = interruptingStateInfo; + } + } else { + layerInfos.clipInfoCount = clipInfoCount; + layerInfos.nextClipInfoCount = nextClipInfoCount; + layerInfos.interruptingClipInfoCount = 0; + layerInfos.isLastFrameOfInterruption = false; + + if (clipInfos.Capacity < clipInfoCount) clipInfos.Capacity = clipInfoCount; + if (nextClipInfos.Capacity < nextClipInfoCount) nextClipInfos.Capacity = nextClipInfoCount; + + animator.GetCurrentAnimatorClipInfo(layer, clipInfos); + animator.GetNextAnimatorClipInfo(layer, nextClipInfos); + + layerInfos.stateInfo = animator.GetCurrentAnimatorStateInfo(layer); + layerInfos.nextStateInfo = animator.GetNextAnimatorStateInfo(layer); + } + } + + void GetAnimatorClipInfos ( + int layer, + out bool isInterruptionActive, + out int clipInfoCount, + out int nextClipInfoCount, + out int interruptingClipInfoCount, + out IList clipInfo, + out IList nextClipInfo, + out IList interruptingClipInfo, + out bool shallInterpolateWeightTo1) { + + var layerInfos = layerClipInfos[layer]; + isInterruptionActive = layerInfos.isInterruptionActive; + + clipInfoCount = layerInfos.clipInfoCount; + nextClipInfoCount = layerInfos.nextClipInfoCount; + interruptingClipInfoCount = layerInfos.interruptingClipInfoCount; + + clipInfo = layerInfos.clipInfos; + nextClipInfo = layerInfos.nextClipInfos; + interruptingClipInfo = isInterruptionActive ? layerInfos.interruptingClipInfos : null; + shallInterpolateWeightTo1 = layerInfos.isLastFrameOfInterruption; + } + + void GetAnimatorStateInfos ( + int layer, + out bool isInterruptionActive, + out AnimatorStateInfo stateInfo, + out AnimatorStateInfo nextStateInfo, + out AnimatorStateInfo interruptingStateInfo, + out float interruptingClipTimeAddition) { + + var layerInfos = layerClipInfos[layer]; + isInterruptionActive = layerInfos.isInterruptionActive; + + stateInfo = layerInfos.stateInfo; + nextStateInfo = layerInfos.nextStateInfo; + interruptingStateInfo = layerInfos.interruptingStateInfo; + interruptingClipTimeAddition = layerInfos.isLastFrameOfInterruption ? layerInfos.interruptingClipTimeAddition : 0; + } + + Spine.Animation GetAnimation (AnimationClip clip) { + int clipNameHashCode; + if (!clipNameHashCodeTable.TryGetValue(clip, out clipNameHashCode)) { + clipNameHashCode = clip.name.GetHashCode(); + clipNameHashCodeTable.Add(clip, clipNameHashCode); + } + Spine.Animation animation; + animationTable.TryGetValue(clipNameHashCode, out animation); + return animation; + } + + class AnimationClipEqualityComparer : IEqualityComparer { + internal static readonly IEqualityComparer Instance = new AnimationClipEqualityComparer(); + public bool Equals (AnimationClip x, AnimationClip y) { return x.GetInstanceID() == y.GetInstanceID(); } + public int GetHashCode (AnimationClip o) { return o.GetInstanceID(); } + } + + class IntEqualityComparer : IEqualityComparer { + internal static readonly IEqualityComparer Instance = new IntEqualityComparer(); + public bool Equals (int x, int y) { return x == y; } + public int GetHashCode(int o) { return o; } + } + } + + } +} diff --git a/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonMecanim.cs.meta b/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonMecanim.cs.meta new file mode 100644 index 00000000..ebd50dc4 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonMecanim.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: f9db98c60740638449864eb028fbe7ad +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonRenderSeparator.meta b/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonRenderSeparator.meta new file mode 100644 index 00000000..72398a41 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonRenderSeparator.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 3a361f5ac799a5149b340f9e20da27d1 +folderAsset: yes +timeCreated: 1457405502 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonRenderSeparator/SkeletonPartsRenderer.cs b/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonRenderSeparator/SkeletonPartsRenderer.cs new file mode 100644 index 00000000..cb3479aa --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonRenderSeparator/SkeletonPartsRenderer.cs @@ -0,0 +1,151 @@ +/****************************************************************************** + * 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; + +namespace Spine.Unity { + [RequireComponent(typeof(MeshRenderer), typeof(MeshFilter))] + [HelpURL("http://esotericsoftware.com/spine-unity#SkeletonRenderSeparator")] + public class SkeletonPartsRenderer : MonoBehaviour { + + #region Properties + MeshGenerator meshGenerator; + public MeshGenerator MeshGenerator { + get { + LazyIntialize(); + return meshGenerator; + } + } + + MeshRenderer meshRenderer; + public MeshRenderer MeshRenderer { + get { + LazyIntialize(); + return meshRenderer; + } + } + + MeshFilter meshFilter; + public MeshFilter MeshFilter { + get { + LazyIntialize(); + return meshFilter; + } + } + #endregion + + #region Callback Delegates + public delegate void SkeletonPartsRendererDelegate (SkeletonPartsRenderer skeletonPartsRenderer); + + /// OnMeshAndMaterialsUpdated is called at the end of LateUpdate after the Mesh and + /// all materials have been updated. + public event SkeletonPartsRendererDelegate OnMeshAndMaterialsUpdated; + #endregion + + MeshRendererBuffers buffers; + SkeletonRendererInstruction currentInstructions = new SkeletonRendererInstruction(); + + + void LazyIntialize () { + if (buffers == null) { + buffers = new MeshRendererBuffers(); + buffers.Initialize(); + + if (meshGenerator != null) return; + meshGenerator = new MeshGenerator(); + meshFilter = GetComponent(); + meshRenderer = GetComponent(); + currentInstructions.Clear(); + } + } + + public void ClearMesh () { + LazyIntialize(); + meshFilter.sharedMesh = null; + } + + public void RenderParts (ExposedList instructions, int startSubmesh, int endSubmesh) { + LazyIntialize(); + + // STEP 1: Create instruction + var smartMesh = buffers.GetNextMesh(); + currentInstructions.SetWithSubset(instructions, startSubmesh, endSubmesh); + bool updateTriangles = SkeletonRendererInstruction.GeometryNotEqual(currentInstructions, smartMesh.instructionUsed); + + // STEP 2: Generate mesh buffers. + var currentInstructionsSubmeshesItems = currentInstructions.submeshInstructions.Items; + meshGenerator.Begin(); + if (currentInstructions.hasActiveClipping) { + for (int i = 0; i < currentInstructions.submeshInstructions.Count; i++) + meshGenerator.AddSubmesh(currentInstructionsSubmeshesItems[i], updateTriangles); + } else { + meshGenerator.BuildMeshWithArrays(currentInstructions, updateTriangles); + } + + buffers.UpdateSharedMaterials(currentInstructions.submeshInstructions); + + // STEP 3: modify mesh. + var mesh = smartMesh.mesh; + + if (meshGenerator.VertexCount <= 0) { // Clear an empty mesh + updateTriangles = false; + mesh.Clear(); + } else { + meshGenerator.FillVertexData(mesh); + if (updateTriangles) { + meshGenerator.FillTriangles(mesh); + meshRenderer.sharedMaterials = buffers.GetUpdatedSharedMaterialsArray(); + } else if (buffers.MaterialsChangedInLastUpdate()) { + meshRenderer.sharedMaterials = buffers.GetUpdatedSharedMaterialsArray(); + } + meshGenerator.FillLateVertexData(mesh); + } + + meshFilter.sharedMesh = mesh; + smartMesh.instructionUsed.Set(currentInstructions); + + if (OnMeshAndMaterialsUpdated != null) + OnMeshAndMaterialsUpdated(this); + } + + public void SetPropertyBlock (MaterialPropertyBlock block) { + LazyIntialize(); + meshRenderer.SetPropertyBlock(block); + } + + public static SkeletonPartsRenderer NewPartsRendererGameObject (Transform parent, string name, int sortingOrder = 0) { + var go = new GameObject(name, typeof(MeshFilter), typeof(MeshRenderer)); + go.transform.SetParent(parent, false); + var returnComponent = go.AddComponent(); + returnComponent.MeshRenderer.sortingOrder = sortingOrder; + + return returnComponent; + } + } +} diff --git a/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonRenderSeparator/SkeletonPartsRenderer.cs.meta b/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonRenderSeparator/SkeletonPartsRenderer.cs.meta new file mode 100644 index 00000000..9359388b --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonRenderSeparator/SkeletonPartsRenderer.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 1c0b968d1e7333b499e347acb644f1c1 +timeCreated: 1458045480 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonRenderSeparator/SkeletonRenderSeparator.cs b/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonRenderSeparator/SkeletonRenderSeparator.cs new file mode 100644 index 00000000..d2d187ef --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonRenderSeparator/SkeletonRenderSeparator.cs @@ -0,0 +1,269 @@ +/****************************************************************************** + * 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 +#define SPINE_OPTIONAL_RENDEROVERRIDE + +using UnityEngine; +using System.Collections.Generic; + +namespace Spine.Unity { + + #if NEW_PREFAB_SYSTEM + [ExecuteAlways] + #else + [ExecuteInEditMode] + #endif + [HelpURL("http://esotericsoftware.com/spine-unity#SkeletonRenderSeparator")] + public class SkeletonRenderSeparator : MonoBehaviour { + public const int DefaultSortingOrderIncrement = 5; + + #region Inspector + [SerializeField] + protected SkeletonRenderer skeletonRenderer; + public SkeletonRenderer SkeletonRenderer { + get { return skeletonRenderer; } + set { + #if SPINE_OPTIONAL_RENDEROVERRIDE + if (skeletonRenderer != null) + skeletonRenderer.GenerateMeshOverride -= HandleRender; + #endif + + skeletonRenderer = value; + if (value == null) + this.enabled = false; + } + } + + MeshRenderer mainMeshRenderer; + public bool copyPropertyBlock = true; + [Tooltip("Copies MeshRenderer flags into each parts renderer")] + public bool copyMeshRendererFlags = true; + public List partsRenderers = new List(); + + #if UNITY_EDITOR + void Reset () { + if (skeletonRenderer == null) + skeletonRenderer = GetComponent(); + } + #endif + #endregion + + #region Callback Delegates + /// OnMeshAndMaterialsUpdated is called at the end of LateUpdate after the Mesh and + /// all materials have been updated. + public event SkeletonRenderer.SkeletonRendererDelegate OnMeshAndMaterialsUpdated; + #endregion + + #region Runtime Instantiation + /// Adds a SkeletonRenderSeparator and child SkeletonPartsRenderer GameObjects to a given SkeletonRenderer. + /// The to skeleton renderer. + /// The target SkeletonRenderer or SkeletonAnimation. + /// Sorting layer to be used for the parts renderers. + /// Number of additional SkeletonPartsRenderers on top of the ones determined by counting the number of separator slots. + /// The integer to increment the sorting order per SkeletonPartsRenderer to separate them. + /// The sorting order value of the first SkeletonPartsRenderer. + /// If set to true, a minimum number of SkeletonPartsRenderer GameObjects (determined by separatorSlots.Count + 1) will be added. + public static SkeletonRenderSeparator AddToSkeletonRenderer (SkeletonRenderer skeletonRenderer, int sortingLayerID = 0, int extraPartsRenderers = 0, int sortingOrderIncrement = DefaultSortingOrderIncrement, int baseSortingOrder = 0, bool addMinimumPartsRenderers = true) { + if (skeletonRenderer == null) { + Debug.Log("Tried to add SkeletonRenderSeparator to a null SkeletonRenderer reference."); + return null; + } + + var srs = skeletonRenderer.gameObject.AddComponent(); + srs.skeletonRenderer = skeletonRenderer; + + skeletonRenderer.Initialize(false); + int count = extraPartsRenderers; + if (addMinimumPartsRenderers) + count = extraPartsRenderers + skeletonRenderer.separatorSlots.Count + 1; + + var skeletonRendererTransform = skeletonRenderer.transform; + var componentRenderers = srs.partsRenderers; + + for (int i = 0; i < count; i++) { + var spr = SkeletonPartsRenderer.NewPartsRendererGameObject(skeletonRendererTransform, i.ToString()); + var mr = spr.MeshRenderer; + mr.sortingLayerID = sortingLayerID; + mr.sortingOrder = baseSortingOrder + (i * sortingOrderIncrement); + componentRenderers.Add(spr); + } + + srs.OnEnable(); + + #if UNITY_EDITOR + // Make sure editor updates properly in edit mode. + if (!Application.isPlaying) { + skeletonRenderer.enabled = false; + skeletonRenderer.enabled = true; + skeletonRenderer.LateUpdate(); + } + #endif + + return srs; + } + + /// Add a child SkeletonPartsRenderer GameObject to this SkeletonRenderSeparator. + public SkeletonPartsRenderer AddPartsRenderer (int sortingOrderIncrement = DefaultSortingOrderIncrement, string name = null) { + int sortingLayerID = 0; + int sortingOrder = 0; + if (partsRenderers.Count > 0) { + var previous = partsRenderers[partsRenderers.Count - 1]; + var previousMeshRenderer = previous.MeshRenderer; + sortingLayerID = previousMeshRenderer.sortingLayerID; + sortingOrder = previousMeshRenderer.sortingOrder + sortingOrderIncrement; + } + + if (string.IsNullOrEmpty(name)) + name = partsRenderers.Count.ToString(); + + var spr = SkeletonPartsRenderer.NewPartsRendererGameObject(skeletonRenderer.transform, name); + partsRenderers.Add(spr); + + var mr = spr.MeshRenderer; + mr.sortingLayerID = sortingLayerID; + mr.sortingOrder = sortingOrder; + + return spr; + } + #endregion + + public void OnEnable () { + if (skeletonRenderer == null) return; + if (copiedBlock == null) copiedBlock = new MaterialPropertyBlock(); + mainMeshRenderer = skeletonRenderer.GetComponent(); + + #if SPINE_OPTIONAL_RENDEROVERRIDE + skeletonRenderer.GenerateMeshOverride -= HandleRender; + skeletonRenderer.GenerateMeshOverride += HandleRender; + #endif + + if (copyMeshRendererFlags) { + var lightProbeUsage = mainMeshRenderer.lightProbeUsage; + bool receiveShadows = mainMeshRenderer.receiveShadows; + var reflectionProbeUsage = mainMeshRenderer.reflectionProbeUsage; + var shadowCastingMode = mainMeshRenderer.shadowCastingMode; + var motionVectorGenerationMode = mainMeshRenderer.motionVectorGenerationMode; + var probeAnchor = mainMeshRenderer.probeAnchor; + + for (int i = 0; i < partsRenderers.Count; i++) { + var currentRenderer = partsRenderers[i]; + if (currentRenderer == null) continue; // skip null items. + + var mr = currentRenderer.MeshRenderer; + mr.lightProbeUsage = lightProbeUsage; + mr.receiveShadows = receiveShadows; + mr.reflectionProbeUsage = reflectionProbeUsage; + mr.shadowCastingMode = shadowCastingMode; + mr.motionVectorGenerationMode = motionVectorGenerationMode; + mr.probeAnchor = probeAnchor; + } + } + } + + public void OnDisable () { + if (skeletonRenderer == null) return; + #if SPINE_OPTIONAL_RENDEROVERRIDE + skeletonRenderer.GenerateMeshOverride -= HandleRender; + #endif + + skeletonRenderer.LateUpdate(); + + foreach (var partsRenderer in partsRenderers) { + if (partsRenderer != null) + partsRenderer.ClearMesh(); + } + } + + MaterialPropertyBlock copiedBlock; + + void HandleRender (SkeletonRendererInstruction instruction) { + int rendererCount = partsRenderers.Count; + if (rendererCount <= 0) return; + + if (copyPropertyBlock) + mainMeshRenderer.GetPropertyBlock(copiedBlock); + + var settings = new MeshGenerator.Settings { + addNormals = skeletonRenderer.addNormals, + calculateTangents = skeletonRenderer.calculateTangents, + immutableTriangles = false, // parts cannot do immutable triangles. + pmaVertexColors = skeletonRenderer.pmaVertexColors, + tintBlack = skeletonRenderer.tintBlack, + useClipping = true, + zSpacing = skeletonRenderer.zSpacing + }; + + var submeshInstructions = instruction.submeshInstructions; + var submeshInstructionsItems = submeshInstructions.Items; + int lastSubmeshInstruction = submeshInstructions.Count - 1; + + int rendererIndex = 0; + var currentRenderer = partsRenderers[rendererIndex]; + for (int si = 0, start = 0; si <= lastSubmeshInstruction; si++) { + if (currentRenderer == null) + continue; + if (submeshInstructionsItems[si].forceSeparate || si == lastSubmeshInstruction) { + // Apply properties + var meshGenerator = currentRenderer.MeshGenerator; + meshGenerator.settings = settings; + + if (copyPropertyBlock) + currentRenderer.SetPropertyBlock(copiedBlock); + + // Render + currentRenderer.RenderParts(instruction.submeshInstructions, start, si + 1); + + start = si + 1; + rendererIndex++; + if (rendererIndex < rendererCount) { + currentRenderer = partsRenderers[rendererIndex]; + } else { + // Not enough renderers. Skip the rest of the instructions. + break; + } + } + } + + if (OnMeshAndMaterialsUpdated != null) + OnMeshAndMaterialsUpdated(this.skeletonRenderer); + + // Clear extra renderers if they exist. + for (; rendererIndex < rendererCount; rendererIndex++) { + currentRenderer = partsRenderers[rendererIndex]; + if (currentRenderer != null) + partsRenderers[rendererIndex].ClearMesh(); + } + + } + + } +} diff --git a/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonRenderSeparator/SkeletonRenderSeparator.cs.meta b/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonRenderSeparator/SkeletonRenderSeparator.cs.meta new file mode 100644 index 00000000..0c344f75 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonRenderSeparator/SkeletonRenderSeparator.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 5c70a5b35f6ff2541aed8e8346b7e4d5 +timeCreated: 1457405791 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonRenderer.cs b/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonRenderer.cs new file mode 100644 index 00000000..77c7433c --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonRenderer.cs @@ -0,0 +1,692 @@ +/****************************************************************************** + * 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 + +#if UNITY_2018_1_OR_NEWER +#define PER_MATERIAL_PROPERTY_BLOCKS +#endif + +#if UNITY_2017_1_OR_NEWER +#define BUILT_IN_SPRITE_MASK_COMPONENT +#endif + +#define SPINE_OPTIONAL_RENDEROVERRIDE +#define SPINE_OPTIONAL_MATERIALOVERRIDE + +using System.Collections.Generic; +using UnityEngine; + +namespace Spine.Unity { + /// Base class of animated Spine skeleton components. This component manages and renders a skeleton. + #if NEW_PREFAB_SYSTEM + [ExecuteAlways] + #else + [ExecuteInEditMode] + #endif + [RequireComponent(typeof(MeshFilter), typeof(MeshRenderer)), DisallowMultipleComponent] + [HelpURL("http://esotericsoftware.com/spine-unity#SkeletonRenderer-Component")] + public class SkeletonRenderer : MonoBehaviour, ISkeletonComponent, IHasSkeletonDataAsset { + public SkeletonDataAsset skeletonDataAsset; + + #region Initialization settings + /// Skin name to use when the Skeleton is initialized. + [SpineSkin(defaultAsEmptyString:true)] public string initialSkinName; + + /// Enable this parameter when overwriting the Skeleton's skin from an editor script. + /// Otherwise any changes will be overwritten by the next inspector update. + #if UNITY_EDITOR + public bool EditorSkipSkinSync { + get { return editorSkipSkinSync; } + set { editorSkipSkinSync = value; } + } + protected bool editorSkipSkinSync = false; + #endif + /// Flip X and Y to use when the Skeleton is initialized. + public bool initialFlipX, initialFlipY; + #endregion + + #region Advanced Render Settings + + /// Update mode to optionally limit updates to e.g. only apply animations but not update the mesh. + public UpdateMode UpdateMode { get { return updateMode; } set { updateMode = value; } } + [SerializeField] protected UpdateMode updateMode = UpdateMode.FullUpdate; + + /// Update mode used when the MeshRenderer becomes invisible + /// (when OnBecameInvisible() is called). Update mode is automatically + /// reset to UpdateMode.FullUpdate when the mesh becomes visible again. + public UpdateMode updateWhenInvisible = UpdateMode.FullUpdate; + + // Submesh Separation + /// Slot names used to populate separatorSlots list when the Skeleton is initialized. Changing this after initialization does nothing. + [UnityEngine.Serialization.FormerlySerializedAs("submeshSeparators")][SerializeField][SpineSlot] protected string[] separatorSlotNames = new string[0]; + + /// 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. + [System.NonSerialized] public readonly List separatorSlots = new List(); + + // Render Settings + [Range(-0.1f, 0f)] public float zSpacing; + /// Use Spine's clipping feature. If false, ClippingAttachments will be ignored. + public bool useClipping = true; + + /// If true, triangles will not be updated. Enable this as an optimization if the skeleton does not make use of attachment swapping or hiding, or draw order keys. Otherwise, setting this to false may cause errors in rendering. + public bool immutableTriangles = false; + + /// Multiply vertex color RGB with vertex color alpha. Set this to true if the shader used for rendering is a premultiplied alpha shader. Setting this to false disables single-batch additive slots. + public bool pmaVertexColors = true; + + /// Clears the state of the render and skeleton when this component or its GameObject is disabled. This prevents previous state from being retained when it is enabled again. When pooling your skeleton, setting this to true can be helpful. + public bool clearStateOnDisable = false; + + /// If true, second colors on slots will be added to the output Mesh as UV2 and UV3. A special "tint black" shader that interprets UV2 and UV3 as black point colors is required to render this properly. + public bool tintBlack = false; + + /// If true, the renderer assumes the skeleton only requires one Material and one submesh to render. This allows the MeshGenerator to skip checking for changes in Materials. Enable this as an optimization if the skeleton only uses one Material. + /// This disables SkeletonRenderSeparator functionality. + public bool singleSubmesh = false; + + #if PER_MATERIAL_PROPERTY_BLOCKS + /// Applies only when 3+ submeshes are used (2+ materials with alternating order, e.g. "A B A"). + /// If true, GPU instancing is disabled at all materials and MaterialPropertyBlocks are assigned at each + /// material to prevent aggressive batching of submeshes by e.g. the LWRP renderer, leading to incorrect + /// draw order (e.g. "A1 B A2" changed to "A1A2 B"). + /// You can disable this parameter when everything is drawn correctly to save the additional performance cost. + /// + public bool fixDrawOrder = false; + #endif + + /// If true, the mesh generator adds normals to the output mesh. For better performance and reduced memory requirements, use a shader that assumes the desired normal. + [UnityEngine.Serialization.FormerlySerializedAs("calculateNormals")] public bool addNormals = false; + + /// If true, tangents are calculated every frame and added to the Mesh. Enable this when using a shader that uses lighting that requires tangents. + public bool calculateTangents = false; + + #if BUILT_IN_SPRITE_MASK_COMPONENT + /// This enum controls the mode under which the sprite will interact with the masking system. + /// Interaction modes with components are identical to Unity's , + /// see https://docs.unity3d.com/ScriptReference/SpriteMaskInteraction.html. + public SpriteMaskInteraction maskInteraction = SpriteMaskInteraction.None; + + [System.Serializable] + public class SpriteMaskInteractionMaterials { + public bool AnyMaterialCreated { + get { + return materialsMaskDisabled.Length > 0 || + materialsInsideMask.Length > 0 || + materialsOutsideMask.Length > 0; + } + } + + /// Material references for switching material sets at runtime when changes to . + public Material[] materialsMaskDisabled = new Material[0]; + /// Material references for switching material sets at runtime when changes to . + public Material[] materialsInsideMask = new Material[0]; + /// Material references for switching material sets at runtime when changes to . + public Material[] materialsOutsideMask = new Material[0]; + } + /// Material references for switching material sets at runtime when changes. + public SpriteMaskInteractionMaterials maskMaterials = new SpriteMaskInteractionMaterials(); + + /// Shader property ID used for the Stencil comparison function. + public static readonly int STENCIL_COMP_PARAM_ID = Shader.PropertyToID("_StencilComp"); + /// Shader property value used as Stencil comparison function for . + public const UnityEngine.Rendering.CompareFunction STENCIL_COMP_MASKINTERACTION_NONE = UnityEngine.Rendering.CompareFunction.Always; + /// Shader property value used as Stencil comparison function for . + public const UnityEngine.Rendering.CompareFunction STENCIL_COMP_MASKINTERACTION_VISIBLE_INSIDE = UnityEngine.Rendering.CompareFunction.LessEqual; + /// Shader property value used as Stencil comparison function for . + public const UnityEngine.Rendering.CompareFunction STENCIL_COMP_MASKINTERACTION_VISIBLE_OUTSIDE = UnityEngine.Rendering.CompareFunction.Greater; + #if UNITY_EDITOR + private static bool haveStencilParametersBeenFixed = false; + #endif + #endif // #if BUILT_IN_SPRITE_MASK_COMPONENT + #endregion + + #region Overrides + #if SPINE_OPTIONAL_RENDEROVERRIDE + // These are API for anything that wants to take over rendering for a SkeletonRenderer. + public bool disableRenderingOnOverride = true; + public delegate void InstructionDelegate (SkeletonRendererInstruction instruction); + event InstructionDelegate generateMeshOverride; + + /// Allows separate code to take over rendering for this SkeletonRenderer component. The subscriber is passed a SkeletonRendererInstruction argument to determine how to render a skeleton. + public event InstructionDelegate GenerateMeshOverride { + add { + generateMeshOverride += value; + if (disableRenderingOnOverride && generateMeshOverride != null) { + Initialize(false); + meshRenderer.enabled = false; + } + } + remove { + generateMeshOverride -= value; + if (disableRenderingOnOverride && generateMeshOverride == null) { + Initialize(false); + meshRenderer.enabled = true; + } + } + } + + /// Occurs after the vertex data is populated every frame, before the vertices are pushed into the mesh. + public event Spine.Unity.MeshGeneratorDelegate OnPostProcessVertices; + #endif + + #if SPINE_OPTIONAL_MATERIALOVERRIDE + [System.NonSerialized] readonly Dictionary customMaterialOverride = new Dictionary(); + /// Use this Dictionary to override a Material with a different Material. + public Dictionary CustomMaterialOverride { get { return customMaterialOverride; } } + #endif + + [System.NonSerialized] readonly Dictionary customSlotMaterials = new Dictionary(); + /// Use this Dictionary to use a different Material to render specific Slots. + public Dictionary CustomSlotMaterials { get { return customSlotMaterials; } } + #endregion + + #region Mesh Generator + [System.NonSerialized] readonly SkeletonRendererInstruction currentInstructions = new SkeletonRendererInstruction(); + readonly MeshGenerator meshGenerator = new MeshGenerator(); + [System.NonSerialized] readonly MeshRendererBuffers rendererBuffers = new MeshRendererBuffers(); + #endregion + + #region Cached component references + MeshRenderer meshRenderer; + MeshFilter meshFilter; + #endregion + + #region Skeleton + [System.NonSerialized] public bool valid; + [System.NonSerialized] public Skeleton skeleton; + public Skeleton Skeleton { + get { + Initialize(false); + return skeleton; + } + } + #endregion + + public delegate void SkeletonRendererDelegate (SkeletonRenderer skeletonRenderer); + + /// OnRebuild is raised after the Skeleton is successfully initialized. + public event SkeletonRendererDelegate OnRebuild; + + /// OnMeshAndMaterialsUpdated is called at the end of LateUpdate after the Mesh and + /// all materials have been updated. + public event SkeletonRendererDelegate OnMeshAndMaterialsUpdated; + + public SkeletonDataAsset SkeletonDataAsset { get { return skeletonDataAsset; } } // ISkeletonComponent + + #region Runtime Instantiation + public static T NewSpineGameObject (SkeletonDataAsset skeletonDataAsset) where T : SkeletonRenderer { + return SkeletonRenderer.AddSpineComponent(new GameObject("New Spine GameObject"), skeletonDataAsset); + } + + /// Add and prepare a Spine component that derives from SkeletonRenderer to a GameObject at runtime. + /// T should be SkeletonRenderer or any of its derived classes. + public static T AddSpineComponent (GameObject gameObject, SkeletonDataAsset skeletonDataAsset) where T : SkeletonRenderer { + var c = gameObject.AddComponent(); + if (skeletonDataAsset != null) { + c.skeletonDataAsset = skeletonDataAsset; + c.Initialize(false); + } + return c; + } + + /// Applies MeshGenerator settings to the SkeletonRenderer and its internal MeshGenerator. + public void SetMeshSettings (MeshGenerator.Settings settings) { + this.calculateTangents = settings.calculateTangents; + this.immutableTriangles = settings.immutableTriangles; + this.pmaVertexColors = settings.pmaVertexColors; + this.tintBlack = settings.tintBlack; + this.useClipping = settings.useClipping; + this.zSpacing = settings.zSpacing; + + this.meshGenerator.settings = settings; + } + #endregion + + + public virtual void Awake () { + Initialize(false); + } + + void OnDisable () { + if (clearStateOnDisable && valid) + ClearState(); + } + + void OnDestroy () { + rendererBuffers.Dispose(); + valid = false; + } + + /// + /// Clears the previously generated mesh and resets the skeleton's pose. + public virtual void ClearState () { + var meshFilter = GetComponent(); + if (meshFilter != null) meshFilter.sharedMesh = null; + currentInstructions.Clear(); + if (skeleton != null) skeleton.SetToSetupPose(); + } + + /// + /// Sets a minimum buffer size for the internal MeshGenerator to prevent excess allocations during animation. + /// + public void EnsureMeshGeneratorCapacity (int minimumVertexCount) { + meshGenerator.EnsureVertexCapacity(minimumVertexCount); + } + + /// + /// Initialize this component. Attempts to load the SkeletonData and creates the internal Skeleton object and buffers. + /// If set to true, it will overwrite internal objects if they were already generated. Otherwise, the initialized component will ignore subsequent calls to initialize. + public virtual void Initialize (bool overwrite) { + if (valid && !overwrite) + return; + + // Clear + { + // Note: do not reset meshFilter.sharedMesh or meshRenderer.sharedMaterial to null, + // otherwise constant reloading will be triggered at prefabs. + currentInstructions.Clear(); + rendererBuffers.Clear(); + meshGenerator.Begin(); + skeleton = null; + valid = false; + } + + if (skeletonDataAsset == null) + return; + + SkeletonData skeletonData = skeletonDataAsset.GetSkeletonData(false); + if (skeletonData == null) return; + valid = true; + + meshFilter = GetComponent(); + meshRenderer = GetComponent(); + rendererBuffers.Initialize(); + + skeleton = new Skeleton(skeletonData) { + ScaleX = initialFlipX ? -1 : 1, + ScaleY = initialFlipY ? -1 : 1 + }; + + if (!string.IsNullOrEmpty(initialSkinName) && !string.Equals(initialSkinName, "default", System.StringComparison.Ordinal)) + skeleton.SetSkin(initialSkinName); + + separatorSlots.Clear(); + for (int i = 0; i < separatorSlotNames.Length; i++) + separatorSlots.Add(skeleton.FindSlot(separatorSlotNames[i])); + + LateUpdate(); // Generate mesh for the first frame it exists. + + if (OnRebuild != null) + OnRebuild(this); + + #if UNITY_EDITOR + if (!Application.isPlaying) { + string errorMessage = null; + if (MaterialChecks.IsMaterialSetupProblematic(this, ref errorMessage)) + Debug.LogWarningFormat(this, "Problematic material setup at {0}: {1}", this.name, errorMessage); + } + #endif + } + + /// + /// Generates a new UnityEngine.Mesh from the internal Skeleton. + public virtual void LateUpdate () { + if (!valid) return; + + #if UNITY_EDITOR && NEW_PREFAB_SYSTEM + // Don't store mesh or material at the prefab, otherwise it will permanently reload + var prefabType = UnityEditor.PrefabUtility.GetPrefabAssetType(this); + if (UnityEditor.PrefabUtility.IsPartOfPrefabAsset(this) && + (prefabType == UnityEditor.PrefabAssetType.Regular || prefabType == UnityEditor.PrefabAssetType.Variant)) { + return; + } + #endif + + if (updateMode <= UpdateMode.EverythingExceptMesh) return; + + #if SPINE_OPTIONAL_RENDEROVERRIDE + bool doMeshOverride = generateMeshOverride != null; + if ((!meshRenderer.enabled) && !doMeshOverride) return; + #else + const bool doMeshOverride = false; + if (!meshRenderer.enabled) return; + #endif + var currentInstructions = this.currentInstructions; + var workingSubmeshInstructions = currentInstructions.submeshInstructions; + var currentSmartMesh = rendererBuffers.GetNextMesh(); // Double-buffer for performance. + + bool updateTriangles; + + if (this.singleSubmesh) { + // STEP 1. Determine a SmartMesh.Instruction. Split up instructions into submeshes. ============================================= + MeshGenerator.GenerateSingleSubmeshInstruction(currentInstructions, skeleton, skeletonDataAsset.atlasAssets[0].PrimaryMaterial); + + // STEP 1.9. Post-process workingInstructions. ================================================================================== + #if SPINE_OPTIONAL_MATERIALOVERRIDE + if (customMaterialOverride.Count > 0) // isCustomMaterialOverridePopulated + MeshGenerator.TryReplaceMaterials(workingSubmeshInstructions, customMaterialOverride); + #endif + + // STEP 2. Update vertex buffer based on verts from the attachments. =========================================================== + meshGenerator.settings = new MeshGenerator.Settings { + pmaVertexColors = this.pmaVertexColors, + zSpacing = this.zSpacing, + useClipping = this.useClipping, + tintBlack = this.tintBlack, + calculateTangents = this.calculateTangents, + addNormals = this.addNormals + }; + meshGenerator.Begin(); + updateTriangles = SkeletonRendererInstruction.GeometryNotEqual(currentInstructions, currentSmartMesh.instructionUsed); + if (currentInstructions.hasActiveClipping) { + meshGenerator.AddSubmesh(workingSubmeshInstructions.Items[0], updateTriangles); + } else { + meshGenerator.BuildMeshWithArrays(currentInstructions, updateTriangles); + } + + } else { + // STEP 1. Determine a SmartMesh.Instruction. Split up instructions into submeshes. ============================================= + MeshGenerator.GenerateSkeletonRendererInstruction(currentInstructions, skeleton, customSlotMaterials, separatorSlots, doMeshOverride, this.immutableTriangles); + + // STEP 1.9. Post-process workingInstructions. ================================================================================== +#if SPINE_OPTIONAL_MATERIALOVERRIDE + if (customMaterialOverride.Count > 0) // isCustomMaterialOverridePopulated + MeshGenerator.TryReplaceMaterials(workingSubmeshInstructions, customMaterialOverride); +#endif + +#if SPINE_OPTIONAL_RENDEROVERRIDE + if (doMeshOverride) { + this.generateMeshOverride(currentInstructions); + if (disableRenderingOnOverride) return; + } +#endif + + updateTriangles = SkeletonRendererInstruction.GeometryNotEqual(currentInstructions, currentSmartMesh.instructionUsed); + + // STEP 2. Update vertex buffer based on verts from the attachments. =========================================================== + meshGenerator.settings = new MeshGenerator.Settings { + pmaVertexColors = this.pmaVertexColors, + zSpacing = this.zSpacing, + useClipping = this.useClipping, + tintBlack = this.tintBlack, + calculateTangents = this.calculateTangents, + addNormals = this.addNormals + }; + meshGenerator.Begin(); + if (currentInstructions.hasActiveClipping) + meshGenerator.BuildMesh(currentInstructions, updateTriangles); + else + meshGenerator.BuildMeshWithArrays(currentInstructions, updateTriangles); + } + + if (OnPostProcessVertices != null) OnPostProcessVertices.Invoke(this.meshGenerator.Buffers); + + // STEP 3. Move the mesh data into a UnityEngine.Mesh =========================================================================== + var currentMesh = currentSmartMesh.mesh; + meshGenerator.FillVertexData(currentMesh); + + rendererBuffers.UpdateSharedMaterials(workingSubmeshInstructions); + + bool materialsChanged = rendererBuffers.MaterialsChangedInLastUpdate(); + if (updateTriangles) { // Check if the triangles should also be updated. + meshGenerator.FillTriangles(currentMesh); + meshRenderer.sharedMaterials = rendererBuffers.GetUpdatedSharedMaterialsArray(); + } else if (materialsChanged) { + meshRenderer.sharedMaterials = rendererBuffers.GetUpdatedSharedMaterialsArray(); + } + if (materialsChanged && (this.maskMaterials.AnyMaterialCreated)) { + this.maskMaterials = new SpriteMaskInteractionMaterials(); + } + + meshGenerator.FillLateVertexData(currentMesh); + + // STEP 4. The UnityEngine.Mesh is ready. Set it as the MeshFilter's mesh. Store the instructions used for that mesh. =========== + meshFilter.sharedMesh = currentMesh; + currentSmartMesh.instructionUsed.Set(currentInstructions); + + #if BUILT_IN_SPRITE_MASK_COMPONENT + if (meshRenderer != null) { + AssignSpriteMaskMaterials(); + } + #endif + + #if PER_MATERIAL_PROPERTY_BLOCKS + if (fixDrawOrder && meshRenderer.sharedMaterials.Length > 2) { + SetMaterialSettingsToFixDrawOrder(); + } + #endif + + if (OnMeshAndMaterialsUpdated != null) + OnMeshAndMaterialsUpdated(this); + } + + public void OnBecameVisible () { + updateMode = UpdateMode.FullUpdate; + } + + public void OnBecameInvisible () { + updateMode = updateWhenInvisible; + } + + public void FindAndApplySeparatorSlots (string startsWith, bool clearExistingSeparators = true, bool updateStringArray = false) { + if (string.IsNullOrEmpty(startsWith)) return; + + FindAndApplySeparatorSlots( + (slotName) => slotName.StartsWith(startsWith), + clearExistingSeparators, + updateStringArray + ); + } + + public void FindAndApplySeparatorSlots (System.Func slotNamePredicate, bool clearExistingSeparators = true, bool updateStringArray = false) { + if (slotNamePredicate == null) return; + if (!valid) return; + + if (clearExistingSeparators) + separatorSlots.Clear(); + + var slots = skeleton.slots; + foreach (var slot in slots) { + if (slotNamePredicate.Invoke(slot.data.name)) + separatorSlots.Add(slot); + } + + if (updateStringArray) { + var detectedSeparatorNames = new List(); + foreach (var slot in skeleton.slots) { + string slotName = slot.data.name; + if (slotNamePredicate.Invoke(slotName)) + detectedSeparatorNames.Add(slotName); + } + if (!clearExistingSeparators) { + string[] originalNames = this.separatorSlotNames; + foreach (string originalName in originalNames) + detectedSeparatorNames.Add(originalName); + } + + this.separatorSlotNames = detectedSeparatorNames.ToArray(); + } + + } + + public void ReapplySeparatorSlotNames () { + if (!valid) + return; + + separatorSlots.Clear(); + for (int i = 0, n = separatorSlotNames.Length; i < n; i++) { + var slot = skeleton.FindSlot(separatorSlotNames[i]); + if (slot != null) { + separatorSlots.Add(slot); + } + #if UNITY_EDITOR + else if (!string.IsNullOrEmpty(separatorSlotNames[i])) + { + Debug.LogWarning(separatorSlotNames[i] + " is not a slot in " + skeletonDataAsset.skeletonJSON.name); + } + #endif + } + } + + #if BUILT_IN_SPRITE_MASK_COMPONENT + private void AssignSpriteMaskMaterials() + { + #if UNITY_EDITOR + if (!Application.isPlaying && !UnityEditor.EditorApplication.isUpdating) { + EditorFixStencilCompParameters(); + } + #endif + + if (Application.isPlaying) { + if (maskInteraction != SpriteMaskInteraction.None && maskMaterials.materialsMaskDisabled.Length == 0) + maskMaterials.materialsMaskDisabled = meshRenderer.sharedMaterials; + } + + if (maskMaterials.materialsMaskDisabled.Length > 0 && maskMaterials.materialsMaskDisabled[0] != null && + maskInteraction == SpriteMaskInteraction.None) { + this.meshRenderer.materials = maskMaterials.materialsMaskDisabled; + } + else if (maskInteraction == SpriteMaskInteraction.VisibleInsideMask) { + if (maskMaterials.materialsInsideMask.Length == 0 || maskMaterials.materialsInsideMask[0] == null) { + if (!InitSpriteMaskMaterialsInsideMask()) + return; + } + this.meshRenderer.materials = maskMaterials.materialsInsideMask; + } + else if (maskInteraction == SpriteMaskInteraction.VisibleOutsideMask) { + if (maskMaterials.materialsOutsideMask.Length == 0 || maskMaterials.materialsOutsideMask[0] == null) { + if (!InitSpriteMaskMaterialsOutsideMask()) + return; + } + this.meshRenderer.materials = maskMaterials.materialsOutsideMask; + } + } + + private bool InitSpriteMaskMaterialsInsideMask() + { + return InitSpriteMaskMaterialsForMaskType(STENCIL_COMP_MASKINTERACTION_VISIBLE_INSIDE, ref maskMaterials.materialsInsideMask); + } + + private bool InitSpriteMaskMaterialsOutsideMask() + { + return InitSpriteMaskMaterialsForMaskType(STENCIL_COMP_MASKINTERACTION_VISIBLE_OUTSIDE, ref maskMaterials.materialsOutsideMask); + } + + private bool InitSpriteMaskMaterialsForMaskType(UnityEngine.Rendering.CompareFunction maskFunction, ref Material[] materialsToFill) + { + #if UNITY_EDITOR + if (!Application.isPlaying) { + return false; + } + #endif + + var originalMaterials = maskMaterials.materialsMaskDisabled; + materialsToFill = new Material[originalMaterials.Length]; + for (int i = 0; i < originalMaterials.Length; i++) { + Material newMaterial = new Material(originalMaterials[i]); + newMaterial.SetFloat(STENCIL_COMP_PARAM_ID, (int)maskFunction); + materialsToFill[i] = newMaterial; + } + return true; + } + + #if UNITY_EDITOR + private void EditorFixStencilCompParameters() { + if (!haveStencilParametersBeenFixed && HasAnyStencilComp0Material()) { + haveStencilParametersBeenFixed = true; + FixAllProjectMaterialsStencilCompParameters(); + } + } + + private void FixAllProjectMaterialsStencilCompParameters() { + string[] materialGUIDS = UnityEditor.AssetDatabase.FindAssets("t:material"); + foreach (var guid in materialGUIDS) { + string path = UnityEditor.AssetDatabase.GUIDToAssetPath(guid); + if (!string.IsNullOrEmpty(path)) { + var mat = UnityEditor.AssetDatabase.LoadAssetAtPath(path); + if (mat.HasProperty(STENCIL_COMP_PARAM_ID) && mat.GetFloat(STENCIL_COMP_PARAM_ID) == 0) { + mat.SetFloat(STENCIL_COMP_PARAM_ID, (int)STENCIL_COMP_MASKINTERACTION_NONE); + } + } + } + UnityEditor.AssetDatabase.Refresh(); + UnityEditor.AssetDatabase.SaveAssets(); + } + + private bool HasAnyStencilComp0Material() { + if (meshRenderer == null) + return false; + + foreach (var mat in meshRenderer.sharedMaterials) { + if (mat != null && mat.HasProperty(STENCIL_COMP_PARAM_ID)) { + float currentCompValue = mat.GetFloat(STENCIL_COMP_PARAM_ID); + if (currentCompValue == 0) + return true; + } + } + return false; + } + #endif // UNITY_EDITOR + + #endif //#if BUILT_IN_SPRITE_MASK_COMPONENT + + #if PER_MATERIAL_PROPERTY_BLOCKS + private MaterialPropertyBlock reusedPropertyBlock; + public static readonly int SUBMESH_DUMMY_PARAM_ID = Shader.PropertyToID("_Submesh"); + + /// + /// This method was introduced as a workaround for too aggressive submesh draw call batching, + /// leading to incorrect draw order when 3+ materials are used at submeshes in alternating order. + /// Otherwise, e.g. when using Lightweight Render Pipeline, deliberately separated draw calls + /// "A1 B A2" are reordered to "A1A2 B", regardless of batching-related project settings. + /// + private void SetMaterialSettingsToFixDrawOrder() { + if (reusedPropertyBlock == null) reusedPropertyBlock = new MaterialPropertyBlock(); + + bool hasPerRendererBlock = meshRenderer.HasPropertyBlock(); + if (hasPerRendererBlock) { + meshRenderer.GetPropertyBlock(reusedPropertyBlock); + } + + for (int i = 0; i < meshRenderer.sharedMaterials.Length; ++i) { + if (!hasPerRendererBlock) meshRenderer.GetPropertyBlock(reusedPropertyBlock, i); + // Note: this parameter shall not exist at any shader, then Unity will create separate + // material instances (not in terms of memory cost or leakage). + reusedPropertyBlock.SetFloat(SUBMESH_DUMMY_PARAM_ID, i); + meshRenderer.SetPropertyBlock(reusedPropertyBlock, i); + + meshRenderer.sharedMaterials[i].enableInstancing = false; + } + } + #endif + } +} diff --git a/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonRenderer.cs.meta b/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonRenderer.cs.meta new file mode 100644 index 00000000..5230098d --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonRenderer.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: e075b9a3e08e2f74fbd651c858ab16ed +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonRendererCustomMaterials.meta b/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonRendererCustomMaterials.meta new file mode 100644 index 00000000..16b542c7 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonRendererCustomMaterials.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: a7236dbdc6a4e5a4989483dac97aee0b +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonRendererCustomMaterials/SkeletonGraphicCustomMaterials.cs b/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonRendererCustomMaterials/SkeletonGraphicCustomMaterials.cs new file mode 100644 index 00000000..afbb84b2 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonRendererCustomMaterials/SkeletonGraphicCustomMaterials.cs @@ -0,0 +1,211 @@ +/****************************************************************************** + * 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 + [HelpURL("http://esotericsoftware.com/spine-unity#SkeletonGraphicCustomMaterials")] + public class SkeletonGraphicCustomMaterials : MonoBehaviour { + + #region Inspector + public SkeletonGraphic skeletonGraphic; + [SerializeField] protected List customMaterialOverrides = new List(); + [SerializeField] protected List customTextureOverrides = new List(); + + #if UNITY_EDITOR + void Reset () { + skeletonGraphic = GetComponent(); + + // Populate material list + if (skeletonGraphic != null && skeletonGraphic.skeletonDataAsset != null) { + var atlasAssets = skeletonGraphic.skeletonDataAsset.atlasAssets; + + var initialAtlasMaterialOverrides = new List(); + 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(); + 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(); + + 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 { + 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 { + public bool overrideEnabled; + public Texture originalTexture; + public Texture replacementTexture; + + public bool Equals (AtlasTextureOverride other) { + return overrideEnabled == other.overrideEnabled && originalTexture == other.originalTexture && replacementTexture == other.replacementTexture; + } + } + } +} diff --git a/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonRendererCustomMaterials/SkeletonGraphicCustomMaterials.cs.meta b/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonRendererCustomMaterials/SkeletonGraphicCustomMaterials.cs.meta new file mode 100644 index 00000000..3f0170a1 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonRendererCustomMaterials/SkeletonGraphicCustomMaterials.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 6c8717e10b272bf42b05d363ac2679a6 +timeCreated: 1588789074 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonRendererCustomMaterials/SkeletonRendererCustomMaterials.cs b/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonRendererCustomMaterials/SkeletonRendererCustomMaterials.cs new file mode 100644 index 00000000..c137570b --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonRendererCustomMaterials/SkeletonRendererCustomMaterials.cs @@ -0,0 +1,212 @@ +/****************************************************************************** + * 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 +#define SPINE_OPTIONAL_MATERIALOVERRIDE + +// Contributed by: Lost Polygon + +using System; +using System.Collections.Generic; +using UnityEngine; + +namespace Spine.Unity { + #if NEW_PREFAB_SYSTEM + [ExecuteAlways] + #else + [ExecuteInEditMode] + #endif + [HelpURL("http://esotericsoftware.com/spine-unity#SkeletonRendererCustomMaterials")] + public class SkeletonRendererCustomMaterials : MonoBehaviour { + + #region Inspector + public SkeletonRenderer skeletonRenderer; + [SerializeField] protected List customSlotMaterials = new List(); + [SerializeField] protected List customMaterialOverrides = new List(); + + #if UNITY_EDITOR + void Reset () { + skeletonRenderer = GetComponent(); + + // Populate atlas list + if (skeletonRenderer != null && skeletonRenderer.skeletonDataAsset != null) { + var atlasAssets = skeletonRenderer.skeletonDataAsset.atlasAssets; + + var initialAtlasMaterialOverrides = new List(); + foreach (AtlasAssetBase atlasAsset in atlasAssets) { + foreach (Material atlasMaterial in atlasAsset.Materials) { + var atlasMaterialOverride = new AtlasMaterialOverride { + overrideDisabled = true, + originalMaterial = atlasMaterial + }; + + initialAtlasMaterialOverrides.Add(atlasMaterialOverride); + } + } + + customMaterialOverrides = initialAtlasMaterialOverrides; + } + } + #endif + #endregion + + void SetCustomSlotMaterials () { + if (skeletonRenderer == null) { + Debug.LogError("skeletonRenderer == null"); + return; + } + + for (int i = 0; i < customSlotMaterials.Count; i++) { + SlotMaterialOverride slotMaterialOverride = customSlotMaterials[i]; + if (slotMaterialOverride.overrideDisabled || string.IsNullOrEmpty(slotMaterialOverride.slotName)) + continue; + + Slot slotObject = skeletonRenderer.skeleton.FindSlot(slotMaterialOverride.slotName); + skeletonRenderer.CustomSlotMaterials[slotObject] = slotMaterialOverride.material; + } + } + + void RemoveCustomSlotMaterials () { + if (skeletonRenderer == null) { + Debug.LogError("skeletonRenderer == null"); + return; + } + + for (int i = 0; i < customSlotMaterials.Count; i++) { + SlotMaterialOverride slotMaterialOverride = customSlotMaterials[i]; + if (string.IsNullOrEmpty(slotMaterialOverride.slotName)) + continue; + + Slot slotObject = skeletonRenderer.skeleton.FindSlot(slotMaterialOverride.slotName); + + Material currentMaterial; + if (!skeletonRenderer.CustomSlotMaterials.TryGetValue(slotObject, out currentMaterial)) + continue; + + // Do not revert the material if it was changed by something else + if (currentMaterial != slotMaterialOverride.material) + continue; + + skeletonRenderer.CustomSlotMaterials.Remove(slotObject); + } + } + + void SetCustomMaterialOverrides () { + if (skeletonRenderer == null) { + Debug.LogError("skeletonRenderer == null"); + return; + } + + #if SPINE_OPTIONAL_MATERIALOVERRIDE + for (int i = 0; i < customMaterialOverrides.Count; i++) { + AtlasMaterialOverride atlasMaterialOverride = customMaterialOverrides[i]; + if (atlasMaterialOverride.overrideDisabled) + continue; + + skeletonRenderer.CustomMaterialOverride[atlasMaterialOverride.originalMaterial] = atlasMaterialOverride.replacementMaterial; + } + #endif + } + + void RemoveCustomMaterialOverrides () { + if (skeletonRenderer == null) { + Debug.LogError("skeletonRenderer == null"); + return; + } + + #if SPINE_OPTIONAL_MATERIALOVERRIDE + for (int i = 0; i < customMaterialOverrides.Count; i++) { + AtlasMaterialOverride atlasMaterialOverride = customMaterialOverrides[i]; + Material currentMaterial; + + if (!skeletonRenderer.CustomMaterialOverride.TryGetValue(atlasMaterialOverride.originalMaterial, out currentMaterial)) + continue; + + // Do not revert the material if it was changed by something else + if (currentMaterial != atlasMaterialOverride.replacementMaterial) + continue; + + skeletonRenderer.CustomMaterialOverride.Remove(atlasMaterialOverride.originalMaterial); + } + #endif + } + + // OnEnable applies the overrides at runtime, and when the editor loads. + void OnEnable () { + if (skeletonRenderer == null) + skeletonRenderer = GetComponent(); + + if (skeletonRenderer == null) { + Debug.LogError("skeletonRenderer == null"); + return; + } + + skeletonRenderer.Initialize(false); + SetCustomMaterialOverrides(); + SetCustomSlotMaterials(); + } + + // OnDisable removes the overrides at runtime, and in the editor when the component is disabled or destroyed. + void OnDisable () { + if (skeletonRenderer == null) { + Debug.LogError("skeletonRenderer == null"); + return; + } + + RemoveCustomMaterialOverrides(); + RemoveCustomSlotMaterials(); + } + + [Serializable] + public struct SlotMaterialOverride : IEquatable { + public bool overrideDisabled; + + [SpineSlot] + public string slotName; + public Material material; + + public bool Equals (SlotMaterialOverride other) { + return overrideDisabled == other.overrideDisabled && slotName == other.slotName && material == other.material; + } + } + + [Serializable] + public struct AtlasMaterialOverride : IEquatable { + public bool overrideDisabled; + public Material originalMaterial; + public Material replacementMaterial; + + public bool Equals (AtlasMaterialOverride other) { + return overrideDisabled == other.overrideDisabled && originalMaterial == other.originalMaterial && replacementMaterial == other.replacementMaterial; + } + } + } +} diff --git a/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonRendererCustomMaterials/SkeletonRendererCustomMaterials.cs.meta b/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonRendererCustomMaterials/SkeletonRendererCustomMaterials.cs.meta new file mode 100644 index 00000000..eb50faf2 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonRendererCustomMaterials/SkeletonRendererCustomMaterials.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 26947ae098a8447408d80c0c86e35b48 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonUtility.meta b/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonUtility.meta new file mode 100644 index 00000000..d690c94d --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonUtility.meta @@ -0,0 +1,5 @@ +fileFormatVersion: 2 +guid: f6e0caaafe294de48af468a6a9321473 +folderAsset: yes +DefaultImporter: + userData: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonUtility/ActivateBasedOnFlipDirection.cs b/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonUtility/ActivateBasedOnFlipDirection.cs new file mode 100644 index 00000000..4855fd08 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonUtility/ActivateBasedOnFlipDirection.cs @@ -0,0 +1,92 @@ +/****************************************************************************** + * 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; + +namespace Spine.Unity { + + /// + /// Utility component to support flipping of 2D hinge chains (chains of HingeJoint2D objects) along + /// with the parent skeleton by activating the respective mirrored versions of the hinge chain. + /// Note: This component is automatically attached when calling "Create Hinge Chain 2D" at , + /// do not attempt to use this component for other purposes. + /// + public class ActivateBasedOnFlipDirection : MonoBehaviour { + + public SkeletonRenderer skeletonRenderer; + public SkeletonGraphic skeletonGraphic; + public GameObject activeOnNormalX; + public GameObject activeOnFlippedX; + HingeJoint2D[] jointsNormalX; + HingeJoint2D[] jointsFlippedX; + ISkeletonComponent skeletonComponent; + + bool wasFlippedXBefore = false; + + private void Start () { + jointsNormalX = activeOnNormalX.GetComponentsInChildren(); + jointsFlippedX = activeOnFlippedX.GetComponentsInChildren(); + skeletonComponent = skeletonRenderer != null ? (ISkeletonComponent)skeletonRenderer : (ISkeletonComponent)skeletonGraphic; + } + + private void FixedUpdate () { + bool isFlippedX = (skeletonComponent.Skeleton.ScaleX < 0); + if (isFlippedX != wasFlippedXBefore) { + HandleFlip(isFlippedX); + } + wasFlippedXBefore = isFlippedX; + } + + void HandleFlip (bool isFlippedX) { + GameObject gameObjectToActivate = isFlippedX ? activeOnFlippedX : activeOnNormalX; + GameObject gameObjectToDeactivate = isFlippedX ? activeOnNormalX : activeOnFlippedX; + + gameObjectToActivate.SetActive(true); + gameObjectToDeactivate.SetActive(false); + + ResetJointPositions(isFlippedX ? jointsFlippedX : jointsNormalX); + ResetJointPositions(isFlippedX ? jointsNormalX : jointsFlippedX); + CompensateMovementAfterFlipX(gameObjectToActivate.transform, gameObjectToDeactivate.transform); + } + + void ResetJointPositions (HingeJoint2D[] joints) { + for (int i = 0; i < joints.Length; ++i) { + var joint = joints[i]; + var parent = joint.connectedBody.transform; + joint.transform.position = parent.TransformPoint(joint.connectedAnchor); + } + } + + void CompensateMovementAfterFlipX (Transform toActivate, Transform toDeactivate) { + Transform targetLocation = toDeactivate.GetChild(0); + Transform currentLocation = toActivate.GetChild(0); + toActivate.position += targetLocation.position - currentLocation.position; + } + } +} diff --git a/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonUtility/ActivateBasedOnFlipDirection.cs.meta b/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonUtility/ActivateBasedOnFlipDirection.cs.meta new file mode 100644 index 00000000..428af1bd --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonUtility/ActivateBasedOnFlipDirection.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 70ae96e4f2feb654681a2f16e4effeec +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonUtility/FollowLocationRigidbody.cs b/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonUtility/FollowLocationRigidbody.cs new file mode 100644 index 00000000..f0ede08e --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonUtility/FollowLocationRigidbody.cs @@ -0,0 +1,54 @@ +/****************************************************************************** + * 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; + +namespace Spine.Unity { + + /// + /// Utility component to support flipping of hinge chains (chains of HingeJoint objects) along with the parent skeleton. + /// + /// Note: This component is automatically attached when calling "Create Hinge Chain" at . + /// + [RequireComponent(typeof(Rigidbody))] + public class FollowLocationRigidbody : MonoBehaviour { + + public Transform reference; + Rigidbody ownRigidbody; + + private void Awake () { + ownRigidbody = this.GetComponent(); + } + + void FixedUpdate () { + ownRigidbody.rotation = reference.rotation; + ownRigidbody.position = reference.position; + } + } +} diff --git a/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonUtility/FollowLocationRigidbody.cs.meta b/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonUtility/FollowLocationRigidbody.cs.meta new file mode 100644 index 00000000..4354d36d --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonUtility/FollowLocationRigidbody.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 9fc20d5e917562341a5007777a9d0db2 +timeCreated: 1571763023 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonUtility/FollowLocationRigidbody2D.cs b/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonUtility/FollowLocationRigidbody2D.cs new file mode 100644 index 00000000..76c12b99 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonUtility/FollowLocationRigidbody2D.cs @@ -0,0 +1,59 @@ +/****************************************************************************** + * 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; + +namespace Spine.Unity { + + /// + /// Utility component to support flipping of hinge chains (chains of HingeJoint objects) along with the parent skeleton. + /// + /// Note: This component is automatically attached when calling "Create Hinge Chain" at . + /// + [RequireComponent(typeof(Rigidbody2D))] + public class FollowLocationRigidbody2D : MonoBehaviour { + + public Transform reference; + public bool followFlippedX; + Rigidbody2D ownRigidbody; + + private void Awake () { + ownRigidbody = this.GetComponent(); + } + + void FixedUpdate () { + if (followFlippedX) { + ownRigidbody.rotation = ((-reference.rotation.eulerAngles.z + 270f) % 360f) - 90f; + } + else + ownRigidbody.rotation = reference.rotation.eulerAngles.z; + ownRigidbody.position = reference.position; + } + } +} diff --git a/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonUtility/FollowLocationRigidbody2D.cs.meta b/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonUtility/FollowLocationRigidbody2D.cs.meta new file mode 100644 index 00000000..a62ccec6 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonUtility/FollowLocationRigidbody2D.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 02aae87c39b869548a9051fbdb1975e6 +timeCreated: 1572012493 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonUtility/FollowSkeletonUtilityRootRotation.cs b/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonUtility/FollowSkeletonUtilityRootRotation.cs new file mode 100644 index 00000000..a970ae98 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonUtility/FollowSkeletonUtilityRootRotation.cs @@ -0,0 +1,86 @@ +/****************************************************************************** + * 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; + +namespace Spine.Unity { + + /// + /// Utility component to support flipping of hinge chains (chains of HingeJoint objects) along with the parent skeleton. + /// Note that flipping needs to be performed by 180 degree rotation at , + /// by setting to true, not via negative scale. + /// + /// Note: This component is automatically attached when calling "Create Hinge Chain" at , + /// do not attempt to use this component for other purposes. + /// + public class FollowSkeletonUtilityRootRotation : MonoBehaviour { + + const float FLIP_ANGLE_THRESHOLD = 100.0f; + + public Transform reference; + Vector3 prevLocalEulerAngles; + + private void Start () { + prevLocalEulerAngles = this.transform.localEulerAngles; + } + + void FixedUpdate () { + this.transform.rotation = reference.rotation; + + bool wasFlippedAroundY = Mathf.Abs(this.transform.localEulerAngles.y - prevLocalEulerAngles.y) > FLIP_ANGLE_THRESHOLD; + bool wasFlippedAroundX = Mathf.Abs(this.transform.localEulerAngles.x - prevLocalEulerAngles.x) > FLIP_ANGLE_THRESHOLD; + if (wasFlippedAroundY) + CompensatePositionToYRotation(); + if (wasFlippedAroundX) + CompensatePositionToXRotation(); + + prevLocalEulerAngles = this.transform.localEulerAngles; + } + + /// + /// Compensates the position so that a child at the reference position remains in the same place, + /// to counter any movement that occurred by rotation. + /// + void CompensatePositionToYRotation () { + Vector3 newPosition = reference.position + (reference.position - this.transform.position); + newPosition.y = this.transform.position.y; + this.transform.position = newPosition; + } + + /// + /// Compensates the position so that a child at the reference position remains in the same place, + /// to counter any movement that occurred by rotation. + /// + void CompensatePositionToXRotation () { + Vector3 newPosition = reference.position + (reference.position - this.transform.position); + newPosition.x = this.transform.position.x; + this.transform.position = newPosition; + } + } +} diff --git a/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonUtility/FollowSkeletonUtilityRootRotation.cs.meta b/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonUtility/FollowSkeletonUtilityRootRotation.cs.meta new file mode 100644 index 00000000..60292410 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonUtility/FollowSkeletonUtilityRootRotation.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 456a736ebb92ebf4b959fa9c4b704427 +timeCreated: 1571763206 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonUtility/SkeletonUtility.cs b/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonUtility/SkeletonUtility.cs new file mode 100644 index 00000000..f4dcacf4 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonUtility/SkeletonUtility.cs @@ -0,0 +1,465 @@ +/****************************************************************************** + * 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 UnityEngine; +using System.Collections.Generic; + +namespace Spine.Unity { + + #if NEW_PREFAB_SYSTEM + [ExecuteAlways] + #else + [ExecuteInEditMode] + #endif + [RequireComponent(typeof(ISkeletonAnimation))] + [HelpURL("http://esotericsoftware.com/spine-unity#SkeletonUtility")] + public sealed class SkeletonUtility : MonoBehaviour { + + #region BoundingBoxAttachment + public static PolygonCollider2D AddBoundingBoxGameObject (Skeleton skeleton, string skinName, string slotName, string attachmentName, Transform parent, bool isTrigger = true) { + Skin skin = string.IsNullOrEmpty(skinName) ? skeleton.data.defaultSkin : skeleton.data.FindSkin(skinName); + if (skin == null) { + Debug.LogError("Skin " + skinName + " not found!"); + return null; + } + + var attachment = skin.GetAttachment(skeleton.FindSlotIndex(slotName), attachmentName); + if (attachment == null) { + Debug.LogFormat("Attachment in slot '{0}' named '{1}' not found in skin '{2}'.", slotName, attachmentName, skin.name); + return null; + } + + var box = attachment as BoundingBoxAttachment; + if (box != null) { + var slot = skeleton.FindSlot(slotName); + return AddBoundingBoxGameObject(box.Name, box, slot, parent, isTrigger); + } else { + Debug.LogFormat("Attachment '{0}' was not a Bounding Box.", attachmentName); + return null; + } + } + + public static PolygonCollider2D AddBoundingBoxGameObject (string name, BoundingBoxAttachment box, Slot slot, Transform parent, bool isTrigger = true) { + var go = new GameObject("[BoundingBox]" + (string.IsNullOrEmpty(name) ? box.Name : name)); +#if UNITY_EDITOR + if (!Application.isPlaying) + UnityEditor.Undo.RegisterCreatedObjectUndo(go, "Spawn BoundingBox"); +# endif + var got = go.transform; + got.parent = parent; + got.localPosition = Vector3.zero; + got.localRotation = Quaternion.identity; + got.localScale = Vector3.one; + return AddBoundingBoxAsComponent(box, slot, go, isTrigger); + } + + public static PolygonCollider2D AddBoundingBoxAsComponent (BoundingBoxAttachment box, Slot slot, GameObject gameObject, bool isTrigger = true) { + if (box == null) return null; + var collider = gameObject.AddComponent(); + collider.isTrigger = isTrigger; + SetColliderPointsLocal(collider, slot, box); + return collider; + } + + public static void SetColliderPointsLocal (PolygonCollider2D collider, Slot slot, BoundingBoxAttachment box) { + if (box == null) return; + if (box.IsWeighted()) Debug.LogWarning("UnityEngine.PolygonCollider2D does not support weighted or animated points. Collider points will not be animated and may have incorrect orientation. If you want to use it as a collider, please remove weights and animations from the bounding box in Spine editor."); + var verts = box.GetLocalVertices(slot, null); + collider.SetPath(0, verts); + } + + public static Bounds GetBoundingBoxBounds (BoundingBoxAttachment boundingBox, float depth = 0) { + float[] floats = boundingBox.Vertices; + int floatCount = floats.Length; + + Bounds bounds = new Bounds(); + + bounds.center = new Vector3(floats[0], floats[1], 0); + for (int i = 2; i < floatCount; i += 2) + bounds.Encapsulate(new Vector3(floats[i], floats[i + 1], 0)); + + Vector3 size = bounds.size; + size.z = depth; + bounds.size = size; + + return bounds; + } + + public static Rigidbody2D AddBoneRigidbody2D (GameObject gameObject, bool isKinematic = true, float gravityScale = 0f) { + var rb = gameObject.GetComponent(); + if (rb == null) { + rb = gameObject.AddComponent(); + rb.isKinematic = isKinematic; + rb.gravityScale = gravityScale; + } + return rb; + } + #endregion + + public delegate void SkeletonUtilityDelegate (); + public event SkeletonUtilityDelegate OnReset; + public Transform boneRoot; + /// + /// If true, and are followed + /// by 180 degree rotation. If false, negative Transform scale is used. + /// Note that using negative scale is consistent with previous behaviour (hence the default), + /// however causes serious problems with rigidbodies and physics. Therefore, it is recommended to + /// enable this parameter where possible. When creating hinge chains for a chain of skeleton bones + /// via , it is mandatory to have flipBy180DegreeRotation enabled. + /// + public bool flipBy180DegreeRotation = false; + + void Update () { + var skeleton = skeletonComponent.Skeleton; + if (skeleton != null && boneRoot != null) { + + if (flipBy180DegreeRotation) { + boneRoot.localScale = new Vector3(Mathf.Abs(skeleton.ScaleX), Mathf.Abs(skeleton.ScaleY), 1f); + boneRoot.eulerAngles = new Vector3(skeleton.ScaleY > 0 ? 0 : 180, + skeleton.ScaleX > 0 ? 0 : 180, + 0); + } + else { + boneRoot.localScale = new Vector3(skeleton.ScaleX, skeleton.ScaleY, 1f); + } + } + + if (canvas != null) { + positionScale = canvas.referencePixelsPerUnit; + } + } + + [HideInInspector] public SkeletonRenderer skeletonRenderer; + [HideInInspector] public SkeletonGraphic skeletonGraphic; + private Canvas canvas; + [System.NonSerialized] public ISkeletonAnimation skeletonAnimation; + + private ISkeletonComponent skeletonComponent; + [System.NonSerialized] public List boneComponents = new List(); + [System.NonSerialized] public List constraintComponents = new List(); + + + public ISkeletonComponent SkeletonComponent { + get { + if (skeletonComponent == null) { + skeletonComponent = skeletonRenderer != null ? skeletonRenderer.GetComponent() : + skeletonGraphic != null ? skeletonGraphic.GetComponent() : + GetComponent(); + } + return skeletonComponent; + } + } + public Skeleton Skeleton { + get { + if (SkeletonComponent == null) + return null; + return skeletonComponent.Skeleton; + } + } + + public bool IsValid { + get { + return (skeletonRenderer != null && skeletonRenderer.valid) || + (skeletonGraphic != null && skeletonGraphic.IsValid); + } + } + + public float PositionScale { get { return positionScale; } } + + float positionScale = 1.0f; + bool hasOverrideBones; + bool hasConstraints; + bool needToReprocessBones; + + public void ResubscribeEvents () { + OnDisable(); + OnEnable(); + } + + void OnEnable () { + if (skeletonRenderer == null) { + skeletonRenderer = GetComponent(); + } + if (skeletonGraphic == null) { + skeletonGraphic = GetComponent(); + } + if (skeletonAnimation == null) { + skeletonAnimation = skeletonRenderer != null ? skeletonRenderer.GetComponent() : + skeletonGraphic != null ? skeletonGraphic.GetComponent() : + GetComponent(); + } + if (skeletonComponent == null) { + skeletonComponent = skeletonRenderer != null ? skeletonRenderer.GetComponent() : + skeletonGraphic != null ? skeletonGraphic.GetComponent() : + GetComponent(); + } + + if (skeletonRenderer != null) { + skeletonRenderer.OnRebuild -= HandleRendererReset; + skeletonRenderer.OnRebuild += HandleRendererReset; + } + else if (skeletonGraphic != null) { + skeletonGraphic.OnRebuild -= HandleRendererReset; + skeletonGraphic.OnRebuild += HandleRendererReset; + canvas = skeletonGraphic.canvas; + if (canvas == null) + canvas = skeletonGraphic.GetComponentInParent(); + if (canvas == null) + positionScale = 100.0f; + } + + if (skeletonAnimation != null) { + skeletonAnimation.UpdateLocal -= UpdateLocal; + skeletonAnimation.UpdateLocal += UpdateLocal; + } + + CollectBones(); + } + + void Start () { + //recollect because order of operations failure when switching between game mode and edit mode... + CollectBones(); + } + + void OnDisable () { + if (skeletonRenderer != null) + skeletonRenderer.OnRebuild -= HandleRendererReset; + if (skeletonGraphic != null) + skeletonGraphic.OnRebuild -= HandleRendererReset; + + if (skeletonAnimation != null) { + skeletonAnimation.UpdateLocal -= UpdateLocal; + skeletonAnimation.UpdateWorld -= UpdateWorld; + skeletonAnimation.UpdateComplete -= UpdateComplete; + } + } + + void HandleRendererReset (SkeletonRenderer r) { + if (OnReset != null) OnReset(); + CollectBones(); + } + + void HandleRendererReset (SkeletonGraphic g) { + if (OnReset != null) OnReset(); + CollectBones(); + } + + public void RegisterBone (SkeletonUtilityBone bone) { + if (boneComponents.Contains(bone)) { + return; + } else { + boneComponents.Add(bone); + needToReprocessBones = true; + } + } + + public void UnregisterBone (SkeletonUtilityBone bone) { + boneComponents.Remove(bone); + } + + public void RegisterConstraint (SkeletonUtilityConstraint constraint) { + if (constraintComponents.Contains(constraint)) + return; + else { + constraintComponents.Add(constraint); + needToReprocessBones = true; + } + } + + public void UnregisterConstraint (SkeletonUtilityConstraint constraint) { + constraintComponents.Remove(constraint); + } + + public void CollectBones () { + var skeleton = skeletonComponent.Skeleton; + if (skeleton == null) return; + + if (boneRoot != null) { + var constraintTargets = new List(); + var ikConstraints = skeleton.IkConstraints; + for (int i = 0, n = ikConstraints.Count; i < n; i++) + constraintTargets.Add(ikConstraints.Items[i].target); + + var transformConstraints = skeleton.TransformConstraints; + for (int i = 0, n = transformConstraints.Count; i < n; i++) + constraintTargets.Add(transformConstraints.Items[i].target); + + var boneComponents = this.boneComponents; + for (int i = 0, n = boneComponents.Count; i < n; i++) { + var b = boneComponents[i]; + if (b.bone == null) { + b.DoUpdate(SkeletonUtilityBone.UpdatePhase.Local); + if (b.bone == null) continue; + } + hasOverrideBones |= (b.mode == SkeletonUtilityBone.Mode.Override); + hasConstraints |= constraintTargets.Contains(b.bone); + } + + hasConstraints |= constraintComponents.Count > 0; + + if (skeletonAnimation != null) { + skeletonAnimation.UpdateWorld -= UpdateWorld; + skeletonAnimation.UpdateComplete -= UpdateComplete; + + if (hasOverrideBones || hasConstraints) + skeletonAnimation.UpdateWorld += UpdateWorld; + + if (hasConstraints) + skeletonAnimation.UpdateComplete += UpdateComplete; + } + + needToReprocessBones = false; + } else { + boneComponents.Clear(); + constraintComponents.Clear(); + } + } + + void UpdateLocal (ISkeletonAnimation anim) { + if (needToReprocessBones) + CollectBones(); + + var boneComponents = this.boneComponents; + if (boneComponents == null) return; + for (int i = 0, n = boneComponents.Count; i < n; i++) + boneComponents[i].transformLerpComplete = false; + + UpdateAllBones(SkeletonUtilityBone.UpdatePhase.Local); + } + + void UpdateWorld (ISkeletonAnimation anim) { + UpdateAllBones(SkeletonUtilityBone.UpdatePhase.World); + for (int i = 0, n = constraintComponents.Count; i < n; i++) + constraintComponents[i].DoUpdate(); + } + + void UpdateComplete (ISkeletonAnimation anim) { + UpdateAllBones(SkeletonUtilityBone.UpdatePhase.Complete); + } + + void UpdateAllBones (SkeletonUtilityBone.UpdatePhase phase) { + if (boneRoot == null) + CollectBones(); + + var boneComponents = this.boneComponents; + if (boneComponents == null) return; + for (int i = 0, n = boneComponents.Count; i < n; i++) + boneComponents[i].DoUpdate(phase); + } + + public Transform GetBoneRoot () { + if (boneRoot != null) + return boneRoot; + + var boneRootObject = new GameObject("SkeletonUtility-SkeletonRoot"); +#if UNITY_EDITOR + if (!Application.isPlaying) + UnityEditor.Undo.RegisterCreatedObjectUndo(boneRootObject, "Spawn Bone"); +#endif + if (skeletonGraphic != null) + boneRootObject.AddComponent(); + + boneRoot = boneRootObject.transform; + boneRoot.SetParent(transform); + boneRoot.localPosition = Vector3.zero; + boneRoot.localRotation = Quaternion.identity; + boneRoot.localScale = Vector3.one; + + return boneRoot; + } + + public GameObject SpawnRoot (SkeletonUtilityBone.Mode mode, bool pos, bool rot, bool sca) { + GetBoneRoot(); + Skeleton skeleton = this.skeletonComponent.Skeleton; + + GameObject go = SpawnBone(skeleton.RootBone, boneRoot, mode, pos, rot, sca); + CollectBones(); + return go; + } + + public GameObject SpawnHierarchy (SkeletonUtilityBone.Mode mode, bool pos, bool rot, bool sca) { + GetBoneRoot(); + Skeleton skeleton = this.skeletonComponent.Skeleton; + GameObject go = SpawnBoneRecursively(skeleton.RootBone, boneRoot, mode, pos, rot, sca); + CollectBones(); + return go; + } + + public GameObject SpawnBoneRecursively (Bone bone, Transform parent, SkeletonUtilityBone.Mode mode, bool pos, bool rot, bool sca) { + GameObject go = SpawnBone(bone, parent, mode, pos, rot, sca); + + ExposedList childrenBones = bone.Children; + for (int i = 0, n = childrenBones.Count; i < n; i++) { + Bone child = childrenBones.Items[i]; + SpawnBoneRecursively(child, go.transform, mode, pos, rot, sca); + } + + return go; + } + + public GameObject SpawnBone (Bone bone, Transform parent, SkeletonUtilityBone.Mode mode, bool pos, bool rot, bool sca) { + GameObject go = new GameObject(bone.Data.Name); + #if UNITY_EDITOR + if (!Application.isPlaying) + UnityEditor.Undo.RegisterCreatedObjectUndo(go, "Spawn Bone"); + #endif + if (skeletonGraphic != null) + go.AddComponent(); + + var goTransform = go.transform; + goTransform.SetParent(parent); + + SkeletonUtilityBone b = go.AddComponent(); + b.hierarchy = this; + b.position = pos; + b.rotation = rot; + b.scale = sca; + b.mode = mode; + b.zPosition = true; + b.Reset(); + b.bone = bone; + b.boneName = bone.Data.Name; + b.valid = true; + + if (mode == SkeletonUtilityBone.Mode.Override) { + if (rot) goTransform.localRotation = Quaternion.Euler(0, 0, b.bone.AppliedRotation); + if (pos) goTransform.localPosition = new Vector3(b.bone.X * positionScale, b.bone.Y * positionScale, 0); + goTransform.localScale = new Vector3(b.bone.scaleX, b.bone.scaleY, 0); + } + + return go; + } + + } + +} diff --git a/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonUtility/SkeletonUtility.cs.meta b/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonUtility/SkeletonUtility.cs.meta new file mode 100644 index 00000000..29f2fd70 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonUtility/SkeletonUtility.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 7f726fb798ad621458c431cb9966d91d +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonUtility/SkeletonUtilityBone.cs b/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonUtility/SkeletonUtilityBone.cs new file mode 100644 index 00000000..c3e16f28 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonUtility/SkeletonUtilityBone.cs @@ -0,0 +1,243 @@ +/****************************************************************************** + * 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 UnityEngine; + +namespace Spine.Unity { + /// Sets a GameObject's transform to match a bone on a Spine skeleton. + #if NEW_PREFAB_SYSTEM + [ExecuteAlways] + #else + [ExecuteInEditMode] + #endif + [AddComponentMenu("Spine/SkeletonUtilityBone")] + [HelpURL("http://esotericsoftware.com/spine-unity#SkeletonUtilityBone")] + public class SkeletonUtilityBone : MonoBehaviour { + public enum Mode { + Follow, + Override + } + + public enum UpdatePhase { + Local, + World, + Complete + } + + #region Inspector + /// If a bone isn't set, boneName is used to find the bone. + public string boneName; + public Transform parentReference; + public Mode mode; + public bool position, rotation, scale, zPosition = true; + [Range(0f, 1f)] + public float overrideAlpha = 1; + #endregion + + public SkeletonUtility hierarchy; + [System.NonSerialized] public Bone bone; + [System.NonSerialized] public bool transformLerpComplete; + [System.NonSerialized] public bool valid; + Transform cachedTransform; + Transform skeletonTransform; + bool incompatibleTransformMode; + public bool IncompatibleTransformMode { get { return incompatibleTransformMode; } } + + public void Reset () { + bone = null; + cachedTransform = transform; + valid = hierarchy != null && hierarchy.IsValid; + if (!valid) + return; + skeletonTransform = hierarchy.transform; + hierarchy.OnReset -= HandleOnReset; + hierarchy.OnReset += HandleOnReset; + DoUpdate(UpdatePhase.Local); + } + + void OnEnable () { + if (hierarchy == null) hierarchy = transform.GetComponentInParent(); + if (hierarchy == null) return; + + hierarchy.RegisterBone(this); + hierarchy.OnReset += HandleOnReset; + } + + void HandleOnReset () { + Reset(); + } + + void OnDisable () { + if (hierarchy != null) { + hierarchy.OnReset -= HandleOnReset; + hierarchy.UnregisterBone(this); + } + } + + public void DoUpdate (UpdatePhase phase) { + if (!valid) { + Reset(); + return; + } + + var skeleton = hierarchy.Skeleton; + + if (bone == null) { + if (string.IsNullOrEmpty(boneName)) return; + bone = skeleton.FindBone(boneName); + if (bone == null) { + Debug.LogError("Bone not found: " + boneName, this); + return; + } + } + if (!bone.Active) return; + + float positionScale = hierarchy.PositionScale; + + var thisTransform = cachedTransform; + float skeletonFlipRotation = Mathf.Sign(skeleton.ScaleX * skeleton.ScaleY); + if (mode == Mode.Follow) { + switch (phase) { + case UpdatePhase.Local: + if (position) + thisTransform.localPosition = new Vector3(bone.x * positionScale, bone.y * positionScale, 0); + + if (rotation) { + if (bone.data.transformMode.InheritsRotation()) { + thisTransform.localRotation = Quaternion.Euler(0, 0, bone.rotation); + } else { + Vector3 euler = skeletonTransform.rotation.eulerAngles; + thisTransform.rotation = Quaternion.Euler(euler.x, euler.y, euler.z + (bone.WorldRotationX * skeletonFlipRotation)); + } + } + + if (scale) { + thisTransform.localScale = new Vector3(bone.scaleX, bone.scaleY, 1f); + incompatibleTransformMode = BoneTransformModeIncompatible(bone); + } + break; + case UpdatePhase.World: + case UpdatePhase.Complete: + // Use Applied transform values (ax, ay, AppliedRotation, ascale) if world values were modified by constraints. + if (!bone.appliedValid) { + bone.UpdateAppliedTransform(); + } + + if (position) + thisTransform.localPosition = new Vector3(bone.ax * positionScale, bone.ay * positionScale, 0); + + if (rotation) { + if (bone.data.transformMode.InheritsRotation()) { + thisTransform.localRotation = Quaternion.Euler(0, 0, bone.AppliedRotation); + } else { + Vector3 euler = skeletonTransform.rotation.eulerAngles; + thisTransform.rotation = Quaternion.Euler(euler.x, euler.y, euler.z + (bone.WorldRotationX * skeletonFlipRotation)); + } + } + + if (scale) { + thisTransform.localScale = new Vector3(bone.ascaleX, bone.ascaleY, 1f); + incompatibleTransformMode = BoneTransformModeIncompatible(bone); + } + break; + } + + } else if (mode == Mode.Override) { + if (transformLerpComplete) + return; + + if (parentReference == null) { + if (position) { + Vector3 clp = thisTransform.localPosition / positionScale; + bone.x = Mathf.Lerp(bone.x, clp.x, overrideAlpha); + bone.y = Mathf.Lerp(bone.y, clp.y, overrideAlpha); + } + + if (rotation) { + float angle = Mathf.LerpAngle(bone.Rotation, thisTransform.localRotation.eulerAngles.z, overrideAlpha); + bone.Rotation = angle; + bone.AppliedRotation = angle; + } + + if (scale) { + Vector3 cls = thisTransform.localScale; + bone.scaleX = Mathf.Lerp(bone.scaleX, cls.x, overrideAlpha); + bone.scaleY = Mathf.Lerp(bone.scaleY, cls.y, overrideAlpha); + } + + } else { + if (transformLerpComplete) + return; + + if (position) { + Vector3 pos = parentReference.InverseTransformPoint(thisTransform.position) / positionScale; + bone.x = Mathf.Lerp(bone.x, pos.x, overrideAlpha); + bone.y = Mathf.Lerp(bone.y, pos.y, overrideAlpha); + } + + if (rotation) { + float angle = Mathf.LerpAngle(bone.Rotation, Quaternion.LookRotation(Vector3.forward, parentReference.InverseTransformDirection(thisTransform.up)).eulerAngles.z, overrideAlpha); + bone.Rotation = angle; + bone.AppliedRotation = angle; + } + + if (scale) { + Vector3 cls = thisTransform.localScale; + bone.scaleX = Mathf.Lerp(bone.scaleX, cls.x, overrideAlpha); + bone.scaleY = Mathf.Lerp(bone.scaleY, cls.y, overrideAlpha); + } + + incompatibleTransformMode = BoneTransformModeIncompatible(bone); + } + + transformLerpComplete = true; + } + } + + public static bool BoneTransformModeIncompatible (Bone bone) { + return !bone.data.transformMode.InheritsScale(); + } + + public void AddBoundingBox (string skinName, string slotName, string attachmentName) { + SkeletonUtility.AddBoneRigidbody2D(transform.gameObject); + SkeletonUtility.AddBoundingBoxGameObject(bone.skeleton, skinName, slotName, attachmentName, transform); + } + +#if UNITY_EDITOR + void OnDrawGizmos () { + if (IncompatibleTransformMode) + Gizmos.DrawIcon(transform.position + new Vector3(0, 0.128f, 0), "icon-warning"); + } + #endif + } +} diff --git a/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonUtility/SkeletonUtilityBone.cs.meta b/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonUtility/SkeletonUtilityBone.cs.meta new file mode 100644 index 00000000..51537b4c --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonUtility/SkeletonUtilityBone.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: b238dfcde8209044b97d23f62bcaadf6 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonUtility/SkeletonUtilityConstraint.cs b/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonUtility/SkeletonUtilityConstraint.cs new file mode 100644 index 00000000..f549afaa --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonUtility/SkeletonUtilityConstraint.cs @@ -0,0 +1,62 @@ +/****************************************************************************** + * 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 UnityEngine; + +namespace Spine.Unity { + + #if NEW_PREFAB_SYSTEM + [ExecuteAlways] + #else + [ExecuteInEditMode] + #endif + [RequireComponent(typeof(SkeletonUtilityBone))] + [HelpURL("http://esotericsoftware.com/spine-unity#SkeletonUtilityConstraint")] + public abstract class SkeletonUtilityConstraint : MonoBehaviour { + + protected SkeletonUtilityBone bone; + protected SkeletonUtility hierarchy; + + protected virtual void OnEnable () { + bone = GetComponent(); + hierarchy = transform.GetComponentInParent(); + hierarchy.RegisterConstraint(this); + } + + protected virtual void OnDisable () { + hierarchy.UnregisterConstraint(this); + } + + public abstract void DoUpdate (); + } +} diff --git a/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonUtility/SkeletonUtilityConstraint.cs.meta b/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonUtility/SkeletonUtilityConstraint.cs.meta new file mode 100644 index 00000000..b78abdc1 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Components/SkeletonUtility/SkeletonUtilityConstraint.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 522dbfcc6c916df4396f14f35048d185 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Deprecated.meta b/box1/Assets/Spine/Runtime/spine-unity/Deprecated.meta new file mode 100644 index 00000000..099ea4ab --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Deprecated.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 04817e31b917de6489f349dd332d7468 +folderAsset: yes +timeCreated: 1563295668 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Deprecated/SlotBlendModes.meta b/box1/Assets/Spine/Runtime/spine-unity/Deprecated/SlotBlendModes.meta new file mode 100644 index 00000000..c3ef039c --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Deprecated/SlotBlendModes.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: dfdd78a071ca1a04bb64c6cc41e14aa0 +folderAsset: yes +timeCreated: 1496447038 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Deprecated/SlotBlendModes/SlotBlendModes.cs b/box1/Assets/Spine/Runtime/spine-unity/Deprecated/SlotBlendModes/SlotBlendModes.cs new file mode 100644 index 00000000..69b01b62 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Deprecated/SlotBlendModes/SlotBlendModes.cs @@ -0,0 +1,230 @@ +/****************************************************************************** + * 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.Collections.Generic; +using UnityEngine; +using System; + +namespace Spine.Unity.Deprecated { + + /// + /// Deprecated. The spine-unity 3.7 runtime introduced SkeletonDataModifierAssets BlendModeMaterials which replaced SlotBlendModes. See the + /// SkeletonDataModifierAssets BlendModeMaterials documentation page and + /// this forum thread for further information. + /// This class will be removed in the spine-unity 3.9 runtime. + /// + [Obsolete("The spine-unity 3.7 runtime introduced SkeletonDataModifierAssets BlendModeMaterials which replaced SlotBlendModes. Will be removed in spine-unity 3.9.", false)] + [DisallowMultipleComponent] + public class SlotBlendModes : MonoBehaviour { + + #region Internal Material Dictionary + public struct MaterialTexturePair { + public Texture2D texture2D; + public Material material; + } + + internal class MaterialWithRefcount { + public Material materialClone; + public int refcount = 1; + + public MaterialWithRefcount(Material mat) { + this.materialClone = mat; + } + } + static Dictionary materialTable; + internal static Dictionary MaterialTable { + get { + if (materialTable == null) materialTable = new Dictionary(); + return materialTable; + } + } + + internal struct SlotMaterialTextureTuple { + public Slot slot; + public Texture2D texture2D; + public Material material; + + public SlotMaterialTextureTuple(Slot slot, Material material, Texture2D texture) { + this.slot = slot; + this.material = material; + this.texture2D = texture; + } + } + + internal static Material GetOrAddMaterialFor(Material materialSource, Texture2D texture) { + if (materialSource == null || texture == null) return null; + + var mt = SlotBlendModes.MaterialTable; + MaterialWithRefcount matWithRefcount; + var key = new MaterialTexturePair { material = materialSource, texture2D = texture }; + if (!mt.TryGetValue(key, out matWithRefcount)) { + matWithRefcount = new MaterialWithRefcount(new Material(materialSource)); + var m = matWithRefcount.materialClone; + m.name = "(Clone)" + texture.name + "-" + materialSource.name; + m.mainTexture = texture; + mt[key] = matWithRefcount; + } + else { + matWithRefcount.refcount++; + } + return matWithRefcount.materialClone; + } + + internal static MaterialWithRefcount GetExistingMaterialFor(Material materialSource, Texture2D texture) + { + if (materialSource == null || texture == null) return null; + + var mt = SlotBlendModes.MaterialTable; + MaterialWithRefcount matWithRefcount; + var key = new MaterialTexturePair { material = materialSource, texture2D = texture }; + if (!mt.TryGetValue(key, out matWithRefcount)) { + return null; + } + return matWithRefcount; + } + + internal static void RemoveMaterialFromTable(Material materialSource, Texture2D texture) { + var mt = SlotBlendModes.MaterialTable; + var key = new MaterialTexturePair { material = materialSource, texture2D = texture }; + mt.Remove(key); + } + #endregion + + #region Inspector + public Material multiplyMaterialSource; + public Material screenMaterialSource; + + Texture2D texture; + #endregion + + SlotMaterialTextureTuple[] slotsWithCustomMaterial = new SlotMaterialTextureTuple[0]; + + public bool Applied { get; private set; } + + void Start() { + if (!Applied) Apply(); + } + + void OnDestroy() { + if (Applied) Remove(); + } + + public void Apply() { + GetTexture(); + if (texture == null) return; + + var skeletonRenderer = GetComponent(); + if (skeletonRenderer == null) return; + + var slotMaterials = skeletonRenderer.CustomSlotMaterials; + + int numSlotsWithCustomMaterial = 0; + foreach (var s in skeletonRenderer.Skeleton.Slots) { + switch (s.data.blendMode) { + case BlendMode.Multiply: + if (multiplyMaterialSource != null) { + slotMaterials[s] = GetOrAddMaterialFor(multiplyMaterialSource, texture); + ++numSlotsWithCustomMaterial; + } + break; + case BlendMode.Screen: + if (screenMaterialSource != null) { + slotMaterials[s] = GetOrAddMaterialFor(screenMaterialSource, texture); + ++numSlotsWithCustomMaterial; + } + break; + } + } + slotsWithCustomMaterial = new SlotMaterialTextureTuple[numSlotsWithCustomMaterial]; + int storedSlotIndex = 0; + foreach (var s in skeletonRenderer.Skeleton.Slots) { + switch (s.data.blendMode) { + case BlendMode.Multiply: + if (multiplyMaterialSource != null) { + slotsWithCustomMaterial[storedSlotIndex++] = new SlotMaterialTextureTuple(s, multiplyMaterialSource, texture); + } + break; + case BlendMode.Screen: + if (screenMaterialSource != null) { + slotsWithCustomMaterial[storedSlotIndex++] = new SlotMaterialTextureTuple(s, screenMaterialSource, texture); + } + break; + } + } + + Applied = true; + skeletonRenderer.LateUpdate(); + } + + public void Remove() { + GetTexture(); + if (texture == null) return; + + var skeletonRenderer = GetComponent(); + if (skeletonRenderer == null) return; + + var slotMaterials = skeletonRenderer.CustomSlotMaterials; + + foreach (var slotWithCustomMat in slotsWithCustomMaterial) { + + Slot s = slotWithCustomMat.slot; + Material storedMaterialSource = slotWithCustomMat.material; + Texture2D storedTexture = slotWithCustomMat.texture2D; + + var matWithRefcount = GetExistingMaterialFor(storedMaterialSource, storedTexture); + if (--matWithRefcount.refcount == 0) { + RemoveMaterialFromTable(storedMaterialSource, storedTexture); + } + // we don't want to remove slotMaterials[s] if it has been changed in the meantime. + Material m; + if (slotMaterials.TryGetValue(s, out m)) { + var existingMat = matWithRefcount == null ? null : matWithRefcount.materialClone; + if (Material.ReferenceEquals(m, existingMat)) { + slotMaterials.Remove(s); + } + } + } + slotsWithCustomMaterial = null; + + Applied = false; + if (skeletonRenderer.valid) skeletonRenderer.LateUpdate(); + } + + public void GetTexture() { + if (texture == null) { + var sr = GetComponent(); if (sr == null) return; + var sda = sr.skeletonDataAsset; if (sda == null) return; + var aa = sda.atlasAssets[0]; if (aa == null) return; + var am = aa.PrimaryMaterial; if (am == null) return; + texture = am.mainTexture as Texture2D; + } + } + + } +} diff --git a/box1/Assets/Spine/Runtime/spine-unity/Deprecated/SlotBlendModes/SlotBlendModes.cs.meta b/box1/Assets/Spine/Runtime/spine-unity/Deprecated/SlotBlendModes/SlotBlendModes.cs.meta new file mode 100644 index 00000000..6750f110 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Deprecated/SlotBlendModes/SlotBlendModes.cs.meta @@ -0,0 +1,16 @@ +fileFormatVersion: 2 +guid: f1f8243645ba2e74aa3564bd956eed89 +timeCreated: 1496794038 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: + - multiplyMaterialSource: {fileID: 2100000, guid: 53bf0ab317d032d418cf1252d68f51df, + type: 2} + - screenMaterialSource: {fileID: 2100000, guid: 73f0f46d3177c614baf0fa48d646a9be, + type: 2} + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/ISkeletonAnimation.cs b/box1/Assets/Spine/Runtime/spine-unity/ISkeletonAnimation.cs new file mode 100644 index 00000000..36e300ec --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/ISkeletonAnimation.cs @@ -0,0 +1,79 @@ +/****************************************************************************** + * 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. + *****************************************************************************/ + +namespace Spine.Unity { + public enum UpdateMode { + Nothing = 0, + OnlyAnimationStatus, + EverythingExceptMesh, + FullUpdate + }; + + public delegate void UpdateBonesDelegate (ISkeletonAnimation animated); + + /// A Spine-Unity Component that animates a Skeleton but not necessarily with a Spine.AnimationState. + public interface ISkeletonAnimation { + event UpdateBonesDelegate UpdateLocal; + event UpdateBonesDelegate UpdateWorld; + event UpdateBonesDelegate UpdateComplete; + Skeleton Skeleton { get; } + } + + /// Holds a reference to a SkeletonDataAsset. + public interface IHasSkeletonDataAsset { + /// Gets the SkeletonDataAsset of the Spine Component. + SkeletonDataAsset SkeletonDataAsset { get; } + } + + /// A Spine-Unity Component that manages a Spine.Skeleton instance, instantiated from a SkeletonDataAsset. + public interface ISkeletonComponent { + /// Gets the SkeletonDataAsset of the Spine Component. + //[System.Obsolete] + SkeletonDataAsset SkeletonDataAsset { get; } + + /// Gets the Spine.Skeleton instance of the Spine Component. This is equivalent to SkeletonRenderer's .skeleton. + Skeleton Skeleton { get; } + } + + /// A Spine-Unity Component that uses a Spine.AnimationState to animate its skeleton. + public interface IAnimationStateComponent { + /// Gets the Spine.AnimationState of the animated Spine Component. This is equivalent to SkeletonAnimation.state. + AnimationState AnimationState { get; } + } + + /// A Spine-Unity Component that holds a reference to a SkeletonRenderer. + public interface IHasSkeletonRenderer { + SkeletonRenderer SkeletonRenderer { get; } + } + + /// A Spine-Unity Component that holds a reference to an ISkeletonComponent. + public interface IHasSkeletonComponent { + ISkeletonComponent SkeletonComponent { get; } + } +} diff --git a/box1/Assets/Spine/Runtime/spine-unity/ISkeletonAnimation.cs.meta b/box1/Assets/Spine/Runtime/spine-unity/ISkeletonAnimation.cs.meta new file mode 100644 index 00000000..68e421f6 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/ISkeletonAnimation.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: a7b480b941568134891f411137bfbf55 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Materials.meta b/box1/Assets/Spine/Runtime/spine-unity/Materials.meta new file mode 100644 index 00000000..da6d0a29 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Materials.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 43897010c7e77c54897cb98c1ddf84f1 +folderAsset: yes +timeCreated: 1455128695 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Materials/SkeletonGraphicDefault.mat b/box1/Assets/Spine/Runtime/spine-unity/Materials/SkeletonGraphicDefault.mat new file mode 100644 index 00000000..08d7764c --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Materials/SkeletonGraphicDefault.mat @@ -0,0 +1,87 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 6 + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_Name: SkeletonGraphicDefault + m_Shader: {fileID: 4800000, guid: fa95b0fb6983c0f40a152e6f9aa82bfb, type: 3} + m_ShaderKeywords: + m_LightmapFlags: 5 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: -1 + stringTagMap: {} + disabledShaderPasses: [] + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _AlphaTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Floats: + - PixelSnap: 0 + - _BumpScale: 1 + - _ColorMask: 15 + - _Cutoff: 0.5 + - _DetailNormalMapScale: 1 + - _DstBlend: 0 + - _EnableExternalAlpha: 0 + - _Glossiness: 0.5 + - _Metallic: 0 + - _Mode: 0 + - _OcclusionStrength: 1 + - _Parallax: 0.02 + - _SrcBlend: 1 + - _Stencil: 0 + - _StencilComp: 8 + - _StencilOp: 0 + - _StencilReadMask: 255 + - _StencilWriteMask: 255 + - _UVSec: 0 + - _UseUIAlphaClip: 0 + - _ZWrite: 1 + m_Colors: + - _Color: {r: 1, g: 1, b: 1, a: 1} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} + - _Flip: {r: 1, g: 1, b: 1, a: 1} + - _RendererColor: {r: 1, g: 1, b: 1, a: 1} diff --git a/box1/Assets/Spine/Runtime/spine-unity/Materials/SkeletonGraphicDefault.mat.meta b/box1/Assets/Spine/Runtime/spine-unity/Materials/SkeletonGraphicDefault.mat.meta new file mode 100644 index 00000000..aaa80ff6 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Materials/SkeletonGraphicDefault.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: b66cf7a186d13054989b33a5c90044e4 +timeCreated: 1455140322 +licenseType: Free +NativeFormatImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Materials/SkeletonGraphicDefaultOutline.mat b/box1/Assets/Spine/Runtime/spine-unity/Materials/SkeletonGraphicDefaultOutline.mat new file mode 100644 index 00000000..7082bbf6 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Materials/SkeletonGraphicDefaultOutline.mat @@ -0,0 +1,95 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 6 + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_Name: SkeletonGraphicDefaultOutline + m_Shader: {fileID: 4800000, guid: 8f5d14d2a7fedb84998c50eb96c8b748, type: 3} + m_ShaderKeywords: _USE8NEIGHBOURHOOD_ON + m_LightmapFlags: 5 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: -1 + stringTagMap: {} + disabledShaderPasses: [] + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _AlphaTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Floats: + - PixelSnap: 0 + - _BumpScale: 1 + - _ColorMask: 15 + - _Cutoff: 0.5 + - _DetailNormalMapScale: 1 + - _DstBlend: 0 + - _EnableExternalAlpha: 0 + - _Glossiness: 0.5 + - _Metallic: 0 + - _Mode: 0 + - _OcclusionStrength: 1 + - _OutlineMipLevel: 0 + - _OutlineReferenceTexWidth: 1024 + - _OutlineSmoothness: 1 + - _OutlineWidth: 3 + - _Parallax: 0.02 + - _SrcBlend: 1 + - _Stencil: 0 + - _StencilComp: 8 + - _StencilOp: 0 + - _StencilReadMask: 255 + - _StencilWriteMask: 255 + - _StraightAlphaInput: 0 + - _ThresholdEnd: 0.25 + - _UVSec: 0 + - _Use8Neighbourhood: 1 + - _UseUIAlphaClip: 0 + - _ZWrite: 1 + m_Colors: + - _Color: {r: 1, g: 1, b: 1, a: 1} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} + - _Flip: {r: 1, g: 1, b: 1, a: 1} + - _OutlineColor: {r: 1, g: 1, b: 0, a: 1} + - _RendererColor: {r: 1, g: 1, b: 1, a: 1} diff --git a/box1/Assets/Spine/Runtime/spine-unity/Materials/SkeletonGraphicDefaultOutline.mat.meta b/box1/Assets/Spine/Runtime/spine-unity/Materials/SkeletonGraphicDefaultOutline.mat.meta new file mode 100644 index 00000000..beaf12d1 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Materials/SkeletonGraphicDefaultOutline.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: c4ee0f8f4be17434aa3df5774a03b366 +timeCreated: 1455140322 +licenseType: Free +NativeFormatImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Materials/SkeletonGraphicTintBlack.mat b/box1/Assets/Spine/Runtime/spine-unity/Materials/SkeletonGraphicTintBlack.mat new file mode 100644 index 00000000..d78d4152 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Materials/SkeletonGraphicTintBlack.mat @@ -0,0 +1,79 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 6 + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_Name: SkeletonGraphicTintBlack + m_Shader: {fileID: 4800000, guid: f64c7bc238bb2c246b8ca1912b2b6b9c, type: 3} + m_ShaderKeywords: + m_LightmapFlags: 5 + m_EnableInstancingVariants: 0 + m_CustomRenderQueue: -1 + stringTagMap: {} + disabledShaderPasses: [] + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Floats: + - _BumpScale: 1 + - _ColorMask: 15 + - _Cutoff: 0.5 + - _DetailNormalMapScale: 1 + - _DstBlend: 0 + - _Glossiness: 0.5 + - _Metallic: 0 + - _Mode: 0 + - _OcclusionStrength: 1 + - _Parallax: 0.02 + - _SrcBlend: 1 + - _Stencil: 0 + - _StencilComp: 8 + - _StencilOp: 0 + - _StencilReadMask: 255 + - _StencilWriteMask: 255 + - _UVSec: 0 + - _UseUIAlphaClip: 0 + - _ZWrite: 1 + m_Colors: + - _Black: {r: 0, g: 0, b: 0, a: 0} + - _Color: {r: 1, g: 1, b: 1, a: 1} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} diff --git a/box1/Assets/Spine/Runtime/spine-unity/Materials/SkeletonGraphicTintBlack.mat.meta b/box1/Assets/Spine/Runtime/spine-unity/Materials/SkeletonGraphicTintBlack.mat.meta new file mode 100644 index 00000000..0d83b238 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Materials/SkeletonGraphicTintBlack.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: cfcea0e11aa80bb4b8d05790b905fc31 +timeCreated: 1455140322 +licenseType: Free +NativeFormatImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Materials/SkeletonGraphicTintBlackOutline.mat b/box1/Assets/Spine/Runtime/spine-unity/Materials/SkeletonGraphicTintBlackOutline.mat new file mode 100644 index 00000000..30d42c7f --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Materials/SkeletonGraphicTintBlackOutline.mat @@ -0,0 +1,88 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 6 + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_Name: SkeletonGraphicTintBlackOutline + m_Shader: {fileID: 4800000, guid: d55d64dd09c46af40a319933a62fa1b2, type: 3} + m_ShaderKeywords: _USE8NEIGHBOURHOOD_ON + m_LightmapFlags: 5 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: -1 + stringTagMap: {} + disabledShaderPasses: [] + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Floats: + - _BumpScale: 1 + - _ColorMask: 15 + - _Cutoff: 0.5 + - _DetailNormalMapScale: 1 + - _DstBlend: 0 + - _Glossiness: 0.5 + - _Metallic: 0 + - _Mode: 0 + - _OcclusionStrength: 1 + - _OutlineMipLevel: 0 + - _OutlineReferenceTexWidth: 1024 + - _OutlineSmoothness: 1 + - _OutlineWidth: 3 + - _Parallax: 0.02 + - _SrcBlend: 1 + - _Stencil: 0 + - _StencilComp: 8 + - _StencilOp: 0 + - _StencilReadMask: 255 + - _StencilWriteMask: 255 + - _StraightAlphaInput: 0 + - _ThresholdEnd: 0.25 + - _UVSec: 0 + - _Use8Neighbourhood: 1 + - _UseUIAlphaClip: 0 + - _ZWrite: 1 + m_Colors: + - _Black: {r: 0, g: 0, b: 0, a: 0} + - _Color: {r: 1, g: 1, b: 1, a: 1} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} + - _OutlineColor: {r: 1, g: 1, b: 0, a: 1} diff --git a/box1/Assets/Spine/Runtime/spine-unity/Materials/SkeletonGraphicTintBlackOutline.mat.meta b/box1/Assets/Spine/Runtime/spine-unity/Materials/SkeletonGraphicTintBlackOutline.mat.meta new file mode 100644 index 00000000..a884c7e3 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Materials/SkeletonGraphicTintBlackOutline.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 94fe565c79b0aeb418cd05e4f1f8343c +timeCreated: 1455140322 +licenseType: Free +NativeFormatImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Mesh Generation.meta b/box1/Assets/Spine/Runtime/spine-unity/Mesh Generation.meta new file mode 100644 index 00000000..ae633507 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Mesh Generation.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: c5d065c4fe677ad4495a852580ec32fa +folderAsset: yes +timeCreated: 1455493477 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Mesh Generation/DoubleBuffered.cs b/box1/Assets/Spine/Runtime/spine-unity/Mesh Generation/DoubleBuffered.cs new file mode 100644 index 00000000..9b2c8d9a --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Mesh Generation/DoubleBuffered.cs @@ -0,0 +1,45 @@ +/****************************************************************************** + * 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. + *****************************************************************************/ + +namespace Spine.Unity { + public class DoubleBuffered where T : new() { + readonly T a = new T(); + readonly T b = new T(); + bool usingA; + + public T GetCurrent () { + return usingA ? a : b; + } + + public T GetNext () { + usingA = !usingA; + return usingA ? a : b; + } + } +} diff --git a/box1/Assets/Spine/Runtime/spine-unity/Mesh Generation/DoubleBuffered.cs.meta b/box1/Assets/Spine/Runtime/spine-unity/Mesh Generation/DoubleBuffered.cs.meta new file mode 100644 index 00000000..2e570e48 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Mesh Generation/DoubleBuffered.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 08b76da7751523448a87e528c48a5399 +timeCreated: 1457396939 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Mesh Generation/MeshGenerator.cs b/box1/Assets/Spine/Runtime/spine-unity/Mesh Generation/MeshGenerator.cs new file mode 100644 index 00000000..27a2f0ea --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Mesh Generation/MeshGenerator.cs @@ -0,0 +1,1373 @@ +/****************************************************************************** + * 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. + *****************************************************************************/ + +// Not for optimization. Do not disable. +#define SPINE_TRIANGLECHECK // Avoid calling SetTriangles at the cost of checking for mesh differences (vertex counts, memberwise attachment list compare) every frame. +//#define SPINE_DEBUG + +using UnityEngine; +using System; +using System.Collections.Generic; + +namespace Spine.Unity { + public delegate void MeshGeneratorDelegate (MeshGeneratorBuffers buffers); + public struct MeshGeneratorBuffers { + /// The vertex count that will actually be used for the mesh. The Lengths of the buffer arrays may be larger than this number. + public int vertexCount; + + /// Vertex positions. To be used for UnityEngine.Mesh.vertices. + public Vector3[] vertexBuffer; + + /// Vertex UVs. To be used for UnityEngine.Mesh.uvs. + public Vector2[] uvBuffer; + + /// Vertex colors. To be used for UnityEngine.Mesh.colors32. + public Color32[] colorBuffer; + + /// The Spine rendering component's MeshGenerator. + public MeshGenerator meshGenerator; + } + + /// Holds several methods to prepare and generate a UnityEngine mesh based on a skeleton. Contains buffers needed to perform the operation, and serializes settings for mesh generation. + [System.Serializable] + public class MeshGenerator { + public Settings settings = Settings.Default; + + [System.Serializable] + public struct Settings { + public bool useClipping; + [Space] + [Range(-0.1f, 0f)] public float zSpacing; + [Space] + [Header("Vertex Data")] + public bool pmaVertexColors; + public bool tintBlack; + [Tooltip("Enable when using Additive blend mode at SkeletonGraphic under a CanvasGroup. " + + "When enabled, Additive alpha value is stored at uv2.g instead of color.a to capture CanvasGroup modifying color.a.")] + public bool canvasGroupTintBlack; + public bool calculateTangents; + public bool addNormals; + public bool immutableTriangles; + + static public Settings Default { + get { + return new Settings { + pmaVertexColors = true, + zSpacing = 0f, + useClipping = true, + tintBlack = false, + calculateTangents = false, + //renderMeshes = true, + addNormals = false, + immutableTriangles = false + }; + } + } + } + + const float BoundsMinDefault = float.PositiveInfinity; + const float BoundsMaxDefault = float.NegativeInfinity; + + [NonSerialized] readonly ExposedList vertexBuffer = new ExposedList(4); + [NonSerialized] readonly ExposedList uvBuffer = new ExposedList(4); + [NonSerialized] readonly ExposedList colorBuffer = new ExposedList(4); + [NonSerialized] readonly ExposedList> submeshes = new ExposedList> { new ExposedList(6) }; // start with 1 submesh. + + [NonSerialized] Vector2 meshBoundsMin, meshBoundsMax; + [NonSerialized] float meshBoundsThickness; + [NonSerialized] int submeshIndex = 0; + + [NonSerialized] SkeletonClipping clipper = new SkeletonClipping(); + [NonSerialized] float[] tempVerts = new float[8]; + [NonSerialized] int[] regionTriangles = { 0, 1, 2, 2, 3, 0 }; + + #region Optional Buffers + // These optional buffers are lazy-instantiated when the feature is used. + [NonSerialized] Vector3[] normals; + [NonSerialized] Vector4[] tangents; + [NonSerialized] Vector2[] tempTanBuffer; + [NonSerialized] ExposedList uv2; + [NonSerialized] ExposedList uv3; + #endregion + + public int VertexCount { get { return vertexBuffer.Count; } } + + /// A set of mesh arrays whose values are modifiable by the user. Modify these values before they are passed to the UnityEngine mesh object in order to see the effect. + public MeshGeneratorBuffers Buffers { + get { + return new MeshGeneratorBuffers { + vertexCount = this.VertexCount, + vertexBuffer = this.vertexBuffer.Items, + uvBuffer = this.uvBuffer.Items, + colorBuffer = this.colorBuffer.Items, + meshGenerator = this + }; + } + } + + public MeshGenerator () { + submeshes.TrimExcess(); + } + + #region Step 1 : Generate Instructions + /// + /// A specialized variant of . + /// Generates renderer instructions using a single submesh, using only a single material and texture. + /// + /// The resulting instructions. + /// The skeleton to generate renderer instructions for. + /// Material to be set at the renderer instruction. When null, the last attachment + /// in the draw order list is assigned as the instruction's material. + public static void GenerateSingleSubmeshInstruction (SkeletonRendererInstruction instructionOutput, Skeleton skeleton, Material material) { + ExposedList drawOrder = skeleton.drawOrder; + int drawOrderCount = drawOrder.Count; + + // Clear last state of attachments and submeshes + instructionOutput.Clear(); // submeshInstructions.Clear(); attachments.Clear(); + var workingSubmeshInstructions = instructionOutput.submeshInstructions; + + #if SPINE_TRIANGLECHECK + instructionOutput.attachments.Resize(drawOrderCount); + var workingAttachmentsItems = instructionOutput.attachments.Items; + int totalRawVertexCount = 0; + #endif + + var current = new SubmeshInstruction { + skeleton = skeleton, + preActiveClippingSlotSource = -1, + startSlot = 0, + #if SPINE_TRIANGLECHECK + rawFirstVertexIndex = 0, + #endif + material = material, + forceSeparate = false, + endSlot = drawOrderCount + }; + + #if SPINE_TRIANGLECHECK + object rendererObject = null; + bool skeletonHasClipping = false; + var drawOrderItems = drawOrder.Items; + for (int i = 0; i < drawOrderCount; i++) { + Slot slot = drawOrderItems[i]; + if (!slot.bone.active) continue; + Attachment attachment = slot.attachment; + + workingAttachmentsItems[i] = attachment; + int attachmentTriangleCount; + int attachmentVertexCount; + + var regionAttachment = attachment as RegionAttachment; + if (regionAttachment != null) { + rendererObject = regionAttachment.RendererObject; + attachmentVertexCount = 4; + attachmentTriangleCount = 6; + } else { + var meshAttachment = attachment as MeshAttachment; + if (meshAttachment != null) { + rendererObject = meshAttachment.RendererObject; + attachmentVertexCount = meshAttachment.worldVerticesLength >> 1; + attachmentTriangleCount = meshAttachment.triangles.Length; + } else { + var clippingAttachment = attachment as ClippingAttachment; + if (clippingAttachment != null) { + current.hasClipping = true; + skeletonHasClipping = true; + } + attachmentVertexCount = 0; + attachmentTriangleCount = 0; + } + } + current.rawTriangleCount += attachmentTriangleCount; + current.rawVertexCount += attachmentVertexCount; + totalRawVertexCount += attachmentVertexCount; + } + + #if !SPINE_TK2D + if (material == null && rendererObject != null) + current.material = (Material)((AtlasRegion)rendererObject).page.rendererObject; + #else + if (material == null && rendererObject != null) + current.material = (rendererObject is Material) ? (Material)rendererObject : (Material)((AtlasRegion)rendererObject).page.rendererObject; + #endif + + instructionOutput.hasActiveClipping = skeletonHasClipping; + instructionOutput.rawVertexCount = totalRawVertexCount; + #endif + + if (totalRawVertexCount > 0) { + workingSubmeshInstructions.Resize(1); + workingSubmeshInstructions.Items[0] = current; + } + else { + workingSubmeshInstructions.Resize(0); + } + } + + public static bool RequiresMultipleSubmeshesByDrawOrder (Skeleton skeleton) { + + #if SPINE_TK2D + return false; + #endif + ExposedList 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 customSlotMaterials, List separatorSlots, bool generateMeshOverride, bool immutableTriangles = false) { + // if (skeleton == null) throw new ArgumentNullException("skeleton"); + // if (instructionOutput == null) throw new ArgumentNullException("instructionOutput"); + + ExposedList drawOrder = skeleton.drawOrder; + int drawOrderCount = drawOrder.Count; + + // Clear last state of attachments and submeshes + instructionOutput.Clear(); // submeshInstructions.Clear(); attachments.Clear(); + var workingSubmeshInstructions = instructionOutput.submeshInstructions; + #if SPINE_TRIANGLECHECK + instructionOutput.attachments.Resize(drawOrderCount); + var workingAttachmentsItems = instructionOutput.attachments.Items; + int totalRawVertexCount = 0; + bool skeletonHasClipping = false; + #endif + + var current = new SubmeshInstruction { + skeleton = skeleton, + preActiveClippingSlotSource = -1 + }; + + #if !SPINE_TK2D + bool isCustomSlotMaterialsPopulated = customSlotMaterials != null && customSlotMaterials.Count > 0; + #endif + + int separatorCount = separatorSlots == null ? 0 : separatorSlots.Count; + bool hasSeparators = separatorCount > 0; + + int clippingAttachmentSource = -1; + int lastPreActiveClipping = -1; // The index of the last slot that had an active ClippingAttachment. + SlotData clippingEndSlot = null; + int submeshIndex = 0; + var drawOrderItems = drawOrder.Items; + for (int i = 0; i < drawOrderCount; i++) { + Slot slot = drawOrderItems[i]; + if (!slot.bone.active) continue; + Attachment attachment = slot.attachment; + #if SPINE_TRIANGLECHECK + workingAttachmentsItems[i] = attachment; + int attachmentVertexCount = 0, attachmentTriangleCount = 0; + #endif + + object rendererObject = null; // An AtlasRegion in plain Spine-Unity. Spine-TK2D hooks into TK2D's system. eventual source of Material object. + bool noRender = false; // Using this allows empty slots as separators, and keeps separated parts more stable despite slots being reordered + + var regionAttachment = attachment as RegionAttachment; + if (regionAttachment != null) { + rendererObject = regionAttachment.RendererObject; + #if SPINE_TRIANGLECHECK + attachmentVertexCount = 4; + attachmentTriangleCount = 6; + #endif + } else { + var meshAttachment = attachment as MeshAttachment; + if (meshAttachment != null) { + rendererObject = meshAttachment.RendererObject; + #if SPINE_TRIANGLECHECK + attachmentVertexCount = meshAttachment.worldVerticesLength >> 1; + attachmentTriangleCount = meshAttachment.triangles.Length; + #endif + } else { + #if SPINE_TRIANGLECHECK + var clippingAttachment = attachment as ClippingAttachment; + if (clippingAttachment != null) { + clippingEndSlot = clippingAttachment.endSlot; + clippingAttachmentSource = i; + current.hasClipping = true; + skeletonHasClipping = true; + } + #endif + noRender = true; + } + } + + // Create a new SubmeshInstruction when material changes. (or when forced to separate by a submeshSeparator) + // Slot with a separator/new material will become the starting slot of the next new instruction. + if (hasSeparators) { //current.forceSeparate = hasSeparators && separatorSlots.Contains(slot); + current.forceSeparate = false; + for (int s = 0; s < separatorCount; s++) { + if (Slot.ReferenceEquals(slot, separatorSlots[s])) { + current.forceSeparate = true; + break; + } + } + } + + if (noRender) { + if (current.forceSeparate && generateMeshOverride) { // && current.rawVertexCount > 0) { + { // Add + current.endSlot = i; + current.preActiveClippingSlotSource = lastPreActiveClipping; + + workingSubmeshInstructions.Resize(submeshIndex + 1); + workingSubmeshInstructions.Items[submeshIndex] = current; + + submeshIndex++; + } + + current.startSlot = i; + lastPreActiveClipping = clippingAttachmentSource; + #if SPINE_TRIANGLECHECK + current.rawTriangleCount = 0; + current.rawVertexCount = 0; + current.rawFirstVertexIndex = totalRawVertexCount; + current.hasClipping = clippingAttachmentSource >= 0; + #endif + } + } else { + #if !SPINE_TK2D + Material material; + if (isCustomSlotMaterialsPopulated) { + if (!customSlotMaterials.TryGetValue(slot, out material)) + material = (Material)((AtlasRegion)rendererObject).page.rendererObject; + } else { + material = (Material)((AtlasRegion)rendererObject).page.rendererObject; + } + #else + Material material = (rendererObject is Material) ? (Material)rendererObject : (Material)((AtlasRegion)rendererObject).page.rendererObject; + #endif + + if (current.forceSeparate || (current.rawVertexCount > 0 && !System.Object.ReferenceEquals(current.material, material))) { // Material changed. Add the previous submesh. + { // Add + current.endSlot = i; + current.preActiveClippingSlotSource = lastPreActiveClipping; + + workingSubmeshInstructions.Resize(submeshIndex + 1); + workingSubmeshInstructions.Items[submeshIndex] = current; + submeshIndex++; + } + current.startSlot = i; + lastPreActiveClipping = clippingAttachmentSource; + #if SPINE_TRIANGLECHECK + current.rawTriangleCount = 0; + current.rawVertexCount = 0; + current.rawFirstVertexIndex = totalRawVertexCount; + current.hasClipping = clippingAttachmentSource >= 0; + #endif + } + + // Update state for the next Attachment. + current.material = material; + #if SPINE_TRIANGLECHECK + current.rawTriangleCount += attachmentTriangleCount; + current.rawVertexCount += attachmentVertexCount; + current.rawFirstVertexIndex = totalRawVertexCount; + totalRawVertexCount += attachmentVertexCount; + #endif + } + + if (clippingEndSlot != null && slot.data == clippingEndSlot && i != clippingAttachmentSource) { + clippingEndSlot = null; + clippingAttachmentSource = -1; + } + } + + if (current.rawVertexCount > 0) { + { // Add last or only submesh. + current.endSlot = drawOrderCount; + current.preActiveClippingSlotSource = lastPreActiveClipping; + current.forceSeparate = false; + + workingSubmeshInstructions.Resize(submeshIndex + 1); + workingSubmeshInstructions.Items[submeshIndex] = current; + //submeshIndex++; + } + } + + #if SPINE_TRIANGLECHECK + instructionOutput.hasActiveClipping = skeletonHasClipping; + instructionOutput.rawVertexCount = totalRawVertexCount; + #endif + instructionOutput.immutableTriangles = immutableTriangles; + } + + public static void TryReplaceMaterials (ExposedList workingSubmeshInstructions, Dictionary customMaterialOverride) { + // Material overrides are done here so they can be applied per submesh instead of per slot + // but they will still be passed through the GenerateMeshOverride delegate, + // and will still go through the normal material match check step in STEP 3. + var wsii = workingSubmeshInstructions.Items; + for (int i = 0; i < workingSubmeshInstructions.Count; i++) { + var m = wsii[i].material; + Material mo; + if (customMaterialOverride.TryGetValue(m, out mo)) + wsii[i].material = mo; + } + } + #endregion + + #region Step 2 : Populate vertex data and triangle index buffers. + public void Begin () { + vertexBuffer.Clear(false); + colorBuffer.Clear(false); + uvBuffer.Clear(false); + clipper.ClipEnd(); + + { + meshBoundsMin.x = BoundsMinDefault; + meshBoundsMin.y = BoundsMinDefault; + meshBoundsMax.x = BoundsMaxDefault; + meshBoundsMax.y = BoundsMaxDefault; + meshBoundsThickness = 0f; + } + + submeshIndex = 0; + submeshes.Count = 1; + //submeshes.Items[0].Clear(false); + } + + public void AddSubmesh (SubmeshInstruction instruction, bool updateTriangles = true) { + var settings = this.settings; + + int newSubmeshCount = submeshIndex + 1; + if (submeshes.Items.Length < newSubmeshCount) + submeshes.Resize(newSubmeshCount); + submeshes.Count = newSubmeshCount; + var submesh = submeshes.Items[submeshIndex]; + if (submesh == null) + submeshes.Items[submeshIndex] = submesh = new ExposedList(); + submesh.Clear(false); + + var skeleton = instruction.skeleton; + var drawOrderItems = skeleton.drawOrder.Items; + + Color32 color = default(Color32); + float skeletonA = skeleton.a, skeletonR = skeleton.r, skeletonG = skeleton.g, skeletonB = skeleton.b; + Vector2 meshBoundsMin = this.meshBoundsMin, meshBoundsMax = this.meshBoundsMax; + + // Settings + float zSpacing = settings.zSpacing; + bool pmaVertexColors = settings.pmaVertexColors; + bool tintBlack = settings.tintBlack; + #if SPINE_TRIANGLECHECK + bool useClipping = settings.useClipping && instruction.hasClipping; + #else + bool useClipping = settings.useClipping; + #endif + bool canvasGroupTintBlack = settings.tintBlack && settings.canvasGroupTintBlack; + + if (useClipping) { + if (instruction.preActiveClippingSlotSource >= 0) { + var slot = drawOrderItems[instruction.preActiveClippingSlotSource]; + clipper.ClipStart(slot, slot.attachment as ClippingAttachment); + } + } + + for (int slotIndex = instruction.startSlot; slotIndex < instruction.endSlot; slotIndex++) { + var slot = drawOrderItems[slotIndex]; + if (!slot.bone.active) { + clipper.ClipEnd(slot); + continue; + } + var attachment = slot.attachment; + float z = zSpacing * slotIndex; + + var workingVerts = this.tempVerts; + float[] uvs; + int[] attachmentTriangleIndices; + int attachmentVertexCount; + int attachmentIndexCount; + + Color c = default(Color); + + // Identify and prepare values. + var region = attachment as RegionAttachment; + if (region != null) { + region.ComputeWorldVertices(slot.bone, workingVerts, 0); + uvs = region.uvs; + attachmentTriangleIndices = regionTriangles; + c.r = region.r; c.g = region.g; c.b = region.b; c.a = region.a; + attachmentVertexCount = 4; + attachmentIndexCount = 6; + } else { + var mesh = attachment as MeshAttachment; + if (mesh != null) { + int meshVerticesLength = mesh.worldVerticesLength; + if (workingVerts.Length < meshVerticesLength) { + workingVerts = new float[meshVerticesLength]; + this.tempVerts = workingVerts; + } + mesh.ComputeWorldVertices(slot, 0, meshVerticesLength, workingVerts, 0); //meshAttachment.ComputeWorldVertices(slot, tempVerts); + uvs = mesh.uvs; + attachmentTriangleIndices = mesh.triangles; + c.r = mesh.r; c.g = mesh.g; c.b = mesh.b; c.a = mesh.a; + attachmentVertexCount = meshVerticesLength >> 1; // meshVertexCount / 2; + attachmentIndexCount = mesh.triangles.Length; + } else { + if (useClipping) { + var clippingAttachment = attachment as ClippingAttachment; + if (clippingAttachment != null) { + clipper.ClipStart(slot, clippingAttachment); + continue; + } + } + + // If not any renderable attachment. + clipper.ClipEnd(slot); + continue; + } + } + + float tintBlackAlpha = 1.0f; + if (pmaVertexColors) { + color.a = (byte)(skeletonA * slot.a * c.a * 255); + color.r = (byte)(skeletonR * slot.r * c.r * color.a); + color.g = (byte)(skeletonG * slot.g * c.g * color.a); + color.b = (byte)(skeletonB * slot.b * c.b * color.a); + if (slot.data.blendMode == BlendMode.Additive) { + if (canvasGroupTintBlack) + tintBlackAlpha = 0; + else + color.a = 0; + } + } else { + color.a = (byte)(skeletonA * slot.a * c.a * 255); + color.r = (byte)(skeletonR * slot.r * c.r * 255); + color.g = (byte)(skeletonG * slot.g * c.g * 255); + color.b = (byte)(skeletonB * slot.b * c.b * 255); + } + + if (useClipping && clipper.IsClipping) { + clipper.ClipTriangles(workingVerts, attachmentVertexCount << 1, attachmentTriangleIndices, attachmentIndexCount, uvs); + workingVerts = clipper.clippedVertices.Items; + attachmentVertexCount = clipper.clippedVertices.Count >> 1; + attachmentTriangleIndices = clipper.clippedTriangles.Items; + attachmentIndexCount = clipper.clippedTriangles.Count; + uvs = clipper.clippedUVs.Items; + } + + // Actually add slot/attachment data into buffers. + if (attachmentVertexCount != 0 && attachmentIndexCount != 0) { + if (tintBlack) { + float r2 = slot.r2; + float g2 = slot.g2; + float b2 = slot.b2; + if (pmaVertexColors) { + float alpha = skeletonA * slot.a * c.a; + r2 *= alpha; + g2 *= alpha; + b2 *= alpha; + } + AddAttachmentTintBlack(r2, g2, b2, tintBlackAlpha, attachmentVertexCount); + } + + //AddAttachment(workingVerts, uvs, color, attachmentTriangleIndices, attachmentVertexCount, attachmentIndexCount, ref meshBoundsMin, ref meshBoundsMax, z); + int ovc = vertexBuffer.Count; + // Add data to vertex buffers + { + int newVertexCount = ovc + attachmentVertexCount; + int oldArraySize = vertexBuffer.Items.Length; + if (newVertexCount > oldArraySize) { + int newArraySize = (int)(oldArraySize * 1.3f); + if (newArraySize < newVertexCount) newArraySize = newVertexCount; + Array.Resize(ref vertexBuffer.Items, newArraySize); + Array.Resize(ref uvBuffer.Items, newArraySize); + Array.Resize(ref colorBuffer.Items, newArraySize); + } + vertexBuffer.Count = uvBuffer.Count = colorBuffer.Count = newVertexCount; + } + + var vbi = vertexBuffer.Items; + var ubi = uvBuffer.Items; + var cbi = colorBuffer.Items; + if (ovc == 0) { + for (int i = 0; i < attachmentVertexCount; i++) { + int vi = ovc + i; + int i2 = i << 1; // i * 2 + float x = workingVerts[i2]; + float y = workingVerts[i2 + 1]; + + vbi[vi].x = x; + vbi[vi].y = y; + vbi[vi].z = z; + ubi[vi].x = uvs[i2]; + ubi[vi].y = uvs[i2 + 1]; + cbi[vi] = color; + + // Calculate bounds. + if (x < meshBoundsMin.x) meshBoundsMin.x = x; + if (x > meshBoundsMax.x) meshBoundsMax.x = x; + if (y < meshBoundsMin.y) meshBoundsMin.y = y; + if (y > meshBoundsMax.y) meshBoundsMax.y = y; + } + } else { + for (int i = 0; i < attachmentVertexCount; i++) { + int vi = ovc + i; + int i2 = i << 1; // i * 2 + float x = workingVerts[i2]; + float y = workingVerts[i2 + 1]; + + vbi[vi].x = x; + vbi[vi].y = y; + vbi[vi].z = z; + ubi[vi].x = uvs[i2]; + ubi[vi].y = uvs[i2 + 1]; + cbi[vi] = color; + + // Calculate bounds. + if (x < meshBoundsMin.x) meshBoundsMin.x = x; + else if (x > meshBoundsMax.x) meshBoundsMax.x = x; + if (y < meshBoundsMin.y) meshBoundsMin.y = y; + else if (y > meshBoundsMax.y) meshBoundsMax.y = y; + } + } + + + // Add data to triangle buffer + if (updateTriangles) { + int oldTriangleCount = submesh.Count; + { //submesh.Resize(oldTriangleCount + attachmentIndexCount); + int newTriangleCount = oldTriangleCount + attachmentIndexCount; + if (newTriangleCount > submesh.Items.Length) Array.Resize(ref submesh.Items, newTriangleCount); + submesh.Count = newTriangleCount; + } + var submeshItems = submesh.Items; + for (int i = 0; i < attachmentIndexCount; i++) + submeshItems[oldTriangleCount + i] = attachmentTriangleIndices[i] + ovc; + } + } + + clipper.ClipEnd(slot); + } + clipper.ClipEnd(); + + this.meshBoundsMin = meshBoundsMin; + this.meshBoundsMax = meshBoundsMax; + meshBoundsThickness = instruction.endSlot * zSpacing; + + // Trim or zero submesh triangles. + var currentSubmeshItems = submesh.Items; + for (int i = submesh.Count, n = currentSubmeshItems.Length; i < n; i++) + currentSubmeshItems[i] = 0; + + submeshIndex++; // Next AddSubmesh will use a new submeshIndex value. + } + + public void BuildMesh (SkeletonRendererInstruction instruction, bool updateTriangles) { + var wsii = instruction.submeshInstructions.Items; + for (int i = 0, n = instruction.submeshInstructions.Count; i < n; i++) + this.AddSubmesh(wsii[i], updateTriangles); + } + + // Use this faster method when no clipping is involved. + public void BuildMeshWithArrays (SkeletonRendererInstruction instruction, bool updateTriangles) { + var settings = this.settings; + bool canvasGroupTintBlack = settings.tintBlack && settings.canvasGroupTintBlack; + int totalVertexCount = instruction.rawVertexCount; + + // Add data to vertex buffers + { + if (totalVertexCount > vertexBuffer.Items.Length) { // Manual ExposedList.Resize() + Array.Resize(ref vertexBuffer.Items, totalVertexCount); + Array.Resize(ref uvBuffer.Items, totalVertexCount); + Array.Resize(ref colorBuffer.Items, totalVertexCount); + } + vertexBuffer.Count = uvBuffer.Count = colorBuffer.Count = totalVertexCount; + } + + // Populate Verts + Color32 color = default(Color32); + + int vertexIndex = 0; + var tempVerts = this.tempVerts; + Vector2 bmin = this.meshBoundsMin; + Vector2 bmax = this.meshBoundsMax; + + var vbi = vertexBuffer.Items; + var ubi = uvBuffer.Items; + var cbi = colorBuffer.Items; + int lastSlotIndex = 0; + + // drawOrder[endSlot] is excluded + for (int si = 0, n = instruction.submeshInstructions.Count; si < n; si++) { + var submesh = instruction.submeshInstructions.Items[si]; + var skeleton = submesh.skeleton; + var drawOrderItems = skeleton.drawOrder.Items; + float a = skeleton.a, r = skeleton.r, g = skeleton.g, b = skeleton.b; + + int endSlot = submesh.endSlot; + int startSlot = submesh.startSlot; + lastSlotIndex = endSlot; + + if (settings.tintBlack) { + Vector2 rg, b2; + int vi = vertexIndex; + b2.y = 1f; + + { + if (uv2 == null) { + uv2 = new ExposedList(); + uv3 = new ExposedList(); + } + if (totalVertexCount > uv2.Items.Length) { // Manual ExposedList.Resize() + Array.Resize(ref uv2.Items, totalVertexCount); + Array.Resize(ref uv3.Items, totalVertexCount); + } + uv2.Count = uv3.Count = totalVertexCount; + } + + var uv2i = uv2.Items; + var uv3i = uv3.Items; + + for (int slotIndex = startSlot; slotIndex < endSlot; slotIndex++) { + var slot = drawOrderItems[slotIndex]; + if (!slot.bone.active) continue; + var attachment = slot.attachment; + + rg.x = slot.r2; //r + rg.y = slot.g2; //g + b2.x = slot.b2; //b + b2.y = 1.0f; + + var regionAttachment = attachment as RegionAttachment; + if (regionAttachment != null) { + if (settings.pmaVertexColors) { + float alpha = a * slot.a * regionAttachment.a; + rg.x *= alpha; + rg.y *= alpha; + b2.x *= alpha; + b2.y = slot.data.blendMode == BlendMode.Additive ? 0 : alpha; + } + uv2i[vi] = rg; uv2i[vi + 1] = rg; uv2i[vi + 2] = rg; uv2i[vi + 3] = rg; + uv3i[vi] = b2; uv3i[vi + 1] = b2; uv3i[vi + 2] = b2; uv3i[vi + 3] = b2; + vi += 4; + } else { //} if (settings.renderMeshes) { + var meshAttachment = attachment as MeshAttachment; + if (meshAttachment != null) { + if (settings.pmaVertexColors) { + float alpha = a * slot.a * meshAttachment.a; + rg.x *= alpha; + rg.y *= alpha; + b2.x *= alpha; + b2.y = slot.data.blendMode == BlendMode.Additive ? 0 : alpha; + } + int meshVertexCount = meshAttachment.worldVerticesLength; + for (int iii = 0; iii < meshVertexCount; iii += 2) { + uv2i[vi] = rg; + uv3i[vi] = b2; + vi++; + } + } + } + } + } + + for (int slotIndex = startSlot; slotIndex < endSlot; slotIndex++) { + var slot = drawOrderItems[slotIndex]; + if (!slot.bone.active) continue; + var attachment = slot.attachment; + float z = slotIndex * settings.zSpacing; + + var regionAttachment = attachment as RegionAttachment; + if (regionAttachment != null) { + regionAttachment.ComputeWorldVertices(slot.bone, tempVerts, 0); + + float x1 = tempVerts[RegionAttachment.BLX], y1 = tempVerts[RegionAttachment.BLY]; + float x2 = tempVerts[RegionAttachment.ULX], y2 = tempVerts[RegionAttachment.ULY]; + float x3 = tempVerts[RegionAttachment.URX], y3 = tempVerts[RegionAttachment.URY]; + float x4 = tempVerts[RegionAttachment.BRX], y4 = tempVerts[RegionAttachment.BRY]; + vbi[vertexIndex].x = x1; vbi[vertexIndex].y = y1; vbi[vertexIndex].z = z; + vbi[vertexIndex + 1].x = x4; vbi[vertexIndex + 1].y = y4; vbi[vertexIndex + 1].z = z; + vbi[vertexIndex + 2].x = x2; vbi[vertexIndex + 2].y = y2; vbi[vertexIndex + 2].z = z; + vbi[vertexIndex + 3].x = x3; vbi[vertexIndex + 3].y = y3; vbi[vertexIndex + 3].z = z; + + if (settings.pmaVertexColors) { + color.a = (byte)(a * slot.a * regionAttachment.a * 255); + color.r = (byte)(r * slot.r * regionAttachment.r * color.a); + color.g = (byte)(g * slot.g * regionAttachment.g * color.a); + color.b = (byte)(b * slot.b * regionAttachment.b * color.a); + if (slot.data.blendMode == BlendMode.Additive && !canvasGroupTintBlack) color.a = 0; + } else { + color.a = (byte)(a * slot.a * regionAttachment.a * 255); + color.r = (byte)(r * slot.r * regionAttachment.r * 255); + color.g = (byte)(g * slot.g * regionAttachment.g * 255); + color.b = (byte)(b * slot.b * regionAttachment.b * 255); + } + + cbi[vertexIndex] = color; cbi[vertexIndex + 1] = color; cbi[vertexIndex + 2] = color; cbi[vertexIndex + 3] = color; + + float[] regionUVs = regionAttachment.uvs; + ubi[vertexIndex].x = regionUVs[RegionAttachment.BLX]; ubi[vertexIndex].y = regionUVs[RegionAttachment.BLY]; + ubi[vertexIndex + 1].x = regionUVs[RegionAttachment.BRX]; ubi[vertexIndex + 1].y = regionUVs[RegionAttachment.BRY]; + ubi[vertexIndex + 2].x = regionUVs[RegionAttachment.ULX]; ubi[vertexIndex + 2].y = regionUVs[RegionAttachment.ULY]; + ubi[vertexIndex + 3].x = regionUVs[RegionAttachment.URX]; ubi[vertexIndex + 3].y = regionUVs[RegionAttachment.URY]; + + if (x1 < bmin.x) bmin.x = x1; // Potential first attachment bounds initialization. Initial min should not block initial max. Same for Y below. + if (x1 > bmax.x) bmax.x = x1; + if (x2 < bmin.x) bmin.x = x2; + else if (x2 > bmax.x) bmax.x = x2; + if (x3 < bmin.x) bmin.x = x3; + else if (x3 > bmax.x) bmax.x = x3; + if (x4 < bmin.x) bmin.x = x4; + else if (x4 > bmax.x) bmax.x = x4; + + if (y1 < bmin.y) bmin.y = y1; + if (y1 > bmax.y) bmax.y = y1; + if (y2 < bmin.y) bmin.y = y2; + else if (y2 > bmax.y) bmax.y = y2; + if (y3 < bmin.y) bmin.y = y3; + else if (y3 > bmax.y) bmax.y = y3; + if (y4 < bmin.y) bmin.y = y4; + else if (y4 > bmax.y) bmax.y = y4; + + vertexIndex += 4; + } else { //if (settings.renderMeshes) { + var meshAttachment = attachment as MeshAttachment; + if (meshAttachment != null) { + int meshVertexCount = meshAttachment.worldVerticesLength; + if (tempVerts.Length < meshVertexCount) this.tempVerts = tempVerts = new float[meshVertexCount]; + meshAttachment.ComputeWorldVertices(slot, tempVerts); + + if (settings.pmaVertexColors) { + color.a = (byte)(a * slot.a * meshAttachment.a * 255); + color.r = (byte)(r * slot.r * meshAttachment.r * color.a); + color.g = (byte)(g * slot.g * meshAttachment.g * color.a); + color.b = (byte)(b * slot.b * meshAttachment.b * color.a); + if (slot.data.blendMode == BlendMode.Additive && !canvasGroupTintBlack) color.a = 0; + } else { + color.a = (byte)(a * slot.a * meshAttachment.a * 255); + color.r = (byte)(r * slot.r * meshAttachment.r * 255); + color.g = (byte)(g * slot.g * meshAttachment.g * 255); + color.b = (byte)(b * slot.b * meshAttachment.b * 255); + } + + float[] attachmentUVs = meshAttachment.uvs; + + // Potential first attachment bounds initialization. See conditions in RegionAttachment logic. + if (vertexIndex == 0) { + // Initial min should not block initial max. + // vi == vertexIndex does not always mean the bounds are fresh. It could be a submesh. Do not nuke old values by omitting the check. + // Should know that this is the first attachment in the submesh. slotIndex == startSlot could be an empty slot. + float fx = tempVerts[0], fy = tempVerts[1]; + if (fx < bmin.x) bmin.x = fx; + if (fx > bmax.x) bmax.x = fx; + if (fy < bmin.y) bmin.y = fy; + if (fy > bmax.y) bmax.y = fy; + } + + for (int iii = 0; iii < meshVertexCount; iii += 2) { + float x = tempVerts[iii], y = tempVerts[iii + 1]; + vbi[vertexIndex].x = x; vbi[vertexIndex].y = y; vbi[vertexIndex].z = z; + cbi[vertexIndex] = color; ubi[vertexIndex].x = attachmentUVs[iii]; ubi[vertexIndex].y = attachmentUVs[iii + 1]; + + if (x < bmin.x) bmin.x = x; + else if (x > bmax.x) bmax.x = x; + + if (y < bmin.y) bmin.y = y; + else if (y > bmax.y) bmax.y = y; + + vertexIndex++; + } + } + } + } + } + + this.meshBoundsMin = bmin; + this.meshBoundsMax = bmax; + this.meshBoundsThickness = lastSlotIndex * settings.zSpacing; + + int submeshInstructionCount = instruction.submeshInstructions.Count; + submeshes.Count = submeshInstructionCount; + + // Add triangles + if (updateTriangles) { + // Match submesh buffers count with submeshInstruction count. + if (this.submeshes.Items.Length < submeshInstructionCount) { + this.submeshes.Resize(submeshInstructionCount); + for (int i = 0, n = submeshInstructionCount; i < n; i++) { + var submeshBuffer = this.submeshes.Items[i]; + if (submeshBuffer == null) + this.submeshes.Items[i] = new ExposedList(); + else + submeshBuffer.Clear(false); + } + } + + var submeshInstructionsItems = instruction.submeshInstructions.Items; // This relies on the resize above. + + // Fill the buffers. + int attachmentFirstVertex = 0; + for (int smbi = 0; smbi < submeshInstructionCount; smbi++) { + var submeshInstruction = submeshInstructionsItems[smbi]; + var currentSubmeshBuffer = this.submeshes.Items[smbi]; + { //submesh.Resize(submesh.rawTriangleCount); + int newTriangleCount = submeshInstruction.rawTriangleCount; + if (newTriangleCount > currentSubmeshBuffer.Items.Length) + Array.Resize(ref currentSubmeshBuffer.Items, newTriangleCount); + else if (newTriangleCount < currentSubmeshBuffer.Items.Length) { + // Zero the extra. + var sbi = currentSubmeshBuffer.Items; + for (int ei = newTriangleCount, nn = sbi.Length; ei < nn; ei++) + sbi[ei] = 0; + } + currentSubmeshBuffer.Count = newTriangleCount; + } + + var tris = currentSubmeshBuffer.Items; + int triangleIndex = 0; + var skeleton = submeshInstruction.skeleton; + var drawOrderItems = skeleton.drawOrder.Items; + for (int slotIndex = submeshInstruction.startSlot, endSlot = submeshInstruction.endSlot; slotIndex < endSlot; slotIndex++) { + var slot = drawOrderItems[slotIndex]; + if (!slot.bone.active) continue; + + var attachment = drawOrderItems[slotIndex].attachment; + if (attachment is RegionAttachment) { + tris[triangleIndex] = attachmentFirstVertex; + tris[triangleIndex + 1] = attachmentFirstVertex + 2; + tris[triangleIndex + 2] = attachmentFirstVertex + 1; + tris[triangleIndex + 3] = attachmentFirstVertex + 2; + tris[triangleIndex + 4] = attachmentFirstVertex + 3; + tris[triangleIndex + 5] = attachmentFirstVertex + 1; + triangleIndex += 6; + attachmentFirstVertex += 4; + continue; + } + var meshAttachment = attachment as MeshAttachment; + if (meshAttachment != null) { + int[] attachmentTriangles = meshAttachment.triangles; + for (int ii = 0, nn = attachmentTriangles.Length; ii < nn; ii++, triangleIndex++) + tris[triangleIndex] = attachmentFirstVertex + attachmentTriangles[ii]; + attachmentFirstVertex += meshAttachment.worldVerticesLength >> 1; // length/2; + } + } + } + } + } + + public void ScaleVertexData (float scale) { + var vbi = vertexBuffer.Items; + for (int i = 0, n = vertexBuffer.Count; i < n; i++) { + vbi[i] *= scale; // vbi[i].x *= scale; vbi[i].y *= scale; + } + + meshBoundsMin *= scale; + meshBoundsMax *= scale; + meshBoundsThickness *= scale; + } + + void AddAttachmentTintBlack (float r2, float g2, float b2, float a, int vertexCount) { + var rg = new Vector2(r2, g2); + var bo = new Vector2(b2, a); + + int ovc = vertexBuffer.Count; + int newVertexCount = ovc + vertexCount; + { + if (uv2 == null) { + uv2 = new ExposedList(); + uv3 = new ExposedList(); + } + if (newVertexCount > uv2.Items.Length) { // Manual ExposedList.Resize() + Array.Resize(ref uv2.Items, newVertexCount); + Array.Resize(ref uv3.Items, newVertexCount); + } + uv2.Count = uv3.Count = newVertexCount; + } + + var uv2i = uv2.Items; + var uv3i = uv3.Items; + for (int i = 0; i < vertexCount; i++) { + uv2i[ovc + i] = rg; + uv3i[ovc + i] = bo; + } + } + #endregion + + #region Step 3 : Transfer vertex and triangle data to UnityEngine.Mesh + public void FillVertexData (Mesh mesh) { + var vbi = vertexBuffer.Items; + var ubi = uvBuffer.Items; + var cbi = colorBuffer.Items; + int vbiLength = vbi.Length; + + // Zero the extra. + { + int listCount = vertexBuffer.Count; + var vector3zero = Vector3.zero; + for (int i = listCount; i < vbiLength; i++) + vbi[i] = vector3zero; + } + + // Set the vertex buffer. + { + mesh.vertices = vbi; + mesh.uv = ubi; + mesh.colors32 = cbi; + + if (float.IsInfinity(meshBoundsMin.x)) { // meshBoundsMin.x == BoundsMinDefault // == doesn't work on float Infinity constants. + mesh.bounds = new Bounds(); + } else { + //mesh.bounds = ArraysMeshGenerator.ToBounds(meshBoundsMin, meshBoundsMax); + float halfWidth = (meshBoundsMax.x - meshBoundsMin.x) * 0.5f; + float halfHeight = (meshBoundsMax.y - meshBoundsMin.y) * 0.5f; + mesh.bounds = new Bounds { + center = new Vector3(meshBoundsMin.x + halfWidth, meshBoundsMin.y + halfHeight), + extents = new Vector3(halfWidth, halfHeight, meshBoundsThickness * 0.5f) + }; + } + } + + { + if (settings.addNormals) { + int oldLength = 0; + + if (normals == null) + normals = new Vector3[vbiLength]; + else + oldLength = normals.Length; + + if (oldLength != vbiLength) { + Array.Resize(ref this.normals, vbiLength); + var localNormals = this.normals; + for (int i = oldLength; i < vbiLength; i++) localNormals[i] = Vector3.back; + } + mesh.normals = this.normals; + } + + if (settings.tintBlack) { + if (uv2 != null) { + // Sometimes, the vertex buffer becomes smaller. We need to trim the size of the tint black buffers to match. + if (vbiLength != uv2.Items.Length) { + Array.Resize(ref uv2.Items, vbiLength); + Array.Resize(ref uv3.Items, vbiLength); + uv2.Count = uv3.Count = vbiLength; + } + mesh.uv2 = this.uv2.Items; + mesh.uv3 = this.uv3.Items; + } + } + } + } + + public void FillLateVertexData (Mesh mesh) { + if (settings.calculateTangents) { + int vertexCount = this.vertexBuffer.Count; + var sbi = submeshes.Items; + int submeshCount = submeshes.Count; + var vbi = vertexBuffer.Items; + var ubi = uvBuffer.Items; + + MeshGenerator.SolveTangents2DEnsureSize(ref this.tangents, ref this.tempTanBuffer, vertexCount, vbi.Length); + for (int i = 0; i < submeshCount; i++) { + var submesh = sbi[i].Items; + int triangleCount = sbi[i].Count; + MeshGenerator.SolveTangents2DTriangles(this.tempTanBuffer, submesh, triangleCount, vbi, ubi, vertexCount); + } + MeshGenerator.SolveTangents2DBuffer(this.tangents, this.tempTanBuffer, vertexCount); + mesh.tangents = this.tangents; + } + } + + public void FillTriangles (Mesh mesh) { + int submeshCount = submeshes.Count; + var submeshesItems = submeshes.Items; + mesh.subMeshCount = submeshCount; + + for (int i = 0; i < submeshCount; i++) + mesh.SetTriangles(submeshesItems[i].Items, i, false); + } + #endregion + + public void EnsureVertexCapacity (int minimumVertexCount, bool inlcudeTintBlack = false, bool includeTangents = false, bool includeNormals = false) { + if (minimumVertexCount > vertexBuffer.Items.Length) { + Array.Resize(ref vertexBuffer.Items, minimumVertexCount); + Array.Resize(ref uvBuffer.Items, minimumVertexCount); + Array.Resize(ref colorBuffer.Items, minimumVertexCount); + + if (inlcudeTintBlack) { + if (uv2 == null) { + uv2 = new ExposedList(minimumVertexCount); + uv3 = new ExposedList(minimumVertexCount); + } + uv2.Resize(minimumVertexCount); + uv3.Resize(minimumVertexCount); + } + + if (includeNormals) { + if (normals == null) + normals = new Vector3[minimumVertexCount]; + else + Array.Resize(ref normals, minimumVertexCount); + + } + + if (includeTangents) { + if (tangents == null) + tangents = new Vector4[minimumVertexCount]; + else + Array.Resize(ref tangents, minimumVertexCount); + } + } + } + + /// Trims internal buffers to reduce the resulting mesh data stream size. + public void TrimExcess () { + vertexBuffer.TrimExcess(); + uvBuffer.TrimExcess(); + colorBuffer.TrimExcess(); + + if (uv2 != null) uv2.TrimExcess(); + if (uv3 != null) uv3.TrimExcess(); + + int vbiLength = vertexBuffer.Items.Length; + if (normals != null) Array.Resize(ref normals, vbiLength); + if (tangents != null) Array.Resize(ref tangents, vbiLength); + } + + #region TangentSolver2D + // Thanks to contributions from forum user ToddRivers + + /// Step 1 of solving tangents. Ensure you have buffers of the correct size. + /// Eventual Vector4[] tangent buffer to assign to Mesh.tangents. + /// Temporary Vector2 buffer for calculating directions. + /// Number of vertices that require tangents (or the size of the vertex array) + internal static void SolveTangents2DEnsureSize (ref Vector4[] tangentBuffer, ref Vector2[] tempTanBuffer, int vertexCount, int vertexBufferLength) { + if (tangentBuffer == null || tangentBuffer.Length != vertexBufferLength) + tangentBuffer = new Vector4[vertexBufferLength]; + + if (tempTanBuffer == null || tempTanBuffer.Length < vertexCount * 2) + tempTanBuffer = new Vector2[vertexCount * 2]; // two arrays in one. + } + + /// Step 2 of solving tangents. Fills (part of) a temporary tangent-solution buffer based on the vertices and uvs defined by a submesh's triangle buffer. Only needs to be called once for single-submesh meshes. + /// A temporary Vector3[] for calculating tangents. + /// The mesh's current vertex position buffer. + /// The mesh's current triangles buffer. + /// The mesh's current uvs buffer. + /// Number of vertices that require tangents (or the size of the vertex array) + /// The number of triangle indexes in the triangle array to be used. + internal static void SolveTangents2DTriangles (Vector2[] tempTanBuffer, int[] triangles, int triangleCount, Vector3[] vertices, Vector2[] uvs, int vertexCount) { + Vector2 sdir; + Vector2 tdir; + for (int t = 0; t < triangleCount; t += 3) { + int i1 = triangles[t + 0]; + int i2 = triangles[t + 1]; + int i3 = triangles[t + 2]; + + Vector3 v1 = vertices[i1]; + Vector3 v2 = vertices[i2]; + Vector3 v3 = vertices[i3]; + + Vector2 w1 = uvs[i1]; + Vector2 w2 = uvs[i2]; + Vector2 w3 = uvs[i3]; + + float x1 = v2.x - v1.x; + float x2 = v3.x - v1.x; + float y1 = v2.y - v1.y; + float y2 = v3.y - v1.y; + + float s1 = w2.x - w1.x; + float s2 = w3.x - w1.x; + float t1 = w2.y - w1.y; + float t2 = w3.y - w1.y; + + float div = s1 * t2 - s2 * t1; + float r = (div == 0f) ? 0f : 1f / div; + + sdir.x = (t2 * x1 - t1 * x2) * r; + sdir.y = (t2 * y1 - t1 * y2) * r; + tempTanBuffer[i1] = tempTanBuffer[i2] = tempTanBuffer[i3] = sdir; + + tdir.x = (s1 * x2 - s2 * x1) * r; + tdir.y = (s1 * y2 - s2 * y1) * r; + tempTanBuffer[vertexCount + i1] = tempTanBuffer[vertexCount + i2] = tempTanBuffer[vertexCount + i3] = tdir; + } + } + + /// Step 3 of solving tangents. Fills a Vector4[] tangents array according to values calculated in step 2. + /// A Vector4[] that will eventually be used to set Mesh.tangents + /// A temporary Vector3[] for calculating tangents. + /// Number of vertices that require tangents (or the size of the vertex array) + internal static void SolveTangents2DBuffer (Vector4[] tangents, Vector2[] tempTanBuffer, int vertexCount) { + Vector4 tangent; + tangent.z = 0; + for (int i = 0; i < vertexCount; ++i) { + Vector2 t = tempTanBuffer[i]; + + // t.Normalize() (aggressively inlined). Even better if offloaded to GPU via vertex shader. + float magnitude = Mathf.Sqrt(t.x * t.x + t.y * t.y); + if (magnitude > 1E-05) { + float reciprocalMagnitude = 1f/magnitude; + t.x *= reciprocalMagnitude; + t.y *= reciprocalMagnitude; + } + + Vector2 t2 = tempTanBuffer[vertexCount + i]; + tangent.x = t.x; + tangent.y = t.y; + //tangent.z = 0; + tangent.w = (t.y * t2.x > t.x * t2.y) ? 1 : -1; // 2D direction calculation. Used for binormals. + tangents[i] = tangent; + } + } + #endregion + + #region AttachmentRendering + static List AttachmentVerts = new List(); + static List AttachmentUVs = new List(); + static List AttachmentColors32 = new List(); + static List AttachmentIndices = new List(); + + /// Fills mesh vertex data to render a RegionAttachment. + public static void FillMeshLocal (Mesh mesh, RegionAttachment regionAttachment) { + if (mesh == null) return; + if (regionAttachment == null) return; + + AttachmentVerts.Clear(); + var offsets = regionAttachment.Offset; + AttachmentVerts.Add(new Vector3(offsets[RegionAttachment.BLX], offsets[RegionAttachment.BLY])); + AttachmentVerts.Add(new Vector3(offsets[RegionAttachment.ULX], offsets[RegionAttachment.ULY])); + AttachmentVerts.Add(new Vector3(offsets[RegionAttachment.URX], offsets[RegionAttachment.URY])); + AttachmentVerts.Add(new Vector3(offsets[RegionAttachment.BRX], offsets[RegionAttachment.BRY])); + + AttachmentUVs.Clear(); + var uvs = regionAttachment.UVs; + AttachmentUVs.Add(new Vector2(uvs[RegionAttachment.ULX], uvs[RegionAttachment.ULY])); + AttachmentUVs.Add(new Vector2(uvs[RegionAttachment.URX], uvs[RegionAttachment.URY])); + AttachmentUVs.Add(new Vector2(uvs[RegionAttachment.BRX], uvs[RegionAttachment.BRY])); + AttachmentUVs.Add(new Vector2(uvs[RegionAttachment.BLX], uvs[RegionAttachment.BLY])); + + AttachmentColors32.Clear(); + Color32 c = (Color32)(new Color(regionAttachment.r, regionAttachment.g, regionAttachment.b, regionAttachment.a)); + for (int i = 0; i < 4; i++) + AttachmentColors32.Add(c); + + AttachmentIndices.Clear(); + AttachmentIndices.AddRange(new[] { 0, 2, 1, 0, 3, 2 }); + + mesh.Clear(); + mesh.name = regionAttachment.Name; + mesh.SetVertices(AttachmentVerts); + mesh.SetUVs(0, AttachmentUVs); + mesh.SetColors(AttachmentColors32); + mesh.SetTriangles(AttachmentIndices, 0); + mesh.RecalculateBounds(); + + AttachmentVerts.Clear(); + AttachmentUVs.Clear(); + AttachmentColors32.Clear(); + AttachmentIndices.Clear(); + } + + public static void FillMeshLocal (Mesh mesh, MeshAttachment meshAttachment, SkeletonData skeletonData) { + if (mesh == null) return; + if (meshAttachment == null) return; + int vertexCount = meshAttachment.WorldVerticesLength / 2; + + AttachmentVerts.Clear(); + if (meshAttachment.IsWeighted()) { + int count = meshAttachment.WorldVerticesLength; + int[] meshAttachmentBones = meshAttachment.bones; + int v = 0; + + float[] vertices = meshAttachment.vertices; + for (int w = 0, b = 0; w < count; w += 2) { + float wx = 0, wy = 0; + int n = meshAttachmentBones[v++]; + n += v; + for (; v < n; v++, b += 3) { + BoneMatrix bm = BoneMatrix.CalculateSetupWorld(skeletonData.bones.Items[meshAttachmentBones[v]]); + float vx = vertices[b], vy = vertices[b + 1], weight = vertices[b + 2]; + wx += (vx * bm.a + vy * bm.b + bm.x) * weight; + wy += (vx * bm.c + vy * bm.d + bm.y) * weight; + } + AttachmentVerts.Add(new Vector3(wx, wy)); + } + } else { + var localVerts = meshAttachment.Vertices; + Vector3 pos = default(Vector3); + for (int i = 0; i < vertexCount; i++) { + int ii = i * 2; + pos.x = localVerts[ii]; + pos.y = localVerts[ii + 1]; + AttachmentVerts.Add(pos); + } + } + + var uvs = meshAttachment.uvs; + Vector2 uv = default(Vector2); + Color32 c = (Color32)(new Color(meshAttachment.r, meshAttachment.g, meshAttachment.b, meshAttachment.a)); + AttachmentUVs.Clear(); + AttachmentColors32.Clear(); + for (int i = 0; i < vertexCount; i++) { + int ii = i * 2; + uv.x = uvs[ii]; + uv.y = uvs[ii + 1]; + AttachmentUVs.Add(uv); + + AttachmentColors32.Add(c); + } + + AttachmentIndices.Clear(); + AttachmentIndices.AddRange(meshAttachment.triangles); + + mesh.Clear(); + mesh.name = meshAttachment.Name; + mesh.SetVertices(AttachmentVerts); + mesh.SetUVs(0, AttachmentUVs); + mesh.SetColors(AttachmentColors32); + mesh.SetTriangles(AttachmentIndices, 0); + mesh.RecalculateBounds(); + + AttachmentVerts.Clear(); + AttachmentUVs.Clear(); + AttachmentColors32.Clear(); + AttachmentIndices.Clear(); + } + #endregion + } +} diff --git a/box1/Assets/Spine/Runtime/spine-unity/Mesh Generation/MeshGenerator.cs.meta b/box1/Assets/Spine/Runtime/spine-unity/Mesh Generation/MeshGenerator.cs.meta new file mode 100644 index 00000000..712b4927 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Mesh Generation/MeshGenerator.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 311447d6e56727c4dad7611d5fa5afbf +timeCreated: 1563322425 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Mesh Generation/MeshRendererBuffers.cs b/box1/Assets/Spine/Runtime/spine-unity/Mesh Generation/MeshRendererBuffers.cs new file mode 100644 index 00000000..e108bbda --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Mesh Generation/MeshRendererBuffers.cs @@ -0,0 +1,135 @@ +/****************************************************************************** + * 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. + *****************************************************************************/ + +// Not for optimization. Do not disable. +#define SPINE_TRIANGLECHECK // Avoid calling SetTriangles at the cost of checking for mesh differences (vertex counts, memberwise attachment list compare) every frame. +//#define SPINE_DEBUG + +using UnityEngine; +using System; +using System.Collections.Generic; + +namespace Spine.Unity { + /// A double-buffered Mesh, and a shared material array, bundled for use by Spine components that need to push a Mesh and materials to a Unity MeshRenderer and MeshFilter. + public class MeshRendererBuffers : IDisposable { + DoubleBuffered doubleBufferedMesh; + internal readonly ExposedList submeshMaterials = new ExposedList(); + internal Material[] sharedMaterials = new Material[0]; + + public void Initialize () { + if (doubleBufferedMesh != null) { + doubleBufferedMesh.GetNext().Clear(); + doubleBufferedMesh.GetNext().Clear(); + submeshMaterials.Clear(); + } else { + doubleBufferedMesh = new DoubleBuffered(); + } + } + + /// Returns a sharedMaterials array for use on a MeshRenderer. + /// + public Material[] GetUpdatedSharedMaterialsArray () { + if (submeshMaterials.Count == sharedMaterials.Length) + submeshMaterials.CopyTo(sharedMaterials); + else + sharedMaterials = submeshMaterials.ToArray(); + + return sharedMaterials; + } + + /// Returns true if the materials were modified since the buffers were last updated. + public bool MaterialsChangedInLastUpdate () { + int newSubmeshMaterials = submeshMaterials.Count; + var sharedMaterials = this.sharedMaterials; + if (newSubmeshMaterials != sharedMaterials.Length) return true; + + var submeshMaterialsItems = submeshMaterials.Items; + for (int i = 0; i < newSubmeshMaterials; i++) + if (!Material.ReferenceEquals(submeshMaterialsItems[i], sharedMaterials[i])) return true; //if (submeshMaterialsItems[i].GetInstanceID() != sharedMaterials[i].GetInstanceID()) return true; + + return false; + } + + /// Updates the internal shared materials array with the given instruction list. + public void UpdateSharedMaterials (ExposedList instructions) { + int newSize = instructions.Count; + { //submeshMaterials.Resize(instructions.Count); + if (newSize > submeshMaterials.Items.Length) + Array.Resize(ref submeshMaterials.Items, newSize); + submeshMaterials.Count = newSize; + } + + var submeshMaterialsItems = submeshMaterials.Items; + var instructionsItems = instructions.Items; + for (int i = 0; i < newSize; i++) + submeshMaterialsItems[i] = instructionsItems[i].material; + } + + public SmartMesh GetNextMesh () { + return doubleBufferedMesh.GetNext(); + } + + public void Clear () { + sharedMaterials = new Material[0]; + submeshMaterials.Clear(); + } + + public void Dispose () { + if (doubleBufferedMesh == null) return; + doubleBufferedMesh.GetNext().Dispose(); + doubleBufferedMesh.GetNext().Dispose(); + doubleBufferedMesh = null; + } + + ///This is a Mesh that also stores the instructions SkeletonRenderer generated for it. + public class SmartMesh : IDisposable { + public Mesh mesh = SpineMesh.NewSkeletonMesh(); + public SkeletonRendererInstruction instructionUsed = new SkeletonRendererInstruction(); + + public void Clear () { + mesh.Clear(); + instructionUsed.Clear(); + } + + public void Dispose () { + if (mesh != null) { + #if UNITY_EDITOR + if (Application.isEditor && !Application.isPlaying) + UnityEngine.Object.DestroyImmediate(mesh); + else + UnityEngine.Object.Destroy(mesh); + #else + UnityEngine.Object.Destroy(mesh); + #endif + } + mesh = null; + } + } + } +} diff --git a/box1/Assets/Spine/Runtime/spine-unity/Mesh Generation/MeshRendererBuffers.cs.meta b/box1/Assets/Spine/Runtime/spine-unity/Mesh Generation/MeshRendererBuffers.cs.meta new file mode 100644 index 00000000..3e4c8a1b --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Mesh Generation/MeshRendererBuffers.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: b1ab80744ac17724dbc0d15fdb6f4727 +timeCreated: 1563322425 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Mesh Generation/SkeletonRendererInstruction.cs b/box1/Assets/Spine/Runtime/spine-unity/Mesh Generation/SkeletonRendererInstruction.cs new file mode 100644 index 00000000..54821fa5 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Mesh Generation/SkeletonRendererInstruction.cs @@ -0,0 +1,178 @@ +/****************************************************************************** + * 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. + *****************************************************************************/ + +// Not for optimization. Do not disable. +#define SPINE_TRIANGLECHECK // Avoid calling SetTriangles at the cost of checking for mesh differences (vertex counts, memberwise attachment list compare) every frame. +//#define SPINE_DEBUG + +using UnityEngine; +using System; +using System.Collections.Generic; + +namespace Spine.Unity { + /// Instructions used by a SkeletonRenderer to render a mesh. + public class SkeletonRendererInstruction { + public readonly ExposedList submeshInstructions = new ExposedList(); + + public bool immutableTriangles; + #if SPINE_TRIANGLECHECK + public bool hasActiveClipping; + public int rawVertexCount = -1; + public readonly ExposedList attachments = new ExposedList(); + #endif + + public void Clear () { + #if SPINE_TRIANGLECHECK + this.attachments.Clear(false); + rawVertexCount = -1; + hasActiveClipping = false; + #endif + this.submeshInstructions.Clear(false); + } + + public void Dispose () { + attachments.Clear(true); + } + + public void SetWithSubset (ExposedList instructions, int startSubmesh, int endSubmesh) { + #if SPINE_TRIANGLECHECK + int runningVertexCount = 0; + #endif + + var submeshes = this.submeshInstructions; + submeshes.Clear(false); + int submeshCount = endSubmesh - startSubmesh; + submeshes.Resize(submeshCount); + var submeshesItems = submeshes.Items; + var instructionsItems = instructions.Items; + for (int i = 0; i < submeshCount; i++) { + var instruction = instructionsItems[startSubmesh + i]; + submeshesItems[i] = instruction; + #if SPINE_TRIANGLECHECK + this.hasActiveClipping |= instruction.hasClipping; + submeshesItems[i].rawFirstVertexIndex = runningVertexCount; // Ensure current instructions have correct cached values. + runningVertexCount += instruction.rawVertexCount; // vertexCount will also be used for the rest of this method. + #endif + } + #if SPINE_TRIANGLECHECK + this.rawVertexCount = runningVertexCount; + + // assumption: instructions are contiguous. start and end are valid within instructions. + + int startSlot = instructionsItems[startSubmesh].startSlot; + int endSlot = instructionsItems[endSubmesh - 1].endSlot; + attachments.Clear(false); + int attachmentCount = endSlot - startSlot; + attachments.Resize(attachmentCount); + var attachmentsItems = attachments.Items; + + var drawOrderItems = instructionsItems[0].skeleton.drawOrder.Items; + for (int i = 0; i < attachmentCount; i++) { + Slot slot = drawOrderItems[startSlot + i]; + if (!slot.bone.active) continue; + attachmentsItems[i] = slot.attachment; + } + + #endif + } + + public void Set (SkeletonRendererInstruction other) { + this.immutableTriangles = other.immutableTriangles; + + #if SPINE_TRIANGLECHECK + this.hasActiveClipping = other.hasActiveClipping; + this.rawVertexCount = other.rawVertexCount; + this.attachments.Clear(false); + this.attachments.EnsureCapacity(other.attachments.Capacity); + this.attachments.Count = other.attachments.Count; + other.attachments.CopyTo(this.attachments.Items); + #endif + + this.submeshInstructions.Clear(false); + this.submeshInstructions.EnsureCapacity(other.submeshInstructions.Capacity); + this.submeshInstructions.Count = other.submeshInstructions.Count; + other.submeshInstructions.CopyTo(this.submeshInstructions.Items); + } + + public static bool GeometryNotEqual (SkeletonRendererInstruction a, SkeletonRendererInstruction b) { + #if SPINE_TRIANGLECHECK + #if UNITY_EDITOR + if (!Application.isPlaying) + return true; + #endif + + if (a.hasActiveClipping || b.hasActiveClipping) return true; // Triangles are unpredictable when clipping is active. + + // Everything below assumes the raw vertex and triangle counts were used. (ie, no clipping was done) + if (a.rawVertexCount != b.rawVertexCount) return true; + + if (a.immutableTriangles != b.immutableTriangles) return true; + + int attachmentCountB = b.attachments.Count; + if (a.attachments.Count != attachmentCountB) return true; // Bounds check for the looped storedAttachments count below. + + // Submesh count changed + int submeshCountA = a.submeshInstructions.Count; + int submeshCountB = b.submeshInstructions.Count; + if (submeshCountA != submeshCountB) return true; + + // Submesh Instruction mismatch + var submeshInstructionsItemsA = a.submeshInstructions.Items; + var submeshInstructionsItemsB = b.submeshInstructions.Items; + + var attachmentsA = a.attachments.Items; + var attachmentsB = b.attachments.Items; + for (int i = 0; i < attachmentCountB; i++) + if (!System.Object.ReferenceEquals(attachmentsA[i], attachmentsB[i])) return true; + + for (int i = 0; i < submeshCountB; i++) { + var submeshA = submeshInstructionsItemsA[i]; + var submeshB = submeshInstructionsItemsB[i]; + + if (!( + submeshA.rawVertexCount == submeshB.rawVertexCount && + submeshA.startSlot == submeshB.startSlot && + submeshA.endSlot == submeshB.endSlot + && submeshA.rawTriangleCount == submeshB.rawTriangleCount && + submeshA.rawFirstVertexIndex == submeshB.rawFirstVertexIndex + )) + return true; + } + + return false; + #else + // In normal immutable triangle use, immutableTriangles will be initially false, forcing the smartmesh to update the first time but never again after that, unless there was an immutableTriangles flag mismatch.. + if (a.immutableTriangles || b.immutableTriangles) + return (a.immutableTriangles != b.immutableTriangles); + + return true; + #endif + } + } +} diff --git a/box1/Assets/Spine/Runtime/spine-unity/Mesh Generation/SkeletonRendererInstruction.cs.meta b/box1/Assets/Spine/Runtime/spine-unity/Mesh Generation/SkeletonRendererInstruction.cs.meta new file mode 100644 index 00000000..50a8a97d --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Mesh Generation/SkeletonRendererInstruction.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: d07866ade25bd0b44a7bb1d59bacf4cb +timeCreated: 1563322425 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Mesh Generation/SpineMesh.cs b/box1/Assets/Spine/Runtime/spine-unity/Mesh Generation/SpineMesh.cs new file mode 100644 index 00000000..31a25e19 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Mesh Generation/SpineMesh.cs @@ -0,0 +1,84 @@ +/****************************************************************************** + * 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. + *****************************************************************************/ + +// Not for optimization. Do not disable. +#define SPINE_TRIANGLECHECK // Avoid calling SetTriangles at the cost of checking for mesh differences (vertex counts, memberwise attachment list compare) every frame. +//#define SPINE_DEBUG + +using UnityEngine; +using System; +using System.Collections.Generic; + +namespace Spine.Unity { + public static class SpineMesh { + internal const HideFlags MeshHideflags = HideFlags.DontSaveInBuild | HideFlags.DontSaveInEditor; + + /// Factory method for creating a new mesh for use in Spine components. This can be called in field initializers. + public static Mesh NewSkeletonMesh () { + var m = new Mesh(); + m.MarkDynamic(); + m.name = "Skeleton Mesh"; + m.hideFlags = SpineMesh.MeshHideflags; + return m; + } + } + + /// Instructions for how to generate a mesh or submesh: "Render this skeleton's slots: start slot, up to but not including endSlot, using this material." + public struct SubmeshInstruction { + public Skeleton skeleton; + public int startSlot; + public int endSlot; + public Material material; + + public bool forceSeparate; + public int preActiveClippingSlotSource; + + #if SPINE_TRIANGLECHECK + // Cached values because they are determined in the process of generating instructions, + // but could otherwise be pulled from accessing attachments, checking materials and counting tris and verts. + public int rawTriangleCount; + public int rawVertexCount; + public int rawFirstVertexIndex; + public bool hasClipping; + #endif + + /// The number of slots in this SubmeshInstruction's range. Not necessarily the number of attachments. + public int SlotCount { get { return endSlot - startSlot; } } + + public override string ToString () { + return + string.Format("[SubmeshInstruction: slots {0} to {1}. (Material){2}. preActiveClippingSlotSource:{3}]", + startSlot, + endSlot - 1, + material == null ? "" : material.name, + preActiveClippingSlotSource + ); + } + } +} diff --git a/box1/Assets/Spine/Runtime/spine-unity/Mesh Generation/SpineMesh.cs.meta b/box1/Assets/Spine/Runtime/spine-unity/Mesh Generation/SpineMesh.cs.meta new file mode 100644 index 00000000..b30649ab --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Mesh Generation/SpineMesh.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: f834c8746034db645a52a9506ff1de89 +timeCreated: 1455416715 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Modules.meta b/box1/Assets/Spine/Runtime/spine-unity/Modules.meta new file mode 100644 index 00000000..2dc106cc --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Modules.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: a7935399edad9a14bb5708cf59c94b67 +folderAsset: yes +timeCreated: 1455489260 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Modules/TK2D.meta b/box1/Assets/Spine/Runtime/spine-unity/Modules/TK2D.meta new file mode 100644 index 00000000..bd32abb6 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Modules/TK2D.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: e70d3026a0242e5418232b2015be29f7 +folderAsset: yes +timeCreated: 1456509301 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Modules/TK2D/SpriteCollectionAttachmentLoader.cs b/box1/Assets/Spine/Runtime/spine-unity/Modules/TK2D/SpriteCollectionAttachmentLoader.cs new file mode 100644 index 00000000..a3ce3de2 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Modules/TK2D/SpriteCollectionAttachmentLoader.cs @@ -0,0 +1,156 @@ +/****************************************************************************** + * 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 SPINE_TK2D +using System; +using UnityEngine; +using Spine; + +// MITCH: handle TPackerCW flip mode (probably not swap uv horizontaly) +namespace Spine.Unity.TK2D { + public class SpriteCollectionAttachmentLoader : AttachmentLoader { + private tk2dSpriteCollectionData sprites; + private float u, v, u2, v2; + private bool regionRotated; + private float regionOriginalWidth, regionOriginalHeight; + private float regionWidth, regionHeight; + private float regionOffsetX, regionOffsetY; + private Material material; + + public SpriteCollectionAttachmentLoader (tk2dSpriteCollectionData sprites) { + if (sprites == null) + throw new ArgumentNullException("sprites cannot be null."); + this.sprites = sprites; + } + + private void ProcessSpriteDefinition (String name) { + // Strip folder names. + int index = name.LastIndexOfAny(new char[] {'/', '\\'}); + if (index != -1) + name = name.Substring(index + 1); + + tk2dSpriteDefinition def = sprites.inst.GetSpriteDefinition(name); + + if (def == null) { + Debug.Log("Sprite not found in atlas: " + name, sprites); + throw new Exception("Sprite not found in atlas: " + name); + } + if (def.complexGeometry) + throw new NotImplementedException("Complex geometry is not supported: " + name); + if (def.flipped == tk2dSpriteDefinition.FlipMode.TPackerCW) + throw new NotImplementedException("Only 2D Toolkit atlases are supported: " + name); + + Vector2 minTexCoords = Vector2.one, maxTexCoords = Vector2.zero; + for (int i = 0; i < def.uvs.Length; ++i) { + Vector2 uv = def.uvs[i]; + minTexCoords = Vector2.Min(minTexCoords, uv); + maxTexCoords = Vector2.Max(maxTexCoords, uv); + } + regionRotated = def.flipped == tk2dSpriteDefinition.FlipMode.Tk2d; + if (regionRotated) { + float temp = minTexCoords.x; + minTexCoords.x = maxTexCoords.x; + maxTexCoords.x = temp; + } + u = minTexCoords.x; + v = maxTexCoords.y; + u2 = maxTexCoords.x; + v2 = minTexCoords.y; + + regionOriginalWidth = (int)(def.untrimmedBoundsData[1].x / def.texelSize.x); + regionOriginalHeight = (int)(def.untrimmedBoundsData[1].y / def.texelSize.y); + + regionWidth = (int)(def.boundsData[1].x / def.texelSize.x); + regionHeight = (int)(def.boundsData[1].y / def.texelSize.y); + + float x0 = def.untrimmedBoundsData[0].x - def.untrimmedBoundsData[1].x / 2; + float x1 = def.boundsData[0].x - def.boundsData[1].x / 2; + regionOffsetX = (int)((x1 - x0) / def.texelSize.x); + + float y0 = def.untrimmedBoundsData[0].y - def.untrimmedBoundsData[1].y / 2; + float y1 = def.boundsData[0].y - def.boundsData[1].y / 2; + regionOffsetY = (int)((y1 - y0) / def.texelSize.y); + + material = def.materialInst; + } + + public RegionAttachment NewRegionAttachment (Skin skin, String name, String path) { + ProcessSpriteDefinition(path); + + RegionAttachment region = new RegionAttachment(name); + region.Path = path; + region.RendererObject = material; + region.SetUVs(u, v, u2, v2, regionRotated); + region.RegionOriginalWidth = regionOriginalWidth; + region.RegionOriginalHeight = regionOriginalHeight; + region.RegionWidth = regionWidth; + region.RegionHeight = regionHeight; + region.RegionOffsetX = regionOffsetX; + region.RegionOffsetY = regionOffsetY; + return region; + } + + public MeshAttachment NewMeshAttachment (Skin skin, String name, String path) { + ProcessSpriteDefinition(path); + + MeshAttachment mesh = new MeshAttachment(name); + mesh.Path = path; + mesh.RendererObject = material; + mesh.RegionU = u; + mesh.RegionV = v; + mesh.RegionU2 = u2; + mesh.RegionV2 = v2; + mesh.RegionRotate = regionRotated; + mesh.RegionOriginalWidth = regionOriginalWidth; + mesh.RegionOriginalHeight = regionOriginalHeight; + mesh.RegionWidth = regionWidth; + mesh.RegionHeight = regionHeight; + mesh.RegionOffsetX = regionOffsetX; + mesh.RegionOffsetY = regionOffsetY; + return mesh; + } + + public BoundingBoxAttachment NewBoundingBoxAttachment (Skin skin, String name) { + return new BoundingBoxAttachment(name); + } + + public PathAttachment NewPathAttachment (Skin skin, string name) { + return new PathAttachment(name); + } + + public PointAttachment NewPointAttachment (Skin skin, string name) { + return new PointAttachment(name); + } + + public ClippingAttachment NewClippingAttachment (Skin skin, string name) { + return new ClippingAttachment(name); + } + } +} +#endif diff --git a/box1/Assets/Spine/Runtime/spine-unity/Modules/TK2D/SpriteCollectionAttachmentLoader.cs.meta b/box1/Assets/Spine/Runtime/spine-unity/Modules/TK2D/SpriteCollectionAttachmentLoader.cs.meta new file mode 100644 index 00000000..671d5c76 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Modules/TK2D/SpriteCollectionAttachmentLoader.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 03238e4a73953c045a6cb289162532f3 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders.meta b/box1/Assets/Spine/Runtime/spine-unity/Shaders.meta new file mode 100644 index 00000000..96c6a80b --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders.meta @@ -0,0 +1,4 @@ +fileFormatVersion: 2 +guid: ef8189a68a74bec4eba582e65fb98dbd +DefaultImporter: + userData: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/BlendModes.meta b/box1/Assets/Spine/Runtime/spine-unity/Shaders/BlendModes.meta new file mode 100644 index 00000000..5fd19dfb --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/BlendModes.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: baf1d09e18b500d41a714f6207ddda2d +folderAsset: yes +timeCreated: 1536402197 +licenseType: Pro +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/BlendModes/Spine-Skeleton-PMA-Additive.shader b/box1/Assets/Spine/Runtime/spine-unity/Shaders/BlendModes/Spine-Skeleton-PMA-Additive.shader new file mode 100644 index 00000000..322c9a45 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/BlendModes/Spine-Skeleton-PMA-Additive.shader @@ -0,0 +1,128 @@ +// Spine/Skeleton PMA Screen +// - single color multiply tint +// - unlit +// - Premultiplied alpha Multiply blending +// - No depth, no backface culling, no fog. +// - ShadowCaster pass + +Shader "Spine/Blend Modes/Skeleton PMA Additive" { + Properties { + _Color ("Tint Color", Color) = (1,1,1,1) + [NoScaleOffset] _MainTex ("MainTex", 2D) = "black" {} + [Toggle(_STRAIGHT_ALPHA_INPUT)] _StraightAlphaInput("Straight Alpha Texture", Int) = 0 + _Cutoff ("Shadow alpha cutoff", Range(0,1)) = 0.1 + [HideInInspector] _StencilRef("Stencil Reference", Float) = 1.0 + [HideInInspector][Enum(UnityEngine.Rendering.CompareFunction)] _StencilComp("Stencil Comparison", Float) = 8 // Set to Always as default + + // Outline properties are drawn via custom editor. + [HideInInspector] _OutlineWidth("Outline Width", Range(0,8)) = 3.0 + [HideInInspector] _OutlineColor("Outline Color", Color) = (1,1,0,1) + [HideInInspector] _OutlineReferenceTexWidth("Reference Texture Width", Int) = 1024 + [HideInInspector] _ThresholdEnd("Outline Threshold", Range(0,1)) = 0.25 + [HideInInspector] _OutlineSmoothness("Outline Smoothness", Range(0,1)) = 1.0 + [HideInInspector][MaterialToggle(_USE8NEIGHBOURHOOD_ON)] _Use8Neighbourhood("Sample 8 Neighbours", Float) = 1 + [HideInInspector] _OutlineMipLevel("Outline Mip Level", Range(0,3)) = 0 + } + + SubShader { + Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" } + LOD 100 + + Fog { Mode Off } + Cull Off + ZWrite Off + Blend One One + Lighting Off + + Stencil { + Ref[_StencilRef] + Comp[_StencilComp] + Pass Keep + } + + Pass { + Name "Normal" + + CGPROGRAM + #pragma shader_feature _ _STRAIGHT_ALPHA_INPUT + #pragma vertex vert + #pragma fragment frag + #include "UnityCG.cginc" + uniform sampler2D _MainTex; + uniform float4 _Color; + + struct VertexInput { + float4 vertex : POSITION; + float2 uv : TEXCOORD0; + float4 vertexColor : COLOR; + }; + + struct VertexOutput { + float4 pos : SV_POSITION; + float2 uv : TEXCOORD0; + float4 vertexColor : COLOR; + }; + + VertexOutput vert (VertexInput v) { + VertexOutput o; + o.pos = UnityObjectToClipPos(v.vertex); + o.uv = v.uv; + o.vertexColor = v.vertexColor * float4(_Color.rgb * _Color.a, _Color.a); // Combine a PMA version of _Color with vertexColor. + return o; + } + + float4 frag (VertexOutput i) : SV_Target { + float4 texColor = tex2D(_MainTex, i.uv); + + #if defined(_STRAIGHT_ALPHA_INPUT) + texColor.rgb *= texColor.a; + #endif + + return (texColor * i.vertexColor); + } + ENDCG + } + + Pass { + Name "Caster" + Tags { "LightMode"="ShadowCaster" } + Offset 1, 1 + + ZWrite On + ZTest LEqual + + CGPROGRAM + #pragma vertex vert + #pragma fragment frag + #pragma multi_compile_shadowcaster + #pragma fragmentoption ARB_precision_hint_fastest + #include "UnityCG.cginc" + struct v2f { + V2F_SHADOW_CASTER; + float4 uvAndAlpha : TEXCOORD1; + }; + + uniform float4 _MainTex_ST; + + v2f vert (appdata_base v, float4 vertexColor : COLOR) { + v2f o; + TRANSFER_SHADOW_CASTER(o) + o.uvAndAlpha.xy = TRANSFORM_TEX(v.texcoord, _MainTex); + o.uvAndAlpha.z = 0; + o.uvAndAlpha.a = vertexColor.a; + return o; + } + + uniform sampler2D _MainTex; + uniform fixed _Cutoff; + + float4 frag (v2f i) : SV_Target { + fixed4 texcol = tex2D(_MainTex, i.uvAndAlpha.xy); + clip(texcol.a * i.uvAndAlpha.a - _Cutoff); + SHADOW_CASTER_FRAGMENT(i) + } + ENDCG + } + } + CustomEditor "SpineShaderWithOutlineGUI" +} diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/BlendModes/Spine-Skeleton-PMA-Additive.shader.meta b/box1/Assets/Spine/Runtime/spine-unity/Shaders/BlendModes/Spine-Skeleton-PMA-Additive.shader.meta new file mode 100644 index 00000000..1204d945 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/BlendModes/Spine-Skeleton-PMA-Additive.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 53efa1d97f5d9f74285d4330cda14e36 +timeCreated: 1496446742 +licenseType: Free +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/BlendModes/Spine-Skeleton-PMA-Multiply.shader b/box1/Assets/Spine/Runtime/spine-unity/Shaders/BlendModes/Spine-Skeleton-PMA-Multiply.shader new file mode 100644 index 00000000..7b35130b --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/BlendModes/Spine-Skeleton-PMA-Multiply.shader @@ -0,0 +1,128 @@ +// Spine/Skeleton PMA Multiply +// - single color multiply tint +// - unlit +// - Premultiplied alpha Multiply blending +// - No depth, no backface culling, no fog. +// - ShadowCaster pass + +Shader "Spine/Blend Modes/Skeleton PMA Multiply" { + Properties { + _Color ("Tint Color", Color) = (1,1,1,1) + [NoScaleOffset] _MainTex ("MainTex", 2D) = "black" {} + [Toggle(_STRAIGHT_ALPHA_INPUT)] _StraightAlphaInput("Straight Alpha Texture", Int) = 0 + _Cutoff ("Shadow alpha cutoff", Range(0,1)) = 0.1 + [HideInInspector] _StencilRef("Stencil Reference", Float) = 1.0 + [HideInInspector][Enum(UnityEngine.Rendering.CompareFunction)] _StencilComp("Stencil Comparison", Float) = 8 // Set to Always as default + + // Outline properties are drawn via custom editor. + [HideInInspector] _OutlineWidth("Outline Width", Range(0,8)) = 3.0 + [HideInInspector] _OutlineColor("Outline Color", Color) = (1,1,0,1) + [HideInInspector] _OutlineReferenceTexWidth("Reference Texture Width", Int) = 1024 + [HideInInspector] _ThresholdEnd("Outline Threshold", Range(0,1)) = 0.25 + [HideInInspector] _OutlineSmoothness("Outline Smoothness", Range(0,1)) = 1.0 + [HideInInspector][MaterialToggle(_USE8NEIGHBOURHOOD_ON)] _Use8Neighbourhood("Sample 8 Neighbours", Float) = 1 + [HideInInspector] _OutlineMipLevel("Outline Mip Level", Range(0,3)) = 0 + } + + SubShader { + Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" } + LOD 100 + + Fog { Mode Off } + Cull Off + ZWrite Off + Blend DstColor OneMinusSrcAlpha + Lighting Off + + Stencil { + Ref[_StencilRef] + Comp[_StencilComp] + Pass Keep + } + + Pass { + Name "Normal" + + CGPROGRAM + #pragma shader_feature _ _STRAIGHT_ALPHA_INPUT + #pragma vertex vert + #pragma fragment frag + #include "UnityCG.cginc" + uniform sampler2D _MainTex; + uniform float4 _Color; + + struct VertexInput { + float4 vertex : POSITION; + float2 uv : TEXCOORD0; + float4 vertexColor : COLOR; + }; + + struct VertexOutput { + float4 pos : SV_POSITION; + float2 uv : TEXCOORD0; + float4 vertexColor : COLOR; + }; + + VertexOutput vert (VertexInput v) { + VertexOutput o; + o.pos = UnityObjectToClipPos(v.vertex); + o.uv = v.uv; + o.vertexColor = v.vertexColor * float4(_Color.rgb * _Color.a, _Color.a); // Combine a PMA version of _Color with vertexColor. + return o; + } + + float4 frag (VertexOutput i) : SV_Target { + float4 texColor = tex2D(_MainTex, i.uv); + + #if defined(_STRAIGHT_ALPHA_INPUT) + texColor.rgb *= texColor.a; + #endif + + return (texColor * i.vertexColor); + } + ENDCG + } + + Pass { + Name "Caster" + Tags { "LightMode"="ShadowCaster" } + Offset 1, 1 + + ZWrite On + ZTest LEqual + + CGPROGRAM + #pragma vertex vert + #pragma fragment frag + #pragma multi_compile_shadowcaster + #pragma fragmentoption ARB_precision_hint_fastest + #include "UnityCG.cginc" + struct v2f { + V2F_SHADOW_CASTER; + float4 uvAndAlpha : TEXCOORD1; + }; + + uniform float4 _MainTex_ST; + + v2f vert (appdata_base v, float4 vertexColor : COLOR) { + v2f o; + TRANSFER_SHADOW_CASTER(o) + o.uvAndAlpha.xy = TRANSFORM_TEX(v.texcoord, _MainTex); + o.uvAndAlpha.z = 0; + o.uvAndAlpha.a = vertexColor.a; + return o; + } + + uniform sampler2D _MainTex; + uniform fixed _Cutoff; + + float4 frag (v2f i) : SV_Target { + fixed4 texcol = tex2D(_MainTex, i.uvAndAlpha.xy); + clip(texcol.a * i.uvAndAlpha.a - _Cutoff); + SHADOW_CASTER_FRAGMENT(i) + } + ENDCG + } + } + CustomEditor "SpineShaderWithOutlineGUI" +} diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/BlendModes/Spine-Skeleton-PMA-Multiply.shader.meta b/box1/Assets/Spine/Runtime/spine-unity/Shaders/BlendModes/Spine-Skeleton-PMA-Multiply.shader.meta new file mode 100644 index 00000000..f3119889 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/BlendModes/Spine-Skeleton-PMA-Multiply.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 8bdcdc7ee298e594a9c20c61d25c33b6 +timeCreated: 1496446742 +licenseType: Free +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/BlendModes/Spine-Skeleton-PMA-Screen.shader b/box1/Assets/Spine/Runtime/spine-unity/Shaders/BlendModes/Spine-Skeleton-PMA-Screen.shader new file mode 100644 index 00000000..3f0220c3 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/BlendModes/Spine-Skeleton-PMA-Screen.shader @@ -0,0 +1,128 @@ +// Spine/Skeleton PMA Screen +// - single color multiply tint +// - unlit +// - Premultiplied alpha Multiply blending +// - No depth, no backface culling, no fog. +// - ShadowCaster pass + +Shader "Spine/Blend Modes/Skeleton PMA Screen" { + Properties { + _Color ("Tint Color", Color) = (1,1,1,1) + [NoScaleOffset] _MainTex ("MainTex", 2D) = "black" {} + [Toggle(_STRAIGHT_ALPHA_INPUT)] _StraightAlphaInput("Straight Alpha Texture", Int) = 0 + _Cutoff ("Shadow alpha cutoff", Range(0,1)) = 0.1 + [HideInInspector] _StencilRef("Stencil Reference", Float) = 1.0 + [HideInInspector][Enum(UnityEngine.Rendering.CompareFunction)] _StencilComp("Stencil Comparison", Float) = 8 // Set to Always as default + + // Outline properties are drawn via custom editor. + [HideInInspector] _OutlineWidth("Outline Width", Range(0,8)) = 3.0 + [HideInInspector] _OutlineColor("Outline Color", Color) = (1,1,0,1) + [HideInInspector] _OutlineReferenceTexWidth("Reference Texture Width", Int) = 1024 + [HideInInspector] _ThresholdEnd("Outline Threshold", Range(0,1)) = 0.25 + [HideInInspector] _OutlineSmoothness("Outline Smoothness", Range(0,1)) = 1.0 + [HideInInspector][MaterialToggle(_USE8NEIGHBOURHOOD_ON)] _Use8Neighbourhood("Sample 8 Neighbours", Float) = 1 + [HideInInspector] _OutlineMipLevel("Outline Mip Level", Range(0,3)) = 0 + } + + SubShader { + Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" } + LOD 100 + + Fog { Mode Off } + Cull Off + ZWrite Off + Blend One OneMinusSrcColor + Lighting Off + + Stencil { + Ref[_StencilRef] + Comp[_StencilComp] + Pass Keep + } + + Pass { + Name "Normal" + + CGPROGRAM + #pragma shader_feature _ _STRAIGHT_ALPHA_INPUT + #pragma vertex vert + #pragma fragment frag + #include "UnityCG.cginc" + uniform sampler2D _MainTex; + uniform float4 _Color; + + struct VertexInput { + float4 vertex : POSITION; + float2 uv : TEXCOORD0; + float4 vertexColor : COLOR; + }; + + struct VertexOutput { + float4 pos : SV_POSITION; + float2 uv : TEXCOORD0; + float4 vertexColor : COLOR; + }; + + VertexOutput vert (VertexInput v) { + VertexOutput o; + o.pos = UnityObjectToClipPos(v.vertex); + o.uv = v.uv; + o.vertexColor = v.vertexColor * float4(_Color.rgb * _Color.a, _Color.a); // Combine a PMA version of _Color with vertexColor. + return o; + } + + float4 frag (VertexOutput i) : SV_Target { + float4 texColor = tex2D(_MainTex, i.uv); + + #if defined(_STRAIGHT_ALPHA_INPUT) + texColor.rgb *= texColor.a; + #endif + + return (texColor * i.vertexColor); + } + ENDCG + } + + Pass { + Name "Caster" + Tags { "LightMode"="ShadowCaster" } + Offset 1, 1 + + ZWrite On + ZTest LEqual + + CGPROGRAM + #pragma vertex vert + #pragma fragment frag + #pragma multi_compile_shadowcaster + #pragma fragmentoption ARB_precision_hint_fastest + #include "UnityCG.cginc" + struct v2f { + V2F_SHADOW_CASTER; + float4 uvAndAlpha : TEXCOORD1; + }; + + uniform float4 _MainTex_ST; + + v2f vert (appdata_base v, float4 vertexColor : COLOR) { + v2f o; + TRANSFER_SHADOW_CASTER(o) + o.uvAndAlpha.xy = TRANSFORM_TEX(v.texcoord, _MainTex); + o.uvAndAlpha.z = 0; + o.uvAndAlpha.a = vertexColor.a; + return o; + } + + uniform sampler2D _MainTex; + uniform fixed _Cutoff; + + float4 frag (v2f i) : SV_Target { + fixed4 texcol = tex2D(_MainTex, i.uvAndAlpha.xy); + clip(texcol.a * i.uvAndAlpha.a - _Cutoff); + SHADOW_CASTER_FRAGMENT(i) + } + ENDCG + } + } + CustomEditor "SpineShaderWithOutlineGUI" +} diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/BlendModes/Spine-Skeleton-PMA-Screen.shader.meta b/box1/Assets/Spine/Runtime/spine-unity/Shaders/BlendModes/Spine-Skeleton-PMA-Screen.shader.meta new file mode 100644 index 00000000..173ff6a2 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/BlendModes/Spine-Skeleton-PMA-Screen.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 4e8caa36c07aacf4ab270da00784e4d9 +timeCreated: 1496448787 +licenseType: Free +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/CGIncludes.meta b/box1/Assets/Spine/Runtime/spine-unity/Shaders/CGIncludes.meta new file mode 100644 index 00000000..c8804508 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/CGIncludes.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 511f90ee1fe01c146836d5ed23f2e70f +folderAsset: yes +timeCreated: 1564083752 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/CGIncludes/Spine-DepthOnlyPass.cginc b/box1/Assets/Spine/Runtime/spine-unity/Shaders/CGIncludes/Spine-DepthOnlyPass.cginc new file mode 100644 index 00000000..9a7e1402 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/CGIncludes/Spine-DepthOnlyPass.cginc @@ -0,0 +1,41 @@ +#ifndef SPRITES_DEPTH_ONLY_PASS_INCLUDED +#define SPRITES_DEPTH_ONLY_PASS_INCLUDED + +#include "UnityCG.cginc" + +sampler2D _MainTex; +float _Cutoff; +float _ZWriteOffset; + +struct VertexInput { + float4 positionOS : POSITION; + float2 texcoord : TEXCOORD0; + float4 vertexColor : COLOR; +}; + +struct VertexOutput { + float4 positionCS : SV_POSITION; + float4 texcoordAndAlpha: TEXCOORD0; +}; + +VertexOutput DepthOnlyVertex (VertexInput v) { + VertexOutput o; + o.positionCS = UnityObjectToClipPos(v.positionOS - float4(0, 0, _ZWriteOffset, 0)); + o.texcoordAndAlpha.xy = v.texcoord; + o.texcoordAndAlpha.z = 0; + o.texcoordAndAlpha.a = v.vertexColor.a; + return o; +} + +float4 DepthOnlyFragment (VertexOutput input) : SV_Target{ + float4 texColor = tex2D(_MainTex, input.texcoordAndAlpha.rg); + + #if defined(_STRAIGHT_ALPHA_INPUT) + texColor.rgb *= texColor.a; + #endif + + clip(texColor.a * input.texcoordAndAlpha.a - _Cutoff); + return 0; +} + +#endif diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/CGIncludes/Spine-DepthOnlyPass.cginc.meta b/box1/Assets/Spine/Runtime/spine-unity/Shaders/CGIncludes/Spine-DepthOnlyPass.cginc.meta new file mode 100644 index 00000000..eb8386bb --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/CGIncludes/Spine-DepthOnlyPass.cginc.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 27351ce55d3beb643ae8d9385db21941 +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/CGIncludes/Spine-Skeleton-Lit-Common-Shadow.cginc b/box1/Assets/Spine/Runtime/spine-unity/Shaders/CGIncludes/Spine-Skeleton-Lit-Common-Shadow.cginc new file mode 100644 index 00000000..f5150ab6 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/CGIncludes/Spine-Skeleton-Lit-Common-Shadow.cginc @@ -0,0 +1,30 @@ +#ifndef SKELETON_LIT_COMMON_SHADOW_INCLUDED +#define SKELETON_LIT_COMMON_SHADOW_INCLUDED + +#include "UnityCG.cginc" +struct v2f { + V2F_SHADOW_CASTER; + float4 uvAndAlpha : TEXCOORD1; +}; + +uniform float4 _MainTex_ST; + +v2f vertShadow(appdata_base v, float4 vertexColor : COLOR) { + v2f o; + TRANSFER_SHADOW_CASTER(o) + o.uvAndAlpha.xy = TRANSFORM_TEX(v.texcoord, _MainTex); + o.uvAndAlpha.z = 0; + o.uvAndAlpha.a = vertexColor.a; + return o; +} + +uniform sampler2D _MainTex; +uniform fixed SHADOW_CUTOFF; + +float4 fragShadow (v2f i) : SV_Target { + fixed4 texcol = tex2D(_MainTex, i.uvAndAlpha.xy); + clip(texcol.a * i.uvAndAlpha.a - SHADOW_CUTOFF); + SHADOW_CASTER_FRAGMENT(i) +} + +#endif diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/CGIncludes/Spine-Skeleton-Lit-Common-Shadow.cginc.meta b/box1/Assets/Spine/Runtime/spine-unity/Shaders/CGIncludes/Spine-Skeleton-Lit-Common-Shadow.cginc.meta new file mode 100644 index 00000000..b325e236 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/CGIncludes/Spine-Skeleton-Lit-Common-Shadow.cginc.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: c7297b25c81d2494e8e73b742e3c7345 +timeCreated: 1564083752 +licenseType: Free +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/CGIncludes/Spine-Skeleton-Lit-Common.cginc b/box1/Assets/Spine/Runtime/spine-unity/Shaders/CGIncludes/Spine-Skeleton-Lit-Common.cginc new file mode 100644 index 00000000..73a6e187 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/CGIncludes/Spine-Skeleton-Lit-Common.cginc @@ -0,0 +1,125 @@ +#ifndef SKELETON_LIT_COMMON_INCLUDED +#define SKELETON_LIT_COMMON_INCLUDED + +#include "UnityCG.cginc" + +// ES2.0/WebGL/3DS can not do loops with non-constant-expression iteration counts :( +#if defined(SHADER_API_GLES) +#define LIGHT_LOOP_LIMIT 8 +#elif defined(SHADER_API_N3DS) +#define LIGHT_LOOP_LIMIT 4 +#else +#define LIGHT_LOOP_LIMIT unity_VertexLightParams.x +#endif + + +//////////////////////////////////////// +// Alpha Clipping +// + +#if defined(_ALPHA_CLIP) + uniform fixed _Cutoff; + #define ALPHA_CLIP(pixel, color) clip((pixel.a * color.a) - _Cutoff); +#else + #define ALPHA_CLIP(pixel, color) +#endif + +half3 computeLighting (int idx, half3 dirToLight, half3 eyeNormal, half4 diffuseColor, half atten) { + half NdotL = max(dot(eyeNormal, dirToLight), 0.0); + // diffuse + half3 color = NdotL * diffuseColor.rgb * unity_LightColor[idx].rgb; + return color * atten; +} + +half3 computeOneLight (int idx, float3 eyePosition, half3 eyeNormal, half4 diffuseColor) { + float3 dirToLight = unity_LightPosition[idx].xyz; + half att = 1.0; + + #if defined(POINT) || defined(SPOT) + dirToLight -= eyePosition * unity_LightPosition[idx].w; + + // distance attenuation + float distSqr = dot(dirToLight, dirToLight); + att /= (1.0 + unity_LightAtten[idx].z * distSqr); + if (unity_LightPosition[idx].w != 0 && distSqr > unity_LightAtten[idx].w) att = 0.0; // set to 0 if outside of range + distSqr = max(distSqr, 0.000001); // don't produce NaNs if some vertex position overlaps with the light + dirToLight *= rsqrt(distSqr); + #if defined(SPOT) + + // spot angle attenuation + half rho = max(dot(dirToLight, unity_SpotDirection[idx].xyz), 0.0); + half spotAtt = (rho - unity_LightAtten[idx].x) * unity_LightAtten[idx].y; + att *= saturate(spotAtt); + #endif + #endif + + att *= 0.5; // passed in light colors are 2x brighter than what used to be in FFP + return min (computeLighting (idx, dirToLight, eyeNormal, diffuseColor, att), 1.0); +} + +int4 unity_VertexLightParams; // x: light count, y: zero, z: one (y/z needed by d3d9 vs loop instruction) + +struct appdata { + float3 pos : POSITION; + float3 normal : NORMAL; + half4 color : COLOR; + float2 uv0 : TEXCOORD0; + UNITY_VERTEX_INPUT_INSTANCE_ID +}; + +struct VertexOutput { + fixed4 color : COLOR0; + float2 uv0 : TEXCOORD0; + float4 pos : SV_POSITION; + UNITY_VERTEX_OUTPUT_STEREO +}; + +VertexOutput vert (appdata v) { + VertexOutput o; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + + half4 color = v.color; + float3 eyePos = UnityObjectToViewPos(float4(v.pos, 1)).xyz; //mul(UNITY_MATRIX_MV, float4(v.pos,1)).xyz; + half3 fixedNormal = half3(0,0,-1); + half3 eyeNormal = normalize(mul((float3x3)UNITY_MATRIX_IT_MV, fixedNormal)); + +#ifdef _DOUBLE_SIDED_LIGHTING + // unfortunately we have to compute the sign here in the vertex shader + // instead of using VFACE in fragment shader stage. + half faceSign = sign(eyeNormal.z); + eyeNormal *= faceSign; +#endif + + // Lights + half3 lcolor = half4(0,0,0,1).rgb + color.rgb * glstate_lightmodel_ambient.rgb; + for (int il = 0; il < LIGHT_LOOP_LIMIT; ++il) { + lcolor += computeOneLight(il, eyePos, eyeNormal, color); + } + + color.rgb = lcolor.rgb; + o.color = saturate(color); + o.uv0 = v.uv0; + o.pos = UnityObjectToClipPos(v.pos); + return o; +} + +sampler2D _MainTex; + +fixed4 frag (VertexOutput i) : SV_Target { + fixed4 tex = tex2D(_MainTex, i.uv0); + ALPHA_CLIP(tex, i.color); + + fixed4 col; + #if defined(_STRAIGHT_ALPHA_INPUT) + col.rgb = tex * i.color * tex.a; + #else + col.rgb = tex * i.color; + #endif + + col *= 2; + col.a = tex.a * i.color.a; + return col; +} + +#endif diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/CGIncludes/Spine-Skeleton-Lit-Common.cginc.meta b/box1/Assets/Spine/Runtime/spine-unity/Shaders/CGIncludes/Spine-Skeleton-Lit-Common.cginc.meta new file mode 100644 index 00000000..ee348103 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/CGIncludes/Spine-Skeleton-Lit-Common.cginc.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 70c77c02aabd5e44f94aab48dd0be7b2 +timeCreated: 1564083752 +licenseType: Free +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/CGIncludes/Spine-Skeleton-Tint-Common.cginc b/box1/Assets/Spine/Runtime/spine-unity/Shaders/CGIncludes/Spine-Skeleton-Tint-Common.cginc new file mode 100644 index 00000000..9d9989b0 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/CGIncludes/Spine-Skeleton-Tint-Common.cginc @@ -0,0 +1,27 @@ +#ifndef SKELETON_TINT_COMMON_INCLUDED +#define SKELETON_TINT_COMMON_INCLUDED + +float4 fragTintedColor(float4 texColor, float3 darkTintColor, float4 lightTintColor, float darkColorAlpha) { + + float a = texColor.a * lightTintColor.a; + +#if !defined(_STRAIGHT_ALPHA_INPUT) + float3 texDarkColor = (texColor.a - texColor.rgb); +#else + float3 texDarkColor = (1 - texColor.rgb); +#endif + float3 darkColor = texDarkColor * darkTintColor.rgb; + float3 lightColor = texColor.rgb * lightTintColor.rgb; + + float4 fragColor = float4(darkColor + lightColor, a); +#if defined(_STRAIGHT_ALPHA_INPUT) + fragColor.rgb *= fragColor.a; +#endif + +#if defined(_DARK_COLOR_ALPHA_ADDITIVE) + fragColor.a = a * (1 - darkColorAlpha); +#endif + return fragColor; +} + +#endif diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/CGIncludes/Spine-Skeleton-Tint-Common.cginc.meta b/box1/Assets/Spine/Runtime/spine-unity/Shaders/CGIncludes/Spine-Skeleton-Tint-Common.cginc.meta new file mode 100644 index 00000000..333f4c1f --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/CGIncludes/Spine-Skeleton-Tint-Common.cginc.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: cc9439c8e75fb7e4c82ad725b649b047 +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline.meta b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline.meta new file mode 100644 index 00000000..a058eebc --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: e8c87a44b93daed4383ca2ca5dfb3c43 +folderAsset: yes +timeCreated: 1573827942 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/BlendModes.meta b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/BlendModes.meta new file mode 100644 index 00000000..cf3eaf42 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/BlendModes.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 6a7bd28c2cf2e41499693d9f8f9e2e1a +folderAsset: yes +timeCreated: 1573829102 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/BlendModes/Spine-Skeleton-PMA-Additive-Outline.shader b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/BlendModes/Spine-Skeleton-PMA-Additive-Outline.shader new file mode 100644 index 00000000..ded84bb8 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/BlendModes/Spine-Skeleton-PMA-Additive-Outline.shader @@ -0,0 +1,46 @@ +// Outline shader variant of "Spine/Blend Modes/Skeleton PMA Additive" + +Shader "Spine/Outline/Blend Modes/Skeleton PMA Additive" { + Properties { + _Color ("Tint Color", Color) = (1,1,1,1) + [NoScaleOffset] _MainTex ("MainTex", 2D) = "black" {} + [Toggle(_STRAIGHT_ALPHA_INPUT)] _StraightAlphaInput("Straight Alpha Texture", Int) = 0 + _Cutoff ("Shadow alpha cutoff", Range(0,1)) = 0.1 + [HideInInspector] _StencilRef("Stencil Reference", Float) = 1.0 + [HideInInspector][Enum(UnityEngine.Rendering.CompareFunction)] _StencilComp("Stencil Comparison", Float) = 8 // Set to Always as default + + // Outline properties are drawn via custom editor. + [HideInInspector] _OutlineWidth("Outline Width", Range(0,8)) = 3.0 + [HideInInspector] _OutlineColor("Outline Color", Color) = (1,1,0,1) + [HideInInspector] _OutlineReferenceTexWidth("Reference Texture Width", Int) = 1024 + [HideInInspector] _ThresholdEnd("Outline Threshold", Range(0,1)) = 0.25 + [HideInInspector] _OutlineSmoothness("Outline Smoothness", Range(0,1)) = 1.0 + [HideInInspector][MaterialToggle(_USE8NEIGHBOURHOOD_ON)] _Use8Neighbourhood("Sample 8 Neighbours", Float) = 1 + [HideInInspector] _OutlineMipLevel("Outline Mip Level", Range(0,3)) = 0 + } + + SubShader { + Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" } + LOD 100 + + Fog { Mode Off } + Cull Off + ZWrite Off + Blend One One + Lighting Off + + Stencil { + Ref[_StencilRef] + Comp[_StencilComp] + Pass Keep + } + + UsePass "Spine/Outline/Skeleton/OUTLINE" + + UsePass "Spine/Blend Modes/Skeleton PMA Additive/NORMAL" + + UsePass "Spine/Blend Modes/Skeleton PMA Additive/CASTER" + } + FallBack "Spine/Blend Modes/Skeleton PMA Additive" + CustomEditor "SpineShaderWithOutlineGUI" +} diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/BlendModes/Spine-Skeleton-PMA-Additive-Outline.shader.meta b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/BlendModes/Spine-Skeleton-PMA-Additive-Outline.shader.meta new file mode 100644 index 00000000..4e5f97b8 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/BlendModes/Spine-Skeleton-PMA-Additive-Outline.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 0299ffae826705448b6c80ccc6a53b75 +timeCreated: 1573829476 +licenseType: Free +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/BlendModes/Spine-Skeleton-PMA-Multiply-Outline.shader b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/BlendModes/Spine-Skeleton-PMA-Multiply-Outline.shader new file mode 100644 index 00000000..3ef828f2 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/BlendModes/Spine-Skeleton-PMA-Multiply-Outline.shader @@ -0,0 +1,46 @@ +// Outline shader variant of "Spine/Blend Modes/Skeleton PMA Multiply" + +Shader "Spine/Outline/Blend Modes/Skeleton PMA Multiply" { + Properties { + _Color ("Tint Color", Color) = (1,1,1,1) + [NoScaleOffset] _MainTex ("MainTex", 2D) = "black" {} + [Toggle(_STRAIGHT_ALPHA_INPUT)] _StraightAlphaInput("Straight Alpha Texture", Int) = 0 + _Cutoff ("Shadow alpha cutoff", Range(0,1)) = 0.1 + [HideInInspector] _StencilRef("Stencil Reference", Float) = 1.0 + [HideInInspector][Enum(UnityEngine.Rendering.CompareFunction)] _StencilComp("Stencil Comparison", Float) = 8 // Set to Always as default + + // Outline properties are drawn via custom editor. + [HideInInspector] _OutlineWidth("Outline Width", Range(0,8)) = 3.0 + [HideInInspector] _OutlineColor("Outline Color", Color) = (1,1,0,1) + [HideInInspector] _OutlineReferenceTexWidth("Reference Texture Width", Int) = 1024 + [HideInInspector] _ThresholdEnd("Outline Threshold", Range(0,1)) = 0.25 + [HideInInspector] _OutlineSmoothness("Outline Smoothness", Range(0,1)) = 1.0 + [HideInInspector][MaterialToggle(_USE8NEIGHBOURHOOD_ON)] _Use8Neighbourhood("Sample 8 Neighbours", Float) = 1 + [HideInInspector] _OutlineMipLevel("Outline Mip Level", Range(0,3)) = 0 + } + + SubShader { + Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" } + LOD 100 + + Fog { Mode Off } + Cull Off + ZWrite Off + Blend DstColor OneMinusSrcAlpha + Lighting Off + + Stencil { + Ref[_StencilRef] + Comp[_StencilComp] + Pass Keep + } + + UsePass "Spine/Outline/Skeleton/OUTLINE" + + UsePass "Spine/Blend Modes/Skeleton PMA Multiply/NORMAL" + + UsePass "Spine/Blend Modes/Skeleton PMA Multiply/CASTER" + } + FallBack "Spine/Blend Modes/Skeleton PMA Multiply" + CustomEditor "SpineShaderWithOutlineGUI" +} diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/BlendModes/Spine-Skeleton-PMA-Multiply-Outline.shader.meta b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/BlendModes/Spine-Skeleton-PMA-Multiply-Outline.shader.meta new file mode 100644 index 00000000..741a24eb --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/BlendModes/Spine-Skeleton-PMA-Multiply-Outline.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 4b3566a937643b8498d1ec6df5880b77 +timeCreated: 1573829476 +licenseType: Free +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/BlendModes/Spine-Skeleton-PMA-Screen-Outline.shader b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/BlendModes/Spine-Skeleton-PMA-Screen-Outline.shader new file mode 100644 index 00000000..9a935604 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/BlendModes/Spine-Skeleton-PMA-Screen-Outline.shader @@ -0,0 +1,46 @@ +// Outline shader variant of "Spine/Blend Modes/Skeleton PMA Screen" + +Shader "Spine/Outline/Blend Modes/Skeleton PMA Screen" { + Properties { + _Color ("Tint Color", Color) = (1,1,1,1) + [NoScaleOffset] _MainTex ("MainTex", 2D) = "black" {} + [Toggle(_STRAIGHT_ALPHA_INPUT)] _StraightAlphaInput("Straight Alpha Texture", Int) = 0 + _Cutoff ("Shadow alpha cutoff", Range(0,1)) = 0.1 + [HideInInspector] _StencilRef("Stencil Reference", Float) = 1.0 + [HideInInspector][Enum(UnityEngine.Rendering.CompareFunction)] _StencilComp("Stencil Comparison", Float) = 8 // Set to Always as default + + // Outline properties are drawn via custom editor. + [HideInInspector] _OutlineWidth("Outline Width", Range(0,8)) = 3.0 + [HideInInspector] _OutlineColor("Outline Color", Color) = (1,1,0,1) + [HideInInspector] _OutlineReferenceTexWidth("Reference Texture Width", Int) = 1024 + [HideInInspector] _ThresholdEnd("Outline Threshold", Range(0,1)) = 0.25 + [HideInInspector] _OutlineSmoothness("Outline Smoothness", Range(0,1)) = 1.0 + [HideInInspector][MaterialToggle(_USE8NEIGHBOURHOOD_ON)] _Use8Neighbourhood("Sample 8 Neighbours", Float) = 1 + [HideInInspector] _OutlineMipLevel("Outline Mip Level", Range(0,3)) = 0 + } + + SubShader { + Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" } + LOD 100 + + Fog { Mode Off } + Cull Off + ZWrite Off + Blend One OneMinusSrcColor + Lighting Off + + Stencil { + Ref[_StencilRef] + Comp[_StencilComp] + Pass Keep + } + + UsePass "Spine/Outline/Skeleton/OUTLINE" + + UsePass "Spine/Blend Modes/Skeleton PMA Screen/NORMAL" + + UsePass "Spine/Blend Modes/Skeleton PMA Screen/CASTER" + } + FallBack "Spine/Blend Modes/Skeleton PMA Screen" + CustomEditor "SpineShaderWithOutlineGUI" +} diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/BlendModes/Spine-Skeleton-PMA-Screen-Outline.shader.meta b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/BlendModes/Spine-Skeleton-PMA-Screen-Outline.shader.meta new file mode 100644 index 00000000..bfb5ad6c --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/BlendModes/Spine-Skeleton-PMA-Screen-Outline.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: e61a8d94e453ff641a7e39c4b11cac95 +timeCreated: 1573829476 +licenseType: Free +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/CGIncludes.meta b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/CGIncludes.meta new file mode 100644 index 00000000..42c97866 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/CGIncludes.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 329bda94bce571446a1a149b53ccf45c +folderAsset: yes +timeCreated: 1574096529 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/CGIncludes/Spine-Outline-Pass.cginc b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/CGIncludes/Spine-Outline-Pass.cginc new file mode 100644 index 00000000..7ed2a286 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/CGIncludes/Spine-Outline-Pass.cginc @@ -0,0 +1,119 @@ +#ifndef SPINE_OUTLINE_PASS_INCLUDED +#define SPINE_OUTLINE_PASS_INCLUDED + +#include "UnityCG.cginc" + +#ifdef SKELETON_GRAPHIC +#include "UnityUI.cginc" +#endif + +sampler2D _MainTex; + +float _OutlineWidth; +float4 _OutlineColor; +float4 _MainTex_TexelSize; +float _ThresholdEnd; +float _OutlineSmoothness; +float _OutlineMipLevel; +int _OutlineReferenceTexWidth; + +#ifdef SKELETON_GRAPHIC +float4 _ClipRect; +#endif + +struct VertexInput { + float4 vertex : POSITION; + float2 uv : TEXCOORD0; + float4 vertexColor : COLOR; + UNITY_VERTEX_INPUT_INSTANCE_ID +}; + +struct VertexOutput { + float4 pos : SV_POSITION; + float2 uv : TEXCOORD0; + float vertexColorAlpha : COLOR; +#ifdef SKELETON_GRAPHIC + float4 worldPosition : TEXCOORD1; +#endif + UNITY_VERTEX_OUTPUT_STEREO +}; + + +#ifdef SKELETON_GRAPHIC + +VertexOutput vertOutlineGraphic(VertexInput v) { + VertexOutput o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + + o.worldPosition = v.vertex; + o.pos = UnityObjectToClipPos(o.worldPosition); + o.uv = v.uv; + +#ifdef UNITY_HALF_TEXEL_OFFSET + o.pos.xy += (_ScreenParams.zw - 1.0) * float2(-1, 1); +#endif + + o.vertexColorAlpha = v.vertexColor.a; + return o; +} + +#else // !SKELETON_GRAPHIC + +VertexOutput vertOutline(VertexInput v) { + VertexOutput o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + + o.pos = UnityObjectToClipPos(v.vertex); + o.uv = v.uv; + o.vertexColorAlpha = v.vertexColor.a; + return o; +} +#endif + +float4 fragOutline(VertexOutput i) : SV_Target { + + float4 texColor = fixed4(0,0,0,0); + + float outlineWidthCompensated = _OutlineWidth / (_OutlineReferenceTexWidth * _MainTex_TexelSize.x); + float xOffset = _MainTex_TexelSize.x * outlineWidthCompensated; + float yOffset = _MainTex_TexelSize.y * outlineWidthCompensated; + float xOffsetDiagonal = _MainTex_TexelSize.x * outlineWidthCompensated * 0.7; + float yOffsetDiagonal = _MainTex_TexelSize.y * outlineWidthCompensated * 0.7; + + float pixelCenter = tex2D(_MainTex, i.uv).a; + + float4 uvCenterWithLod = float4(i.uv, 0, _OutlineMipLevel); + float pixelTop = tex2Dlod(_MainTex, uvCenterWithLod + float4(0, yOffset, 0, 0)).a; + float pixelBottom = tex2Dlod(_MainTex, uvCenterWithLod + float4(0, -yOffset, 0, 0)).a; + float pixelLeft = tex2Dlod(_MainTex, uvCenterWithLod + float4(-xOffset, 0, 0, 0)).a; + float pixelRight = tex2Dlod(_MainTex, uvCenterWithLod + float4(xOffset, 0, 0, 0)).a; +#if _USE8NEIGHBOURHOOD_ON + float numSamples = 8; + float pixelTopLeft = tex2Dlod(_MainTex, uvCenterWithLod + float4(-xOffsetDiagonal, yOffsetDiagonal, 0, 0)).a; + float pixelTopRight = tex2Dlod(_MainTex, uvCenterWithLod + float4(xOffsetDiagonal, yOffsetDiagonal, 0, 0)).a; + float pixelBottomLeft = tex2Dlod(_MainTex, uvCenterWithLod + float4(-xOffsetDiagonal, -yOffsetDiagonal, 0, 0)).a; + float pixelBottomRight = tex2Dlod(_MainTex, uvCenterWithLod + float4(xOffsetDiagonal, -yOffsetDiagonal, 0, 0)).a; + float average = (pixelTop + pixelBottom + pixelLeft + pixelRight + + pixelTopLeft + pixelTopRight + pixelBottomLeft + pixelBottomRight) + * i.vertexColorAlpha / numSamples; +#else // 4 neighbourhood + float numSamples = 1; + float average = (pixelTop + pixelBottom + pixelLeft + pixelRight) * i.vertexColorAlpha / numSamples; +#endif + + float thresholdStart = _ThresholdEnd * (1.0 - _OutlineSmoothness); + float outlineAlpha = saturate((average - thresholdStart) / (_ThresholdEnd - thresholdStart)) - pixelCenter; + texColor.rgba = lerp(texColor, _OutlineColor, outlineAlpha); + +#ifdef SKELETON_GRAPHIC + texColor *= UnityGet2DClipping(i.worldPosition.xy, _ClipRect); +#endif + + return texColor; +} + +#endif // SPINE_OUTLINE_PASS_INCLUDED diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/CGIncludes/Spine-Outline-Pass.cginc.meta b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/CGIncludes/Spine-Outline-Pass.cginc.meta new file mode 100644 index 00000000..f67e757c --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/CGIncludes/Spine-Outline-Pass.cginc.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 2ec781e799f97504c8a418e168759f70 +timeCreated: 1574096529 +licenseType: Free +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/SkeletonGraphic.meta b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/SkeletonGraphic.meta new file mode 100644 index 00000000..230f1709 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/SkeletonGraphic.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 6e8ed065898e65f4d9303492725fb912 +folderAsset: yes +timeCreated: 1573829873 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/SkeletonGraphic/Spine-SkeletonGraphic-Outline.shader b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/SkeletonGraphic/Spine-SkeletonGraphic-Outline.shader new file mode 100644 index 00000000..05f279ea --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/SkeletonGraphic/Spine-SkeletonGraphic-Outline.shader @@ -0,0 +1,75 @@ +// Outline shader variant of "Spine/SkeletonGraphic" + +Shader "Spine/Outline/SkeletonGraphic" +{ + Properties + { + [PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {} + [Toggle(_STRAIGHT_ALPHA_INPUT)] _StraightAlphaInput("Straight Alpha Texture", Int) = 0 + [Toggle(_CANVAS_GROUP_COMPATIBLE)] _CanvasGroupCompatible("CanvasGroup Compatible", Int) = 0 + _Color ("Tint", Color) = (1,1,1,1) + + [HideInInspector][Enum(UnityEngine.Rendering.CompareFunction)] _StencilComp ("Stencil Comparison", Float) = 8 + [HideInInspector] _Stencil ("Stencil ID", Float) = 0 + [HideInInspector][Enum(UnityEngine.Rendering.StencilOp)] _StencilOp ("Stencil Operation", Float) = 0 + [HideInInspector] _StencilWriteMask ("Stencil Write Mask", Float) = 255 + [HideInInspector] _StencilReadMask ("Stencil Read Mask", Float) = 255 + + [HideInInspector] _ColorMask ("Color Mask", Float) = 15 + + [Toggle(UNITY_UI_ALPHACLIP)] _UseUIAlphaClip ("Use Alpha Clip", Float) = 0 + + // Outline properties are drawn via custom editor. + [HideInInspector] _OutlineWidth("Outline Width", Range(0,8)) = 3.0 + [HideInInspector] _OutlineColor("Outline Color", Color) = (1,1,0,1) + [HideInInspector] _OutlineReferenceTexWidth("Reference Texture Width", Int) = 1024 + [HideInInspector] _ThresholdEnd("Outline Threshold", Range(0,1)) = 0.25 + [HideInInspector] _OutlineSmoothness("Outline Smoothness", Range(0,1)) = 1.0 + [HideInInspector][MaterialToggle(_USE8NEIGHBOURHOOD_ON)] _Use8Neighbourhood("Sample 8 Neighbours", Float) = 1 + [HideInInspector] _OutlineMipLevel("Outline Mip Level", Range(0,3)) = 0 + } + + SubShader + { + Tags + { + "Queue"="Transparent" + "IgnoreProjector"="True" + "RenderType"="Transparent" + "PreviewType"="Plane" + "CanUseSpriteAtlas"="True" + } + + Stencil + { + Ref [_Stencil] + Comp [_StencilComp] + Pass [_StencilOp] + ReadMask [_StencilReadMask] + WriteMask [_StencilWriteMask] + } + + Cull Off + Lighting Off + ZWrite Off + ZTest [unity_GUIZTestMode] + Fog { Mode Off } + Blend One OneMinusSrcAlpha + ColorMask [_ColorMask] + + Pass { + Name "Outline" + CGPROGRAM + #pragma vertex vertOutlineGraphic + #pragma fragment fragOutline + #define SKELETON_GRAPHIC + #pragma shader_feature _ _USE8NEIGHBOURHOOD_ON + #include "../CGIncludes/Spine-Outline-Pass.cginc" + ENDCG + } + + UsePass "Spine/SkeletonGraphic/NORMAL" + } + FallBack "Spine/SkeletonGraphic" + CustomEditor "SpineShaderWithOutlineGUI" +} diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/SkeletonGraphic/Spine-SkeletonGraphic-Outline.shader.meta b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/SkeletonGraphic/Spine-SkeletonGraphic-Outline.shader.meta new file mode 100644 index 00000000..2968808e --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/SkeletonGraphic/Spine-SkeletonGraphic-Outline.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 8f5d14d2a7fedb84998c50eb96c8b748 +timeCreated: 1573829873 +licenseType: Free +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/SkeletonGraphic/Spine-SkeletonGraphic-TintBlack-Outline.shader b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/SkeletonGraphic/Spine-SkeletonGraphic-TintBlack-Outline.shader new file mode 100644 index 00000000..f739f114 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/SkeletonGraphic/Spine-SkeletonGraphic-TintBlack-Outline.shader @@ -0,0 +1,68 @@ +// Outline shader variant of "Spine/SkeletonGraphic Tint Black" + +Shader "Spine/Outline/SkeletonGraphic Tint Black" +{ + Properties + { + [PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {} + [Toggle(_STRAIGHT_ALPHA_INPUT)] _StraightAlphaInput("Straight Alpha Texture", Int) = 0 + [Toggle(_CANVAS_GROUP_COMPATIBLE)] _CanvasGroupCompatible("CanvasGroup Compatible", Int) = 0 + + _Color ("Tint", Color) = (1,1,1,1) + _Black ("Black Point", Color) = (0,0,0,0) + + [HideInInspector][Enum(UnityEngine.Rendering.CompareFunction)] _StencilComp ("Stencil Comparison", Float) = 8 + [HideInInspector] _Stencil ("Stencil ID", Float) = 0 + [HideInInspector][Enum(UnityEngine.Rendering.StencilOp)] _StencilOp ("Stencil Operation", Float) = 0 + [HideInInspector] _StencilWriteMask ("Stencil Write Mask", Float) = 255 + [HideInInspector] _StencilReadMask ("Stencil Read Mask", Float) = 255 + + [HideInInspector] _ColorMask ("Color Mask", Float) = 15 + + [Toggle(UNITY_UI_ALPHACLIP)] _UseUIAlphaClip ("Use Alpha Clip", Float) = 0 + + // Outline properties are drawn via custom editor. + [HideInInspector] _OutlineWidth("Outline Width", Range(0,8)) = 3.0 + [HideInInspector] _OutlineColor("Outline Color", Color) = (1,1,0,1) + [HideInInspector] _OutlineReferenceTexWidth("Reference Texture Width", Int) = 1024 + [HideInInspector] _ThresholdEnd("Outline Threshold", Range(0,1)) = 0.25 + [HideInInspector] _OutlineSmoothness("Outline Smoothness", Range(0,1)) = 1.0 + [HideInInspector][MaterialToggle(_USE8NEIGHBOURHOOD_ON)] _Use8Neighbourhood("Sample 8 Neighbours", Float) = 1 + [HideInInspector] _OutlineMipLevel("Outline Mip Level", Range(0,3)) = 0 + } + + SubShader + { + Tags + { + "Queue"="Transparent" + "IgnoreProjector"="True" + "RenderType"="Transparent" + "PreviewType"="Plane" + "CanUseSpriteAtlas"="True" + } + + Stencil + { + Ref [_Stencil] + Comp [_StencilComp] + Pass [_StencilOp] + ReadMask [_StencilReadMask] + WriteMask [_StencilWriteMask] + } + + Cull Off + Lighting Off + ZWrite Off + ZTest [unity_GUIZTestMode] + Fog { Mode Off } + Blend One OneMinusSrcAlpha + ColorMask [_ColorMask] + + UsePass "Spine/Outline/SkeletonGraphic/OUTLINE" + + UsePass "Spine/SkeletonGraphic Tint Black/NORMAL" + } + FallBack "Spine/SkeletonGraphic Tint Black" + CustomEditor "SpineShaderWithOutlineGUI" +} diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/SkeletonGraphic/Spine-SkeletonGraphic-TintBlack-Outline.shader.meta b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/SkeletonGraphic/Spine-SkeletonGraphic-TintBlack-Outline.shader.meta new file mode 100644 index 00000000..a35c5b2e --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/SkeletonGraphic/Spine-SkeletonGraphic-TintBlack-Outline.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: d55d64dd09c46af40a319933a62fa1b2 +timeCreated: 1573830121 +licenseType: Free +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Spine-Skeleton-Fill-Outline.shader b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Spine-Skeleton-Fill-Outline.shader new file mode 100644 index 00000000..fc254517 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Spine-Skeleton-Fill-Outline.shader @@ -0,0 +1,43 @@ +// Outline shader variant of "Spine/Skeleton Fill" + +Shader "Spine/Outline/Skeleton Fill" { + Properties { + _FillColor ("FillColor", Color) = (1,1,1,1) + _FillPhase ("FillPhase", Range(0, 1)) = 0 + [NoScaleOffset] _MainTex ("MainTex", 2D) = "white" {} + _Cutoff ("Shadow alpha cutoff", Range(0,1)) = 0.1 + [Toggle(_STRAIGHT_ALPHA_INPUT)] _StraightAlphaInput("Straight Alpha Texture", Int) = 0 + [HideInInspector] _StencilRef("Stencil Reference", Float) = 1.0 + [HideInInspector][Enum(UnityEngine.Rendering.CompareFunction)] _StencilComp("Stencil Comparison", Float) = 8 // Set to Always as default + + // Outline properties are drawn via custom editor. + [HideInInspector] _OutlineWidth("Outline Width", Range(0,8)) = 3.0 + [HideInInspector] _OutlineColor("Outline Color", Color) = (1,1,0,1) + [HideInInspector] _OutlineReferenceTexWidth("Reference Texture Width", Int) = 1024 + [HideInInspector] _ThresholdEnd("Outline Threshold", Range(0,1)) = 0.25 + [HideInInspector] _OutlineSmoothness("Outline Smoothness", Range(0,1)) = 1.0 + [HideInInspector][MaterialToggle(_USE8NEIGHBOURHOOD_ON)] _Use8Neighbourhood("Sample 8 Neighbours", Float) = 1 + [HideInInspector] _OutlineMipLevel("Outline Mip Level", Range(0,3)) = 0 + } + SubShader { + Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" "PreviewType"="Plane" } + Blend One OneMinusSrcAlpha + Cull Off + ZWrite Off + Lighting Off + + Stencil { + Ref[_StencilRef] + Comp[_StencilComp] + Pass Keep + } + + UsePass "Spine/Outline/Skeleton/OUTLINE" + + UsePass "Spine/Skeleton Fill/NORMAL" + + UsePass "Spine/Skeleton Fill/CASTER" + } + FallBack "Spine/Skeleton Fill" + CustomEditor "SpineShaderWithOutlineGUI" +} diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Spine-Skeleton-Fill-Outline.shader.meta b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Spine-Skeleton-Fill-Outline.shader.meta new file mode 100644 index 00000000..3793896d --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Spine-Skeleton-Fill-Outline.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: e158cbe58baa093438feb3d691f3daba +timeCreated: 1573817434 +licenseType: Free +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Spine-Skeleton-Lit-Outline.shader b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Spine-Skeleton-Lit-Outline.shader new file mode 100644 index 00000000..75c0a9f5 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Spine-Skeleton-Lit-Outline.shader @@ -0,0 +1,40 @@ +// Outline shader variant of "Spine/Skeleton Lit" + +Shader "Spine/Outline/Skeleton Lit" { + Properties { + _Cutoff ("Shadow alpha cutoff", Range(0,1)) = 0.1 + [NoScaleOffset] _MainTex ("Main Texture", 2D) = "black" {} + [Toggle(_STRAIGHT_ALPHA_INPUT)] _StraightAlphaInput("Straight Alpha Texture", Int) = 0 + [Toggle(_DOUBLE_SIDED_LIGHTING)] _DoubleSidedLighting("Double-Sided Lighting", Int) = 0 + [HideInInspector] _StencilRef("Stencil Reference", Float) = 1.0 + [HideInInspector][Enum(UnityEngine.Rendering.CompareFunction)] _StencilComp("Stencil Comparison", Float) = 8 // Set to Always as default + + // Outline properties are drawn via custom editor. + [HideInInspector] _OutlineWidth("Outline Width", Range(0,8)) = 3.0 + [HideInInspector] _OutlineColor("Outline Color", Color) = (1,1,0,1) + [HideInInspector] _OutlineReferenceTexWidth("Reference Texture Width", Int) = 1024 + [HideInInspector] _ThresholdEnd("Outline Threshold", Range(0,1)) = 0.25 + [HideInInspector] _OutlineSmoothness("Outline Smoothness", Range(0,1)) = 1.0 + [HideInInspector][MaterialToggle(_USE8NEIGHBOURHOOD_ON)] _Use8Neighbourhood("Sample 8 Neighbours", Float) = 1 + [HideInInspector] _OutlineMipLevel("Outline Mip Level", Range(0,3)) = 0 + } + + SubShader { + Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" } + LOD 100 + + Stencil { + Ref[_StencilRef] + Comp[_StencilComp] + Pass Keep + } + + UsePass "Spine/Outline/Skeleton/OUTLINE" + + UsePass "Spine/Skeleton Lit/NORMAL" + + UsePass "Spine/Skeleton Lit/CASTER" + } + FallBack "Spine/Skeleton Lit" + CustomEditor "SpineShaderWithOutlineGUI" +} diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Spine-Skeleton-Lit-Outline.shader.meta b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Spine-Skeleton-Lit-Outline.shader.meta new file mode 100644 index 00000000..4dd9501b --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Spine-Skeleton-Lit-Outline.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 10fab3f69a099be4391fe8a1ad880c65 +timeCreated: 1573828963 +licenseType: Free +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Spine-Skeleton-Lit-ZWrite-Outline.shader b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Spine-Skeleton-Lit-ZWrite-Outline.shader new file mode 100644 index 00000000..04430856 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Spine-Skeleton-Lit-ZWrite-Outline.shader @@ -0,0 +1,41 @@ +// Outline shader variant of "Spine/Skeleton Lit ZWrite" + +Shader "Spine/Outline/Skeleton Lit ZWrite" { + Properties { + _Cutoff ("Depth alpha cutoff", Range(0,1)) = 0.1 + _ShadowAlphaCutoff ("Shadow alpha cutoff", Range(0,1)) = 0.1 + [NoScaleOffset] _MainTex ("Main Texture", 2D) = "black" {} + [Toggle(_STRAIGHT_ALPHA_INPUT)] _StraightAlphaInput("Straight Alpha Texture", Int) = 0 + [Toggle(_DOUBLE_SIDED_LIGHTING)] _DoubleSidedLighting("Double-Sided Lighting", Int) = 0 + [HideInInspector] _StencilRef("Stencil Reference", Float) = 1.0 + [HideInInspector][Enum(UnityEngine.Rendering.CompareFunction)] _StencilComp("Stencil Comparison", Float) = 8 // Set to Always as default + + // Outline properties are drawn via custom editor. + [HideInInspector] _OutlineWidth("Outline Width", Range(0,8)) = 3.0 + [HideInInspector] _OutlineColor("Outline Color", Color) = (1,1,0,1) + [HideInInspector] _OutlineReferenceTexWidth("Reference Texture Width", Int) = 1024 + [HideInInspector] _ThresholdEnd("Outline Threshold", Range(0,1)) = 0.25 + [HideInInspector] _OutlineSmoothness("Outline Smoothness", Range(0,1)) = 1.0 + [HideInInspector][MaterialToggle(_USE8NEIGHBOURHOOD_ON)] _Use8Neighbourhood("Sample 8 Neighbours", Float) = 1 + [HideInInspector] _OutlineMipLevel("Outline Mip Level", Range(0,3)) = 0 + } + + SubShader { + Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" } + LOD 100 + + Stencil { + Ref[_StencilRef] + Comp[_StencilComp] + Pass Keep + } + + UsePass "Spine/Outline/Skeleton/OUTLINE" + + UsePass "Spine/Skeleton Lit ZWrite/NORMAL" + + UsePass "Spine/Skeleton Lit ZWrite/CASTER" + } + FallBack "Spine/Skeleton Lit ZWrite" + CustomEditor "SpineShaderWithOutlineGUI" +} diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Spine-Skeleton-Lit-ZWrite-Outline.shader.meta b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Spine-Skeleton-Lit-ZWrite-Outline.shader.meta new file mode 100644 index 00000000..e772ed45 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Spine-Skeleton-Lit-ZWrite-Outline.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 756be4f2f738f6c4583bb1c90e16bf0b +timeCreated: 1573828964 +licenseType: Free +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Spine-Skeleton-Outline.shader b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Spine-Skeleton-Outline.shader new file mode 100644 index 00000000..e60ef068 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Spine-Skeleton-Outline.shader @@ -0,0 +1,52 @@ +// Outline shader variant of "Spine/Skeleton" + +Shader "Spine/Outline/Skeleton" { + Properties { + _Cutoff ("Shadow alpha cutoff", Range(0,1)) = 0.1 + [NoScaleOffset] _MainTex ("Main Texture", 2D) = "black" {} + [Toggle(_STRAIGHT_ALPHA_INPUT)] _StraightAlphaInput("Straight Alpha Texture", Int) = 0 + [HideInInspector] _StencilRef("Stencil Reference", Float) = 1.0 + [HideInInspector][Enum(UnityEngine.Rendering.CompareFunction)] _StencilComp("Stencil Comparison", Float) = 8 // Set to Always as default + + // Outline properties are drawn via custom editor. + [HideInInspector] _OutlineWidth("Outline Width", Range(0,8)) = 3.0 + [HideInInspector] _OutlineColor("Outline Color", Color) = (1,1,0,1) + [HideInInspector] _OutlineReferenceTexWidth("Reference Texture Width", Int) = 1024 + [HideInInspector] _ThresholdEnd("Outline Threshold", Range(0,1)) = 0.25 + [HideInInspector] _OutlineSmoothness("Outline Smoothness", Range(0,1)) = 1.0 + [HideInInspector][MaterialToggle(_USE8NEIGHBOURHOOD_ON)] _Use8Neighbourhood("Sample 8 Neighbours", Float) = 1 + [HideInInspector] _OutlineMipLevel("Outline Mip Level", Range(0,3)) = 0 + } + + SubShader { + Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" "PreviewType"="Plane" } + + Fog { Mode Off } + Cull Off + ZWrite Off + Blend One OneMinusSrcAlpha + Lighting Off + + Stencil { + Ref[_StencilRef] + Comp[_StencilComp] + Pass Keep + } + + Pass { + Name "Outline" + CGPROGRAM + #pragma vertex vertOutline + #pragma fragment fragOutline + #pragma shader_feature _ _USE8NEIGHBOURHOOD_ON + #include "CGIncludes/Spine-Outline-Pass.cginc" + ENDCG + } + + UsePass "Spine/Skeleton/NORMAL" + + UsePass "Spine/Skeleton/CASTER" + } + FallBack "Spine/Skeleton" + CustomEditor "SpineShaderWithOutlineGUI" +} diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Spine-Skeleton-Outline.shader.meta b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Spine-Skeleton-Outline.shader.meta new file mode 100644 index 00000000..e7dcd76e --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Spine-Skeleton-Outline.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 28b5cf4804845fe4b868531fd0bb81d5 +timeCreated: 1573817434 +licenseType: Free +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Spine-Skeleton-OutlineOnly-ZWrite.shader b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Spine-Skeleton-OutlineOnly-ZWrite.shader new file mode 100644 index 00000000..82dc8cf7 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Spine-Skeleton-OutlineOnly-ZWrite.shader @@ -0,0 +1,62 @@ +Shader "Spine/Outline/OutlineOnly-ZWrite" { + Properties { + _Cutoff ("Depth alpha cutoff", Range(0,1)) = 0.1 + _ZWriteOffset ("Depth offset", Range(0,1)) = 0.01 + [NoScaleOffset] _MainTex ("Main Texture", 2D) = "black" {} + [Toggle(_STRAIGHT_ALPHA_INPUT)] _StraightAlphaInput("Straight Alpha Texture", Int) = 0 + [HideInInspector] _StencilRef("Stencil Reference", Float) = 1.0 + [HideInInspector][Enum(UnityEngine.Rendering.CompareFunction)] _StencilComp("Stencil Comparison", Float) = 8 // Set to Always as default + + // Outline properties are drawn via custom editor. + [HideInInspector] _OutlineWidth("Outline Width", Range(0,8)) = 3.0 + [HideInInspector] _OutlineColor("Outline Color", Color) = (1,1,0,1) + [HideInInspector] _OutlineReferenceTexWidth("Reference Texture Width", Int) = 1024 + [HideInInspector] _ThresholdEnd("Outline Threshold", Range(0,1)) = 0.25 + [HideInInspector] _OutlineSmoothness("Outline Smoothness", Range(0,1)) = 1.0 + [HideInInspector][MaterialToggle(_USE8NEIGHBOURHOOD_ON)] _Use8Neighbourhood("Sample 8 Neighbours", Float) = 1 + [HideInInspector] _OutlineMipLevel("Outline Mip Level", Range(0,3)) = 0 + } + + SubShader { + Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" "PreviewType"="Plane" } + + Fog { Mode Off } + Cull Off + ZWrite Off + Blend One OneMinusSrcAlpha + Lighting Off + + Stencil { + Ref[_StencilRef] + Comp[_StencilComp] + Pass Keep + } + + Pass + { + Name "DepthOnly" + + ZWrite On + ColorMask 0 + Cull Off + + CGPROGRAM + #pragma vertex DepthOnlyVertex + #pragma fragment DepthOnlyFragment + #include "../CGIncludes/Spine-DepthOnlyPass.cginc" + ENDCG + } + + Pass { + Name "Outline" + CGPROGRAM + #pragma vertex vertOutline + #pragma fragment fragOutline + #pragma shader_feature _ _USE8NEIGHBOURHOOD_ON + #include "CGIncludes/Spine-Outline-Pass.cginc" + ENDCG + } + } + FallBack "Spine/Skeleton" + CustomEditor "SpineShaderWithOutlineGUI" +} diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Spine-Skeleton-OutlineOnly-ZWrite.shader.meta b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Spine-Skeleton-OutlineOnly-ZWrite.shader.meta new file mode 100644 index 00000000..9e289558 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Spine-Skeleton-OutlineOnly-ZWrite.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 177da18c3d2e0aa4cb39990ea011973c +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Spine-Skeleton-Tint-Outline.shader b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Spine-Skeleton-Tint-Outline.shader new file mode 100644 index 00000000..2b385f88 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Spine-Skeleton-Tint-Outline.shader @@ -0,0 +1,46 @@ +// Outline shader variant of "Spine/Skeleton Tint" + +Shader "Spine/Outline/Skeleton Tint" { + Properties { + _Color ("Tint Color", Color) = (1,1,1,1) + _Black ("Black Point", Color) = (0,0,0,0) + [NoScaleOffset] _MainTex ("MainTex", 2D) = "black" {} + [Toggle(_STRAIGHT_ALPHA_INPUT)] _StraightAlphaInput("Straight Alpha Texture", Int) = 0 + _Cutoff("Shadow alpha cutoff", Range(0,1)) = 0.1 + [HideInInspector] _StencilRef("Stencil Reference", Float) = 1.0 + [HideInInspector][Enum(UnityEngine.Rendering.CompareFunction)] _StencilComp("Stencil Comparison", Float) = 8 // Set to Always as default + + // Outline properties are drawn via custom editor. + [HideInInspector] _OutlineWidth("Outline Width", Range(0,8)) = 3.0 + [HideInInspector] _OutlineColor("Outline Color", Color) = (1,1,0,1) + [HideInInspector] _OutlineReferenceTexWidth("Reference Texture Width", Int) = 1024 + [HideInInspector] _ThresholdEnd("Outline Threshold", Range(0,1)) = 0.25 + [HideInInspector] _OutlineSmoothness("Outline Smoothness", Range(0,1)) = 1.0 + [HideInInspector][MaterialToggle(_USE8NEIGHBOURHOOD_ON)] _Use8Neighbourhood("Sample 8 Neighbours", Float) = 1 + [HideInInspector] _OutlineMipLevel("Outline Mip Level", Range(0,3)) = 0 + } + + SubShader { + Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" "PreviewType"="Plane" } + + Fog { Mode Off } + Cull Off + ZWrite Off + Blend One OneMinusSrcAlpha + Lighting Off + + Stencil { + Ref[_StencilRef] + Comp[_StencilComp] + Pass Keep + } + + UsePass "Spine/Outline/Skeleton/OUTLINE" + + UsePass "Spine/Skeleton Tint/NORMAL" + + UsePass "Spine/Skeleton Tint/CASTER" + } + FallBack "Spine/Skeleton Tint" + CustomEditor "SpineShaderWithOutlineGUI" +} diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Spine-Skeleton-Tint-Outline.shader.meta b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Spine-Skeleton-Tint-Outline.shader.meta new file mode 100644 index 00000000..e5d5456d --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Spine-Skeleton-Tint-Outline.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 4f1fdc166fed03649835949d3b79cba3 +timeCreated: 1573817434 +licenseType: Free +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Spine-Skeleton-TintBlack-Outline.shader b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Spine-Skeleton-TintBlack-Outline.shader new file mode 100644 index 00000000..64afad4e --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Spine-Skeleton-TintBlack-Outline.shader @@ -0,0 +1,47 @@ +// Outline shader variant of "Spine/Skeleton Tint Black" + +Shader "Spine/Outline/Skeleton Tint Black" { + Properties { + _Color ("Tint Color", Color) = (1,1,1,1) + _Black ("Black Point", Color) = (0,0,0,0) + [NoScaleOffset] _MainTex ("MainTex", 2D) = "black" {} + [Toggle(_STRAIGHT_ALPHA_INPUT)] _StraightAlphaInput("Straight Alpha Texture", Int) = 0 + _Cutoff ("Shadow alpha cutoff", Range(0,1)) = 0.1 + [HideInInspector] _StencilRef("Stencil Reference", Float) = 1.0 + [HideInInspector][Enum(UnityEngine.Rendering.CompareFunction)] _StencilComp("Stencil Comparison", Float) = 8 // Set to Always as default + + // Outline properties are drawn via custom editor. + [HideInInspector] _OutlineWidth("Outline Width", Range(0,8)) = 3.0 + [HideInInspector] _OutlineColor("Outline Color", Color) = (1,1,0,1) + [HideInInspector] _OutlineReferenceTexWidth("Reference Texture Width", Int) = 1024 + [HideInInspector] _ThresholdEnd("Outline Threshold", Range(0,1)) = 0.25 + [HideInInspector] _OutlineSmoothness("Outline Smoothness", Range(0,1)) = 1.0 + [HideInInspector][MaterialToggle(_USE8NEIGHBOURHOOD_ON)] _Use8Neighbourhood("Sample 8 Neighbours", Float) = 1 + [HideInInspector] _OutlineMipLevel("Outline Mip Level", Range(0,3)) = 0 + } + + SubShader { + Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" } + LOD 100 + + Fog { Mode Off } + Cull Off + ZWrite Off + Blend One OneMinusSrcAlpha + Lighting Off + + Stencil { + Ref[_StencilRef] + Comp[_StencilComp] + Pass Keep + } + + UsePass "Spine/Outline/Skeleton/OUTLINE" + + UsePass "Spine/Skeleton Tint Black/NORMAL" + + UsePass "Spine/Skeleton Tint Black/CASTER" + } + FallBack "Spine/Special/Skeleton Grayscale" + CustomEditor "SpineShaderWithOutlineGUI" +} diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Spine-Skeleton-TintBlack-Outline.shader.meta b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Spine-Skeleton-TintBlack-Outline.shader.meta new file mode 100644 index 00000000..8bbce16a --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Spine-Skeleton-TintBlack-Outline.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 49cf725a1e40e7742be92917f83946c3 +timeCreated: 1573828963 +licenseType: Free +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Spine-Special-Skeleton-Grayscale-Outline.shader b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Spine-Special-Skeleton-Grayscale-Outline.shader new file mode 100644 index 00000000..722ed75b --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Spine-Special-Skeleton-Grayscale-Outline.shader @@ -0,0 +1,43 @@ +// Outline shader variant of "Spine/Special/Skeleton Grayscale" + +Shader "Spine/Outline/Special/Skeleton Grayscale" { + Properties { + _GrayPhase ("Phase", Range(0, 1)) = 1 + [NoScaleOffset] _MainTex ("MainTex", 2D) = "white" {} + _Cutoff ("Shadow alpha cutoff", Range(0,1)) = 0.1 + [Toggle(_STRAIGHT_ALPHA_INPUT)] _StraightAlphaInput("Straight Alpha Texture", Int) = 0 + [HideInInspector] _StencilRef("Stencil Reference", Float) = 1.0 + [HideInInspector][Enum(UnityEngine.Rendering.CompareFunction)] _StencilComp("Stencil Comparison", Float) = 8 // Set to Always as default + + // Outline properties are drawn via custom editor. + [HideInInspector] _OutlineWidth("Outline Width", Range(0,8)) = 3.0 + [HideInInspector] _OutlineColor("Outline Color", Color) = (1,1,0,1) + [HideInInspector] _OutlineReferenceTexWidth("Reference Texture Width", Int) = 1024 + [HideInInspector] _ThresholdEnd("Outline Threshold", Range(0,1)) = 0.25 + [HideInInspector] _OutlineSmoothness("Outline Smoothness", Range(0,1)) = 1.0 + [HideInInspector][MaterialToggle(_USE8NEIGHBOURHOOD_ON)] _Use8Neighbourhood("Sample 8 Neighbours", Float) = 1 + [HideInInspector] _OutlineMipLevel("Outline Mip Level", Range(0,3)) = 0 + } + + SubShader { + Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" "PreviewType"="Plane" } + Blend One OneMinusSrcAlpha + Cull Off + ZWrite Off + Lighting Off + + Stencil { + Ref[_StencilRef] + Comp[_StencilComp] + Pass Keep + } + + UsePass "Spine/Outline/Skeleton/OUTLINE" + + UsePass "Spine/Special/Skeleton Grayscale/NORMAL" + + UsePass "Spine/Special/Skeleton Grayscale/CASTER" + } + FallBack "Spine/Special/Skeleton Grayscale" + CustomEditor "SpineShaderWithOutlineGUI" +} diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Spine-Special-Skeleton-Grayscale-Outline.shader.meta b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Spine-Special-Skeleton-Grayscale-Outline.shader.meta new file mode 100644 index 00000000..5f17b0bb --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Spine-Special-Skeleton-Grayscale-Outline.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 1d3e1518ae643a749b086bc7972893d2 +timeCreated: 1573828963 +licenseType: Free +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Sprite.meta b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Sprite.meta new file mode 100644 index 00000000..fff5fc63 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Sprite.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 615182d5e489bf3478299e5bbf15dc23 +folderAsset: yes +timeCreated: 1573830740 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Sprite/SpritesPixelLit-Outline.shader b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Sprite/SpritesPixelLit-Outline.shader new file mode 100644 index 00000000..844a990e --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Sprite/SpritesPixelLit-Outline.shader @@ -0,0 +1,81 @@ +// Outline shader variant of "Spine/Sprite/Pixel Lit" + +Shader "Spine/Outline/Sprite/Pixel Lit" +{ + Properties + { + _MainTex ("Main Texture", 2D) = "white" {} + _Color ("Color", Color) = (1,1,1,1) + + _BumpScale("Scale", Float) = 1.0 + _BumpMap ("Normal Map", 2D) = "bump" {} + + [MaterialToggle] PixelSnap ("Pixel snap", Float) = 0 + + _EmissionColor("Color", Color) = (0,0,0,0) + _EmissionMap("Emission", 2D) = "white" {} + _EmissionPower("Emission Power", Float) = 2.0 + + _Glossiness("Smoothness", Range(0.0, 1.0)) = 0.5 + _GlossMapScale("Smoothness Scale", Range(0.0, 1.0)) = 1.0 + [Gamma] _Metallic("Metallic", Range(0.0, 1.0)) = 0.0 + _MetallicGlossMap("Metallic", 2D) = "white" {} + + _DiffuseRamp ("Diffuse Ramp Texture", 2D) = "gray" {} + + _FixedNormal ("Fixed Normal", Vector) = (0,0,1,1) + _Cutoff ("Depth alpha cutoff", Range(0,1)) = 0.5 + _ShadowAlphaCutoff ("Shadow alpha cutoff", Range(0,1)) = 0.1 + _CustomRenderQueue ("Custom Render Queue", Float) = 0.0 + + _OverlayColor ("Overlay Color", Color) = (0,0,0,0) + _Hue("Hue", Range(-0.5,0.5)) = 0.0 + _Saturation("Saturation", Range(0,2)) = 1.0 + _Brightness("Brightness", Range(0,2)) = 1.0 + + _RimPower("Rim Power", Float) = 2.0 + _RimColor ("Rim Color", Color) = (1,1,1,1) + + _BlendTex ("Blend Texture", 2D) = "white" {} + _BlendAmount ("Blend", Range(0,1)) = 0.0 + + [HideInInspector] _SrcBlend ("__src", Float) = 1.0 + [HideInInspector] _DstBlend ("__dst", Float) = 0.0 + [HideInInspector] _RenderQueue ("__queue", Float) = 0.0 + [HideInInspector] _Cull ("__cull", Float) = 0.0 + [HideInInspector] _StencilRef("Stencil Reference", Float) = 1.0 + [HideInInspector][Enum(UnityEngine.Rendering.CompareFunction)] _StencilComp("Stencil Comparison", Float) = 8 // Set to Always as default + + // Outline properties are drawn via custom editor. + [HideInInspector] _OutlineWidth("Outline Width", Range(0,8)) = 3.0 + [HideInInspector] _OutlineColor("Outline Color", Color) = (1,1,0,1) + [HideInInspector] _OutlineReferenceTexWidth("Reference Texture Width", Int) = 1024 + [HideInInspector] _ThresholdEnd("Outline Threshold", Range(0,1)) = 0.25 + [HideInInspector] _OutlineSmoothness("Outline Smoothness", Range(0,1)) = 1.0 + [HideInInspector][MaterialToggle(_USE8NEIGHBOURHOOD_ON)] _Use8Neighbourhood("Sample 8 Neighbours", Float) = 1 + [HideInInspector] _OutlineMipLevel("Outline Mip Level", Range(0,3)) = 0 + } + + SubShader + { + Tags { "Queue"="Transparent" "RenderType"="Sprite" "AlphaDepth"="False" "CanUseSpriteAtlas"="True" "IgnoreProjector"="True" } + LOD 200 + + Stencil { + Ref[_StencilRef] + Comp[_StencilComp] + Pass Keep + } + + UsePass "Spine/Outline/Skeleton/OUTLINE" + + UsePass "Spine/Sprite/Pixel Lit/FORWARD" + + UsePass "Spine/Sprite/Pixel Lit/FORWARD_DELTA" + + UsePass "Spine/Sprite/Pixel Lit/SHADOWCASTER" + } + + FallBack "Spine/Sprite/Pixel Lit" + CustomEditor "SpineSpriteShaderGUI" +} diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Sprite/SpritesPixelLit-Outline.shader.meta b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Sprite/SpritesPixelLit-Outline.shader.meta new file mode 100644 index 00000000..963554e0 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Sprite/SpritesPixelLit-Outline.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: a27d4b27c8ecd9840a03558ccc5ad8a3 +timeCreated: 1573830741 +licenseType: Free +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Sprite/SpritesUnlit-Outline.shader b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Sprite/SpritesUnlit-Outline.shader new file mode 100644 index 00000000..756f7da3 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Sprite/SpritesUnlit-Outline.shader @@ -0,0 +1,61 @@ +// Outline shader variant of "Spine/Sprite/Unlit" + +Shader "Spine/Outline/Sprite/Unlit" +{ + Properties + { + _MainTex ("Main Texture", 2D) = "white" {} + _Color ("Color", Color) = (1,1,1,1) + + [MaterialToggle] PixelSnap ("Pixel snap", Float) = 0 + + _ZWrite ("Depth Write", Float) = 0.0 + _Cutoff ("Depth alpha cutoff", Range(0,1)) = 0.0 + _ShadowAlphaCutoff ("Shadow alpha cutoff", Range(0,1)) = 0.1 + _CustomRenderQueue ("Custom Render Queue", Float) = 0.0 + + _OverlayColor ("Overlay Color", Color) = (0,0,0,0) + _Hue("Hue", Range(-0.5,0.5)) = 0.0 + _Saturation("Saturation", Range(0,2)) = 1.0 + _Brightness("Brightness", Range(0,2)) = 1.0 + + _BlendTex ("Blend Texture", 2D) = "white" {} + _BlendAmount ("Blend", Range(0,1)) = 0.0 + + [HideInInspector] _SrcBlend ("__src", Float) = 1.0 + [HideInInspector] _DstBlend ("__dst", Float) = 0.0 + [HideInInspector] _RenderQueue ("__queue", Float) = 0.0 + [HideInInspector] _Cull ("__cull", Float) = 0.0 + [HideInInspector] _StencilRef("Stencil Reference", Float) = 1.0 + [HideInInspector][Enum(UnityEngine.Rendering.CompareFunction)] _StencilComp("Stencil Comparison", Float) = 8 // Set to Always as default + + // Outline properties are drawn via custom editor. + [HideInInspector] _OutlineWidth("Outline Width", Range(0,8)) = 3.0 + [HideInInspector] _OutlineColor("Outline Color", Color) = (1,1,0,1) + [HideInInspector] _OutlineReferenceTexWidth("Reference Texture Width", Int) = 1024 + [HideInInspector] _ThresholdEnd("Outline Threshold", Range(0,1)) = 0.25 + [HideInInspector] _OutlineSmoothness("Outline Smoothness", Range(0,1)) = 1.0 + [HideInInspector][MaterialToggle(_USE8NEIGHBOURHOOD_ON)] _Use8Neighbourhood("Sample 8 Neighbours", Float) = 1 + [HideInInspector] _OutlineMipLevel("Outline Mip Level", Range(0,3)) = 0 + } + + SubShader + { + Tags { "Queue"="Transparent" "RenderType"="Sprite" "AlphaDepth"="False" "CanUseSpriteAtlas"="True" "IgnoreProjector"="True" } + LOD 100 + + Stencil { + Ref[_StencilRef] + Comp[_StencilComp] + Pass Keep + } + + UsePass "Spine/Outline/Skeleton/OUTLINE" + + UsePass "Spine/Sprite/Unlit/NORMAL" + + UsePass "Spine/Sprite/Unlit/SHADOWCASTER" + } + FallBack "Spine/Sprite/Unlit" + CustomEditor "SpineSpriteShaderGUI" +} diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Sprite/SpritesUnlit-Outline.shader.meta b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Sprite/SpritesUnlit-Outline.shader.meta new file mode 100644 index 00000000..0ab75345 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Sprite/SpritesUnlit-Outline.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 276c07e3bdd5719458187a5823e9d96a +timeCreated: 1573830740 +licenseType: Free +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Sprite/SpritesVertexLit-Outline.shader b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Sprite/SpritesVertexLit-Outline.shader new file mode 100644 index 00000000..6e087dd0 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Sprite/SpritesVertexLit-Outline.shader @@ -0,0 +1,80 @@ +// Outline shader variant of "Spine/Sprite/Vertex Lit" + +Shader "Spine/Outline/Sprite/Vertex Lit" +{ + Properties + { + _MainTex ("Main Texture", 2D) = "white" {} + _Color ("Color", Color) = (1,1,1,1) + + _BumpScale("Scale", Float) = 1.0 + _BumpMap ("Normal Map", 2D) = "bump" {} + + [MaterialToggle] PixelSnap ("Pixel snap", Float) = 0 + + _EmissionColor("Color", Color) = (0,0,0,0) + _EmissionMap("Emission", 2D) = "white" {} + _EmissionPower("Emission Power", Float) = 2.0 + + _Glossiness("Smoothness", Range(0.0, 1.0)) = 0.5 + _GlossMapScale("Smoothness Scale", Range(0.0, 1.0)) = 1.0 + [Gamma] _Metallic("Metallic", Range(0.0, 1.0)) = 0.0 + _MetallicGlossMap("Metallic", 2D) = "white" {} + + _DiffuseRamp ("Diffuse Ramp Texture", 2D) = "gray" {} + + _FixedNormal ("Fixed Normal", Vector) = (0,0,1,1) + _ZWrite ("Depth Write", Float) = 0.0 + _Cutoff ("Depth alpha cutoff", Range(0,1)) = 0.0 + _ShadowAlphaCutoff ("Shadow alpha cutoff", Range(0,1)) = 0.1 + _CustomRenderQueue ("Custom Render Queue", Float) = 0.0 + + _OverlayColor ("Overlay Color", Color) = (0,0,0,0) + _Hue("Hue", Range(-0.5,0.5)) = 0.0 + _Saturation("Saturation", Range(0,2)) = 1.0 + _Brightness("Brightness", Range(0,2)) = 1.0 + + _RimPower("Rim Power", Float) = 2.0 + _RimColor ("Rim Color", Color) = (1,1,1,1) + + _BlendTex ("Blend Texture", 2D) = "white" {} + _BlendAmount ("Blend", Range(0,1)) = 0.0 + + [HideInInspector] _SrcBlend ("__src", Float) = 1.0 + [HideInInspector] _DstBlend ("__dst", Float) = 0.0 + [HideInInspector] _RenderQueue ("__queue", Float) = 0.0 + [HideInInspector] _Cull ("__cull", Float) = 0.0 + [HideInInspector] _StencilRef("Stencil Reference", Float) = 1.0 + [HideInInspector][Enum(UnityEngine.Rendering.CompareFunction)] _StencilComp("Stencil Comparison", Float) = 8 // Set to Always as default + + // Outline properties are drawn via custom editor. + [HideInInspector] _OutlineWidth("Outline Width", Range(0,8)) = 3.0 + [HideInInspector] _OutlineColor("Outline Color", Color) = (1,1,0,1) + [HideInInspector] _OutlineReferenceTexWidth("Reference Texture Width", Int) = 1024 + [HideInInspector] _ThresholdEnd("Outline Threshold", Range(0,1)) = 0.25 + [HideInInspector] _OutlineSmoothness("Outline Smoothness", Range(0,1)) = 1.0 + [HideInInspector][MaterialToggle(_USE8NEIGHBOURHOOD_ON)] _Use8Neighbourhood("Sample 8 Neighbours", Float) = 1 + [HideInInspector] _OutlineMipLevel("Outline Mip Level", Range(0,3)) = 0 + } + + SubShader + { + Tags { "Queue"="Transparent" "RenderType"="Sprite" "AlphaDepth"="False" "CanUseSpriteAtlas"="True" "IgnoreProjector"="True" } + LOD 150 + + Stencil { + Ref[_StencilRef] + Comp[_StencilComp] + Pass Keep + } + + UsePass "Spine/Outline/Skeleton/OUTLINE" + + UsePass "Spine/Sprite/Vertex Lit/VERTEX" + + UsePass "Spine/Sprite/Vertex Lit/SHADOWCASTER" + } + + FallBack "Spine/Sprite/Vertex Lit" + CustomEditor "SpineSpriteShaderGUI" +} diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Sprite/SpritesVertexLit-Outline.shader.meta b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Sprite/SpritesVertexLit-Outline.shader.meta new file mode 100644 index 00000000..baa2bcfa --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Sprite/SpritesVertexLit-Outline.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 30ef5dd318033004588a6481c092416a +timeCreated: 1573830740 +licenseType: Free +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/SkeletonGraphic.meta b/box1/Assets/Spine/Runtime/spine-unity/Shaders/SkeletonGraphic.meta new file mode 100644 index 00000000..0314067e --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/SkeletonGraphic.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 7a42d52714848d64f8ff99dddb93500e +folderAsset: yes +timeCreated: 1563289150 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/SkeletonGraphic/Spine-SkeletonGraphic-TintBlack.shader b/box1/Assets/Spine/Runtime/spine-unity/Shaders/SkeletonGraphic/Spine-SkeletonGraphic-TintBlack.shader new file mode 100644 index 00000000..16954aca --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/SkeletonGraphic/Spine-SkeletonGraphic-TintBlack.shader @@ -0,0 +1,146 @@ +// This is a premultiply-alpha adaptation of the built-in Unity shader "UI/Default" to allow Unity UI stencil masking. + +Shader "Spine/SkeletonGraphic Tint Black" +{ + Properties + { + [PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {} + [Toggle(_STRAIGHT_ALPHA_INPUT)] _StraightAlphaInput("Straight Alpha Texture", Int) = 0 + [Toggle(_CANVAS_GROUP_COMPATIBLE)] _CanvasGroupCompatible("CanvasGroup Compatible", Int) = 0 + + _Color ("Tint Color", Color) = (1,1,1,1) + _Black ("Dark Color", Color) = (0,0,0,0) + [Toggle(_DARK_COLOR_ALPHA_ADDITIVE)] _DarkColorAlphaAdditive("Additive DarkColor.A", Int) = 0 + + [HideInInspector][Enum(UnityEngine.Rendering.CompareFunction)] _StencilComp ("Stencil Comparison", Float) = 8 + [HideInInspector] _Stencil ("Stencil ID", Float) = 0 + [HideInInspector][Enum(UnityEngine.Rendering.StencilOp)] _StencilOp ("Stencil Operation", Float) = 0 + [HideInInspector] _StencilWriteMask ("Stencil Write Mask", Float) = 255 + [HideInInspector] _StencilReadMask ("Stencil Read Mask", Float) = 255 + + [HideInInspector] _ColorMask ("Color Mask", Float) = 15 + + [Toggle(UNITY_UI_ALPHACLIP)] _UseUIAlphaClip ("Use Alpha Clip", Float) = 0 + + // Outline properties are drawn via custom editor. + [HideInInspector] _OutlineWidth("Outline Width", Range(0,8)) = 3.0 + [HideInInspector] _OutlineColor("Outline Color", Color) = (1,1,0,1) + [HideInInspector] _OutlineReferenceTexWidth("Reference Texture Width", Int) = 1024 + [HideInInspector] _ThresholdEnd("Outline Threshold", Range(0,1)) = 0.25 + [HideInInspector] _OutlineSmoothness("Outline Smoothness", Range(0,1)) = 1.0 + [HideInInspector][MaterialToggle(_USE8NEIGHBOURHOOD_ON)] _Use8Neighbourhood("Sample 8 Neighbours", Float) = 1 + [HideInInspector] _OutlineMipLevel("Outline Mip Level", Range(0,3)) = 0 + } + + SubShader + { + Tags + { + "Queue"="Transparent" + "IgnoreProjector"="True" + "RenderType"="Transparent" + "PreviewType"="Plane" + "CanUseSpriteAtlas"="True" + } + + Stencil + { + Ref [_Stencil] + Comp [_StencilComp] + Pass [_StencilOp] + ReadMask [_StencilReadMask] + WriteMask [_StencilWriteMask] + } + + Cull Off + Lighting Off + ZWrite Off + ZTest [unity_GUIZTestMode] + Fog { Mode Off } + Blend One OneMinusSrcAlpha + ColorMask [_ColorMask] + + Pass + { + Name "Normal" + + CGPROGRAM + #pragma shader_feature _ _STRAIGHT_ALPHA_INPUT + #pragma shader_feature _ _CANVAS_GROUP_COMPATIBLE + #pragma shader_feature _ _DARK_COLOR_ALPHA_ADDITIVE + #pragma vertex vert + #pragma fragment frag + + #include "UnityCG.cginc" + #include "UnityUI.cginc" + + #pragma multi_compile __ UNITY_UI_ALPHACLIP + + struct VertexInput { + float4 vertex : POSITION; + float4 color : COLOR; + float2 texcoord : TEXCOORD0; + float2 uv1 : TEXCOORD1; + float2 uv2 : TEXCOORD2; + UNITY_VERTEX_INPUT_INSTANCE_ID + }; + + struct VertexOutput { + float4 vertex : SV_POSITION; + fixed4 color : COLOR; + half2 texcoord : TEXCOORD0; + float4 darkColor : TEXCOORD1; + float4 worldPosition : TEXCOORD2; + UNITY_VERTEX_OUTPUT_STEREO + }; + + fixed4 _Color; + fixed4 _Black; + fixed4 _TextureSampleAdd; + float4 _ClipRect; + + VertexOutput vert (VertexInput IN) { + VertexOutput OUT; + + UNITY_SETUP_INSTANCE_ID(IN); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(OUT); + + OUT.worldPosition = IN.vertex; + OUT.vertex = UnityObjectToClipPos(OUT.worldPosition); + OUT.texcoord = IN.texcoord; + + OUT.color = IN.color * _Color; + OUT.darkColor = float4(IN.uv1.r, IN.uv1.g, IN.uv2.r, IN.uv2.g); + return OUT; + } + + sampler2D _MainTex; + #include "../CGIncludes/Spine-Skeleton-Tint-Common.cginc" + + fixed4 frag (VertexOutput IN) : SV_Target + { + half4 texColor = (tex2D(_MainTex, IN.texcoord) + _TextureSampleAdd); + texColor *= UnityGet2DClipping(IN.worldPosition.xy, _ClipRect); + #ifdef UNITY_UI_ALPHACLIP + clip(texColor.a - 0.001); + #endif + + float4 vertexColor = IN.color; + #ifdef _CANVAS_GROUP_COMPATIBLE + // CanvasGroup alpha multiplies existing vertex color alpha, but + // does not premultiply it to rgb components. This causes problems + // with additive blending (alpha = 0), which is why we store the + // alpha value in uv2.g (darkColor.a). + vertexColor.a = IN.darkColor.a; + #endif + float4 fragColor = fragTintedColor(texColor, _Black.rgb + IN.darkColor, vertexColor, _Black.a); + #ifdef _CANVAS_GROUP_COMPATIBLE + fragColor.rgba *= IN.color.a; + #endif + return fragColor; + } + ENDCG + } + } + CustomEditor "SpineShaderWithOutlineGUI" +} diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/SkeletonGraphic/Spine-SkeletonGraphic-TintBlack.shader.meta b/box1/Assets/Spine/Runtime/spine-unity/Shaders/SkeletonGraphic/Spine-SkeletonGraphic-TintBlack.shader.meta new file mode 100644 index 00000000..5193a269 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/SkeletonGraphic/Spine-SkeletonGraphic-TintBlack.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: f64c7bc238bb2c246b8ca1912b2b6b9c +timeCreated: 1455080068 +licenseType: Free +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/SkeletonGraphic/Spine-SkeletonGraphic.shader b/box1/Assets/Spine/Runtime/spine-unity/Shaders/SkeletonGraphic/Spine-SkeletonGraphic.shader new file mode 100644 index 00000000..d01657b0 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/SkeletonGraphic/Spine-SkeletonGraphic.shader @@ -0,0 +1,141 @@ +// This is a premultiply-alpha adaptation of the built-in Unity shader "UI/Default" in Unity 5.6.2 to allow Unity UI stencil masking. + +Shader "Spine/SkeletonGraphic" +{ + Properties + { + [PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {} + [Toggle(_STRAIGHT_ALPHA_INPUT)] _StraightAlphaInput("Straight Alpha Texture", Int) = 0 + [Toggle(_CANVAS_GROUP_COMPATIBLE)] _CanvasGroupCompatible("CanvasGroup Compatible", Int) = 0 + _Color ("Tint", Color) = (1,1,1,1) + + [HideInInspector][Enum(UnityEngine.Rendering.CompareFunction)] _StencilComp ("Stencil Comparison", Float) = 8 + [HideInInspector] _Stencil ("Stencil ID", Float) = 0 + [HideInInspector][Enum(UnityEngine.Rendering.StencilOp)] _StencilOp ("Stencil Operation", Float) = 0 + [HideInInspector] _StencilWriteMask ("Stencil Write Mask", Float) = 255 + [HideInInspector] _StencilReadMask ("Stencil Read Mask", Float) = 255 + + [HideInInspector] _ColorMask ("Color Mask", Float) = 15 + + [Toggle(UNITY_UI_ALPHACLIP)] _UseUIAlphaClip ("Use Alpha Clip", Float) = 0 + + // Outline properties are drawn via custom editor. + [HideInInspector] _OutlineWidth("Outline Width", Range(0,8)) = 3.0 + [HideInInspector] _OutlineColor("Outline Color", Color) = (1,1,0,1) + [HideInInspector] _OutlineReferenceTexWidth("Reference Texture Width", Int) = 1024 + [HideInInspector] _ThresholdEnd("Outline Threshold", Range(0,1)) = 0.25 + [HideInInspector] _OutlineSmoothness("Outline Smoothness", Range(0,1)) = 1.0 + [HideInInspector][MaterialToggle(_USE8NEIGHBOURHOOD_ON)] _Use8Neighbourhood("Sample 8 Neighbours", Float) = 1 + [HideInInspector] _OutlineMipLevel("Outline Mip Level", Range(0,3)) = 0 + } + + SubShader + { + Tags + { + "Queue"="Transparent" + "IgnoreProjector"="True" + "RenderType"="Transparent" + "PreviewType"="Plane" + "CanUseSpriteAtlas"="True" + } + + Stencil + { + Ref [_Stencil] + Comp [_StencilComp] + Pass [_StencilOp] + ReadMask [_StencilReadMask] + WriteMask [_StencilWriteMask] + } + + Cull Off + Lighting Off + ZWrite Off + ZTest [unity_GUIZTestMode] + Fog { Mode Off } + Blend One OneMinusSrcAlpha + ColorMask [_ColorMask] + + Pass + { + Name "Normal" + + CGPROGRAM + #pragma shader_feature _ _STRAIGHT_ALPHA_INPUT + #pragma shader_feature _ _CANVAS_GROUP_COMPATIBLE + #pragma vertex vert + #pragma fragment frag + #pragma target 2.0 + + #include "UnityCG.cginc" + #include "UnityUI.cginc" + + #pragma multi_compile __ UNITY_UI_ALPHACLIP + + struct VertexInput { + float4 vertex : POSITION; + float4 color : COLOR; + float2 texcoord : TEXCOORD0; + UNITY_VERTEX_INPUT_INSTANCE_ID + }; + + struct VertexOutput { + float4 vertex : SV_POSITION; + fixed4 color : COLOR; + half2 texcoord : TEXCOORD0; + float4 worldPosition : TEXCOORD1; + UNITY_VERTEX_OUTPUT_STEREO + }; + + fixed4 _Color; + fixed4 _TextureSampleAdd; + float4 _ClipRect; + + VertexOutput vert (VertexInput IN) { + VertexOutput OUT; + + UNITY_SETUP_INSTANCE_ID(IN); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(OUT); + + OUT.worldPosition = IN.vertex; + OUT.vertex = UnityObjectToClipPos(OUT.worldPosition); + OUT.texcoord = IN.texcoord; + + #ifdef UNITY_HALF_TEXEL_OFFSET + OUT.vertex.xy += (_ScreenParams.zw-1.0) * float2(-1,1); + #endif + + OUT.color = IN.color * float4(_Color.rgb * _Color.a, _Color.a); // Combine a PMA version of _Color with vertexColor. + return OUT; + } + + sampler2D _MainTex; + + fixed4 frag (VertexOutput IN) : SV_Target + { + half4 texColor = tex2D(_MainTex, IN.texcoord); + + #if defined(_STRAIGHT_ALPHA_INPUT) + texColor.rgb *= texColor.a; + #endif + + half4 color = (texColor + _TextureSampleAdd) * IN.color; + #ifdef _CANVAS_GROUP_COMPATIBLE + // CanvasGroup alpha sets vertex color alpha, but does not premultiply it to rgb components. + color.rgb *= IN.color.a; + #endif + + color *= UnityGet2DClipping(IN.worldPosition.xy, _ClipRect); + + #ifdef UNITY_UI_ALPHACLIP + clip (color.a - 0.001); + #endif + + return color; + } + ENDCG + } + } + CustomEditor "SpineShaderWithOutlineGUI" +} diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/SkeletonGraphic/Spine-SkeletonGraphic.shader.meta b/box1/Assets/Spine/Runtime/spine-unity/Shaders/SkeletonGraphic/Spine-SkeletonGraphic.shader.meta new file mode 100644 index 00000000..167123f4 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/SkeletonGraphic/Spine-SkeletonGraphic.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: fa95b0fb6983c0f40a152e6f9aa82bfb +timeCreated: 1455080068 +licenseType: Free +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton-Fill.shader b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton-Fill.shader new file mode 100644 index 00000000..a02553f1 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton-Fill.shader @@ -0,0 +1,126 @@ +// - Unlit +// - Premultiplied Alpha Blending (Optional straight alpha input) +// - Double-sided, no depth + +Shader "Spine/Skeleton Fill" { + Properties { + _FillColor ("FillColor", Color) = (1,1,1,1) + _FillPhase ("FillPhase", Range(0, 1)) = 0 + [NoScaleOffset] _MainTex ("MainTex", 2D) = "white" {} + _Cutoff ("Shadow alpha cutoff", Range(0,1)) = 0.1 + [Toggle(_STRAIGHT_ALPHA_INPUT)] _StraightAlphaInput("Straight Alpha Texture", Int) = 0 + [HideInInspector] _StencilRef("Stencil Reference", Float) = 1.0 + [HideInInspector][Enum(UnityEngine.Rendering.CompareFunction)] _StencilComp("Stencil Comparison", Float) = 8 // Set to Always as default + + // Outline properties are drawn via custom editor. + [HideInInspector] _OutlineWidth("Outline Width", Range(0,8)) = 3.0 + [HideInInspector] _OutlineColor("Outline Color", Color) = (1,1,0,1) + [HideInInspector] _OutlineReferenceTexWidth("Reference Texture Width", Int) = 1024 + [HideInInspector] _ThresholdEnd("Outline Threshold", Range(0,1)) = 0.25 + [HideInInspector] _OutlineSmoothness("Outline Smoothness", Range(0,1)) = 1.0 + [HideInInspector][MaterialToggle(_USE8NEIGHBOURHOOD_ON)] _Use8Neighbourhood("Sample 8 Neighbours", Float) = 1 + [HideInInspector] _OutlineMipLevel("Outline Mip Level", Range(0,3)) = 0 + } + SubShader { + Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" "PreviewType"="Plane" } + Blend One OneMinusSrcAlpha + Cull Off + ZWrite Off + Lighting Off + + Stencil { + Ref[_StencilRef] + Comp[_StencilComp] + Pass Keep + } + + Pass { + Name "Normal" + + CGPROGRAM + #pragma shader_feature _ _STRAIGHT_ALPHA_INPUT + #pragma vertex vert + #pragma fragment frag + #include "UnityCG.cginc" + sampler2D _MainTex; + float4 _FillColor; + float _FillPhase; + + struct VertexInput { + float4 vertex : POSITION; + float2 uv : TEXCOORD0; + float4 vertexColor : COLOR; + }; + + struct VertexOutput { + float4 pos : SV_POSITION; + float2 uv : TEXCOORD0; + float4 vertexColor : COLOR; + }; + + VertexOutput vert (VertexInput v) { + VertexOutput o = (VertexOutput)0; + o.uv = v.uv; + o.vertexColor = v.vertexColor; + o.pos = UnityObjectToClipPos(v.vertex); + return o; + } + + float4 frag (VertexOutput i) : SV_Target { + float4 rawColor = tex2D(_MainTex,i.uv); + float finalAlpha = (rawColor.a * i.vertexColor.a); + + #if defined(_STRAIGHT_ALPHA_INPUT) + rawColor.rgb *= rawColor.a; + #endif + + float3 finalColor = lerp((rawColor.rgb * i.vertexColor.rgb), (_FillColor.rgb * finalAlpha), _FillPhase); // make sure to PMA _FillColor. + return fixed4(finalColor, finalAlpha); + } + ENDCG + } + + Pass { + Name "Caster" + Tags { "LightMode"="ShadowCaster" } + Offset 1, 1 + ZWrite On + ZTest LEqual + + Fog { Mode Off } + Cull Off + Lighting Off + + CGPROGRAM + #pragma vertex vert + #pragma fragment frag + #pragma multi_compile_shadowcaster + #pragma fragmentoption ARB_precision_hint_fastest + #include "UnityCG.cginc" + sampler2D _MainTex; + fixed _Cutoff; + + struct VertexOutput { + V2F_SHADOW_CASTER; + float4 uvAndAlpha : TEXCOORD1; + }; + + VertexOutput vert (appdata_base v, float4 vertexColor : COLOR) { + VertexOutput o; + o.uvAndAlpha = v.texcoord; + o.uvAndAlpha.a = vertexColor.a; + TRANSFER_SHADOW_CASTER(o) + return o; + } + + float4 frag (VertexOutput i) : SV_Target { + fixed4 texcol = tex2D(_MainTex, i.uvAndAlpha.xy); + clip(texcol.a * i.uvAndAlpha.a - _Cutoff); + SHADOW_CASTER_FRAGMENT(i) + } + ENDCG + } + } + FallBack "Diffuse" + CustomEditor "SpineShaderWithOutlineGUI" +} diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton-Fill.shader.meta b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton-Fill.shader.meta new file mode 100644 index 00000000..c71933eb --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton-Fill.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 45495790b394f894a967dbf44489b57b +timeCreated: 1492385797 +licenseType: Free +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton-Lit-ZWrite.shader b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton-Lit-ZWrite.shader new file mode 100644 index 00000000..95f77b77 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton-Lit-ZWrite.shader @@ -0,0 +1,82 @@ +// - Vertex Lit + ShadowCaster +// - Premultiplied Alpha Blending (Optional straight alpha input) +// - Double-sided, ZWrite + +Shader "Spine/Skeleton Lit ZWrite" { + Properties { + _Cutoff ("Depth alpha cutoff", Range(0,1)) = 0.1 + _ShadowAlphaCutoff ("Shadow alpha cutoff", Range(0,1)) = 0.1 + [NoScaleOffset] _MainTex ("Main Texture", 2D) = "black" {} + [Toggle(_STRAIGHT_ALPHA_INPUT)] _StraightAlphaInput("Straight Alpha Texture", Int) = 0 + [Toggle(_DOUBLE_SIDED_LIGHTING)] _DoubleSidedLighting("Double-Sided Lighting", Int) = 0 + [HideInInspector] _StencilRef("Stencil Reference", Float) = 1.0 + [HideInInspector][Enum(UnityEngine.Rendering.CompareFunction)] _StencilComp("Stencil Comparison", Float) = 8 // Set to Always as default + + // Outline properties are drawn via custom editor. + [HideInInspector] _OutlineWidth("Outline Width", Range(0,8)) = 3.0 + [HideInInspector] _OutlineColor("Outline Color", Color) = (1,1,0,1) + [HideInInspector] _OutlineReferenceTexWidth("Reference Texture Width", Int) = 1024 + [HideInInspector] _ThresholdEnd("Outline Threshold", Range(0,1)) = 0.25 + [HideInInspector] _OutlineSmoothness("Outline Smoothness", Range(0,1)) = 1.0 + [HideInInspector][MaterialToggle(_USE8NEIGHBOURHOOD_ON)] _Use8Neighbourhood("Sample 8 Neighbours", Float) = 1 + [HideInInspector] _OutlineMipLevel("Outline Mip Level", Range(0,3)) = 0 + } + + SubShader { + Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" } + LOD 100 + + Stencil { + Ref[_StencilRef] + Comp[_StencilComp] + Pass Keep + } + + Pass { + Name "Normal" + + Tags { "LightMode"="Vertex" "Queue"="Transparent" "IgnoreProjector"="true" "RenderType"="Transparent" } + + ZWrite On + Cull Off + Blend One OneMinusSrcAlpha + + CGPROGRAM + #pragma shader_feature _ _STRAIGHT_ALPHA_INPUT + #pragma shader_feature _ _DOUBLE_SIDED_LIGHTING + #pragma vertex vert + #pragma fragment frag + #pragma target 2.0 + + #define _ALPHA_CLIP + #pragma multi_compile __ POINT SPOT + #include "CGIncludes/Spine-Skeleton-Lit-Common.cginc" + ENDCG + + } + + Pass { + Name "Caster" + Tags { "LightMode"="ShadowCaster" } + Offset 1, 1 + + Fog { Mode Off } + ZWrite On + ZTest LEqual + Cull Off + Lighting Off + + CGPROGRAM + #pragma vertex vertShadow + #pragma fragment fragShadow + #pragma multi_compile_shadowcaster + #pragma fragmentoption ARB_precision_hint_fastest + + #define SHADOW_CUTOFF _ShadowAlphaCutoff + #include "CGIncludes/Spine-Skeleton-Lit-Common-Shadow.cginc" + + ENDCG + } + } + CustomEditor "SpineShaderWithOutlineGUI" +} diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton-Lit-ZWrite.shader.meta b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton-Lit-ZWrite.shader.meta new file mode 100644 index 00000000..28243a0f --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton-Lit-ZWrite.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: fde05abf1f7be4b4da1caf8c8de1823a +timeCreated: 1564082883 +licenseType: Free +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton-Lit.shader b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton-Lit.shader new file mode 100644 index 00000000..f10c478f --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton-Lit.shader @@ -0,0 +1,80 @@ +// - Vertex Lit + ShadowCaster +// - Premultiplied Alpha Blending (Optional straight alpha input) +// - Double-sided, no depth + +Shader "Spine/Skeleton Lit" { + Properties { + _Cutoff ("Shadow alpha cutoff", Range(0,1)) = 0.1 + [NoScaleOffset] _MainTex ("Main Texture", 2D) = "black" {} + [Toggle(_STRAIGHT_ALPHA_INPUT)] _StraightAlphaInput("Straight Alpha Texture", Int) = 0 + [Toggle(_DOUBLE_SIDED_LIGHTING)] _DoubleSidedLighting("Double-Sided Lighting", Int) = 0 + [HideInInspector] _StencilRef("Stencil Reference", Float) = 1.0 + [HideInInspector][Enum(UnityEngine.Rendering.CompareFunction)] _StencilComp("Stencil Comparison", Float) = 8 // Set to Always as default + + // Outline properties are drawn via custom editor. + [HideInInspector] _OutlineWidth("Outline Width", Range(0,8)) = 3.0 + [HideInInspector] _OutlineColor("Outline Color", Color) = (1,1,0,1) + [HideInInspector] _OutlineReferenceTexWidth("Reference Texture Width", Int) = 1024 + [HideInInspector] _ThresholdEnd("Outline Threshold", Range(0,1)) = 0.25 + [HideInInspector] _OutlineSmoothness("Outline Smoothness", Range(0,1)) = 1.0 + [HideInInspector][MaterialToggle(_USE8NEIGHBOURHOOD_ON)] _Use8Neighbourhood("Sample 8 Neighbours", Float) = 1 + [HideInInspector] _OutlineMipLevel("Outline Mip Level", Range(0,3)) = 0 + } + + SubShader { + Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" } + LOD 100 + + Stencil { + Ref[_StencilRef] + Comp[_StencilComp] + Pass Keep + } + + Pass { + Name "Normal" + + Tags { "LightMode"="Vertex" "Queue"="Transparent" "IgnoreProjector"="true" "RenderType"="Transparent" } + + ZWrite Off + Cull Off + Blend One OneMinusSrcAlpha + + CGPROGRAM + #pragma shader_feature _ _STRAIGHT_ALPHA_INPUT + #pragma shader_feature _ _DOUBLE_SIDED_LIGHTING + #pragma vertex vert + #pragma fragment frag + #pragma target 2.0 + + #pragma multi_compile __ POINT SPOT + #include "CGIncludes/Spine-Skeleton-Lit-Common.cginc" + ENDCG + + } + + Pass { + Name "Caster" + Tags { "LightMode"="ShadowCaster" } + Offset 1, 1 + + Fog { Mode Off } + ZWrite On + ZTest LEqual + Cull Off + Lighting Off + + CGPROGRAM + #pragma vertex vertShadow + #pragma fragment fragShadow + #pragma multi_compile_shadowcaster + #pragma fragmentoption ARB_precision_hint_fastest + + #define SHADOW_CUTOFF _Cutoff + #include "CGIncludes/Spine-Skeleton-Lit-Common-Shadow.cginc" + + ENDCG + } + } + CustomEditor "SpineShaderWithOutlineGUI" +} diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton-Lit.shader.meta b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton-Lit.shader.meta new file mode 100644 index 00000000..1d0a386d --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton-Lit.shader.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: bd83c75f51f5e23498ae22ffcdfe92c3 +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton-Tint.shader b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton-Tint.shader new file mode 100644 index 00000000..06290f60 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton-Tint.shader @@ -0,0 +1,127 @@ +// Spine/Skeleton Tint +// - Two color tint +// - unlit +// - Premultiplied alpha blending (Optional straight alpha input) +// - No depth, no backface culling, no fog. + +Shader "Spine/Skeleton Tint" { + Properties { + _Color ("Tint Color", Color) = (1,1,1,1) + _Black ("Dark Color", Color) = (0,0,0,0) + [NoScaleOffset] _MainTex ("MainTex", 2D) = "black" {} + [Toggle(_STRAIGHT_ALPHA_INPUT)] _StraightAlphaInput("Straight Alpha Texture", Int) = 0 + _Cutoff("Shadow alpha cutoff", Range(0,1)) = 0.1 + [Toggle(_DARK_COLOR_ALPHA_ADDITIVE)] _DarkColorAlphaAdditive("Additive DarkColor.A", Int) = 0 + [HideInInspector] _StencilRef("Stencil Reference", Float) = 1.0 + [HideInInspector][Enum(UnityEngine.Rendering.CompareFunction)] _StencilComp("Stencil Comparison", Float) = 8 // Set to Always as default + + // Outline properties are drawn via custom editor. + [HideInInspector] _OutlineWidth("Outline Width", Range(0,8)) = 3.0 + [HideInInspector] _OutlineColor("Outline Color", Color) = (1,1,0,1) + [HideInInspector] _OutlineReferenceTexWidth("Reference Texture Width", Int) = 1024 + [HideInInspector] _ThresholdEnd("Outline Threshold", Range(0,1)) = 0.25 + [HideInInspector] _OutlineSmoothness("Outline Smoothness", Range(0,1)) = 1.0 + [HideInInspector][MaterialToggle(_USE8NEIGHBOURHOOD_ON)] _Use8Neighbourhood("Sample 8 Neighbours", Float) = 1 + [HideInInspector] _OutlineMipLevel("Outline Mip Level", Range(0,3)) = 0 + } + + SubShader { + Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" "PreviewType"="Plane" } + + Fog { Mode Off } + Cull Off + ZWrite Off + Blend One OneMinusSrcAlpha + Lighting Off + + Stencil { + Ref[_StencilRef] + Comp[_StencilComp] + Pass Keep + } + + Pass { + Name "Normal" + + CGPROGRAM + #pragma shader_feature _ _STRAIGHT_ALPHA_INPUT + #pragma shader_feature _ _DARK_COLOR_ALPHA_ADDITIVE + #pragma vertex vert + #pragma fragment frag + #include "UnityCG.cginc" + sampler2D _MainTex; + float4 _Color; + float4 _Black; + + struct VertexInput { + float4 vertex : POSITION; + float2 uv : TEXCOORD0; + float4 vertexColor : COLOR; + }; + + struct VertexOutput { + float4 pos : SV_POSITION; + float2 uv : TEXCOORD0; + float4 vertexColor : COLOR; + }; + + VertexOutput vert (VertexInput v) { + VertexOutput o; + o.pos = UnityObjectToClipPos(v.vertex); + o.uv = v.uv; + o.vertexColor = v.vertexColor * _Color; + return o; + } + + #include "CGIncludes/Spine-Skeleton-Tint-Common.cginc" + + float4 frag (VertexOutput i) : SV_Target { + float4 texColor = tex2D(_MainTex, i.uv); + return fragTintedColor(texColor, _Black.rgb, i.vertexColor, _Black.a); + } + ENDCG + } + + Pass { + Name "Caster" + Tags { "LightMode"="ShadowCaster" } + Offset 1, 1 + ZWrite On + ZTest LEqual + + Fog { Mode Off } + Cull Off + Lighting Off + + CGPROGRAM + #pragma vertex vert + #pragma fragment frag + #pragma multi_compile_shadowcaster + #pragma fragmentoption ARB_precision_hint_fastest + #include "UnityCG.cginc" + sampler2D _MainTex; + fixed _Cutoff; + + struct VertexOutput { + V2F_SHADOW_CASTER; + float4 uvAndAlpha : TEXCOORD1; + }; + + VertexOutput vert (appdata_base v, float4 vertexColor : COLOR) { + VertexOutput o; + o.uvAndAlpha = v.texcoord; + o.uvAndAlpha.a = vertexColor.a; + TRANSFER_SHADOW_CASTER(o) + return o; + } + + float4 frag (VertexOutput i) : SV_Target { + fixed4 texcol = tex2D(_MainTex, i.uvAndAlpha.xy); + clip(texcol.a * i.uvAndAlpha.a - _Cutoff); + SHADOW_CASTER_FRAGMENT(i) + } + ENDCG + } + } + CustomEditor "SpineShaderWithOutlineGUI" +} diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton-Tint.shader.meta b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton-Tint.shader.meta new file mode 100644 index 00000000..1efeec6a --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton-Tint.shader.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 522f03282fd79be47b306e2ef4b593fd +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton-TintBlack.shader b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton-TintBlack.shader new file mode 100644 index 00000000..72b069f9 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton-TintBlack.shader @@ -0,0 +1,131 @@ +// Spine/Skeleton Tint Black +// - Two color tint +// - UV2 and UV3 as Black Tint color. +// - Final black tint is (UV black data and _Black/"Black Point") +// - unlit +// - Premultiplied alpha blending (optional straight alpha input) +// - No depth, no backface culling, no fog. + +Shader "Spine/Skeleton Tint Black" { + Properties { + _Color ("Tint Color", Color) = (1,1,1,1) + _Black ("Dark Color", Color) = (0,0,0,0) + [NoScaleOffset] _MainTex ("MainTex", 2D) = "black" {} + [Toggle(_STRAIGHT_ALPHA_INPUT)] _StraightAlphaInput("Straight Alpha Texture", Int) = 0 + _Cutoff ("Shadow alpha cutoff", Range(0,1)) = 0.1 + [Toggle(_DARK_COLOR_ALPHA_ADDITIVE)] _DarkColorAlphaAdditive("Additive DarkColor.A", Int) = 0 + [HideInInspector] _StencilRef("Stencil Reference", Float) = 1.0 + [HideInInspector][Enum(UnityEngine.Rendering.CompareFunction)] _StencilComp("Stencil Comparison", Float) = 8 // Set to Always as default + + // Outline properties are drawn via custom editor. + [HideInInspector] _OutlineWidth("Outline Width", Range(0,8)) = 3.0 + [HideInInspector] _OutlineColor("Outline Color", Color) = (1,1,0,1) + [HideInInspector] _OutlineReferenceTexWidth("Reference Texture Width", Int) = 1024 + [HideInInspector] _ThresholdEnd("Outline Threshold", Range(0,1)) = 0.25 + [HideInInspector] _OutlineSmoothness("Outline Smoothness", Range(0,1)) = 1.0 + [HideInInspector][MaterialToggle(_USE8NEIGHBOURHOOD_ON)] _Use8Neighbourhood("Sample 8 Neighbours", Float) = 1 + [HideInInspector] _OutlineMipLevel("Outline Mip Level", Range(0,3)) = 0 + } + + SubShader { + Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" } + LOD 100 + + Fog { Mode Off } + Cull Off + ZWrite Off + Blend One OneMinusSrcAlpha + Lighting Off + + Stencil { + Ref[_StencilRef] + Comp[_StencilComp] + Pass Keep + } + + Pass { + Name "Normal" + + CGPROGRAM + #pragma shader_feature _ _STRAIGHT_ALPHA_INPUT + #pragma shader_feature _ _DARK_COLOR_ALPHA_ADDITIVE + #pragma vertex vert + #pragma fragment frag + #include "UnityCG.cginc" + sampler2D _MainTex; + float4 _Color; + float4 _Black; + + struct VertexInput { + float4 vertex : POSITION; + float2 uv : TEXCOORD0; + float2 uv1 : TEXCOORD1; + float2 uv2 : TEXCOORD2; + float4 vertexColor : COLOR; + }; + + struct VertexOutput { + float4 pos : SV_POSITION; + float2 uv : TEXCOORD0; + float3 darkColor : TEXCOORD1; + float4 vertexColor : COLOR; + }; + + VertexOutput vert (VertexInput v) { + VertexOutput o; + o.pos = UnityObjectToClipPos(v.vertex); // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)' + o.uv = v.uv; + o.vertexColor = v.vertexColor * _Color; + o.darkColor = float3(v.uv1.r, v.uv1.g, v.uv2.r); + return o; + } + + #include "CGIncludes/Spine-Skeleton-Tint-Common.cginc" + + float4 frag (VertexOutput i) : SV_Target { + float4 texColor = tex2D(_MainTex, i.uv); + return fragTintedColor(texColor, _Black.rgb + i.darkColor, i.vertexColor, _Black.a); + } + ENDCG + } + + Pass { + Name "Caster" + Tags { "LightMode"="ShadowCaster" } + Offset 1, 1 + + ZWrite On + ZTest LEqual + + CGPROGRAM + #pragma vertex vert + #pragma fragment frag + #pragma multi_compile_shadowcaster + #pragma fragmentoption ARB_precision_hint_fastest + #include "UnityCG.cginc" + sampler2D _MainTex; + fixed _Cutoff; + + struct v2f { + V2F_SHADOW_CASTER; + float4 uvAndAlpha : TEXCOORD1; + }; + + v2f vert (appdata_base v, float4 vertexColor : COLOR) { + v2f o; + TRANSFER_SHADOW_CASTER(o) + o.uvAndAlpha = v.texcoord; + o.uvAndAlpha.a = vertexColor.a; + return o; + } + + float4 frag (v2f i) : SV_Target { + fixed4 texcol = tex2D(_MainTex, i.uvAndAlpha.xy); + clip(texcol.a * i.uvAndAlpha.a - _Cutoff); + SHADOW_CASTER_FRAGMENT(i) + } + ENDCG + } + } + CustomEditor "SpineShaderWithOutlineGUI" +} diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton-TintBlack.shader.meta b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton-TintBlack.shader.meta new file mode 100644 index 00000000..2801fe0d --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton-TintBlack.shader.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: deee23ab4aa38564ead2ac05e112c169 +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton.shader b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton.shader new file mode 100644 index 00000000..10edd6c4 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton.shader @@ -0,0 +1,118 @@ +Shader "Spine/Skeleton" { + Properties { + _Cutoff ("Shadow alpha cutoff", Range(0,1)) = 0.1 + [NoScaleOffset] _MainTex ("Main Texture", 2D) = "black" {} + [Toggle(_STRAIGHT_ALPHA_INPUT)] _StraightAlphaInput("Straight Alpha Texture", Int) = 0 + [HideInInspector] _StencilRef("Stencil Reference", Float) = 1.0 + [HideInInspector][Enum(UnityEngine.Rendering.CompareFunction)] _StencilComp("Stencil Comparison", Float) = 8 // Set to Always as default + + // Outline properties are drawn via custom editor. + [HideInInspector] _OutlineWidth("Outline Width", Range(0,8)) = 3.0 + [HideInInspector] _OutlineColor("Outline Color", Color) = (1,1,0,1) + [HideInInspector] _OutlineReferenceTexWidth("Reference Texture Width", Int) = 1024 + [HideInInspector] _ThresholdEnd("Outline Threshold", Range(0,1)) = 0.25 + [HideInInspector] _OutlineSmoothness("Outline Smoothness", Range(0,1)) = 1.0 + [HideInInspector][MaterialToggle(_USE8NEIGHBOURHOOD_ON)] _Use8Neighbourhood("Sample 8 Neighbours", Float) = 1 + [HideInInspector] _OutlineMipLevel("Outline Mip Level", Range(0,3)) = 0 + } + + SubShader { + Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" "PreviewType"="Plane" } + + Fog { Mode Off } + Cull Off + ZWrite Off + Blend One OneMinusSrcAlpha + Lighting Off + + Stencil { + Ref[_StencilRef] + Comp[_StencilComp] + Pass Keep + } + + Pass { + Name "Normal" + + CGPROGRAM + #pragma shader_feature _ _STRAIGHT_ALPHA_INPUT + #pragma vertex vert + #pragma fragment frag + #include "UnityCG.cginc" + sampler2D _MainTex; + + struct VertexInput { + float4 vertex : POSITION; + float2 uv : TEXCOORD0; + float4 vertexColor : COLOR; + }; + + struct VertexOutput { + float4 pos : SV_POSITION; + float2 uv : TEXCOORD0; + float4 vertexColor : COLOR; + }; + + VertexOutput vert (VertexInput v) { + VertexOutput o; + o.pos = UnityObjectToClipPos(v.vertex); + o.uv = v.uv; + o.vertexColor = v.vertexColor; + return o; + } + + float4 frag (VertexOutput i) : SV_Target { + float4 texColor = tex2D(_MainTex, i.uv); + + #if defined(_STRAIGHT_ALPHA_INPUT) + texColor.rgb *= texColor.a; + #endif + + return (texColor * i.vertexColor); + } + ENDCG + } + + Pass { + Name "Caster" + Tags { "LightMode"="ShadowCaster" } + Offset 1, 1 + ZWrite On + ZTest LEqual + + Fog { Mode Off } + Cull Off + Lighting Off + + CGPROGRAM + #pragma vertex vert + #pragma fragment frag + #pragma multi_compile_shadowcaster + #pragma fragmentoption ARB_precision_hint_fastest + #include "UnityCG.cginc" + sampler2D _MainTex; + fixed _Cutoff; + + struct VertexOutput { + V2F_SHADOW_CASTER; + float4 uvAndAlpha : TEXCOORD1; + }; + + VertexOutput vert (appdata_base v, float4 vertexColor : COLOR) { + VertexOutput o; + o.uvAndAlpha = v.texcoord; + o.uvAndAlpha.a = vertexColor.a; + TRANSFER_SHADOW_CASTER(o) + return o; + } + + float4 frag (VertexOutput i) : SV_Target { + fixed4 texcol = tex2D(_MainTex, i.uvAndAlpha.xy); + clip(texcol.a * i.uvAndAlpha.a - _Cutoff); + SHADOW_CASTER_FRAGMENT(i) + } + ENDCG + } + } + CustomEditor "SpineShaderWithOutlineGUI" +} diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton.shader.meta b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton.shader.meta new file mode 100644 index 00000000..06c4b0c2 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton.shader.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 1e8a610c9e01c3648bac42585e5fc676 +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Special-Skeleton-Grayscale.shader b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Special-Skeleton-Grayscale.shader new file mode 100644 index 00000000..75c1d493 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Special-Skeleton-Grayscale.shader @@ -0,0 +1,127 @@ +// - Unlit +// - Premultiplied Alpha Blending (Optional straight alpha input) +// - Double-sided, no depth + +Shader "Spine/Special/Skeleton Grayscale" { + Properties { + _GrayPhase ("Phase", Range(0, 1)) = 1 + [NoScaleOffset] _MainTex ("MainTex", 2D) = "white" {} + _Cutoff ("Shadow alpha cutoff", Range(0,1)) = 0.1 + [Toggle(_STRAIGHT_ALPHA_INPUT)] _StraightAlphaInput("Straight Alpha Texture", Int) = 0 + [HideInInspector] _StencilRef("Stencil Reference", Float) = 1.0 + [HideInInspector][Enum(UnityEngine.Rendering.CompareFunction)] _StencilComp("Stencil Comparison", Float) = 8 // Set to Always as default + + // Outline properties are drawn via custom editor. + [HideInInspector] _OutlineWidth("Outline Width", Range(0,8)) = 3.0 + [HideInInspector] _OutlineColor("Outline Color", Color) = (1,1,0,1) + [HideInInspector] _OutlineReferenceTexWidth("Reference Texture Width", Int) = 1024 + [HideInInspector] _ThresholdEnd("Outline Threshold", Range(0,1)) = 0.25 + [HideInInspector] _OutlineSmoothness("Outline Smoothness", Range(0,1)) = 1.0 + [HideInInspector][MaterialToggle(_USE8NEIGHBOURHOOD_ON)] _Use8Neighbourhood("Sample 8 Neighbours", Float) = 1 + [HideInInspector] _OutlineMipLevel("Outline Mip Level", Range(0,3)) = 0 + } + + SubShader { + Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" "PreviewType"="Plane" } + Blend One OneMinusSrcAlpha + Cull Off + ZWrite Off + Lighting Off + + Stencil { + Ref[_StencilRef] + Comp[_StencilComp] + Pass Keep + } + + Pass { + Name "Normal" + + CGPROGRAM + #pragma shader_feature _ _STRAIGHT_ALPHA_INPUT + #pragma vertex vert + #pragma fragment frag + #include "UnityCG.cginc" + sampler2D _MainTex; + float _GrayPhase; + + struct VertexInput { + float4 vertex : POSITION; + float2 uv : TEXCOORD0; + float4 vertexColor : COLOR; + }; + + struct VertexOutput { + float4 pos : SV_POSITION; + float2 uv : TEXCOORD0; + float4 vertexColor : COLOR; + }; + + VertexOutput vert (VertexInput v) { + VertexOutput o = (VertexOutput)0; + o.uv = v.uv; + o.vertexColor = v.vertexColor; + o.pos = UnityObjectToClipPos(v.vertex); + return o; + } + + float4 frag (VertexOutput i) : SV_Target { + float4 rawColor = tex2D(_MainTex,i.uv); + float finalAlpha = (rawColor.a * i.vertexColor.a); + + #if defined(_STRAIGHT_ALPHA_INPUT) + rawColor.rgb *= rawColor.a; + #endif + + rawColor.rgb *= i.vertexColor.rgb; + + float3 finalColor = lerp(rawColor.rgb, dot(rawColor.rgb, float3(0.3, 0.59, 0.11)), _GrayPhase); + return fixed4(finalColor, finalAlpha); + } + ENDCG + } + + Pass { + Name "Caster" + Tags { "LightMode"="ShadowCaster" } + Offset 1, 1 + ZWrite On + ZTest LEqual + + Fog { Mode Off } + Cull Off + Lighting Off + + CGPROGRAM + #pragma vertex vert + #pragma fragment frag + #pragma multi_compile_shadowcaster + #pragma fragmentoption ARB_precision_hint_fastest + #include "UnityCG.cginc" + sampler2D _MainTex; + fixed _Cutoff; + + struct VertexOutput { + V2F_SHADOW_CASTER; + float4 uvAndAlpha : TEXCOORD1; + }; + + VertexOutput vert (appdata_base v, float4 vertexColor : COLOR) { + VertexOutput o; + o.uvAndAlpha = v.texcoord; + o.uvAndAlpha.a = vertexColor.a; + TRANSFER_SHADOW_CASTER(o) + return o; + } + + float4 frag (VertexOutput i) : SV_Target { + fixed4 texcol = tex2D(_MainTex, i.uvAndAlpha.xy); + clip(texcol.a * i.uvAndAlpha.a - _Cutoff); + SHADOW_CASTER_FRAGMENT(i) + } + ENDCG + } + } + FallBack "Diffuse" + CustomEditor "SpineShaderWithOutlineGUI" +} diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Special-Skeleton-Grayscale.shader.meta b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Special-Skeleton-Grayscale.shader.meta new file mode 100644 index 00000000..6db4577e --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Special-Skeleton-Grayscale.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: ea7e7c05f36541b4bb280f98ebda8ba1 +timeCreated: 1492385797 +licenseType: Free +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite.meta b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite.meta new file mode 100644 index 00000000..f9975031 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: a831a8ed72a588a48b2fb892e7f37371 +folderAsset: yes +timeCreated: 1479419399 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/CGIncludes.meta b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/CGIncludes.meta new file mode 100644 index 00000000..009f6848 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/CGIncludes.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 4b6fb48f295cd8248a7566315212a3c2 +folderAsset: yes +timeCreated: 1494092464 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/CGIncludes/ShaderMaths.cginc b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/CGIncludes/ShaderMaths.cginc new file mode 100644 index 00000000..1ae731ea --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/CGIncludes/ShaderMaths.cginc @@ -0,0 +1,76 @@ +#ifndef SHADER_MATHS_INCLUDED +#define SHADER_MATHS_INCLUDED + +#if defined(USE_LWRP) +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" +#elif defined(USE_URP) +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" +#else +#include "UnityCG.cginc" +#endif + +//////////////////////////////////////// +// Maths functions +// + +inline half3 safeNormalize(half3 inVec) +{ + half dp3 = max(0.001f, dot(inVec, inVec)); + return inVec * rsqrt(dp3); +} + +inline float dotClamped(float3 a, float3 b) +{ + #if (SHADER_TARGET < 30 || defined(SHADER_API_PS3)) + return saturate(dot(a, b)); + #else + return max(0.0h, dot(a, b)); + #endif +} + +inline float oneDividedBy(float value) +{ + //Catches NANs + float sign_value = sign(value); + float sign_value_squared = sign_value*sign_value; + return sign_value_squared / ( value + sign_value_squared - 1.0); +} + +inline half pow5 (half x) +{ + return x*x*x*x*x; +} + +inline float4 quat_from_axis_angle(float3 axis, float angleRadians) +{ + float4 qr; + float half_angle = (angleRadians * 0.5); + qr.x = axis.x * sin(half_angle); + qr.y = axis.y * sin(half_angle); + qr.z = axis.z * sin(half_angle); + qr.w = cos(half_angle); + return qr; +} + +inline float3 rotate_vertex_position(float3 position, float3 axis, float angleRadians) +{ + float4 q = quat_from_axis_angle(axis, angleRadians); + float3 v = position.xyz; + return v + 2.0 * cross(q.xyz, cross(q.xyz, v) + q.w * v); +} + +float3 EncodeFloatRGB(float value) +{ + const float max24int = 256*256*256-1; + float3 decomp = floor( value * float3( max24int/(256*256), max24int/256, max24int ) ) / 255.0; + decomp.z -= decomp.y * 256.0; + decomp.y -= decomp.x * 256.0; + return decomp; +} + +float DecodeFloatRGB(float3 decomp) +{ + return dot( decomp.xyz, float3( 255.0/256, 255.0/(256*256), 255.0/(256*256*256) ) ); +} + +#endif // SHADER_MATHS_INCLUDED diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/CGIncludes/ShaderMaths.cginc.meta b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/CGIncludes/ShaderMaths.cginc.meta new file mode 100644 index 00000000..348f3ac2 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/CGIncludes/ShaderMaths.cginc.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: e1de23de2025abe4a84ff2edd3f24491 +timeCreated: 1494092582 +licenseType: Free +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/CGIncludes/ShaderShared.cginc b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/CGIncludes/ShaderShared.cginc new file mode 100644 index 00000000..34f8c0b4 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/CGIncludes/ShaderShared.cginc @@ -0,0 +1,389 @@ +// Upgrade NOTE: upgraded instancing buffer 'PerDrawSprite' to new syntax. + +#ifndef SHADER_SHARED_INCLUDED +#define SHADER_SHARED_INCLUDED + +#if defined(USE_LWRP) +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" +#elif defined(USE_URP) +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" +#else +#include "UnityCG.cginc" +#endif + +//////////////////////////////////////// +// Space functions +// + +inline float4 calculateWorldPos(float4 vertex) +{ + return mul(unity_ObjectToWorld, vertex); +} + +#if defined(USE_LWRP) || defined(USE_URP) +// snaps post-transformed position to screen pixels +inline float4 UnityPixelSnap(float4 pos) +{ + float2 hpc = _ScreenParams.xy * 0.5f; +#if SHADER_API_PSSL + // sdk 4.5 splits round into v_floor_f32(x+0.5) ... sdk 5.0 uses v_rndne_f32, for compatabilty we use the 4.5 version + float2 temp = ((pos.xy / pos.w) * hpc) + float2(0.5f, 0.5f); + float2 pixelPos = float2(__v_floor_f32(temp.x), __v_floor_f32(temp.y)); +#else + float2 pixelPos = round((pos.xy / pos.w) * hpc); +#endif + pos.xy = pixelPos / hpc * pos.w; + return pos; +} +#endif + +inline float4 calculateLocalPos(float4 vertex) +{ +#if !defined(USE_LWRP) && !defined(USE_URP) +#ifdef UNITY_INSTANCING_ENABLED + vertex.xy *= _Flip.xy; +#endif +#endif + +#if defined(USE_LWRP) || defined(USE_URP) + float4 pos = TransformObjectToHClip(vertex.xyz); +#else + float4 pos = UnityObjectToClipPos(vertex); +#endif + +#ifdef PIXELSNAP_ON + pos = UnityPixelSnap(pos); +#endif + + return pos; +} + +inline half3 calculateWorldNormal(float3 normal) +{ +#if defined(USE_LWRP) || defined(USE_URP) + return TransformObjectToWorldNormal(normal); +#else + return UnityObjectToWorldNormal(normal); +#endif +} + +//////////////////////////////////////// +// Normal map functions +// + +#if defined(_NORMALMAP) + +uniform sampler2D _BumpMap; +uniform half _BumpScale; + +half3 UnpackScaleNormal(half4 packednormal, half bumpScale) +{ + #if defined(UNITY_NO_DXT5nm) + return packednormal.xyz * 2 - 1; + #else + half3 normal; + normal.xy = (packednormal.wy * 2 - 1); + // Note: we allow scaled normals in LWRP since we might be using fewer instructions. + #if (SHADER_TARGET >= 30) || defined(USE_LWRP) || defined(USE_URP) + // SM2.0: instruction count limitation + // SM2.0: normal scaler is not supported + normal.xy *= bumpScale; + #endif + normal.z = sqrt(1.0 - saturate(dot(normal.xy, normal.xy))); + return normal; + #endif +} + + +inline half3 calculateWorldTangent(float4 tangent) +{ +#if defined(USE_LWRP) || defined(USE_URP) + return TransformObjectToWorldDir(tangent.xyz); +#else + return UnityObjectToWorldDir(tangent); +#endif +} + +inline half3 calculateWorldBinormal(half3 normalWorld, half3 tangentWorld, float tangentSign) +{ + //When calculating the binormal we have to flip it when the mesh is scaled negatively. + //Normally this would just be unity_WorldTransformParams.w but this isn't set correctly by Unity for its SpriteRenderer meshes so get from objectToWorld matrix scale instead. + half worldTransformSign = sign(unity_ObjectToWorld[0][0] * unity_ObjectToWorld[1][1] * unity_ObjectToWorld[2][2]); + half sign = tangentSign * worldTransformSign; + return cross(normalWorld, tangentWorld) * sign; +} + +inline half3 calculateNormalFromBumpMap(float2 texUV, half3 tangentWorld, half3 binormalWorld, half3 normalWorld) +{ + half3 localNormal = UnpackScaleNormal(tex2D(_BumpMap, texUV), _BumpScale); + half3x3 rotation = half3x3(tangentWorld, binormalWorld, normalWorld); + half3 normal = normalize(mul(localNormal, rotation)); + return normal; +} + +#endif // _NORMALMAP + +//////////////////////////////////////// +// Blending functions +// + +inline fixed4 prepareLitPixelForOutput(fixed4 finalPixel, fixed4 color) : SV_Target +{ +#if defined(_ALPHABLEND_ON) + //Normal Alpha + finalPixel.rgb *= finalPixel.a; +#elif defined(_ALPHAPREMULTIPLY_ON) + //Pre multiplied alpha + finalPixel.rgb *= color.a; +#elif defined(_MULTIPLYBLEND) + //Multiply + finalPixel = lerp(fixed4(1,1,1,1), finalPixel, finalPixel.a); +#elif defined(_MULTIPLYBLEND_X2) + //Multiply x2 + finalPixel.rgb *= 2.0f; + finalPixel = lerp(fixed4(0.5f,0.5f,0.5f,0.5f), finalPixel, finalPixel.a); +#elif defined(_ADDITIVEBLEND) + //Additive + finalPixel *= 2.0f; + finalPixel.rgb *= color.a; +#elif defined(_ADDITIVEBLEND_SOFT) + //Additive soft + finalPixel.rgb *= finalPixel.a; +#else + //Opaque + finalPixel.a = 1; +#endif + return finalPixel; +} + +inline fixed4 calculateLitPixel(fixed4 texureColor, fixed4 color, fixed3 lighting) : SV_Target +{ + fixed4 finalPixel = texureColor * color * fixed4(lighting, 1); + finalPixel = prepareLitPixelForOutput(finalPixel, color); + return finalPixel; +} + +inline fixed4 calculateLitPixel(fixed4 texureColor, fixed3 lighting) : SV_Target +{ + // note: we let the optimizer work, removed duplicate code. + return calculateLitPixel(texureColor, fixed4(1, 1, 1, 1), lighting); +} + +inline fixed4 calculateAdditiveLitPixel(fixed4 texureColor, fixed4 color, fixed3 lighting) : SV_Target +{ + fixed4 finalPixel; + +#if defined(_ALPHABLEND_ON) || defined(_MULTIPLYBLEND) || defined(_MULTIPLYBLEND_X2) || defined(_ADDITIVEBLEND) || defined(_ADDITIVEBLEND_SOFT) + //Normal Alpha, Additive and Multiply modes + finalPixel.rgb = (texureColor.rgb * lighting * color.rgb) * (texureColor.a * color.a); + finalPixel.a = 1.0; +#elif defined(_ALPHAPREMULTIPLY_ON) + //Pre multiplied alpha + finalPixel.rgb = texureColor.rgb * lighting * color.rgb * color.a; + finalPixel.a = 1.0; +#else + //Opaque + finalPixel.rgb = texureColor.rgb * lighting * color.rgb; + finalPixel.a = 1.0; +#endif + + return finalPixel; +} + +inline fixed4 calculateAdditiveLitPixel(fixed4 texureColor, fixed3 lighting) : SV_Target +{ + fixed4 finalPixel; + +#if defined(_ALPHABLEND_ON) || defined(_MULTIPLYBLEND) || defined(_MULTIPLYBLEND_X2) || defined(_ADDITIVEBLEND) || defined(_ADDITIVEBLEND_SOFT) + //Normal Alpha, Additive and Multiply modes + finalPixel.rgb = (texureColor.rgb * lighting) * texureColor.a; + finalPixel.a = 1.0; +#else + //Pre multiplied alpha and Opaque + finalPixel.rgb = texureColor.rgb * lighting; + finalPixel.a = 1.0; +#endif + + return finalPixel; +} + +inline fixed4 calculatePixel(fixed4 texureColor, fixed4 color) : SV_Target +{ + // note: we let the optimizer work, removed duplicate code. + return calculateLitPixel(texureColor, color, fixed3(1, 1, 1)); +} + +inline fixed4 calculatePixel(fixed4 texureColor) : SV_Target +{ + // note: we let the optimizer work, removed duplicate code. + return calculateLitPixel(texureColor, fixed4(1, 1, 1, 1), fixed3(1, 1, 1)); +} + +//////////////////////////////////////// +// Alpha Clipping +// + +#if defined(_ALPHA_CLIP) + +uniform fixed _Cutoff; + +#define ALPHA_CLIP(pixel, color) clip((pixel.a * color.a) - _Cutoff); + +#else + +#define ALPHA_CLIP(pixel, color) + +#endif + +//////////////////////////////////////// +// Color functions +// + +uniform fixed4 _Color; + +inline fixed4 calculateVertexColor(fixed4 color) +{ + return color * _Color; +} + +#if defined(_COLOR_ADJUST) + +uniform float _Hue; +uniform float _Saturation; +uniform float _Brightness; +uniform fixed4 _OverlayColor; + +float3 rgb2hsv(float3 c) +{ + float4 K = float4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); + float4 p = lerp(float4(c.bg, K.wz), float4(c.gb, K.xy), step(c.b, c.g)); + float4 q = lerp(float4(p.xyw, c.r), float4(c.r, p.yzx), step(p.x, c.r)); + + float d = q.x - min(q.w, q.y); + float e = 1.0e-10; + return float3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x); +} + +float3 hsv2rgb(float3 c) +{ + c = float3(c.x, clamp(c.yz, 0.0, 1.0)); + float4 K = float4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); + float3 p = abs(frac(c.xxx + K.xyz) * 6.0 - K.www); + return c.z * lerp(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y); +} + +inline fixed4 adjustColor(fixed4 color) +{ + float3 hsv = rgb2hsv(color.rgb); + + hsv.x += _Hue; + hsv.y *= _Saturation; + hsv.z *= _Brightness; + + color.rgb = hsv2rgb(hsv); + + return color; +} + +#define COLORISE(pixel) pixel.rgb = lerp(pixel.rgb, _OverlayColor.rgb, _OverlayColor.a * pixel.a); +#define COLORISE_ADDITIVE(pixel) pixel.rgb = ((1.0-_OverlayColor.a) * pixel.rgb); + +#else // !_COLOR_ADJUST + +#define COLORISE(pixel) +#define COLORISE_ADDITIVE(pixel) + +#endif // !_COLOR_ADJUST + +//////////////////////////////////////// +// Fog +// + +#if defined(_FOG) && (defined(FOG_LINEAR) || defined(FOG_EXP) || defined(FOG_EXP2)) + +inline fixed4 applyFog(fixed4 pixel, float fogCoordOrFactorAtLWRP) +{ +#if defined(_ADDITIVEBLEND) || defined(_ADDITIVEBLEND_SOFT) + //In additive mode blend from clear to black based on luminance + float luminance = pixel.r * 0.3 + pixel.g * 0.59 + pixel.b * 0.11; + fixed4 fogColor = lerp(fixed4(0,0,0,0), fixed4(0,0,0,1), luminance); +#elif defined(_MULTIPLYBLEND) + //In multiplied mode fade to white based on inverse luminance + float luminance = pixel.r * 0.3 + pixel.g * 0.59 + pixel.b * 0.11; + fixed4 fogColor = lerp(fixed4(1,1,1,1), fixed4(0,0,0,0), luminance); +#elif defined(_MULTIPLYBLEND_X2) + //In multipliedx2 mode fade to grey based on inverse luminance + float luminance = pixel.r * 0.3 + pixel.g * 0.59 + pixel.b * 0.11; + fixed4 fogColor = lerp(fixed4(0.5f,0.5f,0.5f,0.5f), fixed4(0,0,0,0), luminance); +#elif defined(_ALPHABLEND_ON) || defined(_ALPHAPREMULTIPLY_ON) + //In alpha blended modes blend to fog color based on pixel alpha + fixed4 fogColor = lerp(fixed4(0,0,0,0), unity_FogColor, pixel.a); +#else + //In opaque mode just return fog color; + fixed4 fogColor = unity_FogColor; +#endif + + #if defined(USE_LWRP) || defined(USE_URP) + pixel.rgb = MixFogColor(pixel.rgb, fogColor.rgb, fogCoordOrFactorAtLWRP); + #else + UNITY_APPLY_FOG_COLOR(fogCoordOrFactorAtLWRP, pixel, fogColor); + #endif + + return pixel; +} + +#define APPLY_FOG(pixel, input) pixel = applyFog(pixel, input.fogCoord); +#define APPLY_FOG_LWRP(pixel, fogFactor) pixel = applyFog(pixel, fogFactor); + +#define APPLY_FOG_ADDITIVE(pixel, input) \ + UNITY_APPLY_FOG_COLOR(input.fogCoord, pixel.rgb, fixed4(0,0,0,0)); // fog towards black in additive pass + +#else + +#define APPLY_FOG(pixel, input) +#define APPLY_FOG_LWRP(pixel, fogFactor) +#define APPLY_FOG_ADDITIVE(pixel, input) + +#endif + +//////////////////////////////////////// +// Texture functions +// + +uniform sampler2D _MainTex; + +#if _TEXTURE_BLEND +uniform sampler2D _BlendTex; +uniform float _BlendAmount; + +inline fixed4 calculateBlendedTexturePixel(float2 texcoord) +{ + return (1.0-_BlendAmount) * tex2D(_MainTex, texcoord) + _BlendAmount * tex2D(_BlendTex, texcoord); +} +#endif // _TEXTURE_BLEND + +inline fixed4 calculateTexturePixel(float2 texcoord) +{ + fixed4 pixel; + +#if _TEXTURE_BLEND + pixel = calculateBlendedTexturePixel(texcoord); +#else + pixel = tex2D(_MainTex, texcoord); +#endif // !_TEXTURE_BLEND + +#if defined(_COLOR_ADJUST) + pixel = adjustColor(pixel); +#endif // _COLOR_ADJUST + + return pixel; +} + +uniform fixed4 _MainTex_ST; + +inline float2 calculateTextureCoord(float4 texcoord) +{ + return TRANSFORM_TEX(texcoord, _MainTex); +} + +#endif // SHADER_SHARED_INCLUDED diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/CGIncludes/ShaderShared.cginc.meta b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/CGIncludes/ShaderShared.cginc.meta new file mode 100644 index 00000000..7e1ddf1c --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/CGIncludes/ShaderShared.cginc.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: c18c5cab567666f4d8c5b2bd4e61390b +timeCreated: 1494092582 +licenseType: Free +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/CGIncludes/SpriteLighting.cginc b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/CGIncludes/SpriteLighting.cginc new file mode 100644 index 00000000..3d882493 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/CGIncludes/SpriteLighting.cginc @@ -0,0 +1,206 @@ +#ifndef SPRITE_LIGHTING_INCLUDED +#define SPRITE_LIGHTING_INCLUDED + +//Check for using mesh normals +#if !defined(_FIXED_NORMALS_VIEWSPACE) && !defined(_FIXED_NORMALS_VIEWSPACE_BACKFACE) && !defined(_FIXED_NORMALS_MODELSPACE) && !defined(_FIXED_NORMALS_MODELSPACE_BACKFACE) && !defined(_FIXED_NORMALS_WORLDSPACE) +#define MESH_NORMALS +#endif + +//Check for fixing backfacing tangents +#if defined(_FIXED_NORMALS_VIEWSPACE_BACKFACE) || defined(_FIXED_NORMALS_MODELSPACE_BACKFACE) +#define FIXED_NORMALS_BACKFACE_RENDERING +#endif + +//////////////////////////////////////// +// Vertex structs +// + +struct VertexInput +{ + float4 vertex : POSITION; + float4 texcoord : TEXCOORD0; + float4 color : COLOR; +#if defined(MESH_NORMALS) + float3 normal : NORMAL; +#endif // _FIXED_NORMALS +#if defined(_NORMALMAP) + float4 tangent : TANGENT; +#endif // _NORMALMAP + UNITY_VERTEX_INPUT_INSTANCE_ID +}; + +//////////////////////////////////////// +// Normal functions +// + +uniform float4 _FixedNormal = float4(0, 0, 1, 1); + +inline float3 getFixedNormal() +{ + return _FixedNormal.xyz; +} + +inline float calculateBackfacingSign(float3 worldPos) +{ + //If we're using fixed normals and mesh is facing away from camera, flip tangentSign + //Unity uses a left handed coordinate system so camera always looks down the negative z axis + float3 cameraForward = float3(0,0,-1); + float3 meshWorldForward = mul((float3x3)unity_ObjectToWorld, cameraForward); + float3 toCamera = _WorldSpaceCameraPos - worldPos; + return sign(dot(toCamera, meshWorldForward)); +} + +inline half3 calculateSpriteWorldNormal(VertexInput vertex, float backFaceSign) +{ +#if defined(MESH_NORMALS) + + return calculateWorldNormal(vertex.normal); + +#else // !MESH_NORMALS + + float3 normal = getFixedNormal(); + +#if defined(_FIXED_NORMALS_VIEWSPACE) || defined(_FIXED_NORMALS_VIEWSPACE_BACKFACE) + //View space fixed normal + //Rotate fixed normal by inverse view matrix to convert the fixed normal into world space + float3x3 invView = transpose((float3x3)UNITY_MATRIX_V); + return normalize(mul(invView, normal)); +#elif defined (_FIXED_NORMALS_WORLDSPACE) + //World space fixed normal + return normal; +#else + //Model space fixed normal. +#if defined(FIXED_NORMALS_BACKFACE_RENDERING) + //If back face rendering is enabled and the sprite is facing away from the camera (ie we're rendering the backface) then need to flip the normal + normal *= backFaceSign; +#endif + return calculateWorldNormal(normal); +#endif + +#endif // !MESH_NORMALS +} + +inline half3 calculateSpriteViewNormal(VertexInput vertex, float backFaceSign) +{ +#if defined(MESH_NORMALS) + + return normalize(mul((float3x3)UNITY_MATRIX_IT_MV, vertex.normal)); + +#else // !MESH_NORMALS + + float3 normal = getFixedNormal(); + +#if defined(_FIXED_NORMALS_VIEWSPACE) || defined(_FIXED_NORMALS_VIEWSPACE_BACKFACE) + //View space fixed normal + return normal; +#elif defined (_FIXED_NORMALS_WORLDSPACE) + //World space fixed normal + return normalize(mul((float3x3)UNITY_MATRIX_V, normal)); +#else + //Model space fixed normal +#if defined(FIXED_NORMALS_BACKFACE_RENDERING) + //If back face rendering is enabled and the sprite is facing away from the camera (ie we're rendering the backface) then need to flip the normal + normal *= backFaceSign; +#endif + return normalize(mul((float3x3)UNITY_MATRIX_IT_MV, normal)); +#endif + +#endif // !MESH_NORMALS +} + +//////////////////////////////////////// +// Normal map functions +// + +#if defined(_NORMALMAP) + +inline half3 calculateSpriteWorldBinormal(VertexInput vertex, half3 normalWorld, half3 tangentWorld, float backFaceSign) +{ + float tangentSign = vertex.tangent.w; + +#if defined(FIXED_NORMALS_BACKFACE_RENDERING) + tangentSign *= backFaceSign; +#endif + + return calculateWorldBinormal(normalWorld, tangentWorld, tangentSign); +} + +#endif // _NORMALMAP + +#if defined(_DIFFUSE_RAMP) + + +//////////////////////////////////////// +// Diffuse ramp functions +// + +//Disable for softer, more traditional diffuse ramping +#define HARD_DIFFUSE_RAMP + +uniform sampler2D _DiffuseRamp; + +inline fixed3 calculateDiffuseRamp(float ramp) +{ + return tex2D(_DiffuseRamp, float2(ramp, ramp)).rgb; +} + +inline fixed3 calculateRampedDiffuse(fixed3 lightColor, float attenuation, float angleDot) +{ + float d = angleDot * 0.5 + 0.5; +#if defined(HARD_DIFFUSE_RAMP) + half3 ramp = calculateDiffuseRamp(d * attenuation * 2); + return lightColor * ramp; +#else + half3 ramp = calculateDiffuseRamp(d); + return lightColor * ramp * (attenuation * 2); +#endif +} +#endif // _DIFFUSE_RAMP + +//////////////////////////////////////// +// Rim Lighting functions +// + +#ifdef _RIM_LIGHTING + +uniform float _RimPower; +uniform fixed4 _RimColor; + +inline fixed3 applyRimLighting(fixed3 posWorld, fixed3 normalWorld, fixed4 pixel) : SV_Target +{ + fixed3 viewDir = normalize(_WorldSpaceCameraPos - posWorld); + float invDot = 1.0 - saturate(dot(normalWorld, viewDir)); + float rimPower = pow(invDot, _RimPower); + float rim = saturate(rimPower * _RimColor.a); + +#if defined(_DIFFUSE_RAMP) + rim = calculateDiffuseRamp(rim).r; +#endif + + return lerp(pixel.rgb, _RimColor.xyz * pixel.a, rim); +} + +#endif //_RIM_LIGHTING + +//////////////////////////////////////// +// Emission functions +// + +#ifdef _EMISSION + +uniform sampler2D _EmissionMap; +uniform fixed4 _EmissionColor; +uniform float _EmissionPower; + + +#define APPLY_EMISSION(diffuse, uv) diffuse += tex2D(_EmissionMap, uv).rgb * _EmissionColor.rgb * _EmissionPower; +#define APPLY_EMISSION_SPECULAR(pixel, uv) pixel.rgb += (tex2D(_EmissionMap, uv).rgb * _EmissionColor.rgb * _EmissionPower) * pixel.a; + +#else //!_EMISSION + +#define APPLY_EMISSION(diffuse, uv) +#define APPLY_EMISSION_SPECULAR(pixel, uv) + +#endif //!_EMISSION + +#endif // SPRITE_LIGHTING_INCLUDED diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/CGIncludes/SpriteLighting.cginc.meta b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/CGIncludes/SpriteLighting.cginc.meta new file mode 100644 index 00000000..b25bff32 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/CGIncludes/SpriteLighting.cginc.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 0cfb891658099ca4bb0c9544c08e60f9 +timeCreated: 1494092582 +licenseType: Free +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/CGIncludes/SpritePixelLighting.cginc b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/CGIncludes/SpritePixelLighting.cginc new file mode 100644 index 00000000..8c763f48 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/CGIncludes/SpritePixelLighting.cginc @@ -0,0 +1,252 @@ +#ifndef SPRITE_PIXEL_LIGHTING_INCLUDED +#define SPRITE_PIXEL_LIGHTING_INCLUDED + +#include "ShaderShared.cginc" +#include "SpriteLighting.cginc" +#include "SpriteSpecular.cginc" +#include "AutoLight.cginc" + +//////////////////////////////////////// +// Defines +// + +//////////////////////////////////////// +// Vertex output struct +// + +#if defined(_NORMALMAP) + #define _VERTEX_LIGHTING_INDEX TEXCOORD5 + #define _LIGHT_COORD_INDEX_0 6 + #define _LIGHT_COORD_INDEX_1 7 + #define _FOG_COORD_INDEX 8 +#else + #define _VERTEX_LIGHTING_INDEX TEXCOORD3 + #define _LIGHT_COORD_INDEX_0 4 + #define _LIGHT_COORD_INDEX_1 5 + #define _FOG_COORD_INDEX 6 +#endif // _NORMALMAP + +struct VertexOutput +{ + float4 pos : SV_POSITION; + fixed4 color : COLOR; + float2 texcoord : TEXCOORD0; + float4 posWorld : TEXCOORD1; + half3 normalWorld : TEXCOORD2; +#if defined(_NORMALMAP) + half3 tangentWorld : TEXCOORD3; + half3 binormalWorld : TEXCOORD4; +#endif // _NORMALMAP + fixed3 vertexLighting : _VERTEX_LIGHTING_INDEX; + LIGHTING_COORDS(_LIGHT_COORD_INDEX_0, _LIGHT_COORD_INDEX_1) +#if defined(_FOG) + UNITY_FOG_COORDS(_FOG_COORD_INDEX) +#endif // _FOG + + UNITY_VERTEX_OUTPUT_STEREO +}; + +//////////////////////////////////////// +// Light calculations +// + +uniform fixed4 _LightColor0; + +inline fixed3 calculateLightDiffuse(VertexOutput input, float3 normalWorld, inout fixed4 albedo) +{ + //For directional lights _WorldSpaceLightPos0.w is set to zero + float3 lightWorldDirection = normalize(_WorldSpaceLightPos0.xyz - input.posWorld.xyz * _WorldSpaceLightPos0.w); + + float attenuation = LIGHT_ATTENUATION(input); + float angleDot = max(0, dot(normalWorld, lightWorldDirection)); + +#if defined(_DIFFUSE_RAMP) + fixed3 lightDiffuse = calculateRampedDiffuse(_LightColor0.rgb, attenuation, angleDot); +#else + fixed3 lightDiffuse = _LightColor0.rgb * (attenuation * angleDot); +#endif // _DIFFUSE_RAMP + + return lightDiffuse; +} + +inline float3 calculateNormalWorld(VertexOutput input) +{ +#if defined(_NORMALMAP) + return calculateNormalFromBumpMap(input.texcoord, input.tangentWorld, input.binormalWorld, input.normalWorld); +#else + return input.normalWorld; +#endif +} + +fixed3 calculateVertexLighting(float3 posWorld, float3 normalWorld) +{ + fixed3 vertexLighting = fixed3(0,0,0); + +#ifdef VERTEXLIGHT_ON + //Get approximated illumination from non-important point lights + vertexLighting = Shade4PointLights ( unity_4LightPosX0, unity_4LightPosY0, unity_4LightPosZ0, + unity_LightColor[0].rgb, unity_LightColor[1].rgb, unity_LightColor[2].rgb, unity_LightColor[3].rgb, + unity_4LightAtten0, posWorld, normalWorld) * 0.5; +#endif + + return vertexLighting; +} + +fixed3 calculateAmbientLight(half3 normalWorld) +{ +#if defined(_SPHERICAL_HARMONICS) + fixed3 ambient = ShadeSH9(half4(normalWorld, 1.0)); +#else + fixed3 ambient = unity_AmbientSky.rgb; +#endif + return ambient; +} + +#if defined(SPECULAR) + +fixed4 calculateSpecularLight(SpecularCommonData s, float3 viewDir, float3 normal, float3 lightDir, float3 lightColor, half3 ambient) +{ + SpecularLightData data = calculatePhysicsBasedSpecularLight (s.specColor, s.oneMinusReflectivity, s.smoothness, normal, viewDir, lightDir, lightColor, ambient, unity_IndirectSpecColor.rgb); + fixed4 pixel = calculateLitPixel(fixed4(s.diffColor, s.alpha), data.lighting); + pixel.rgb += data.specular * s.alpha; + return pixel; +} + +fixed4 calculateSpecularLightAdditive(SpecularCommonData s, float3 viewDir, float3 normal, float3 lightDir, float3 lightColor) +{ + SpecularLightData data = calculatePhysicsBasedSpecularLight (s.specColor, s.oneMinusReflectivity, s.smoothness, normal, viewDir, lightDir, lightColor, half3(0,0,0), half3(0,0,0)); + fixed4 pixel = calculateAdditiveLitPixel(fixed4(s.diffColor, s.alpha), data.lighting); + pixel.rgb += data.specular * s.alpha; + return pixel; +} + +#endif //SPECULAR + +//////////////////////////////////////// +// Vertex program +// + +VertexOutput vert(VertexInput v) +{ + VertexOutput output; + + UNITY_SETUP_INSTANCE_ID(input); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output); + + output.pos = calculateLocalPos(v.vertex); + output.color = calculateVertexColor(v.color); + output.texcoord = calculateTextureCoord(v.texcoord); + output.posWorld = calculateWorldPos(v.vertex); + + float backFaceSign = 1; +#if defined(FIXED_NORMALS_BACKFACE_RENDERING) + backFaceSign = calculateBackfacingSign(output.posWorld.xyz); +#endif + + output.normalWorld = calculateSpriteWorldNormal(v, backFaceSign); + output.vertexLighting = calculateVertexLighting(output.posWorld, output.normalWorld); + +#if defined(_NORMALMAP) + output.tangentWorld = calculateWorldTangent(v.tangent); + output.binormalWorld = calculateSpriteWorldBinormal(v, output.normalWorld, output.tangentWorld, backFaceSign); +#endif + + TRANSFER_VERTEX_TO_FRAGMENT(output) + +#if defined(_FOG) + UNITY_TRANSFER_FOG(output,output.pos); +#endif // _FOG + + return output; +} + +//////////////////////////////////////// +// Fragment programs +// + +fixed4 fragBase(VertexOutput input) : SV_Target +{ + fixed4 texureColor = calculateTexturePixel(input.texcoord); + ALPHA_CLIP(texureColor, input.color) + + //Get normal direction + fixed3 normalWorld = calculateNormalWorld(input); + + //Get Ambient diffuse + fixed3 ambient = calculateAmbientLight(normalWorld); + + +#if defined(SPECULAR) + + //For directional lights _WorldSpaceLightPos0.w is set to zero + float3 lightWorldDirection = normalize(_WorldSpaceLightPos0.xyz - input.posWorld.xyz * _WorldSpaceLightPos0.w); + float attenuation = LIGHT_ATTENUATION(input); + + //Returns pixel lit by light, texture color should inlcluded alpha + half3 viewDir = normalize(_WorldSpaceCameraPos - input.posWorld.xyz); + fixed4 pixel = calculateSpecularLight(getSpecularData(input.texcoord.xy, texureColor, input.color), viewDir, normalWorld, lightWorldDirection, _LightColor0.rgb * attenuation, ambient + input.vertexLighting); + + APPLY_EMISSION_SPECULAR(pixel, input.texcoord) + +#else + + //Get primary pixel light diffuse + fixed3 diffuse = calculateLightDiffuse(input, normalWorld, texureColor); + + //Combine along with vertex lighting for the base lighting pass + fixed3 lighting = ambient + diffuse + input.vertexLighting; + + APPLY_EMISSION(lighting, input.texcoord) + + fixed4 pixel = calculateLitPixel(texureColor, input.color, lighting); + +#endif + +#if defined(_RIM_LIGHTING) + pixel.rgb = applyRimLighting(input.posWorld, normalWorld, pixel); +#endif + + COLORISE(pixel) + APPLY_FOG(pixel, input) + + return pixel; +} + +fixed4 fragAdd(VertexOutput input) : SV_Target +{ + fixed4 texureColor = calculateTexturePixel(input.texcoord); + +#if defined(_COLOR_ADJUST) + texureColor = adjustColor(texureColor); +#endif // _COLOR_ADJUST + + ALPHA_CLIP(texureColor, input.color) + + //Get normal direction + fixed3 normalWorld = calculateNormalWorld(input); + +#if defined(SPECULAR) + + //For directional lights _WorldSpaceLightPos0.w is set to zero + float3 lightWorldDirection = normalize(_WorldSpaceLightPos0.xyz - input.posWorld.xyz * _WorldSpaceLightPos0.w); + float attenuation = LIGHT_ATTENUATION(input); + + half3 viewDir = normalize(_WorldSpaceCameraPos - input.posWorld.xyz); + fixed4 pixel = calculateSpecularLightAdditive(getSpecularData(input.texcoord.xy, texureColor, input.color), viewDir, normalWorld, lightWorldDirection, _LightColor0.rgb * attenuation); + +#else + + //Get light diffuse + fixed3 lighting = calculateLightDiffuse(input, normalWorld, texureColor); + fixed4 pixel = calculateAdditiveLitPixel(texureColor, input.color, lighting); + +#endif + + COLORISE_ADDITIVE(pixel) + APPLY_FOG_ADDITIVE(pixel, input) + + return pixel; +} + + +#endif // SPRITE_PIXEL_LIGHTING_INCLUDED \ No newline at end of file diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/CGIncludes/SpritePixelLighting.cginc.meta b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/CGIncludes/SpritePixelLighting.cginc.meta new file mode 100644 index 00000000..73da285b --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/CGIncludes/SpritePixelLighting.cginc.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 7ffc57e05c42ec748838bea0a3aff9f9 +timeCreated: 1494092582 +licenseType: Free +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/CGIncludes/SpriteShadows.cginc b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/CGIncludes/SpriteShadows.cginc new file mode 100644 index 00000000..401ed899 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/CGIncludes/SpriteShadows.cginc @@ -0,0 +1,51 @@ +#ifndef SPRITE_SHADOWS_INCLUDED +#define SPRITE_SHADOWS_INCLUDED + +#include "ShaderShared.cginc" + +//////////////////////////////////////// +// Vertex structs +// + +struct vertexInput +{ + float4 vertex : POSITION; + float4 texcoord : TEXCOORD0; +}; + +struct vertexOutput +{ + V2F_SHADOW_CASTER; + float4 texcoordAndAlpha : TEXCOORD1; +}; + +//////////////////////////////////////// +// Vertex program +// + +vertexOutput vert(vertexInput v, float4 vertexColor : COLOR) +{ + vertexOutput o; + TRANSFER_SHADOW_CASTER(o) + o.texcoordAndAlpha.xy = calculateTextureCoord(v.texcoord); + o.texcoordAndAlpha.z = 0; + o.texcoordAndAlpha.a = vertexColor.a; + return o; +} + +//////////////////////////////////////// +// Fragment program +// + + +uniform fixed _ShadowAlphaCutoff; + +fixed4 frag(vertexOutput IN) : SV_Target +{ + fixed4 texureColor = calculateTexturePixel(IN.texcoordAndAlpha.xy); + clip(texureColor.a * IN.texcoordAndAlpha.a - _ShadowAlphaCutoff); + + SHADOW_CASTER_FRAGMENT(IN) +} + +#endif // SPRITE_SHADOWS_INCLUDED \ No newline at end of file diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/CGIncludes/SpriteShadows.cginc.meta b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/CGIncludes/SpriteShadows.cginc.meta new file mode 100644 index 00000000..09089fb9 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/CGIncludes/SpriteShadows.cginc.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: b7dbdfb1f55ee26459284220ad6d5bc4 +timeCreated: 1494092582 +licenseType: Free +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/CGIncludes/SpriteSpecular.cginc b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/CGIncludes/SpriteSpecular.cginc new file mode 100644 index 00000000..e96d566f --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/CGIncludes/SpriteSpecular.cginc @@ -0,0 +1,246 @@ +#ifndef SPRITE_SPECULAR_INCLUDED +#define SPRITE_SPECULAR_INCLUDED + +#include "ShaderMaths.cginc" + +//////////////////////////////////////// +// Specular functions +// + +#if defined(_SPECULAR) || defined(_SPECULAR_GLOSSMAP) + +#define SPECULAR + + +//ALL THESE FUNCTIONS ARE TAKEN AND ADAPTED FROM UNITY'S OWN PHYSICS BASED STANDARD SHADER + +uniform float _Metallic; +uniform float _Glossiness; +uniform float _GlossMapScale; +uniform sampler2D _MetallicGlossMap; + +struct SpecularLightData +{ + half3 lighting; + half3 specular; +}; + +struct SpecularCommonData +{ + half3 diffColor, specColor; + // Note: smoothness & oneMinusReflectivity for optimization purposes, mostly for DX9 SM2.0 level. + // Most of the math is being done on these (1-x) values, and that saves a few precious ALU slots. + half oneMinusReflectivity, smoothness; + half alpha; +}; + +inline half2 getMetallicGloss(float2 uv) +{ + half2 mg; + +#ifdef _SPECULAR_GLOSSMAP + mg = tex2D(_MetallicGlossMap, uv).ra; + mg.g *= _GlossMapScale; +#else + mg.r = _Metallic; + mg.g = _Glossiness; +#endif + + return mg; +} + +inline half getOneMinusReflectivityFromMetallic(half metallic) +{ + // We'll need oneMinusReflectivity, so + // 1-reflectivity = 1-lerp(dielectricSpec, 1, metallic) = lerp(1-dielectricSpec, 0, metallic) + // store (1-dielectricSpec) in unity_ColorSpaceDielectricSpec.a, then + // 1-reflectivity = lerp(alpha, 0, metallic) = alpha + metallic*(0 - alpha) = + // = alpha - metallic * alpha + half oneMinusDielectricSpec = unity_ColorSpaceDielectricSpec.a; + return oneMinusDielectricSpec - metallic * oneMinusDielectricSpec; +} + +inline SpecularCommonData getSpecularData(float2 uv, half4 texureColor, fixed4 color) +{ + half2 metallicGloss = getMetallicGloss(uv); + half metallic = metallicGloss.x; + half smoothness = metallicGloss.y; // this is 1 minus the square root of real roughness m. + + fixed4 albedo = calculatePixel(texureColor, color); + + half3 specColor = lerp (unity_ColorSpaceDielectricSpec.rgb, albedo, metallic); + half oneMinusReflectivity = getOneMinusReflectivityFromMetallic(metallic); + half3 diffColor = albedo * oneMinusReflectivity; + + SpecularCommonData o = (SpecularCommonData)0; + o.diffColor = diffColor; + o.specColor = specColor; + o.oneMinusReflectivity = oneMinusReflectivity; + o.smoothness = smoothness; + +#if defined(_ALPHAPREMULTIPLY_ON) && (SHADER_TARGET >= 30) + // Reflectivity 'removes' from the rest of components, including Transparency + // outAlpha = 1-(1-alpha)*(1-reflectivity) = 1-(oneMinusReflectivity - alpha*oneMinusReflectivity) = + // = 1-oneMinusReflectivity + alpha*oneMinusReflectivity + //o.alpha = 1-oneMinusReflectivity + albedo.a*oneMinusReflectivity; + o.alpha = albedo.a; +#else + o.alpha = albedo.a; +#endif + + return o; +} +inline half SmoothnessToPerceptualRoughness(half smoothness) +{ + return (1 - smoothness); +} + +inline half PerceptualRoughnessToRoughness(half perceptualRoughness) +{ + return perceptualRoughness * perceptualRoughness; +} + +// Ref: http://jcgt.org/published/0003/02/03/paper.pdf +inline half SmithJointGGXVisibilityTerm (half NdotL, half NdotV, half roughness) +{ +#if 0 + // Original formulation: + // lambda_v = (-1 + sqrt(a2 * (1 - NdotL2) / NdotL2 + 1)) * 0.5f; + // lambda_l = (-1 + sqrt(a2 * (1 - NdotV2) / NdotV2 + 1)) * 0.5f; + // G = 1 / (1 + lambda_v + lambda_l); + + // Reorder code to be more optimal + half a = roughness; + half a2 = a * a; + + half lambdaV = NdotL * sqrt((-NdotV * a2 + NdotV) * NdotV + a2); + half lambdaL = NdotV * sqrt((-NdotL * a2 + NdotL) * NdotL + a2); + + // Simplify visibility term: (2.0f * NdotL * NdotV) / ((4.0f * NdotL * NdotV) * (lambda_v + lambda_l + 1e-5f)); + return 0.5f / (lambdaV + lambdaL + 1e-5f); // This function is not intended to be running on Mobile, + // therefore epsilon is smaller than can be represented by half +#else + // Approximation of the above formulation (simplify the sqrt, not mathematically correct but close enough) + half a = roughness; + half lambdaV = NdotL * (NdotV * (1 - a) + a); + half lambdaL = NdotV * (NdotL * (1 - a) + a); + + return 0.5f / (lambdaV + lambdaL + 1e-5f); +#endif +} + +inline half GGXTerm (half NdotH, half roughness) +{ + half a2 = roughness * roughness; + half d = (NdotH * a2 - NdotH) * NdotH + 1.0f; // 2 mad + return UNITY_INV_PI * a2 / (d * d + 1e-7f); // This function is not intended to be running on Mobile, + // therefore epsilon is smaller than what can be represented by half +} + +inline half3 FresnelTerm (half3 F0, half cosA) +{ + half t = pow5 (1 - cosA); // ala Schlick interpoliation + return F0 + (1-F0) * t; +} + +inline half3 FresnelLerp (half3 F0, half F90, half cosA) +{ + half t = pow5 (1 - cosA); // ala Schlick interpoliation + return lerp (F0, F90, t); +} + +// Note: Disney diffuse must be multiply by diffuseAlbedo / PI. This is done outside of this function. +inline half DisneyDiffuse(half NdotV, half NdotL, half LdotH, half perceptualRoughness) +{ + half fd90 = 0.5 + 2 * LdotH * LdotH * perceptualRoughness; + // Two schlick fresnel term + half lightScatter = (1 + (fd90 - 1) * pow5(1 - NdotL)); + half viewScatter = (1 + (fd90 - 1) * pow5(1 - NdotV)); + + return lightScatter * viewScatter; +} + +// Main Physically Based BRDF +// Derived from Disney work and based on Torrance-Sparrow micro-facet model +// +// BRDF = kD / pi + kS * (D * V * F) / 4 +// I = BRDF * NdotL +// +// * NDF (depending on UNITY_BRDF_GGX): +// a) Normalized BlinnPhong +// b) GGX +// * Smith for Visiblity term +// * Schlick approximation for Fresnel +SpecularLightData calculatePhysicsBasedSpecularLight(half3 specColor, half oneMinusReflectivity, half smoothness, half3 normal, half3 viewDir, half3 lightdir, half3 lightColor, half3 indirectDiffuse, half3 indirectSpecular) +{ + half perceptualRoughness = SmoothnessToPerceptualRoughness (smoothness); + half3 halfDir = safeNormalize (lightdir + viewDir); + +// NdotV should not be negative for visible pixels, but it can happen due to perspective projection and normal mapping +// In this case normal should be modified to become valid (i.e facing camera) and not cause weird artifacts. +// but this operation adds few ALU and users may not want it. Alternative is to simply take the abs of NdotV (less correct but works too). +// Following define allow to control this. Set it to 0 if ALU is critical on your platform. +// This correction is interesting for GGX with SmithJoint visibility function because artifacts are more visible in this case due to highlight edge of rough surface +// Edit: Disable this code by default for now as it is not compatible with two sided lighting used in SpeedTree. +#define UNITY_HANDLE_CORRECTLY_NEGATIVE_NDOTV 0 + +#if UNITY_HANDLE_CORRECTLY_NEGATIVE_NDOTV + // The amount we shift the normal toward the view vector is defined by the dot product. + half shiftAmount = dot(normal, viewDir); + normal = shiftAmount < 0.0f ? normal + viewDir * (-shiftAmount + 1e-5f) : normal; + // A re-normalization should be applied here but as the shift is small we don't do it to save ALU. + //normal = normalize(normal); + + half nv = saturate(dot(normal, viewDir)); // TODO: this saturate should no be necessary here +#else + half nv = abs(dot(normal, viewDir)); // This abs allow to limit artifact +#endif + + half nl = saturate(dot(normal, lightdir)); + half nh = saturate(dot(normal, halfDir)); + + half lv = saturate(dot(lightdir, viewDir)); + half lh = saturate(dot(lightdir, halfDir)); + + // Diffuse term + half diffuseTerm = DisneyDiffuse(nv, nl, lh, perceptualRoughness) * nl; + + // Specular term + // HACK: theoretically we should divide diffuseTerm by Pi and not multiply specularTerm! + // BUT 1) that will make shader look significantly darker than Legacy ones + // and 2) on engine side "Non-important" lights have to be divided by Pi too in cases when they are injected into ambient SH + half roughness = PerceptualRoughnessToRoughness(perceptualRoughness); + half V = SmithJointGGXVisibilityTerm (nl, nv, roughness); + half D = GGXTerm (nh, roughness); + + half specularTerm = V*D * UNITY_PI; // Torrance-Sparrow model, Fresnel is applied later + +# ifdef UNITY_COLORSPACE_GAMMA + specularTerm = sqrt(max(1e-4h, specularTerm)); +# endif + + // specularTerm * nl can be NaN on Metal in some cases, use max() to make sure it's a sane value + specularTerm = max(0, specularTerm * nl); + + // surfaceReduction = Int D(NdotH) * NdotH * Id(NdotL>0) dH = 1/(roughness^2+1) + half surfaceReduction; +# ifdef UNITY_COLORSPACE_GAMMA + surfaceReduction = 1.0 - 0.28f * roughness * perceptualRoughness; // 1-0.28*x^3 as approximation for (1/(x^4+1))^(1/2.2) on the domain [0;1] +# else + surfaceReduction = 1.0 / (roughness*roughness + 1.0); // fade \in [0.5;1] +# endif + + // To provide true Lambert lighting, we need to be able to kill specular completely. + specularTerm *= any(specColor) ? 1.0 : 0.0; + + half grazingTerm = saturate(smoothness + (1-oneMinusReflectivity)); + + SpecularLightData outData = (SpecularLightData)0; + outData.lighting = indirectDiffuse + lightColor * diffuseTerm; + outData.specular = (specularTerm * lightColor * FresnelTerm (specColor, lh)) + (surfaceReduction * indirectSpecular * FresnelLerp (specColor, grazingTerm, nv)); + return outData; +} + +#endif // _SPECULAR && _SPECULAR_GLOSSMAP + +#endif // SPRITE_SPECULAR_INCLUDED \ No newline at end of file diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/CGIncludes/SpriteSpecular.cginc.meta b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/CGIncludes/SpriteSpecular.cginc.meta new file mode 100644 index 00000000..a9fdc4f2 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/CGIncludes/SpriteSpecular.cginc.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: f195336fc94457241a37a0aa85923681 +timeCreated: 1494092582 +licenseType: Free +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/CGIncludes/SpriteUnlit.cginc b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/CGIncludes/SpriteUnlit.cginc new file mode 100644 index 00000000..4385ffcc --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/CGIncludes/SpriteUnlit.cginc @@ -0,0 +1,72 @@ +#ifndef SPRITE_UNLIT_INCLUDED +#define SPRITE_UNLIT_INCLUDED + +#include "ShaderShared.cginc" + +//////////////////////////////////////// +// Vertex structs +// + +struct VertexInput +{ + float4 vertex : POSITION; + float4 texcoord : TEXCOORD0; + fixed4 color : COLOR; + UNITY_VERTEX_INPUT_INSTANCE_ID +}; + +struct VertexOutput +{ + float4 pos : SV_POSITION; + float2 texcoord : TEXCOORD0; + fixed4 color : COLOR; +#if defined(_FOG) + UNITY_FOG_COORDS(1) +#endif // _FOG + + UNITY_VERTEX_OUTPUT_STEREO +}; + +//////////////////////////////////////// +// Vertex program +// + +VertexOutput vert(VertexInput input) +{ + VertexOutput output; + + UNITY_SETUP_INSTANCE_ID(input); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output); + + output.pos = calculateLocalPos(input.vertex); + output.texcoord = calculateTextureCoord(input.texcoord); + output.color = calculateVertexColor(input.color); + +#if defined(_FOG) + UNITY_TRANSFER_FOG(output,output.pos); +#endif // _FOG + + return output; +} + +//////////////////////////////////////// +// Fragment program +// + + + + +fixed4 frag(VertexOutput input) : SV_Target +{ + fixed4 texureColor = calculateTexturePixel(input.texcoord.xy); + ALPHA_CLIP(texureColor, input.color) + + fixed4 pixel = calculatePixel(texureColor, input.color); + + COLORISE(pixel) + APPLY_FOG(pixel, input) + + return pixel; +} + +#endif // SPRITE_UNLIT_INCLUDED \ No newline at end of file diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/CGIncludes/SpriteUnlit.cginc.meta b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/CGIncludes/SpriteUnlit.cginc.meta new file mode 100644 index 00000000..1e8d9746 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/CGIncludes/SpriteUnlit.cginc.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 072e7b07ec7fb1346a9dcd3bcbbb7111 +timeCreated: 1494092582 +licenseType: Free +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/CGIncludes/SpriteVertexLighting.cginc b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/CGIncludes/SpriteVertexLighting.cginc new file mode 100644 index 00000000..3d8ee540 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/CGIncludes/SpriteVertexLighting.cginc @@ -0,0 +1,473 @@ +#ifndef SPRITE_VERTEX_LIGHTING_INCLUDED +#define SPRITE_VERTEX_LIGHTING_INCLUDED + +#include "ShaderShared.cginc" +#include "SpriteLighting.cginc" +#include "SpriteSpecular.cginc" + +//////////////////////////////////////// +// Defines +// + +//Define to use spot lights (more expensive) +#define SPOT_LIGHTS + +//Have to process lighting per pixel if using normal maps or a diffuse ramp or rim lighting or specular +#if defined(_NORMALMAP) || defined(_DIFFUSE_RAMP) || defined(_RIM_LIGHTING) || defined(SPECULAR) +#define PER_PIXEL_LIGHTING +#endif + +//Turn off bump mapping and diffuse ramping on older shader models as they dont support needed number of outputs +#if defined(PER_PIXEL_LIGHTING) && (SHADER_TARGET < 30) + #undef PER_PIXEL_LIGHTING + #undef _NORMALMAP + #undef _DIFFUSE_RAMP + #undef _RIM_LIGHTING +#endif + +//In D3D9 only have a max of 9 TEXCOORD so can't have diffuse ramping or fog or rim lighting if processing lights per pixel +#if defined(SHADER_API_D3D9) && defined(PER_PIXEL_LIGHTING) + #if defined(_NORMALMAP) + #undef _DIFFUSE_RAMP + #undef _FOG + #undef _RIM_LIGHTING + #elif defined(_DIFFUSE_RAMP) + #undef _FOG + #undef _RIM_LIGHTING + #elif defined(_RIM_LIGHTING) + #undef _FOG + #undef _DIFFUSE_RAMP + #else + #undef _DIFFUSE_RAMP + #undef _RIM_LIGHTING + #endif +#endif + +#if defined(PER_PIXEL_LIGHTING) + #if defined(_NORMALMAP) && defined(_DIFFUSE_RAMP) + #define ATTENUATIONS TEXCOORD9 + #if defined(_RIM_LIGHTING) + #define _POS_WORLD_INDEX TEXCOORD10 + #define _FOG_COORD_INDEX 11 + #else + #define _FOG_COORD_INDEX 10 + #endif + #elif defined(_NORMALMAP) != defined(_DIFFUSE_RAMP) + #define ATTENUATIONS TEXCOORD8 + #if defined(_RIM_LIGHTING) + #define _POS_WORLD_INDEX TEXCOORD9 + #define _FOG_COORD_INDEX 10 + #else + #define _FOG_COORD_INDEX 9 + #endif + #else //!_DIFFUSE_RAMP && !_NORMALMAP + #if defined(_RIM_LIGHTING) + #define _POS_WORLD_INDEX TEXCOORD8 + #define _FOG_COORD_INDEX 9 + #else + #define _FOG_COORD_INDEX 8 + #endif + #endif +#else //!PER_PIXEL_LIGHTING + #define _FOG_COORD_INDEX 2 +#endif + +//////////////////////////////////////// +// Vertex output struct +// + +struct VertexOutput +{ + float4 pos : SV_POSITION; + fixed4 color : COLOR; + float3 texcoord : TEXCOORD0; + +#if defined(PER_PIXEL_LIGHTING) + + half4 VertexLightInfo0 : TEXCOORD1; + half4 VertexLightInfo1 : TEXCOORD2; + half4 VertexLightInfo2 : TEXCOORD3; + half4 VertexLightInfo3 : TEXCOORD4; + half4 VertexLightInfo4 : TEXCOORD5; + + #if defined(_NORMALMAP) + half4 normalWorld : TEXCOORD6; + half4 tangentWorld : TEXCOORD7; + half4 binormalWorld : TEXCOORD8; + #else + half3 normalWorld : TEXCOORD6; + half3 VertexLightInfo5 : TEXCOORD7; + #endif + #if defined(_DIFFUSE_RAMP) + half4 LightAttenuations : ATTENUATIONS; + #endif + #if defined(_RIM_LIGHTING) + float4 posWorld : _POS_WORLD_INDEX; + #endif + +#else //!PER_PIXEL_LIGHTING + + half3 FullLighting : TEXCOORD1; + +#endif // !PER_PIXEL_LIGHTING + +#if defined(_FOG) + UNITY_FOG_COORDS(_FOG_COORD_INDEX) +#endif // _FOG + + UNITY_VERTEX_OUTPUT_STEREO +}; + +//////////////////////////////////////// +// Light calculations +// + +struct VertexLightInfo +{ + half3 lightDirection; + fixed3 lightColor; + +#if defined(_DIFFUSE_RAMP) + float attenuation; +#endif // _DIFFUSE_RAMP +}; + +inline VertexLightInfo getVertexLightAttenuatedInfo(int index, float3 viewPos) +{ + VertexLightInfo lightInfo; + + //For directional lights unity_LightPosition.w is set to zero + lightInfo.lightDirection = unity_LightPosition[index].xyz - viewPos.xyz * unity_LightPosition[index].w; + float lengthSq = dot(lightInfo.lightDirection, lightInfo.lightDirection); + + // don't produce NaNs if some vertex position overlaps with the light + lengthSq = max(lengthSq, 0.000001); + + lightInfo.lightDirection *= rsqrt(lengthSq); + + float attenuation = 1.0 / (1.0 + lengthSq * unity_LightAtten[index].z); + +#if defined(SPOT_LIGHTS) + //Spot light attenuation - for non-spot lights unity_LightAtten.x is set to -1 and y is set to 1 + { + float rho = max (0, dot(lightInfo.lightDirection, unity_SpotDirection[index].xyz)); + float spotAtt = (rho - unity_LightAtten[index].x) * unity_LightAtten[index].y; + attenuation *= saturate(spotAtt); + } +#endif // SPOT_LIGHTS + + //If using a diffuse ramp texture then need to pass through the lights attenuation, otherwise premultiply the light color with it +#if defined(_DIFFUSE_RAMP) + lightInfo.lightColor = unity_LightColor[index].rgb; + lightInfo.attenuation = attenuation; +#else + lightInfo.lightColor = unity_LightColor[index].rgb * attenuation; +#endif // _DIFFUSE_RAMP + + return lightInfo; +} + +//Magic constants used to tweak ambient to approximate pixel shader spherical harmonics +static const fixed3 worldUp = fixed3(0, 1, 0); +static const float skyGroundDotMul = 2.5; +static const float minEquatorMix = 0.5; +static const float equatorColorBlur = 0.33; + +fixed3 calculateAmbientLight(half3 normalWorld) +{ +#if defined(_SPHERICAL_HARMONICS) + float upDot = dot(normalWorld, worldUp); + + //Fade between a flat lerp from sky to ground and a 3 way lerp based on how bright the equator light is. + //This simulates how directional lights get blurred using spherical harmonics + + //Work out color from ground and sky, ignoring equator + float adjustedDot = upDot * skyGroundDotMul; + fixed3 skyGroundColor = lerp(unity_AmbientGround, unity_AmbientSky, saturate((adjustedDot + 1.0) * 0.5)); + + //Work out equator lights brightness + float equatorBright = saturate(dot(unity_AmbientEquator.rgb, unity_AmbientEquator.rgb)); + + //Blur equator color with sky and ground colors based on how bright it is. + fixed3 equatorBlurredColor = lerp(unity_AmbientEquator, saturate(unity_AmbientEquator + unity_AmbientGround + unity_AmbientSky), equatorBright * equatorColorBlur); + + //Work out 3 way lerp inc equator light + fixed3 equatorColor = lerp(equatorBlurredColor, unity_AmbientGround, -upDot) * step(upDot, 0) + lerp(equatorBlurredColor, unity_AmbientSky, upDot) * step(0, upDot); + + //Mix the two colors together based on how bright the equator light is + return lerp(skyGroundColor, equatorColor, saturate(equatorBright + minEquatorMix)); + +#else // !_SPHERICAL_HARMONICS + + //Flat ambient is just the sky color + return unity_AmbientSky.rgb; + +#endif // !_SPHERICAL_HARMONICS +} + +//////////////////////////////////////// +// Light Packing Functions +// + +#if defined(_DIFFUSE_RAMP) + +inline fixed3 calculateLightDiffuse(fixed3 lightColor, half3 viewNormal, half3 lightViewDir, float attenuation) +{ + float angleDot = max(0, dot(viewNormal, lightViewDir)); + fixed3 lightDiffuse = calculateRampedDiffuse(lightColor, attenuation, angleDot); + return lightDiffuse; +} + +#else + +inline fixed3 calculateLightDiffuse(fixed3 attenuatedLightColor, half3 viewNormal, half3 lightViewDir) +{ + float angleDot = max(0, dot(viewNormal, lightViewDir)); + fixed3 lightDiffuse = attenuatedLightColor * angleDot; + + return lightDiffuse; +} + +#endif // _NORMALMAP + + +#if defined(PER_PIXEL_LIGHTING) + +#define VERTEX_LIGHT_0_DIR VertexLightInfo0.xyz +#define VERTEX_LIGHT_0_R VertexLightInfo4.x +#define VERTEX_LIGHT_0_G VertexLightInfo4.y +#define VERTEX_LIGHT_0_B VertexLightInfo4.z + +#define VERTEX_LIGHT_1_DIR VertexLightInfo1.xyz +#define VERTEX_LIGHT_1_R VertexLightInfo0.w +#define VERTEX_LIGHT_1_G VertexLightInfo1.w +#define VERTEX_LIGHT_1_B VertexLightInfo2.w + +#define VERTEX_LIGHT_2_DIR VertexLightInfo2.xyz +#define VERTEX_LIGHT_2_R VertexLightInfo3.w +#define VERTEX_LIGHT_2_G VertexLightInfo4.w +#define VERTEX_LIGHT_2_B texcoord.z + +#define VERTEX_LIGHT_3_DIR VertexLightInfo3.xyz + +#if defined(_NORMALMAP) + #define VERTEX_LIGHT_3_R normalWorld.w + #define VERTEX_LIGHT_3_G tangentWorld.w + #define VERTEX_LIGHT_3_B binormalWorld.w +#else + #define VERTEX_LIGHT_3_R VertexLightInfo5.x + #define VERTEX_LIGHT_3_G VertexLightInfo5.y + #define VERTEX_LIGHT_3_B VertexLightInfo5.z +#endif + +#if defined(_DIFFUSE_RAMP) + + #define LIGHT_DIFFUSE_ATTEN_0 LightAttenuations.x + #define LIGHT_DIFFUSE_ATTEN_1 LightAttenuations.y + #define LIGHT_DIFFUSE_ATTEN_2 LightAttenuations.z + #define LIGHT_DIFFUSE_ATTEN_3 LightAttenuations.w + + #define PACK_VERTEX_LIGHT_DIFFUSE(index, output, lightInfo) \ + { \ + output.LIGHT_DIFFUSE_ATTEN_##index = lightInfo.attenuation; \ + } + + #define ADD_VERTEX_LIGHT_DIFFUSE(index, diffuse, input, lightColor, viewNormal, lightViewDir) \ + { \ + diffuse += calculateLightDiffuse(lightColor, viewNormal, lightViewDir, input.LIGHT_DIFFUSE_ATTEN_##index); \ + } +#else + #define PACK_VERTEX_LIGHT_DIFFUSE(index, output, lightInfo) + #define ADD_VERTEX_LIGHT_DIFFUSE(index, diffuse, input, lightColor, viewNormal, lightViewDir) \ + { \ + diffuse += calculateLightDiffuse(lightColor, viewNormal, lightViewDir); \ + } +#endif + +#define PACK_VERTEX_LIGHT(index, output, viewPos) \ + { \ + VertexLightInfo lightInfo = getVertexLightAttenuatedInfo(index, viewPos); \ + output.VERTEX_LIGHT_##index##_DIR = lightInfo.lightDirection; \ + output.VERTEX_LIGHT_##index##_R = lightInfo.lightColor.r; \ + output.VERTEX_LIGHT_##index##_G = lightInfo.lightColor.g; \ + output.VERTEX_LIGHT_##index##_B = lightInfo.lightColor.b; \ + PACK_VERTEX_LIGHT_DIFFUSE(index, output, lightInfo); \ + } + +#define ADD_VERTEX_LIGHT(index, input, viewNormal, diffuse) \ + { \ + half3 lightViewDir = input.VERTEX_LIGHT_##index##_DIR; \ + fixed3 lightColor = fixed3(input.VERTEX_LIGHT_##index##_R, input.VERTEX_LIGHT_##index##_G, input.VERTEX_LIGHT_##index##_B); \ + ADD_VERTEX_LIGHT_DIFFUSE(index, diffuse, input, lightColor, viewNormal, lightViewDir) \ + } + +#if defined(SPECULAR) + +#define ADD_VERTEX_LIGHT_SPEC(index, input, viewNormal, specData, combinedLightData, indirectDiffuse, indirectSpecular) \ + { \ + half3 lightViewDir = input.VERTEX_LIGHT_##index##_DIR; \ + fixed3 lightColor = fixed3(input.VERTEX_LIGHT_##index##_R, input.VERTEX_LIGHT_##index##_G, input.VERTEX_LIGHT_##index##_B); \ + SpecularLightData lightData = calculatePhysicsBasedSpecularLight(specData.specColor, specData.oneMinusReflectivity, specData.smoothness, viewNormal, fixed3(0,0,1), lightViewDir, lightColor, indirectDiffuse, indirectSpecular); \ + combinedLightData.lighting += lightData.lighting; \ + combinedLightData.specular += lightData.specular; \ + } + +#endif + +#else //!PER_PIXEL_LIGHTING + +//////////////////////////////////////// +// Vertex Only Functions +// + +inline fixed3 calculateLightDiffuse(int index, float3 viewPos, half3 viewNormal) +{ + VertexLightInfo lightInfo = getVertexLightAttenuatedInfo(index, viewPos); + float angleDot = max(0, dot(viewNormal, lightInfo.lightDirection)); + return lightInfo.lightColor * angleDot; +} + +#endif // !PER_PIXEL_LIGHTING + +//////////////////////////////////////// +// Vertex program +// + +VertexOutput vert(VertexInput input) +{ + VertexOutput output; + + UNITY_SETUP_INSTANCE_ID(input); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output); + + output.pos = calculateLocalPos(input.vertex); + output.color = calculateVertexColor(input.color); + output.texcoord = float3(calculateTextureCoord(input.texcoord), 0); + + float3 viewPos = UnityObjectToViewPos(input.vertex); //float3 viewPos = mul(UNITY_MATRIX_MV, input.vertex); // +#if defined(FIXED_NORMALS_BACKFACE_RENDERING) || defined(_RIM_LIGHTING) + float4 powWorld = calculateWorldPos(input.vertex); +#endif + + float backFaceSign = 1; +#if defined(FIXED_NORMALS_BACKFACE_RENDERING) + backFaceSign = calculateBackfacingSign(powWorld.xyz); +#endif + +#if defined(PER_PIXEL_LIGHTING) + + #if defined(_RIM_LIGHTING) + output.posWorld = powWorld; + #endif + + PACK_VERTEX_LIGHT(0, output, viewPos) + PACK_VERTEX_LIGHT(1, output, viewPos) + PACK_VERTEX_LIGHT(2, output, viewPos) + PACK_VERTEX_LIGHT(3, output, viewPos) + + output.normalWorld.xyz = calculateSpriteWorldNormal(input, backFaceSign); + + #if defined(_NORMALMAP) + output.tangentWorld.xyz = calculateWorldTangent(input.tangent); + output.binormalWorld.xyz = calculateSpriteWorldBinormal(input, output.normalWorld, output.tangentWorld, backFaceSign); + #endif + +#else // !PER_PIXEL_LIGHTING + + //Just pack full lighting + float3 viewNormal = calculateSpriteViewNormal(input, backFaceSign); + //Get Ambient diffuse + float3 normalWorld = calculateSpriteWorldNormal(input, backFaceSign); + fixed3 ambient = calculateAmbientLight(normalWorld); + + fixed3 diffuse = calculateLightDiffuse(0, viewPos, viewNormal); + diffuse += calculateLightDiffuse(1, viewPos, viewNormal); + diffuse += calculateLightDiffuse(2, viewPos, viewNormal); + diffuse += calculateLightDiffuse(3, viewPos, viewNormal); + + output.FullLighting = ambient + diffuse; + +#endif // !PER_PIXEL_LIGHTING + +#if defined(_FOG) + UNITY_TRANSFER_FOG(output, output.pos); +#endif // _FOG + + return output; +} + +//////////////////////////////////////// +// Fragment program +// + +fixed4 frag(VertexOutput input) : SV_Target +{ + fixed4 texureColor = calculateTexturePixel(input.texcoord.xy); + ALPHA_CLIP(texureColor, input.color) + +#if defined(PER_PIXEL_LIGHTING) + + #if defined(_NORMALMAP) + half3 normalWorld = calculateNormalFromBumpMap(input.texcoord.xy, input.tangentWorld.xyz, input.binormalWorld.xyz, input.normalWorld.xyz); + #else + half3 normalWorld = input.normalWorld.xyz; + #endif + + //Get Ambient diffuse + fixed3 ambient = calculateAmbientLight(normalWorld); + + half3 normalView = normalize(mul((float3x3)UNITY_MATRIX_V, normalWorld)); + +#if defined(SPECULAR) + + SpecularCommonData specData = getSpecularData(input.texcoord.xy, texureColor, input.color); + + SpecularLightData combinedLightData = (SpecularLightData)0; + ADD_VERTEX_LIGHT_SPEC(0, input, normalView, specData, combinedLightData, ambient, unity_IndirectSpecColor.rgb) + ADD_VERTEX_LIGHT_SPEC(1, input, normalView, specData, combinedLightData, fixed3(0,0,0), fixed3(0,0,0)) + ADD_VERTEX_LIGHT_SPEC(2, input, normalView, specData, combinedLightData, fixed3(0,0,0), fixed3(0,0,0)) + ADD_VERTEX_LIGHT_SPEC(3, input, normalView, specData, combinedLightData, fixed3(0,0,0), fixed3(0,0,0)) + + fixed4 pixel = calculateLitPixel(fixed4(specData.diffColor, specData.alpha), combinedLightData.lighting); + pixel.rgb += combinedLightData.specular * specData.alpha; + + APPLY_EMISSION_SPECULAR(pixel, input.texcoord) + +#else + + //Find vertex light diffuse + fixed3 diffuse = fixed3(0,0,0); + + //Add each vertex light to diffuse + ADD_VERTEX_LIGHT(0, input, normalView, diffuse) + ADD_VERTEX_LIGHT(1, input, normalView, diffuse) + ADD_VERTEX_LIGHT(2, input, normalView, diffuse) + ADD_VERTEX_LIGHT(3, input, normalView, diffuse) + + fixed3 lighting = ambient + diffuse; + + APPLY_EMISSION(lighting, input.texcoord.xy) + + fixed4 pixel = calculateLitPixel(texureColor, input.color, lighting); + +#endif + +#if defined(_RIM_LIGHTING) + pixel.rgb = applyRimLighting(input.posWorld, normalWorld, pixel); +#endif + +#else // !PER_PIXEL_LIGHTING + + APPLY_EMISSION(input.FullLighting, input.texcoord.xy) + + fixed4 pixel = calculateLitPixel(texureColor, input.color, input.FullLighting); + +#endif // !PER_PIXEL_LIGHTING + + COLORISE(pixel) + APPLY_FOG(pixel, input) + + return pixel; +} + +#endif // SPRITE_VERTEX_LIGHTING_INCLUDED diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/CGIncludes/SpriteVertexLighting.cginc.meta b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/CGIncludes/SpriteVertexLighting.cginc.meta new file mode 100644 index 00000000..59870543 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/CGIncludes/SpriteVertexLighting.cginc.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: c739dcf9dbcab944898d0b796e11afb9 +timeCreated: 1494092582 +licenseType: Free +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/CameraDepthNormalsTexture.shader b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/CameraDepthNormalsTexture.shader new file mode 100644 index 00000000..0c80ebc3 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/CameraDepthNormalsTexture.shader @@ -0,0 +1,522 @@ +Shader "Hidden/Sprite-CameraDepthNormalsTexture" { + +// Use this shader to render a DepthNormals texture for a camera with correct sprite normals (using camera.RenderWithShader with replacement tag "RenderType") + +Properties { + _MainTex ("", 2D) = "white" {} + _Cutoff ("", Float) = 0.5 + _Color ("", Color) = (1,1,1,1) +} + +SubShader { + Tags { "RenderType"="Sprite" } + Pass { + Cull Off +CGPROGRAM +#pragma target 3.0 +#pragma vertex vert +#pragma fragment frag +#include "UnityCG.cginc" +#include "CGIncludes/ShaderShared.cginc" +struct v2f { + float4 pos : SV_POSITION; + float2 uv : TEXCOORD0; + float4 nz : TEXCOORD1; + UNITY_VERTEX_OUTPUT_STEREO +}; +uniform float4 _FixedNormal; +v2f vert( appdata_base v ) { + v2f o; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.pos = UnityObjectToClipPos(v.vertex); + o.uv = calculateTextureCoord(v.texcoord); + o.nz.xyz = COMPUTE_VIEW_NORMAL; + o.nz.w = COMPUTE_DEPTH_01; + return o; +} +uniform fixed _Cutoff; +fixed4 frag(v2f i) : SV_Target { + fixed4 texcol = calculateTexturePixel(i.uv ); + float alpha = texcol.a*_Color.a; + clip( alpha - _Cutoff ); + return EncodeDepthNormal (i.nz.w, i.nz.xyz); +} +ENDCG + } + } + +SubShader { + Tags { "RenderType"="SpriteViewSpaceFixedNormal" } + Pass { + Cull Off +CGPROGRAM +#pragma target 3.0 +#pragma vertex vert +#pragma fragment frag +#include "UnityCG.cginc" +#include "CGIncludes/ShaderShared.cginc" +#include "CGIncludes/SpriteLighting.cginc" +struct v2f { + float4 pos : SV_POSITION; + float2 uv : TEXCOORD0; + float4 nz : TEXCOORD1; + UNITY_VERTEX_OUTPUT_STEREO +}; +v2f vert( appdata_base v ) { + v2f o; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.pos = UnityObjectToClipPos(v.vertex); + o.uv = calculateTextureCoord(v.texcoord); + o.nz.xyz = getFixedNormal(); + o.nz.w = COMPUTE_DEPTH_01; + return o; +} +uniform fixed _Cutoff; +fixed4 frag(v2f i) : SV_Target { + fixed4 texcol = calculateTexturePixel(i.uv ); + float alpha = texcol.a*_Color.a; + clip( alpha - _Cutoff ); + return EncodeDepthNormal (i.nz.w, i.nz.xyz); +} +ENDCG + } + } + +SubShader { + Tags { "RenderType"="SpriteModelSpaceFixedNormal" } + Pass { + Cull Off +CGPROGRAM +#pragma target 3.0 +#pragma vertex vert +#pragma fragment frag +#include "UnityCG.cginc" +#include "CGIncludes/ShaderShared.cginc" +#include "CGIncludes/SpriteLighting.cginc" +struct v2f { + float4 pos : SV_POSITION; + float2 uv : TEXCOORD0; + float4 nz : TEXCOORD1; + UNITY_VERTEX_OUTPUT_STEREO +}; +v2f vert( appdata_base v ) { + v2f o; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.pos = UnityObjectToClipPos(v.vertex); + o.uv = calculateTextureCoord(v.texcoord); + float3 worldPos = mul(unity_ObjectToWorld, v.vertex); + float3 normal = getFixedNormal(); +//Only do this if backface is enabled :/ + normal *= calculateBackfacingSign(worldPos.xyz); +// + o.nz.xyz = normalize(mul((float3x3)UNITY_MATRIX_IT_MV, normal)); + o.nz.w = COMPUTE_DEPTH_01; + return o; +} +uniform fixed _Cutoff; +fixed4 frag(v2f i) : SV_Target { + fixed4 texcol = calculateTexturePixel(i.uv ); + float alpha = texcol.a*_Color.a; + clip( alpha - _Cutoff ); + return EncodeDepthNormal (i.nz.w, i.nz.xyz); +} +ENDCG + } + } + +SubShader { + Tags { "RenderType"="Opaque" } + Pass { +CGPROGRAM +#pragma target 3.0 +#pragma vertex vert +#pragma fragment frag +#include "UnityCG.cginc" +struct v2f { + float4 pos : SV_POSITION; + float4 nz : TEXCOORD0; + UNITY_VERTEX_OUTPUT_STEREO +}; +v2f vert( appdata_base v ) { + v2f o; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.pos = UnityObjectToClipPos(v.vertex); + o.nz.xyz = COMPUTE_VIEW_NORMAL; + o.nz.w = COMPUTE_DEPTH_01; + return o; +} +fixed4 frag(v2f i) : SV_Target { + return EncodeDepthNormal (i.nz.w, i.nz.xyz); +} +ENDCG + } +} + +SubShader { + Tags { "RenderType"="TransparentCutout" } + Pass { +CGPROGRAM +#pragma target 3.0 +#pragma vertex vert +#pragma fragment frag +#include "UnityCG.cginc" +struct v2f { + float4 pos : SV_POSITION; + float2 uv : TEXCOORD0; + float4 nz : TEXCOORD1; + UNITY_VERTEX_OUTPUT_STEREO +}; +uniform float4 _MainTex_ST; +v2f vert( appdata_base v ) { + v2f o; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.pos = UnityObjectToClipPos(v.vertex); + o.uv = TRANSFORM_TEX(v.texcoord, _MainTex); + o.nz.xyz = COMPUTE_VIEW_NORMAL; + o.nz.w = COMPUTE_DEPTH_01; + return o; +} +uniform sampler2D _MainTex; +uniform fixed _Cutoff; +uniform fixed4 _Color; +fixed4 frag(v2f i) : SV_Target { + fixed4 texcol = tex2D( _MainTex, i.uv ); + clip( texcol.a*_Color.a - _Cutoff ); + return EncodeDepthNormal (i.nz.w, i.nz.xyz); +} +ENDCG + } +} + +SubShader { + Tags { "RenderType"="TreeBark" } + Pass { +CGPROGRAM +#pragma target 3.0 +#pragma vertex vert +#pragma fragment frag +#include "UnityCG.cginc" +#include "Lighting.cginc" +#include "UnityBuiltin3xTreeLibrary.cginc" +struct v2f { + float4 pos : SV_POSITION; + float2 uv : TEXCOORD0; + float4 nz : TEXCOORD1; + UNITY_VERTEX_OUTPUT_STEREO +}; +v2f vert( appdata_full v ) { + v2f o; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + TreeVertBark(v); + + o.pos = UnityObjectToClipPos(v.vertex); + o.uv = v.texcoord.xy; + o.nz.xyz = COMPUTE_VIEW_NORMAL; + o.nz.w = COMPUTE_DEPTH_01; + return o; +} +fixed4 frag( v2f i ) : SV_Target { + return EncodeDepthNormal (i.nz.w, i.nz.xyz); +} +ENDCG + } +} + +SubShader { + Tags { "RenderType"="TreeLeaf" } + Pass { +CGPROGRAM +#pragma target 3.0 +#pragma vertex vert +#pragma fragment frag +#include "UnityCG.cginc" +#include "Lighting.cginc" +#include "UnityBuiltin3xTreeLibrary.cginc" +struct v2f { + float4 pos : SV_POSITION; + float2 uv : TEXCOORD0; + float4 nz : TEXCOORD1; + UNITY_VERTEX_OUTPUT_STEREO +}; +v2f vert( appdata_full v ) { + v2f o; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + TreeVertLeaf(v); + + o.pos = UnityObjectToClipPos(v.vertex); + o.uv = v.texcoord.xy; + o.nz.xyz = COMPUTE_VIEW_NORMAL; + o.nz.w = COMPUTE_DEPTH_01; + return o; +} +uniform sampler2D _MainTex; +uniform fixed _Cutoff; +fixed4 frag( v2f i ) : SV_Target { + half alpha = tex2D(_MainTex, i.uv).a; + + clip (alpha - _Cutoff); + return EncodeDepthNormal (i.nz.w, i.nz.xyz); +} +ENDCG + } +} + +SubShader { + Tags { "RenderType"="TreeOpaque" "DisableBatching"="True" } + Pass { +CGPROGRAM +#pragma target 3.0 +#pragma vertex vert +#pragma fragment frag +#include "UnityCG.cginc" +#include "TerrainEngine.cginc" +struct v2f { + float4 pos : SV_POSITION; + float4 nz : TEXCOORD0; + UNITY_VERTEX_OUTPUT_STEREO +}; +struct appdata { + float4 vertex : POSITION; + float3 normal : NORMAL; + fixed4 color : COLOR; + UNITY_VERTEX_INPUT_INSTANCE_ID +}; +v2f vert( appdata v ) { + v2f o; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + TerrainAnimateTree(v.vertex, v.color.w); + o.pos = UnityObjectToClipPos(v.vertex); + o.nz.xyz = COMPUTE_VIEW_NORMAL; + o.nz.w = COMPUTE_DEPTH_01; + return o; +} +fixed4 frag(v2f i) : SV_Target { + return EncodeDepthNormal (i.nz.w, i.nz.xyz); +} +ENDCG + } +} + +SubShader { + Tags { "RenderType"="TreeTransparentCutout" "DisableBatching"="True" } + Pass { + Cull Back +CGPROGRAM +#pragma target 3.0 +#pragma vertex vert +#pragma fragment frag +#include "UnityCG.cginc" +#include "TerrainEngine.cginc" + +struct v2f { + float4 pos : SV_POSITION; + float2 uv : TEXCOORD0; + float4 nz : TEXCOORD1; + UNITY_VERTEX_OUTPUT_STEREO +}; +struct appdata { + float4 vertex : POSITION; + float3 normal : NORMAL; + fixed4 color : COLOR; + float4 texcoord : TEXCOORD0; + UNITY_VERTEX_INPUT_INSTANCE_ID +}; +v2f vert( appdata v ) { + v2f o; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + TerrainAnimateTree(v.vertex, v.color.w); + o.pos = UnityObjectToClipPos(v.vertex); + o.uv = v.texcoord.xy; + o.nz.xyz = COMPUTE_VIEW_NORMAL; + o.nz.w = COMPUTE_DEPTH_01; + return o; +} +uniform sampler2D _MainTex; +uniform fixed _Cutoff; +fixed4 frag(v2f i) : SV_Target { + half alpha = tex2D(_MainTex, i.uv).a; + + clip (alpha - _Cutoff); + return EncodeDepthNormal (i.nz.w, i.nz.xyz); +} +ENDCG + } + Pass { + Cull Front +CGPROGRAM +#pragma target 3.0 +#pragma vertex vert +#pragma fragment frag +#include "UnityCG.cginc" +#include "TerrainEngine.cginc" + +struct v2f { + float4 pos : SV_POSITION; + float2 uv : TEXCOORD0; + float4 nz : TEXCOORD1; + UNITY_VERTEX_OUTPUT_STEREO +}; +struct appdata { + float4 vertex : POSITION; + float3 normal : NORMAL; + fixed4 color : COLOR; + float4 texcoord : TEXCOORD0; + UNITY_VERTEX_INPUT_INSTANCE_ID +}; +v2f vert( appdata v ) { + v2f o; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + TerrainAnimateTree(v.vertex, v.color.w); + o.pos = UnityObjectToClipPos(v.vertex); + o.uv = v.texcoord.xy; + o.nz.xyz = -COMPUTE_VIEW_NORMAL; + o.nz.w = COMPUTE_DEPTH_01; + return o; +} +uniform sampler2D _MainTex; +uniform fixed _Cutoff; +fixed4 frag(v2f i) : SV_Target { + fixed4 texcol = tex2D( _MainTex, i.uv ); + clip( texcol.a - _Cutoff ); + return EncodeDepthNormal (i.nz.w, i.nz.xyz); +} +ENDCG + } + +} + +SubShader { + Tags { "RenderType"="TreeBillboard" } + Pass { + Cull Off +CGPROGRAM +#pragma target 3.0 +#pragma vertex vert +#pragma fragment frag +#include "UnityCG.cginc" +#include "TerrainEngine.cginc" +struct v2f { + float4 pos : SV_POSITION; + float2 uv : TEXCOORD0; + float4 nz : TEXCOORD1; + UNITY_VERTEX_OUTPUT_STEREO +}; +v2f vert (appdata_tree_billboard v) { + v2f o; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + TerrainBillboardTree(v.vertex, v.texcoord1.xy, v.texcoord.y); + o.pos = UnityObjectToClipPos(v.vertex); + o.uv.x = v.texcoord.x; + o.uv.y = v.texcoord.y > 0; + o.nz.xyz = float3(0,0,1); + o.nz.w = COMPUTE_DEPTH_01; + return o; +} +uniform sampler2D _MainTex; +fixed4 frag(v2f i) : SV_Target { + fixed4 texcol = tex2D( _MainTex, i.uv ); + clip( texcol.a - 0.001 ); + return EncodeDepthNormal (i.nz.w, i.nz.xyz); +} +ENDCG + } +} + +SubShader { + Tags { "RenderType"="GrassBillboard" } + Pass { + Cull Off +CGPROGRAM +#pragma target 3.0 +#pragma vertex vert +#pragma fragment frag +#include "UnityCG.cginc" +#include "TerrainEngine.cginc" + +struct v2f { + float4 pos : SV_POSITION; + fixed4 color : COLOR; + float2 uv : TEXCOORD0; + float4 nz : TEXCOORD1; + UNITY_VERTEX_OUTPUT_STEREO +}; + +v2f vert (appdata_full v) { + v2f o; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + WavingGrassBillboardVert (v); + o.color = v.color; + o.pos = UnityObjectToClipPos(v.vertex); + o.uv = v.texcoord.xy; + o.nz.xyz = COMPUTE_VIEW_NORMAL; + o.nz.w = COMPUTE_DEPTH_01; + return o; +} +uniform sampler2D _MainTex; +uniform fixed _Cutoff; +fixed4 frag(v2f i) : SV_Target { + fixed4 texcol = tex2D( _MainTex, i.uv ); + fixed alpha = texcol.a * i.color.a; + clip( alpha - _Cutoff ); + return EncodeDepthNormal (i.nz.w, i.nz.xyz); +} +ENDCG + } +} + +SubShader { + Tags { "RenderType"="Grass" } + Pass { + Cull Off +CGPROGRAM +#pragma target 3.0 +#pragma vertex vert +#pragma fragment frag +#include "UnityCG.cginc" +#include "TerrainEngine.cginc" +struct v2f { + float4 pos : SV_POSITION; + fixed4 color : COLOR; + float2 uv : TEXCOORD0; + float4 nz : TEXCOORD1; + UNITY_VERTEX_OUTPUT_STEREO +}; + +v2f vert (appdata_full v) { + v2f o; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + WavingGrassVert (v); + o.color = v.color; + o.pos = UnityObjectToClipPos(v.vertex); + o.uv = v.texcoord; + o.nz.xyz = COMPUTE_VIEW_NORMAL; + o.nz.w = COMPUTE_DEPTH_01; + return o; +} +uniform sampler2D _MainTex; +uniform fixed _Cutoff; +fixed4 frag(v2f i) : SV_Target { + fixed4 texcol = tex2D( _MainTex, i.uv ); + fixed alpha = texcol.a * i.color.a; + clip( alpha - _Cutoff ); + return EncodeDepthNormal (i.nz.w, i.nz.xyz); +} +ENDCG + } +} + +Fallback Off +} diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/CameraDepthNormalsTexture.shader.meta b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/CameraDepthNormalsTexture.shader.meta new file mode 100644 index 00000000..ba10b83b --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/CameraDepthNormalsTexture.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 4794ea6b2d07cc546ba97a809b5f9ada +timeCreated: 1494092583 +licenseType: Free +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/CameraDepthTexture.shader b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/CameraDepthTexture.shader new file mode 100644 index 00000000..3a7f60d5 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/CameraDepthTexture.shader @@ -0,0 +1,518 @@ +Shader "Hidden/Sprite-CameraDepthTexture" { + +// Use this shader to render a Depth texture for a camera with soft edged Sprites (using camera.RenderWithShader with replacement tag "RenderType") +// Note the depth is encoded into the pixels RGB not the full RGBA (alpha is needed for blending) + +Properties { + _MainTex ("", 2D) = "white" {} + _Cutoff ("", Float) = 0.5 + _Color ("", Color) = (1,1,1,1) +} + +SubShader { + Tags { "RenderType"="Sprite" } + Pass { + Cull Off + Blend SrcAlpha OneMinusSrcAlpha +CGPROGRAM +#pragma target 3.0 +#pragma vertex vert +#pragma fragment frag +#include "CGIncludes/ShaderShared.cginc" +#include "CGIncludes/ShaderMaths.cginc" + +struct v2f { + float4 pos : SV_POSITION; + float2 uv : TEXCOORD0; + float depth : TEXCOORD1; + UNITY_VERTEX_OUTPUT_STEREO +}; +v2f vert( appdata_base v ) { + v2f o; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.pos = UnityObjectToClipPos(v.vertex); + o.uv = calculateTextureCoord(v.texcoord); + o.depth = COMPUTE_DEPTH_01; + return o; +} +uniform fixed _Cutoff; +fixed4 frag(v2f i) : SV_Target { + fixed4 texcol = calculateTexturePixel(i.uv ); + float alpha = texcol.a*_Color.a; + clip( alpha - _Cutoff ); + return fixed4(EncodeFloatRGB (i.depth), alpha); +} +ENDCG + } + } + +SubShader { + Tags { "RenderType"="SpriteViewSpaceFixedNormal" } + Pass { + Cull Off + Blend SrcAlpha OneMinusSrcAlpha +CGPROGRAM +#pragma target 3.0 +#pragma vertex vert +#pragma fragment frag +#include "CGIncludes/ShaderShared.cginc" +#include "CGIncludes/ShaderMaths.cginc" + +struct v2f { + float4 pos : SV_POSITION; + float2 uv : TEXCOORD0; + float depth : TEXCOORD1; + UNITY_VERTEX_OUTPUT_STEREO +}; +v2f vert( appdata_base v ) { + v2f o; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.pos = UnityObjectToClipPos(v.vertex); + o.uv = calculateTextureCoord(v.texcoord); + o.depth = COMPUTE_DEPTH_01; + return o; +} +uniform fixed _Cutoff; +fixed4 frag(v2f i) : SV_Target { + fixed4 texcol = calculateTexturePixel(i.uv ); + float alpha = texcol.a*_Color.a; + clip( alpha - _Cutoff ); + return fixed4(EncodeFloatRGB (i.depth), alpha); +} +ENDCG + } + } + +SubShader { + Tags { "RenderType"="SpriteModelSpaceFixedNormal" } + Pass { + Cull Off + Blend SrcAlpha OneMinusSrcAlpha +CGPROGRAM +#pragma target 3.0 +#pragma vertex vert +#pragma fragment frag +#include "CGIncludes/ShaderShared.cginc" +#include "CGIncludes/ShaderMaths.cginc" + +struct v2f { + float4 pos : SV_POSITION; + float2 uv : TEXCOORD0; + float depth : TEXCOORD1; + UNITY_VERTEX_OUTPUT_STEREO +}; +v2f vert( appdata_base v ) { + v2f o; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.pos = UnityObjectToClipPos(v.vertex); + o.uv = calculateTextureCoord(v.texcoord); + o.depth = COMPUTE_DEPTH_01; + return o; +} +uniform fixed _Cutoff; +fixed4 frag(v2f i) : SV_Target { + fixed4 texcol = calculateTexturePixel(i.uv ); + float alpha = texcol.a*_Color.a; + clip( alpha - _Cutoff ); + return fixed4(EncodeFloatRGB (i.depth), alpha); +} +ENDCG + } + } + +SubShader { + Tags { "RenderType"="Opaque" } + Pass { +CGPROGRAM +#pragma target 3.0 +#pragma vertex vert +#pragma fragment frag +#include "UnityCG.cginc" +#include "CGIncludes/ShaderMaths.cginc" +struct v2f { + float4 pos : SV_POSITION; + float depth : TEXCOORD1; + UNITY_VERTEX_OUTPUT_STEREO +}; +v2f vert( appdata_base v ) { + v2f o; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.pos = UnityObjectToClipPos(v.vertex); + o.depth = COMPUTE_DEPTH_01; + return o; +} +fixed4 frag(v2f i) : SV_Target { + return fixed4(EncodeFloatRGB (i.depth), 1); +} +ENDCG + } +} + +SubShader { + Tags { "RenderType"="TransparentCutout" } + Pass { +CGPROGRAM +#pragma target 3.0 +#pragma vertex vert +#pragma fragment frag +#include "UnityCG.cginc" +#include "CGIncludes/ShaderMaths.cginc" +struct v2f { + float4 pos : SV_POSITION; + float2 uv : TEXCOORD0; + float depth : TEXCOORD1; + UNITY_VERTEX_OUTPUT_STEREO +}; +uniform float4 _MainTex_ST; +v2f vert( appdata_base v ) { + v2f o; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.pos = UnityObjectToClipPos(v.vertex); + o.uv = TRANSFORM_TEX(v.texcoord, _MainTex); + o.depth = COMPUTE_DEPTH_01; + return o; +} +uniform sampler2D _MainTex; +uniform fixed _Cutoff; +uniform fixed4 _Color; +fixed4 frag(v2f i) : SV_Target { + fixed4 texcol = tex2D( _MainTex, i.uv ); + clip( texcol.a*_Color.a - _Cutoff ); + return fixed4(EncodeFloatRGB (i.depth), 1); +} +ENDCG + } +} + +SubShader { + Tags { "RenderType"="TreeBark" } + Pass { +CGPROGRAM +#pragma target 3.0 +#pragma vertex vert +#pragma fragment frag +#include "UnityCG.cginc" +#include "CGIncludes/ShaderMaths.cginc" +#include "Lighting.cginc" +#include "UnityBuiltin3xTreeLibrary.cginc" +struct v2f { + float4 pos : SV_POSITION; + float2 uv : TEXCOORD0; + float depth : TEXCOORD1; + UNITY_VERTEX_OUTPUT_STEREO +}; +v2f vert( appdata_full v ) { + v2f o; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + TreeVertBark(v); + + o.pos = UnityObjectToClipPos(v.vertex); + o.uv = v.texcoord.xy; + o.depth = COMPUTE_DEPTH_01; + return o; +} +fixed4 frag( v2f i ) : SV_Target { + return fixed4(EncodeFloatRGB (i.depth), 1); +} +ENDCG + } +} + +SubShader { + Tags { "RenderType"="TreeLeaf" } + Pass { +CGPROGRAM +#pragma target 3.0 +#pragma vertex vert +#pragma fragment frag +#include "UnityCG.cginc" +#include "CGIncludes/ShaderMaths.cginc" +#include "Lighting.cginc" +#include "UnityBuiltin3xTreeLibrary.cginc" +struct v2f { + float4 pos : SV_POSITION; + float2 uv : TEXCOORD0; + float depth : TEXCOORD1; + UNITY_VERTEX_OUTPUT_STEREO +}; +v2f vert( appdata_full v ) { + v2f o; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + TreeVertLeaf(v); + + o.pos = UnityObjectToClipPos(v.vertex); + o.uv = v.texcoord.xy; + o.depth = COMPUTE_DEPTH_01; + return o; +} +uniform sampler2D _MainTex; +uniform fixed _Cutoff; +fixed4 frag( v2f i ) : SV_Target { + half alpha = tex2D(_MainTex, i.uv).a; + + clip (alpha - _Cutoff); + return fixed4(EncodeFloatRGB (i.depth), 1); +} +ENDCG + } +} + +SubShader { + Tags { "RenderType"="TreeOpaque" "DisableBatching"="True" } + Pass { +CGPROGRAM +#pragma target 3.0 +#pragma vertex vert +#pragma fragment frag +#include "UnityCG.cginc" +#include "CGIncludes/ShaderMaths.cginc" +#include "TerrainEngine.cginc" +struct v2f { + float4 pos : SV_POSITION; + float depth : TEXCOORD1; + UNITY_VERTEX_OUTPUT_STEREO +}; +struct appdata { + float4 vertex : POSITION; + float3 normal : NORMAL; + fixed4 color : COLOR; + UNITY_VERTEX_INPUT_INSTANCE_ID +}; +v2f vert( appdata v ) { + v2f o; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + TerrainAnimateTree(v.vertex, v.color.w); + o.pos = UnityObjectToClipPos(v.vertex); + o.depth = COMPUTE_DEPTH_01; + return o; +} +fixed4 frag(v2f i) : SV_Target { + return fixed4(EncodeFloatRGB (i.depth), 1); +} +ENDCG + } +} + +SubShader { + Tags { "RenderType"="TreeTransparentCutout" "DisableBatching"="True" } + Pass { + Cull Back +CGPROGRAM +#pragma target 3.0 +#pragma vertex vert +#pragma fragment frag +#include "UnityCG.cginc" +#include "CGIncludes/ShaderMaths.cginc" +#include "TerrainEngine.cginc" + +struct v2f { + float4 pos : SV_POSITION; + float2 uv : TEXCOORD0; + float depth : TEXCOORD1; + UNITY_VERTEX_OUTPUT_STEREO +}; +struct appdata { + float4 vertex : POSITION; + float3 normal : NORMAL; + fixed4 color : COLOR; + float4 texcoord : TEXCOORD0; + UNITY_VERTEX_INPUT_INSTANCE_ID +}; +v2f vert( appdata v ) { + v2f o; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + TerrainAnimateTree(v.vertex, v.color.w); + o.pos = UnityObjectToClipPos(v.vertex); + o.uv = v.texcoord.xy; + o.depth = COMPUTE_DEPTH_01; + return o; +} +uniform sampler2D _MainTex; +uniform fixed _Cutoff; +fixed4 frag(v2f i) : SV_Target { + half alpha = tex2D(_MainTex, i.uv).a; + + clip (alpha - _Cutoff); + return fixed4(EncodeFloatRGB (i.depth), 1); +} +ENDCG + } + Pass { + Cull Front +CGPROGRAM +#pragma target 3.0 +#pragma vertex vert +#pragma fragment frag +#include "UnityCG.cginc" +#include "CGIncludes/ShaderMaths.cginc" +#include "TerrainEngine.cginc" + +struct v2f { + float4 pos : SV_POSITION; + float2 uv : TEXCOORD0; + float depth : TEXCOORD1; + UNITY_VERTEX_OUTPUT_STEREO +}; +struct appdata { + float4 vertex : POSITION; + float3 normal : NORMAL; + fixed4 color : COLOR; + float4 texcoord : TEXCOORD0; + UNITY_VERTEX_INPUT_INSTANCE_ID +}; +v2f vert( appdata v ) { + v2f o; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + TerrainAnimateTree(v.vertex, v.color.w); + o.pos = UnityObjectToClipPos(v.vertex); + o.uv = v.texcoord.xy; + o.depth = COMPUTE_DEPTH_01; + return o; +} +uniform sampler2D _MainTex; +uniform fixed _Cutoff; +fixed4 frag(v2f i) : SV_Target { + fixed4 texcol = tex2D( _MainTex, i.uv ); + clip( texcol.a - _Cutoff ); + return fixed4(EncodeFloatRGB (i.depth), 1); +} +ENDCG + } + +} + +SubShader { + Tags { "RenderType"="TreeBillboard" } + Pass { + Cull Off +CGPROGRAM +#pragma target 3.0 +#pragma vertex vert +#pragma fragment frag +#include "UnityCG.cginc" +#include "CGIncludes/ShaderMaths.cginc" +#include "TerrainEngine.cginc" +struct v2f { + float4 pos : SV_POSITION; + float2 uv : TEXCOORD0; + float depth : TEXCOORD1; + UNITY_VERTEX_OUTPUT_STEREO +}; +v2f vert (appdata_tree_billboard v) { + v2f o; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + TerrainBillboardTree(v.vertex, v.texcoord1.xy, v.texcoord.y); + o.pos = UnityObjectToClipPos(v.vertex); + o.uv.x = v.texcoord.x; + o.uv.y = v.texcoord.y > 0; + o.depth = COMPUTE_DEPTH_01; + return o; +} +uniform sampler2D _MainTex; +fixed4 frag(v2f i) : SV_Target { + fixed4 texcol = tex2D( _MainTex, i.uv ); + clip( texcol.a - 0.001 ); + return fixed4(EncodeFloatRGB (i.depth), 1); +} +ENDCG + } +} + +SubShader { + Tags { "RenderType"="GrassBillboard" } + Pass { + Cull Off +CGPROGRAM +#pragma target 3.0 +#pragma vertex vert +#pragma fragment frag +#include "UnityCG.cginc" +#include "CGIncludes/ShaderMaths.cginc" +#include "TerrainEngine.cginc" + +struct v2f { + float4 pos : SV_POSITION; + fixed4 color : COLOR; + float2 uv : TEXCOORD0; + float depth : TEXCOORD1; + UNITY_VERTEX_OUTPUT_STEREO +}; + +v2f vert (appdata_full v) { + v2f o; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + WavingGrassBillboardVert (v); + o.color = v.color; + o.pos = UnityObjectToClipPos(v.vertex); + o.uv = v.texcoord.xy; + o.depth = COMPUTE_DEPTH_01; + return o; +} +uniform sampler2D _MainTex; +uniform fixed _Cutoff; +fixed4 frag(v2f i) : SV_Target { + fixed4 texcol = tex2D( _MainTex, i.uv ); + fixed alpha = texcol.a * i.color.a; + clip( alpha - _Cutoff ); + return fixed4(EncodeFloatRGB (i.depth), 1); +} +ENDCG + } +} + +SubShader { + Tags { "RenderType"="Grass" } + Pass { + Cull Off +CGPROGRAM +#pragma target 3.0 +#pragma vertex vert +#pragma fragment frag +#include "UnityCG.cginc" +#include "CGIncludes/ShaderMaths.cginc" +#include "TerrainEngine.cginc" +struct v2f { + float4 pos : SV_POSITION; + fixed4 color : COLOR; + float2 uv : TEXCOORD0; + float depth : TEXCOORD1; + UNITY_VERTEX_OUTPUT_STEREO +}; + +v2f vert (appdata_full v) { + v2f o; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + WavingGrassVert (v); + o.color = v.color; + o.pos = UnityObjectToClipPos(v.vertex); + o.uv = v.texcoord; + o.depth = COMPUTE_DEPTH_01; + return o; +} +uniform sampler2D _MainTex; +uniform fixed _Cutoff; +fixed4 frag(v2f i) : SV_Target { + fixed4 texcol = tex2D( _MainTex, i.uv ); + fixed alpha = texcol.a * i.color.a; + clip( alpha - _Cutoff ); + return fixed4(EncodeFloatRGB (i.depth), 1); +} +ENDCG + } +} + +Fallback Off +} diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/CameraDepthTexture.shader.meta b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/CameraDepthTexture.shader.meta new file mode 100644 index 00000000..abf6acbf --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/CameraDepthTexture.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: f768a57e040cc48489ad8c7392a31154 +timeCreated: 1494092586 +licenseType: Free +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/CameraNormalsTexture.shader b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/CameraNormalsTexture.shader new file mode 100644 index 00000000..1cf6a777 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/CameraNormalsTexture.shader @@ -0,0 +1,522 @@ +Shader "Hidden/Sprite-CameraNormalsTexture" { + +// Use this shader to render a Normals texture for a camera with correct sprite normals (using camera.RenderWithShader with replacement tag "RenderType") + +Properties { + _MainTex ("", 2D) = "white" {} + _Cutoff ("", Float) = 0.5 + _Color ("", Color) = (1,1,1,1) +} + +SubShader { + Tags { "RenderType"="Sprite" } + Pass { + Cull Off +CGPROGRAM +#pragma target 3.0 +#pragma vertex vert +#pragma fragment frag +#include "UnityCG.cginc" +#include "CGIncludes/ShaderShared.cginc" +struct v2f { + float4 pos : SV_POSITION; + float2 uv : TEXCOORD0; + float4 nz : TEXCOORD1; + UNITY_VERTEX_OUTPUT_STEREO +}; +uniform float4 _FixedNormal; +v2f vert( appdata_base v ) { + v2f o; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.pos = UnityObjectToClipPos(v.vertex); + o.uv = calculateTextureCoord(v.texcoord); + o.nz.xyz = COMPUTE_VIEW_NORMAL; + o.nz.w = COMPUTE_DEPTH_01; + return o; +} +uniform fixed _Cutoff; +fixed4 frag(v2f i) : SV_Target { + fixed4 texcol = calculateTexturePixel(i.uv ); + float alpha = texcol.a*_Color.a; + clip( alpha - _Cutoff ); + return i.nz; +} +ENDCG + } + } + +SubShader { + Tags { "RenderType"="SpriteViewSpaceFixedNormal" } + Pass { + Cull Off +CGPROGRAM +#pragma target 3.0 +#pragma vertex vert +#pragma fragment frag +#include "UnityCG.cginc" +#include "CGIncludes/ShaderShared.cginc" +#include "CGIncludes/SpriteLighting.cginc" +struct v2f { + float4 pos : SV_POSITION; + float2 uv : TEXCOORD0; + float4 nz : TEXCOORD1; + UNITY_VERTEX_OUTPUT_STEREO +}; +v2f vert( appdata_base v ) { + v2f o; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.pos = UnityObjectToClipPos(v.vertex); + o.uv = calculateTextureCoord(v.texcoord); + o.nz.xyz = getFixedNormal(); + o.nz.w = COMPUTE_DEPTH_01; + return o; +} +uniform fixed _Cutoff; +fixed4 frag(v2f i) : SV_Target { + fixed4 texcol = calculateTexturePixel(i.uv ); + float alpha = texcol.a*_Color.a; + clip( alpha - _Cutoff ); + return i.nz; +} +ENDCG + } + } + +SubShader { + Tags { "RenderType"="SpriteModelSpaceFixedNormal" } + Pass { + Cull Off +CGPROGRAM +#pragma target 3.0 +#pragma vertex vert +#pragma fragment frag +#include "UnityCG.cginc" +#include "CGIncludes/ShaderShared.cginc" +#include "CGIncludes/SpriteLighting.cginc" +struct v2f { + float4 pos : SV_POSITION; + float2 uv : TEXCOORD0; + float4 nz : TEXCOORD1; + UNITY_VERTEX_OUTPUT_STEREO +}; +v2f vert( appdata_base v ) { + v2f o; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.pos = UnityObjectToClipPos(v.vertex); + o.uv = calculateTextureCoord(v.texcoord); + float3 worldPos = mul(unity_ObjectToWorld, v.vertex); + float3 normal = getFixedNormal(); +//Only do this if backface is enabled :/ + normal *= calculateBackfacingSign(worldPos.xyz); +// + o.nz.xyz = normalize(mul((float3x3)UNITY_MATRIX_IT_MV, normal)); + o.nz.w = COMPUTE_DEPTH_01; + return o; +} +uniform fixed _Cutoff; +fixed4 frag(v2f i) : SV_Target { + fixed4 texcol = calculateTexturePixel(i.uv ); + float alpha = texcol.a*_Color.a; + clip( alpha - _Cutoff ); + return i.nz; +} +ENDCG + } + } + +SubShader { + Tags { "RenderType"="Opaque" } + Pass { +CGPROGRAM +#pragma target 3.0 +#pragma vertex vert +#pragma fragment frag +#include "UnityCG.cginc" +struct v2f { + float4 pos : SV_POSITION; + float4 nz : TEXCOORD0; + UNITY_VERTEX_OUTPUT_STEREO +}; +v2f vert( appdata_base v ) { + v2f o; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.pos = UnityObjectToClipPos(v.vertex); + o.nz.xyz = COMPUTE_VIEW_NORMAL; + o.nz.w = COMPUTE_DEPTH_01; + return o; +} +fixed4 frag(v2f i) : SV_Target { + return i.nz; +} +ENDCG + } +} + +SubShader { + Tags { "RenderType"="TransparentCutout" } + Pass { +CGPROGRAM +#pragma target 3.0 +#pragma vertex vert +#pragma fragment frag +#include "UnityCG.cginc" +struct v2f { + float4 pos : SV_POSITION; + float2 uv : TEXCOORD0; + float4 nz : TEXCOORD1; + UNITY_VERTEX_OUTPUT_STEREO +}; +uniform float4 _MainTex_ST; +v2f vert( appdata_base v ) { + v2f o; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.pos = UnityObjectToClipPos(v.vertex); + o.uv = TRANSFORM_TEX(v.texcoord, _MainTex); + o.nz.xyz = COMPUTE_VIEW_NORMAL; + o.nz.w = COMPUTE_DEPTH_01; + return o; +} +uniform sampler2D _MainTex; +uniform fixed _Cutoff; +uniform fixed4 _Color; +fixed4 frag(v2f i) : SV_Target { + fixed4 texcol = tex2D( _MainTex, i.uv ); + clip( texcol.a*_Color.a - _Cutoff ); + return i.nz; +} +ENDCG + } +} + +SubShader { + Tags { "RenderType"="TreeBark" } + Pass { +CGPROGRAM +#pragma target 3.0 +#pragma vertex vert +#pragma fragment frag +#include "UnityCG.cginc" +#include "Lighting.cginc" +#include "UnityBuiltin3xTreeLibrary.cginc" +struct v2f { + float4 pos : SV_POSITION; + float2 uv : TEXCOORD0; + float4 nz : TEXCOORD1; + UNITY_VERTEX_OUTPUT_STEREO +}; +v2f vert( appdata_full v ) { + v2f o; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + TreeVertBark(v); + + o.pos = UnityObjectToClipPos(v.vertex); + o.uv = v.texcoord.xy; + o.nz.xyz = COMPUTE_VIEW_NORMAL; + o.nz.w = COMPUTE_DEPTH_01; + return o; +} +fixed4 frag( v2f i ) : SV_Target { + return i.nz; +} +ENDCG + } +} + +SubShader { + Tags { "RenderType"="TreeLeaf" } + Pass { +CGPROGRAM +#pragma target 3.0 +#pragma vertex vert +#pragma fragment frag +#include "UnityCG.cginc" +#include "Lighting.cginc" +#include "UnityBuiltin3xTreeLibrary.cginc" +struct v2f { + float4 pos : SV_POSITION; + float2 uv : TEXCOORD0; + float4 nz : TEXCOORD1; + UNITY_VERTEX_OUTPUT_STEREO +}; +v2f vert( appdata_full v ) { + v2f o; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + TreeVertLeaf(v); + + o.pos = UnityObjectToClipPos(v.vertex); + o.uv = v.texcoord.xy; + o.nz.xyz = COMPUTE_VIEW_NORMAL; + o.nz.w = COMPUTE_DEPTH_01; + return o; +} +uniform sampler2D _MainTex; +uniform fixed _Cutoff; +fixed4 frag( v2f i ) : SV_Target { + half alpha = tex2D(_MainTex, i.uv).a; + + clip (alpha - _Cutoff); + return i.nz; +} +ENDCG + } +} + +SubShader { + Tags { "RenderType"="TreeOpaque" "DisableBatching"="True" } + Pass { +CGPROGRAM +#pragma target 3.0 +#pragma vertex vert +#pragma fragment frag +#include "UnityCG.cginc" +#include "TerrainEngine.cginc" +struct v2f { + float4 pos : SV_POSITION; + float4 nz : TEXCOORD0; + UNITY_VERTEX_OUTPUT_STEREO +}; +struct appdata { + float4 vertex : POSITION; + float3 normal : NORMAL; + fixed4 color : COLOR; + UNITY_VERTEX_INPUT_INSTANCE_ID +}; +v2f vert( appdata v ) { + v2f o; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + TerrainAnimateTree(v.vertex, v.color.w); + o.pos = UnityObjectToClipPos(v.vertex); + o.nz.xyz = COMPUTE_VIEW_NORMAL; + o.nz.w = COMPUTE_DEPTH_01; + return o; +} +fixed4 frag(v2f i) : SV_Target { + return i.nz; +} +ENDCG + } +} + +SubShader { + Tags { "RenderType"="TreeTransparentCutout" "DisableBatching"="True" } + Pass { + Cull Back +CGPROGRAM +#pragma target 3.0 +#pragma vertex vert +#pragma fragment frag +#include "UnityCG.cginc" +#include "TerrainEngine.cginc" + +struct v2f { + float4 pos : SV_POSITION; + float2 uv : TEXCOORD0; + float4 nz : TEXCOORD1; + UNITY_VERTEX_OUTPUT_STEREO +}; +struct appdata { + float4 vertex : POSITION; + float3 normal : NORMAL; + fixed4 color : COLOR; + float4 texcoord : TEXCOORD0; + UNITY_VERTEX_INPUT_INSTANCE_ID +}; +v2f vert( appdata v ) { + v2f o; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + TerrainAnimateTree(v.vertex, v.color.w); + o.pos = UnityObjectToClipPos(v.vertex); + o.uv = v.texcoord.xy; + o.nz.xyz = COMPUTE_VIEW_NORMAL; + o.nz.w = COMPUTE_DEPTH_01; + return o; +} +uniform sampler2D _MainTex; +uniform fixed _Cutoff; +fixed4 frag(v2f i) : SV_Target { + half alpha = tex2D(_MainTex, i.uv).a; + + clip (alpha - _Cutoff); + return i.nz; +} +ENDCG + } + Pass { + Cull Front +CGPROGRAM +#pragma target 3.0 +#pragma vertex vert +#pragma fragment frag +#include "UnityCG.cginc" +#include "TerrainEngine.cginc" + +struct v2f { + float4 pos : SV_POSITION; + float2 uv : TEXCOORD0; + float4 nz : TEXCOORD1; + UNITY_VERTEX_OUTPUT_STEREO +}; +struct appdata { + float4 vertex : POSITION; + float3 normal : NORMAL; + fixed4 color : COLOR; + float4 texcoord : TEXCOORD0; + UNITY_VERTEX_INPUT_INSTANCE_ID +}; +v2f vert( appdata v ) { + v2f o; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + TerrainAnimateTree(v.vertex, v.color.w); + o.pos = UnityObjectToClipPos(v.vertex); + o.uv = v.texcoord.xy; + o.nz.xyz = -COMPUTE_VIEW_NORMAL; + o.nz.w = COMPUTE_DEPTH_01; + return o; +} +uniform sampler2D _MainTex; +uniform fixed _Cutoff; +fixed4 frag(v2f i) : SV_Target { + fixed4 texcol = tex2D( _MainTex, i.uv ); + clip( texcol.a - _Cutoff ); + return i.nz; +} +ENDCG + } + +} + +SubShader { + Tags { "RenderType"="TreeBillboard" } + Pass { + Cull Off +CGPROGRAM +#pragma target 3.0 +#pragma vertex vert +#pragma fragment frag +#include "UnityCG.cginc" +#include "TerrainEngine.cginc" +struct v2f { + float4 pos : SV_POSITION; + float2 uv : TEXCOORD0; + float4 nz : TEXCOORD1; + UNITY_VERTEX_OUTPUT_STEREO +}; +v2f vert (appdata_tree_billboard v) { + v2f o; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + TerrainBillboardTree(v.vertex, v.texcoord1.xy, v.texcoord.y); + o.pos = UnityObjectToClipPos(v.vertex); + o.uv.x = v.texcoord.x; + o.uv.y = v.texcoord.y > 0; + o.nz.xyz = float3(0,0,1); + o.nz.w = COMPUTE_DEPTH_01; + return o; +} +uniform sampler2D _MainTex; +fixed4 frag(v2f i) : SV_Target { + fixed4 texcol = tex2D( _MainTex, i.uv ); + clip( texcol.a - 0.001 ); + return i.nz; +} +ENDCG + } +} + +SubShader { + Tags { "RenderType"="GrassBillboard" } + Pass { + Cull Off +CGPROGRAM +#pragma target 3.0 +#pragma vertex vert +#pragma fragment frag +#include "UnityCG.cginc" +#include "TerrainEngine.cginc" + +struct v2f { + float4 pos : SV_POSITION; + fixed4 color : COLOR; + float2 uv : TEXCOORD0; + float4 nz : TEXCOORD1; + UNITY_VERTEX_OUTPUT_STEREO +}; + +v2f vert (appdata_full v) { + v2f o; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + WavingGrassBillboardVert (v); + o.color = v.color; + o.pos = UnityObjectToClipPos(v.vertex); + o.uv = v.texcoord.xy; + o.nz.xyz = COMPUTE_VIEW_NORMAL; + o.nz.w = COMPUTE_DEPTH_01; + return o; +} +uniform sampler2D _MainTex; +uniform fixed _Cutoff; +fixed4 frag(v2f i) : SV_Target { + fixed4 texcol = tex2D( _MainTex, i.uv ); + fixed alpha = texcol.a * i.color.a; + clip( alpha - _Cutoff ); + return i.nz; +} +ENDCG + } +} + +SubShader { + Tags { "RenderType"="Grass" } + Pass { + Cull Off +CGPROGRAM +#pragma target 3.0 +#pragma vertex vert +#pragma fragment frag +#include "UnityCG.cginc" +#include "TerrainEngine.cginc" +struct v2f { + float4 pos : SV_POSITION; + fixed4 color : COLOR; + float2 uv : TEXCOORD0; + float4 nz : TEXCOORD1; + UNITY_VERTEX_OUTPUT_STEREO +}; + +v2f vert (appdata_full v) { + v2f o; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + WavingGrassVert (v); + o.color = v.color; + o.pos = UnityObjectToClipPos(v.vertex); + o.uv = v.texcoord; + o.nz.xyz = COMPUTE_VIEW_NORMAL; + o.nz.w = COMPUTE_DEPTH_01; + return o; +} +uniform sampler2D _MainTex; +uniform fixed _Cutoff; +fixed4 frag(v2f i) : SV_Target { + fixed4 texcol = tex2D( _MainTex, i.uv ); + fixed alpha = texcol.a * i.color.a; + clip( alpha - _Cutoff ); + return i.nz; +} +ENDCG + } +} + +Fallback Off +} diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/CameraNormalsTexture.shader.meta b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/CameraNormalsTexture.shader.meta new file mode 100644 index 00000000..88d75056 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/CameraNormalsTexture.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 537141eca02c6df4bb8b4f77567e9de2 +timeCreated: 1494092584 +licenseType: Free +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/README.md b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/README.md new file mode 100644 index 00000000..15d7899d --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/README.md @@ -0,0 +1,46 @@ +Contributed by ToddRivers + +# Unity Sprite Shaders +An Uber Shader specialised for rendering Sprites in Unity. +Even though it's designed for Sprites it can be used for a whole range of uses. It supports a wide range of optional shader features that won't effect performance unless they are used. +It also supports per-pixel effects such as normal maps and diffuse ramping whilst using Vertex Lit rendering. + +### Lighting +The shaders support lighting using both Forward Rendering and Vertex Lit Rendering. +Forward rendering is more accurate but is slower and crucially means the sprite has to write to depth using alpha clipping to avoid overdraw. +Vertex lit means all lighting can be done in one pass meaning full alpha can be used. + +### Normal Mapping +Normals maps are supported in both lighting modes (in Vertex Lit rendering data for normal mapping is packed into texture channels and then processed per pixel). + +### Blend Modes +Easily switch between blend modes including pre-multiplied alpha, additive, multiply etc. + +### Rim Lighting +Camera-space rim lighting is supported in both lighting modes. + +### Diffuse Ramp +A ramp texture is optionally supported for toon shading effects. + +### Shadows +Shadows are supported using alpha clipping. + +### Gradient based Ambient lighting +Both lighting modes support using a gradient for ambient light. In Vertex Lit mode the Spherical Harmonics is approximated from the ground, equator and sky colors. + +### Emission Map +An optional emission map is supported. + +### Camera Space Normals +As sprites are 2d their normals will always be constant. The shaders allow you to define a fixed normal in camera space rather than pass through mesh normals. +This not only saves vertex throughput but means lighting looks less 'flat' for rendering sprites with a perspective camera. + +### Color Adjustment +The shaders allow optional adjustment of hue / saturation and brightness as well as applying a solid color overlay effect for flashing a sprite to a solid color (eg. for damage effects). + +### Fog +Fog is optionally supported + + +## To Use +On your object's material click the drop down for shader and select Spine\Sprite\Pixel Lit, Vertex Lit or Unlit. diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/README.md.meta b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/README.md.meta new file mode 100644 index 00000000..78cb908d --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/README.md.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: cecd0ea162097a94c89a97af6baf0a66 +timeCreated: 1479457854 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/SpriteDepthNormalsTexture.shader b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/SpriteDepthNormalsTexture.shader new file mode 100644 index 00000000..4d834a26 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/SpriteDepthNormalsTexture.shader @@ -0,0 +1,446 @@ +Shader "Hidden/Internal-SpriteDepthNormalsTexture" { + +// Use this shader to render a DepthNormals texture for a camera with correct sprite normals (using camera.RenderWithShader) + +Properties { + _MainTex ("", 2D) = "white" {} + _Cutoff ("", Float) = 0.5 + _Color ("", Color) = (1,1,1,1) +} + +SubShader { + Tags { "RenderType"="Sprite" } + Pass { + Cull Off +CGPROGRAM +#pragma target 3.0 +#pragma vertex vert +#pragma fragment frag +#include "UnityCG.cginc" + +struct v2f { + float4 pos : SV_POSITION; + float2 uv : TEXCOORD0; + float4 nz : TEXCOORD1; + UNITY_VERTEX_OUTPUT_STEREO +}; +uniform float4 _MainTex_ST; +uniform float4 _FixedNormal; +v2f vert( appdata_base v ) { + v2f o; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.pos = UnityObjectToClipPos(v.vertex); + o.uv = TRANSFORM_TEX(v.texcoord, _MainTex); + o.nz.xyz = _FixedNormal.xyz; +#if UNITY_REVERSED_Z + o.nz.z = -o.nz.z; +#endif + o.nz.w = COMPUTE_DEPTH_01; + return o; +} +uniform sampler2D _MainTex; +uniform fixed _Cutoff; +uniform fixed4 _Color; +fixed4 frag(v2f i) : SV_Target { + fixed4 texcol = tex2D( _MainTex, i.uv ); + clip( texcol.a*_Color.a - _Cutoff ); + return EncodeDepthNormal (i.nz.w, i.nz.xyz); +} +ENDCG + } + } + +SubShader { + Tags { "RenderType"="Opaque" } + Pass { +CGPROGRAM +#pragma target 3.0 +#pragma vertex vert +#pragma fragment frag +#include "UnityCG.cginc" +struct v2f { + float4 pos : SV_POSITION; + float4 nz : TEXCOORD0; + UNITY_VERTEX_OUTPUT_STEREO +}; +v2f vert( appdata_base v ) { + v2f o; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.pos = UnityObjectToClipPos(v.vertex); + o.nz.xyz = COMPUTE_VIEW_NORMAL; + o.nz.w = COMPUTE_DEPTH_01; + return o; +} +fixed4 frag(v2f i) : SV_Target { + return EncodeDepthNormal (i.nz.w, i.nz.xyz); +} +ENDCG + } +} + +SubShader { + Tags { "RenderType"="TransparentCutout" } + Pass { +CGPROGRAM +#pragma target 3.0 +#pragma vertex vert +#pragma fragment frag +#include "UnityCG.cginc" +struct v2f { + float4 pos : SV_POSITION; + float2 uv : TEXCOORD0; + float4 nz : TEXCOORD1; + UNITY_VERTEX_OUTPUT_STEREO +}; +uniform float4 _MainTex_ST; +v2f vert( appdata_base v ) { + v2f o; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.pos = UnityObjectToClipPos(v.vertex); + o.uv = TRANSFORM_TEX(v.texcoord, _MainTex); + o.nz.xyz = COMPUTE_VIEW_NORMAL; + o.nz.w = COMPUTE_DEPTH_01; + return o; +} +uniform sampler2D _MainTex; +uniform fixed _Cutoff; +uniform fixed4 _Color; +fixed4 frag(v2f i) : SV_Target { + fixed4 texcol = tex2D( _MainTex, i.uv ); + clip( texcol.a*_Color.a - _Cutoff ); + return EncodeDepthNormal (i.nz.w, i.nz.xyz); +} +ENDCG + } +} + +SubShader { + Tags { "RenderType"="TreeBark" } + Pass { +CGPROGRAM +#pragma target 3.0 +#pragma vertex vert +#pragma fragment frag +#include "UnityCG.cginc" +#include "Lighting.cginc" +#include "UnityBuiltin3xTreeLibrary.cginc" +struct v2f { + float4 pos : SV_POSITION; + float2 uv : TEXCOORD0; + float4 nz : TEXCOORD1; + UNITY_VERTEX_OUTPUT_STEREO +}; +v2f vert( appdata_full v ) { + v2f o; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + TreeVertBark(v); + + o.pos = UnityObjectToClipPos(v.vertex); + o.uv = v.texcoord.xy; + o.nz.xyz = COMPUTE_VIEW_NORMAL; + o.nz.w = COMPUTE_DEPTH_01; + return o; +} +fixed4 frag( v2f i ) : SV_Target { + return EncodeDepthNormal (i.nz.w, i.nz.xyz); +} +ENDCG + } +} + +SubShader { + Tags { "RenderType"="TreeLeaf" } + Pass { +CGPROGRAM +#pragma target 3.0 +#pragma vertex vert +#pragma fragment frag +#include "UnityCG.cginc" +#include "Lighting.cginc" +#include "UnityBuiltin3xTreeLibrary.cginc" +struct v2f { + float4 pos : SV_POSITION; + float2 uv : TEXCOORD0; + float4 nz : TEXCOORD1; + UNITY_VERTEX_OUTPUT_STEREO +}; +v2f vert( appdata_full v ) { + v2f o; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + TreeVertLeaf(v); + + o.pos = UnityObjectToClipPos(v.vertex); + o.uv = v.texcoord.xy; + o.nz.xyz = COMPUTE_VIEW_NORMAL; + o.nz.w = COMPUTE_DEPTH_01; + return o; +} +uniform sampler2D _MainTex; +uniform fixed _Cutoff; +fixed4 frag( v2f i ) : SV_Target { + half alpha = tex2D(_MainTex, i.uv).a; + + clip (alpha - _Cutoff); + return EncodeDepthNormal (i.nz.w, i.nz.xyz); +} +ENDCG + } +} + +SubShader { + Tags { "RenderType"="TreeOpaque" "DisableBatching"="True" } + Pass { +CGPROGRAM +#pragma target 3.0 +#pragma vertex vert +#pragma fragment frag +#include "UnityCG.cginc" +#include "TerrainEngine.cginc" +struct v2f { + float4 pos : SV_POSITION; + float4 nz : TEXCOORD0; + UNITY_VERTEX_OUTPUT_STEREO +}; +struct appdata { + float4 vertex : POSITION; + float3 normal : NORMAL; + fixed4 color : COLOR; + UNITY_VERTEX_INPUT_INSTANCE_ID +}; +v2f vert( appdata v ) { + v2f o; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + TerrainAnimateTree(v.vertex, v.color.w); + o.pos = UnityObjectToClipPos(v.vertex); + o.nz.xyz = COMPUTE_VIEW_NORMAL; + o.nz.w = COMPUTE_DEPTH_01; + return o; +} +fixed4 frag(v2f i) : SV_Target { + return EncodeDepthNormal (i.nz.w, i.nz.xyz); +} +ENDCG + } +} + +SubShader { + Tags { "RenderType"="TreeTransparentCutout" "DisableBatching"="True" } + Pass { + Cull Back +CGPROGRAM +#pragma target 3.0 +#pragma vertex vert +#pragma fragment frag +#include "UnityCG.cginc" +#include "TerrainEngine.cginc" + +struct v2f { + float4 pos : SV_POSITION; + float2 uv : TEXCOORD0; + float4 nz : TEXCOORD1; + UNITY_VERTEX_OUTPUT_STEREO +}; +struct appdata { + float4 vertex : POSITION; + float3 normal : NORMAL; + fixed4 color : COLOR; + float4 texcoord : TEXCOORD0; + UNITY_VERTEX_INPUT_INSTANCE_ID +}; +v2f vert( appdata v ) { + v2f o; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + TerrainAnimateTree(v.vertex, v.color.w); + o.pos = UnityObjectToClipPos(v.vertex); + o.uv = v.texcoord.xy; + o.nz.xyz = COMPUTE_VIEW_NORMAL; + o.nz.w = COMPUTE_DEPTH_01; + return o; +} +uniform sampler2D _MainTex; +uniform fixed _Cutoff; +fixed4 frag(v2f i) : SV_Target { + half alpha = tex2D(_MainTex, i.uv).a; + + clip (alpha - _Cutoff); + return EncodeDepthNormal (i.nz.w, i.nz.xyz); +} +ENDCG + } + Pass { + Cull Front +CGPROGRAM +#pragma target 3.0 +#pragma vertex vert +#pragma fragment frag +#include "UnityCG.cginc" +#include "TerrainEngine.cginc" + +struct v2f { + float4 pos : SV_POSITION; + float2 uv : TEXCOORD0; + float4 nz : TEXCOORD1; + UNITY_VERTEX_OUTPUT_STEREO +}; +struct appdata { + float4 vertex : POSITION; + float3 normal : NORMAL; + fixed4 color : COLOR; + float4 texcoord : TEXCOORD0; + UNITY_VERTEX_INPUT_INSTANCE_ID +}; +v2f vert( appdata v ) { + v2f o; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + TerrainAnimateTree(v.vertex, v.color.w); + o.pos = UnityObjectToClipPos(v.vertex); + o.uv = v.texcoord.xy; + o.nz.xyz = -COMPUTE_VIEW_NORMAL; + o.nz.w = COMPUTE_DEPTH_01; + return o; +} +uniform sampler2D _MainTex; +uniform fixed _Cutoff; +fixed4 frag(v2f i) : SV_Target { + fixed4 texcol = tex2D( _MainTex, i.uv ); + clip( texcol.a - _Cutoff ); + return EncodeDepthNormal (i.nz.w, i.nz.xyz); +} +ENDCG + } + +} + +SubShader { + Tags { "RenderType"="TreeBillboard" } + Pass { + Cull Off +CGPROGRAM +#pragma target 3.0 +#pragma vertex vert +#pragma fragment frag +#include "UnityCG.cginc" +#include "TerrainEngine.cginc" +struct v2f { + float4 pos : SV_POSITION; + float2 uv : TEXCOORD0; + float4 nz : TEXCOORD1; + UNITY_VERTEX_OUTPUT_STEREO +}; +v2f vert (appdata_tree_billboard v) { + v2f o; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + TerrainBillboardTree(v.vertex, v.texcoord1.xy, v.texcoord.y); + o.pos = UnityObjectToClipPos(v.vertex); + o.uv.x = v.texcoord.x; + o.uv.y = v.texcoord.y > 0; + o.nz.xyz = float3(0,0,1); + o.nz.w = COMPUTE_DEPTH_01; + return o; +} +uniform sampler2D _MainTex; +fixed4 frag(v2f i) : SV_Target { + fixed4 texcol = tex2D( _MainTex, i.uv ); + clip( texcol.a - 0.001 ); + return EncodeDepthNormal (i.nz.w, i.nz.xyz); +} +ENDCG + } +} + +SubShader { + Tags { "RenderType"="GrassBillboard" } + Pass { + Cull Off +CGPROGRAM +#pragma target 3.0 +#pragma vertex vert +#pragma fragment frag +#include "UnityCG.cginc" +#include "TerrainEngine.cginc" + +struct v2f { + float4 pos : SV_POSITION; + fixed4 color : COLOR; + float2 uv : TEXCOORD0; + float4 nz : TEXCOORD1; + UNITY_VERTEX_OUTPUT_STEREO +}; + +v2f vert (appdata_full v) { + v2f o; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + WavingGrassBillboardVert (v); + o.color = v.color; + o.pos = UnityObjectToClipPos(v.vertex); + o.uv = v.texcoord.xy; + o.nz.xyz = COMPUTE_VIEW_NORMAL; + o.nz.w = COMPUTE_DEPTH_01; + return o; +} +uniform sampler2D _MainTex; +uniform fixed _Cutoff; +fixed4 frag(v2f i) : SV_Target { + fixed4 texcol = tex2D( _MainTex, i.uv ); + fixed alpha = texcol.a * i.color.a; + clip( alpha - _Cutoff ); + return EncodeDepthNormal (i.nz.w, i.nz.xyz); +} +ENDCG + } +} + +SubShader { + Tags { "RenderType"="Grass" } + Pass { + Cull Off +CGPROGRAM +#pragma target 3.0 +#pragma vertex vert +#pragma fragment frag +#include "UnityCG.cginc" +#include "TerrainEngine.cginc" +struct v2f { + float4 pos : SV_POSITION; + fixed4 color : COLOR; + float2 uv : TEXCOORD0; + float4 nz : TEXCOORD1; + UNITY_VERTEX_OUTPUT_STEREO +}; + +v2f vert (appdata_full v) { + v2f o; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + WavingGrassVert (v); + o.color = v.color; + o.pos = UnityObjectToClipPos(v.vertex); + o.uv = v.texcoord; + o.nz.xyz = COMPUTE_VIEW_NORMAL; + o.nz.w = COMPUTE_DEPTH_01; + return o; +} +uniform sampler2D _MainTex; +uniform fixed _Cutoff; +fixed4 frag(v2f i) : SV_Target { + fixed4 texcol = tex2D( _MainTex, i.uv ); + fixed alpha = texcol.a * i.color.a; + clip( alpha - _Cutoff ); + return EncodeDepthNormal (i.nz.w, i.nz.xyz); +} +ENDCG + } +} + +Fallback Off +} diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/SpriteDepthNormalsTexture.shader.meta b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/SpriteDepthNormalsTexture.shader.meta new file mode 100644 index 00000000..72904677 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/SpriteDepthNormalsTexture.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: abbda12fddbb0b048a842a3835470d30 +timeCreated: 1480325971 +licenseType: Free +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/SpritesPixelLit.shader b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/SpritesPixelLit.shader new file mode 100644 index 00000000..7bdd1ab0 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/SpritesPixelLit.shader @@ -0,0 +1,168 @@ +Shader "Spine/Sprite/Pixel Lit" +{ + Properties + { + _MainTex ("Main Texture", 2D) = "white" {} + _Color ("Color", Color) = (1,1,1,1) + + _BumpScale("Scale", Float) = 1.0 + _BumpMap ("Normal Map", 2D) = "bump" {} + + [MaterialToggle] PixelSnap ("Pixel snap", Float) = 0 + + _EmissionColor("Color", Color) = (0,0,0,0) + _EmissionMap("Emission", 2D) = "white" {} + _EmissionPower("Emission Power", Float) = 2.0 + + _Glossiness("Smoothness", Range(0.0, 1.0)) = 0.5 + _GlossMapScale("Smoothness Scale", Range(0.0, 1.0)) = 1.0 + [Gamma] _Metallic("Metallic", Range(0.0, 1.0)) = 0.0 + _MetallicGlossMap("Metallic", 2D) = "white" {} + + _DiffuseRamp ("Diffuse Ramp Texture", 2D) = "gray" {} + + _FixedNormal ("Fixed Normal", Vector) = (0,0,1,1) + _Cutoff ("Depth alpha cutoff", Range(0,1)) = 0.5 + _ShadowAlphaCutoff ("Shadow alpha cutoff", Range(0,1)) = 0.1 + _CustomRenderQueue ("Custom Render Queue", Float) = 0.0 + + _OverlayColor ("Overlay Color", Color) = (0,0,0,0) + _Hue("Hue", Range(-0.5,0.5)) = 0.0 + _Saturation("Saturation", Range(0,2)) = 1.0 + _Brightness("Brightness", Range(0,2)) = 1.0 + + _RimPower("Rim Power", Float) = 2.0 + _RimColor ("Rim Color", Color) = (1,1,1,1) + + _BlendTex ("Blend Texture", 2D) = "white" {} + _BlendAmount ("Blend", Range(0,1)) = 0.0 + + [HideInInspector] _SrcBlend ("__src", Float) = 1.0 + [HideInInspector] _DstBlend ("__dst", Float) = 0.0 + [HideInInspector] _RenderQueue ("__queue", Float) = 0.0 + [HideInInspector] _Cull ("__cull", Float) = 0.0 + [HideInInspector] _StencilRef("Stencil Reference", Float) = 1.0 + [HideInInspector][Enum(UnityEngine.Rendering.CompareFunction)] _StencilComp("Stencil Comparison", Float) = 8 // Set to Always as default + + // Outline properties are drawn via custom editor. + [HideInInspector] _OutlineWidth("Outline Width", Range(0,8)) = 3.0 + [HideInInspector] _OutlineColor("Outline Color", Color) = (1,1,0,1) + [HideInInspector] _OutlineReferenceTexWidth("Reference Texture Width", Int) = 1024 + [HideInInspector] _ThresholdEnd("Outline Threshold", Range(0,1)) = 0.25 + [HideInInspector] _OutlineSmoothness("Outline Smoothness", Range(0,1)) = 1.0 + [HideInInspector][MaterialToggle(_USE8NEIGHBOURHOOD_ON)] _Use8Neighbourhood("Sample 8 Neighbours", Float) = 1 + [HideInInspector] _OutlineMipLevel("Outline Mip Level", Range(0,3)) = 0 + } + + SubShader + { + Tags { "Queue"="Transparent" "RenderType"="Sprite" "AlphaDepth"="False" "CanUseSpriteAtlas"="True" "IgnoreProjector"="True" } + LOD 200 + + Stencil { + Ref[_StencilRef] + Comp[_StencilComp] + Pass Keep + } + + Pass + { + Name "FORWARD" + Tags { "LightMode" = "ForwardBase" } + Blend [_SrcBlend] [_DstBlend] + // Note: ZWrite needs to be enabled for following ForwardAdd pass, otherwise parts will look as if shining through by getting lit. + ZWrite On + ZTest LEqual + Cull [_Cull] + + CGPROGRAM + #pragma target 3.0 + + #pragma shader_feature _ _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON _ADDITIVEBLEND _ADDITIVEBLEND_SOFT _MULTIPLYBLEND _MULTIPLYBLEND_X2 + #pragma shader_feature _ _FIXED_NORMALS_VIEWSPACE _FIXED_NORMALS_VIEWSPACE_BACKFACE _FIXED_NORMALS_MODELSPACE _FIXED_NORMALS_MODELSPACE_BACKFACE _FIXED_NORMALS_WORLDSPACE + #pragma shader_feature _ _SPECULAR _SPECULAR_GLOSSMAP + #pragma shader_feature _NORMALMAP + #pragma shader_feature _ALPHA_CLIP + #pragma shader_feature _EMISSION + #pragma shader_feature _RIM_LIGHTING + #pragma shader_feature _DIFFUSE_RAMP + #pragma shader_feature _COLOR_ADJUST + #pragma shader_feature _TEXTURE_BLEND + #pragma shader_feature _SPHERICAL_HARMONICS + #pragma shader_feature _FOG + + #pragma multi_compile_fwdbase + #pragma fragmentoption ARB_precision_hint_fastest + #pragma multi_compile_fog + #pragma multi_compile _ PIXELSNAP_ON + #pragma multi_compile _ ETC1_EXTERNAL_ALPHA + + #pragma vertex vert + #pragma fragment fragBase + + #include "CGIncludes/SpritePixelLighting.cginc" + ENDCG + } + Pass + { + Name "FORWARD_DELTA" + Tags { "LightMode" = "ForwardAdd" } + Blend [_SrcBlend] One + ZWrite Off + ZTest LEqual + Cull [_Cull] + + CGPROGRAM + #pragma target 3.0 + + #pragma shader_feature _ _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON _ADDITIVEBLEND _ADDITIVEBLEND_SOFT _MULTIPLYBLEND _MULTIPLYBLEND_X2 + #pragma shader_feature _ _FIXED_NORMALS_VIEWSPACE _FIXED_NORMALS_VIEWSPACE_BACKFACE _FIXED_NORMALS_MODELSPACE _FIXED_NORMALS_MODELSPACE_BACKFACE _FIXED_NORMALS_WORLDSPACE + #pragma shader_feature _ _SPECULAR _SPECULAR_GLOSSMAP + #pragma shader_feature _NORMALMAP + #pragma shader_feature _ALPHA_CLIP + #pragma shader_feature _DIFFUSE_RAMP + #pragma shader_feature _COLOR_ADJUST + #pragma shader_feature _TEXTURE_BLEND + #pragma shader_feature _FOG + + #pragma multi_compile_fwdadd_fullshadows + #pragma fragmentoption ARB_precision_hint_fastest + #pragma multi_compile_fog + #pragma multi_compile _ PIXELSNAP_ON + #pragma multi_compile _ ETC1_EXTERNAL_ALPHA + + #pragma vertex vert + #pragma fragment fragAdd + + #include "CGIncludes/SpritePixelLighting.cginc" + ENDCG + } + Pass + { + Name "ShadowCaster" + Tags { "LightMode"="ShadowCaster" } + Offset 1, 1 + + Fog { Mode Off } + ZWrite On + ZTest LEqual + Cull Off + Lighting Off + + CGPROGRAM + #pragma fragmentoption ARB_precision_hint_fastest + #pragma multi_compile_shadowcaster + #pragma multi_compile _ PIXELSNAP_ON + #pragma multi_compile _ ETC1_EXTERNAL_ALPHA + + #pragma vertex vert + #pragma fragment frag + + #include "CGIncludes/SpriteShadows.cginc" + ENDCG + } + } + + FallBack "Spine/Sprite/Unlit" + CustomEditor "SpineSpriteShaderGUI" +} diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/SpritesPixelLit.shader.meta b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/SpritesPixelLit.shader.meta new file mode 100644 index 00000000..c5a0947d --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/SpritesPixelLit.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 6f7a5a97a82637f478494bc40ea8c8a2 +timeCreated: 1479457857 +licenseType: Free +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/SpritesUnlit.shader b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/SpritesUnlit.shader new file mode 100644 index 00000000..39ae8d99 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/SpritesUnlit.shader @@ -0,0 +1,107 @@ +Shader "Spine/Sprite/Unlit" +{ + Properties + { + _MainTex ("Main Texture", 2D) = "white" {} + _Color ("Color", Color) = (1,1,1,1) + + [MaterialToggle] PixelSnap ("Pixel snap", Float) = 0 + + _ZWrite ("Depth Write", Float) = 0.0 + _Cutoff ("Depth alpha cutoff", Range(0,1)) = 0.0 + _ShadowAlphaCutoff ("Shadow alpha cutoff", Range(0,1)) = 0.1 + _CustomRenderQueue ("Custom Render Queue", Float) = 0.0 + + _OverlayColor ("Overlay Color", Color) = (0,0,0,0) + _Hue("Hue", Range(-0.5,0.5)) = 0.0 + _Saturation("Saturation", Range(0,2)) = 1.0 + _Brightness("Brightness", Range(0,2)) = 1.0 + + _BlendTex ("Blend Texture", 2D) = "white" {} + _BlendAmount ("Blend", Range(0,1)) = 0.0 + + [HideInInspector] _SrcBlend ("__src", Float) = 1.0 + [HideInInspector] _DstBlend ("__dst", Float) = 0.0 + [HideInInspector] _RenderQueue ("__queue", Float) = 0.0 + [HideInInspector] _Cull ("__cull", Float) = 0.0 + [HideInInspector] _StencilRef("Stencil Reference", Float) = 1.0 + [HideInInspector][Enum(UnityEngine.Rendering.CompareFunction)] _StencilComp("Stencil Comparison", Float) = 8 // Set to Always as default + + // Outline properties are drawn via custom editor. + [HideInInspector] _OutlineWidth("Outline Width", Range(0,8)) = 3.0 + [HideInInspector] _OutlineColor("Outline Color", Color) = (1,1,0,1) + [HideInInspector] _OutlineReferenceTexWidth("Reference Texture Width", Int) = 1024 + [HideInInspector] _ThresholdEnd("Outline Threshold", Range(0,1)) = 0.25 + [HideInInspector] _OutlineSmoothness("Outline Smoothness", Range(0,1)) = 1.0 + [HideInInspector][MaterialToggle(_USE8NEIGHBOURHOOD_ON)] _Use8Neighbourhood("Sample 8 Neighbours", Float) = 1 + [HideInInspector] _OutlineMipLevel("Outline Mip Level", Range(0,3)) = 0 + } + + SubShader + { + Tags { "Queue"="Transparent" "RenderType"="Sprite" "AlphaDepth"="False" "CanUseSpriteAtlas"="True" "IgnoreProjector"="True" } + LOD 100 + + Stencil { + Ref[_StencilRef] + Comp[_StencilComp] + Pass Keep + } + + Pass + { + Name "Normal" + + Blend [_SrcBlend] [_DstBlend] + Lighting Off + ZWrite [_ZWrite] + ZTest LEqual + Cull [_Cull] + Lighting Off + + CGPROGRAM + #pragma shader_feature _ _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON _ADDITIVEBLEND _ADDITIVEBLEND_SOFT _MULTIPLYBLEND _MULTIPLYBLEND_X2 + #pragma shader_feature _ALPHA_CLIP + #pragma shader_feature _TEXTURE_BLEND + #pragma shader_feature _COLOR_ADJUST + #pragma shader_feature _FOG + + #pragma fragmentoption ARB_precision_hint_fastest + #pragma multi_compile_fog + #pragma multi_compile _ PIXELSNAP_ON + #pragma multi_compile _ ETC1_EXTERNAL_ALPHA + + #pragma vertex vert + #pragma fragment frag + + #include "CGIncludes/SpriteUnlit.cginc" + ENDCG + } + Pass + { + Name "ShadowCaster" + Tags { "LightMode"="ShadowCaster" } + Offset 1, 1 + + Fog { Mode Off } + ZWrite On + ZTest LEqual + Cull Off + Lighting Off + + CGPROGRAM + #pragma fragmentoption ARB_precision_hint_fastest + #pragma multi_compile_shadowcaster + #pragma multi_compile _ PIXELSNAP_ON + #pragma multi_compile _ ETC1_EXTERNAL_ALPHA + + #pragma vertex vert + #pragma fragment frag + + #include "CGIncludes/SpriteShadows.cginc" + ENDCG + } + } + + CustomEditor "SpineSpriteShaderGUI" +} diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/SpritesUnlit.shader.meta b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/SpritesUnlit.shader.meta new file mode 100644 index 00000000..0304ebb8 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/SpritesUnlit.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 64005298b9a80bb4899eabd5140dc4a8 +timeCreated: 1479457857 +licenseType: Free +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/SpritesVertexLit.shader b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/SpritesVertexLit.shader new file mode 100644 index 00000000..366e75ae --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/SpritesVertexLit.shader @@ -0,0 +1,135 @@ +Shader "Spine/Sprite/Vertex Lit" +{ + Properties + { + _MainTex ("Main Texture", 2D) = "white" {} + _Color ("Color", Color) = (1,1,1,1) + + _BumpScale("Scale", Float) = 1.0 + _BumpMap ("Normal Map", 2D) = "bump" {} + + [MaterialToggle] PixelSnap ("Pixel snap", Float) = 0 + + _EmissionColor("Color", Color) = (0,0,0,0) + _EmissionMap("Emission", 2D) = "white" {} + _EmissionPower("Emission Power", Float) = 2.0 + + _Glossiness("Smoothness", Range(0.0, 1.0)) = 0.5 + _GlossMapScale("Smoothness Scale", Range(0.0, 1.0)) = 1.0 + [Gamma] _Metallic("Metallic", Range(0.0, 1.0)) = 0.0 + _MetallicGlossMap("Metallic", 2D) = "white" {} + + _DiffuseRamp ("Diffuse Ramp Texture", 2D) = "gray" {} + + _FixedNormal ("Fixed Normal", Vector) = (0,0,1,1) + _ZWrite ("Depth Write", Float) = 0.0 + _Cutoff ("Depth alpha cutoff", Range(0,1)) = 0.0 + _ShadowAlphaCutoff ("Shadow alpha cutoff", Range(0,1)) = 0.1 + _CustomRenderQueue ("Custom Render Queue", Float) = 0.0 + + _OverlayColor ("Overlay Color", Color) = (0,0,0,0) + _Hue("Hue", Range(-0.5,0.5)) = 0.0 + _Saturation("Saturation", Range(0,2)) = 1.0 + _Brightness("Brightness", Range(0,2)) = 1.0 + + _RimPower("Rim Power", Float) = 2.0 + _RimColor ("Rim Color", Color) = (1,1,1,1) + + _BlendTex ("Blend Texture", 2D) = "white" {} + _BlendAmount ("Blend", Range(0,1)) = 0.0 + + [HideInInspector] _SrcBlend ("__src", Float) = 1.0 + [HideInInspector] _DstBlend ("__dst", Float) = 0.0 + [HideInInspector] _RenderQueue ("__queue", Float) = 0.0 + [HideInInspector] _Cull ("__cull", Float) = 0.0 + [HideInInspector] _StencilRef("Stencil Reference", Float) = 1.0 + [HideInInspector][Enum(UnityEngine.Rendering.CompareFunction)] _StencilComp("Stencil Comparison", Float) = 8 // Set to Always as default + + // Outline properties are drawn via custom editor. + [HideInInspector] _OutlineWidth("Outline Width", Range(0,8)) = 3.0 + [HideInInspector] _OutlineColor("Outline Color", Color) = (1,1,0,1) + [HideInInspector] _OutlineReferenceTexWidth("Reference Texture Width", Int) = 1024 + [HideInInspector] _ThresholdEnd("Outline Threshold", Range(0,1)) = 0.25 + [HideInInspector] _OutlineSmoothness("Outline Smoothness", Range(0,1)) = 1.0 + [HideInInspector][MaterialToggle(_USE8NEIGHBOURHOOD_ON)] _Use8Neighbourhood("Sample 8 Neighbours", Float) = 1 + [HideInInspector] _OutlineMipLevel("Outline Mip Level", Range(0,3)) = 0 + } + + SubShader + { + Tags { "Queue"="Transparent" "RenderType"="Sprite" "AlphaDepth"="False" "CanUseSpriteAtlas"="True" "IgnoreProjector"="True" } + LOD 150 + + Stencil { + Ref[_StencilRef] + Comp[_StencilComp] + Pass Keep + } + + Pass + { + Name "Vertex" + Tags { "LightMode" = "Vertex" } + Blend [_SrcBlend] [_DstBlend] + ZWrite [_ZWrite] + ZTest LEqual + Cull [_Cull] + Lighting On + + CGPROGRAM + #pragma target 3.0 + + #pragma shader_feature _ _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON _ADDITIVEBLEND _ADDITIVEBLEND_SOFT _MULTIPLYBLEND _MULTIPLYBLEND_X2 + #pragma shader_feature _ _FIXED_NORMALS_VIEWSPACE _FIXED_NORMALS_VIEWSPACE_BACKFACE _FIXED_NORMALS_MODELSPACE _FIXED_NORMALS_MODELSPACE_BACKFACE _FIXED_NORMALS_WORLDSPACE + #pragma shader_feature _ _SPECULAR _SPECULAR_GLOSSMAP + #pragma shader_feature _NORMALMAP + #pragma shader_feature _ALPHA_CLIP + #pragma shader_feature _EMISSION + #pragma shader_feature _DIFFUSE_RAMP + #pragma shader_feature _COLOR_ADJUST + #pragma shader_feature _RIM_LIGHTING + #pragma shader_feature _TEXTURE_BLEND + #pragma shader_feature _SPHERICAL_HARMONICS + #pragma shader_feature _FOG + + + #pragma fragmentoption ARB_precision_hint_fastest + #pragma multi_compile_fog + #pragma multi_compile _ PIXELSNAP_ON + #pragma multi_compile _ ETC1_EXTERNAL_ALPHA + + #pragma vertex vert + #pragma fragment frag + + #include "CGIncludes/SpriteVertexLighting.cginc" + ENDCG + } + Pass + { + Name "ShadowCaster" + Tags { "LightMode"="ShadowCaster" } + Offset 1, 1 + + Fog { Mode Off } + ZWrite On + ZTest LEqual + Cull Off + Lighting Off + + CGPROGRAM + #pragma fragmentoption ARB_precision_hint_fastest + #pragma multi_compile_shadowcaster + #pragma multi_compile _ PIXELSNAP_ON + #pragma multi_compile _ ETC1_EXTERNAL_ALPHA + + #pragma vertex vert + #pragma fragment frag + + #include "CGIncludes/SpriteShadows.cginc" + ENDCG + } + } + + FallBack "Spine/Sprite/Unlit" + CustomEditor "SpineSpriteShaderGUI" +} diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/SpritesVertexLit.shader.meta b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/SpritesVertexLit.shader.meta new file mode 100644 index 00000000..34d232e8 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/SpritesVertexLit.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 2ce511398fb980f41b7d316c51534590 +timeCreated: 1479457856 +licenseType: Free +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Utility.meta b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Utility.meta new file mode 100644 index 00000000..188c117b --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Utility.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: bc59776133d26dc469c8ba66bdc647e4 +folderAsset: yes +timeCreated: 1492387122 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Utility/Hidden-Spine-Bones.shader b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Utility/Hidden-Spine-Bones.shader new file mode 100644 index 00000000..ee2045d4 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Utility/Hidden-Spine-Bones.shader @@ -0,0 +1,66 @@ +Shader "Hidden/Spine/Bones" { +Properties { + _Color ("Color", Color) = (0.5,0.5,0.5,0.5) + _MainTex ("Particle Texture", 2D) = "white" {} +} + +Category { + Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" } + Blend SrcAlpha OneMinusSrcAlpha + AlphaTest Greater .01 + ColorMask RGB + + Lighting Off Cull Off ZTest Always ZWrite Off Fog { Mode Off } + + SubShader { + Pass { + + CGPROGRAM + #pragma vertex vert + #pragma fragment frag +// #pragma multi_compile_particles + + #include "UnityCG.cginc" + + sampler2D _MainTex; + fixed4 _Color; + + struct appdata_t { + float4 vertex : POSITION; + fixed4 color : COLOR; + float2 texcoord : TEXCOORD0; + }; + + struct v2f { + float4 vertex : SV_POSITION; + fixed4 color : COLOR; + float2 texcoord : TEXCOORD0; +// #ifdef SOFTPARTICLES_ON +// float4 projPos : TEXCOORD1; +// #endif + }; + + float4 _MainTex_ST; + + v2f vert (appdata_t v) { + v2f o; + o.vertex = UnityObjectToClipPos(v.vertex); +// #ifdef SOFTPARTICLES_ON +// o.projPos = ComputeScreenPos (o.vertex); +// COMPUTE_EYEDEPTH(o.projPos.z); +// #endif + o.color = v.color; + o.texcoord = TRANSFORM_TEX(v.texcoord,_MainTex); + return o; + } + + sampler2D_float _CameraDepthTexture; + + fixed4 frag (v2f i) : SV_Target { + return i.color * _Color * tex2D(_MainTex, i.texcoord); + } + ENDCG + } + } +} +} diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Utility/Hidden-Spine-Bones.shader.meta b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Utility/Hidden-Spine-Bones.shader.meta new file mode 100644 index 00000000..17117f38 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Utility/Hidden-Spine-Bones.shader.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 66988de88a15abd4e8846c6805485f57 +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Utility/HiddenPass.mat b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Utility/HiddenPass.mat new file mode 100644 index 00000000..c7bc5ada --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Utility/HiddenPass.mat @@ -0,0 +1,37 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 6 + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_Name: HiddenPass + m_Shader: {fileID: 4800000, guid: 913475501bf19374c84390868a9d6d3d, type: 3} + m_ShaderKeywords: + m_LightmapFlags: 5 + m_CustomRenderQueue: -1 + stringTagMap: {} + m_SavedProperties: + serializedVersion: 2 + m_TexEnvs: + - first: + name: _MainTex + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Floats: + - first: + name: _Cutoff + second: 0.1 + - first: + name: _InvFade + second: 1 + m_Colors: + - first: + name: _Color + second: {r: 1, g: 1, b: 1, a: 1} + - first: + name: _TintColor + second: {r: 0.5, g: 0.5, b: 0.5, a: 0} diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Utility/HiddenPass.mat.meta b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Utility/HiddenPass.mat.meta new file mode 100644 index 00000000..f9a2a315 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Utility/HiddenPass.mat.meta @@ -0,0 +1,6 @@ +fileFormatVersion: 2 +guid: 43227e5adadc6f24bb4bf74b92a56fb4 +NativeFormatImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Utility/HiddenPass.shader b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Utility/HiddenPass.shader new file mode 100644 index 00000000..c06650af --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Utility/HiddenPass.shader @@ -0,0 +1,12 @@ +Shader "Spine/Special/HiddenPass" { + SubShader + { + Tags {"Queue" = "Geometry-1" } + Lighting Off + Pass + { + ZWrite Off + ColorMask 0 + } + } +} diff --git a/box1/Assets/Spine/Runtime/spine-unity/Shaders/Utility/HiddenPass.shader.meta b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Utility/HiddenPass.shader.meta new file mode 100644 index 00000000..01ca4ed6 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Shaders/Utility/HiddenPass.shader.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 913475501bf19374c84390868a9d6d3d +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/SkeletonDataModifierAssets.meta b/box1/Assets/Spine/Runtime/spine-unity/SkeletonDataModifierAssets.meta new file mode 100644 index 00000000..0c464666 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/SkeletonDataModifierAssets.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 5d7322e83d799d849bea71dbd6f1c24e +folderAsset: yes +timeCreated: 1563297885 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/SkeletonDataModifierAssets/BlendModeMaterials.meta b/box1/Assets/Spine/Runtime/spine-unity/SkeletonDataModifierAssets/BlendModeMaterials.meta new file mode 100644 index 00000000..642bab4b --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/SkeletonDataModifierAssets/BlendModeMaterials.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 16fbcfb5e341ff44bb99593fff04539d +folderAsset: yes +timeCreated: 1563298958 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/SkeletonDataModifierAssets/BlendModeMaterials/BlendModeMaterialsAsset.cs b/box1/Assets/Spine/Runtime/spine-unity/SkeletonDataModifierAssets/BlendModeMaterials/BlendModeMaterialsAsset.cs new file mode 100644 index 00000000..3f649324 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/SkeletonDataModifierAssets/BlendModeMaterials/BlendModeMaterialsAsset.cs @@ -0,0 +1,129 @@ +/****************************************************************************** + * 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; +using System.Collections.Generic; +using UnityEngine; + +using Spine; +using Spine.Unity; + +namespace Spine.Unity { + [CreateAssetMenu(menuName = "Spine/SkeletonData Modifiers/Blend Mode Materials", order = 200)] + public class BlendModeMaterialsAsset : SkeletonDataModifierAsset { + public Material multiplyMaterialTemplate; + public Material screenMaterialTemplate; + public Material additiveMaterialTemplate; + + public bool applyAdditiveMaterial = true; + + public override void Apply (SkeletonData skeletonData) { + ApplyMaterials(skeletonData, multiplyMaterialTemplate, screenMaterialTemplate, additiveMaterialTemplate, applyAdditiveMaterial); + } + + public static void ApplyMaterials (SkeletonData skeletonData, Material multiplyTemplate, Material screenTemplate, Material additiveTemplate, bool includeAdditiveSlots) { + if (skeletonData == null) throw new ArgumentNullException("skeletonData"); + + using (var materialCache = new AtlasMaterialCache()) { + var entryBuffer = new List(); + var slotsItems = skeletonData.Slots.Items; + for (int slotIndex = 0, slotCount = skeletonData.Slots.Count; slotIndex < slotCount; slotIndex++) { + var slot = slotsItems[slotIndex]; + if (slot.blendMode == BlendMode.Normal) continue; + if (!includeAdditiveSlots && slot.blendMode == BlendMode.Additive) continue; + + entryBuffer.Clear(); + foreach (var skin in skeletonData.Skins) + skin.GetAttachments(slotIndex, entryBuffer); + + Material templateMaterial = null; + switch (slot.blendMode) { + case BlendMode.Multiply: + templateMaterial = multiplyTemplate; + break; + case BlendMode.Screen: + templateMaterial = screenTemplate; + break; + case BlendMode.Additive: + templateMaterial = additiveTemplate; + break; + } + if (templateMaterial == null) continue; + + foreach (var entry in entryBuffer) { + var renderableAttachment = entry.Attachment as IHasRendererObject; + if (renderableAttachment != null) { + renderableAttachment.RendererObject = materialCache.CloneAtlasRegionWithMaterial((AtlasRegion)renderableAttachment.RendererObject, templateMaterial); + } + } + } + + } + //attachmentBuffer.Clear(); + } + + class AtlasMaterialCache : IDisposable { + readonly Dictionary, AtlasPage> cache = new Dictionary, AtlasPage>(); + + /// Creates a clone of an AtlasRegion that uses different Material settings, while retaining the original texture. + public AtlasRegion CloneAtlasRegionWithMaterial (AtlasRegion originalRegion, Material materialTemplate) { + var newRegion = originalRegion.Clone(); + newRegion.page = GetAtlasPageWithMaterial(originalRegion.page, materialTemplate); + return newRegion; + } + + AtlasPage GetAtlasPageWithMaterial (AtlasPage originalPage, Material materialTemplate) { + if (originalPage == null) throw new ArgumentNullException("originalPage"); + + AtlasPage newPage = null; + var key = new KeyValuePair(originalPage, materialTemplate); + cache.TryGetValue(key, out newPage); + + if (newPage == null) { + newPage = originalPage.Clone(); + var originalMaterial = originalPage.rendererObject as Material; + newPage.rendererObject = new Material(materialTemplate) { + name = originalMaterial.name + " " + materialTemplate.name, + mainTexture = originalMaterial.mainTexture + }; + cache.Add(key, newPage); + } + + return newPage; + } + + public void Dispose () { + cache.Clear(); + } + } + + } + +} diff --git a/box1/Assets/Spine/Runtime/spine-unity/SkeletonDataModifierAssets/BlendModeMaterials/BlendModeMaterialsAsset.cs.meta b/box1/Assets/Spine/Runtime/spine-unity/SkeletonDataModifierAssets/BlendModeMaterials/BlendModeMaterialsAsset.cs.meta new file mode 100644 index 00000000..15e21736 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/SkeletonDataModifierAssets/BlendModeMaterials/BlendModeMaterialsAsset.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 12b0b98acbcda44468a7ae4e35000abe +timeCreated: 1536404384 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: + - multiplyMaterialTemplate: {fileID: 2100000, guid: 53bf0ab317d032d418cf1252d68f51df, + type: 2} + - screenMaterialTemplate: {fileID: 2100000, guid: 73f0f46d3177c614baf0fa48d646a9be, + type: 2} + - additiveMaterialTemplate: {fileID: 2100000, guid: 4deba332d47209e4780b3c5fcf0e3745, + type: 2} + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/SkeletonDataModifierAssets/BlendModeMaterials/Default BlendModeMaterials.asset b/box1/Assets/Spine/Runtime/spine-unity/SkeletonDataModifierAssets/BlendModeMaterials/Default BlendModeMaterials.asset new file mode 100644 index 00000000..4e4446fc --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/SkeletonDataModifierAssets/BlendModeMaterials/Default BlendModeMaterials.asset @@ -0,0 +1,20 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 12b0b98acbcda44468a7ae4e35000abe, type: 3} + m_Name: Default BlendModeMaterials + m_EditorClassIdentifier: + multiplyMaterialTemplate: {fileID: 2100000, guid: 53bf0ab317d032d418cf1252d68f51df, + type: 2} + screenMaterialTemplate: {fileID: 2100000, guid: 73f0f46d3177c614baf0fa48d646a9be, + type: 2} + additiveMaterialTemplate: {fileID: 2100000, guid: 4deba332d47209e4780b3c5fcf0e3745, + type: 2} + applyAdditiveMaterial: 1 diff --git a/box1/Assets/Spine/Runtime/spine-unity/SkeletonDataModifierAssets/BlendModeMaterials/Default BlendModeMaterials.asset.meta b/box1/Assets/Spine/Runtime/spine-unity/SkeletonDataModifierAssets/BlendModeMaterials/Default BlendModeMaterials.asset.meta new file mode 100644 index 00000000..7f9d67ac --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/SkeletonDataModifierAssets/BlendModeMaterials/Default BlendModeMaterials.asset.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 22c0225612a65ee4fb15bad49f644762 +timeCreated: 1536404361 +licenseType: Pro +NativeFormatImporter: + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/SkeletonDataModifierAssets/BlendModeMaterials/SkeletonPMAAdditive.mat b/box1/Assets/Spine/Runtime/spine-unity/SkeletonDataModifierAssets/BlendModeMaterials/SkeletonPMAAdditive.mat new file mode 100644 index 00000000..f40488ba --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/SkeletonDataModifierAssets/BlendModeMaterials/SkeletonPMAAdditive.mat @@ -0,0 +1,35 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 6 + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_Name: SkeletonPMAAdditive + m_Shader: {fileID: 4800000, guid: 53efa1d97f5d9f74285d4330cda14e36, type: 3} + m_ShaderKeywords: + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: -1 + stringTagMap: {} + disabledShaderPasses: [] + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - : + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Floats: + - : 0 + - _Cutoff: 0.1 + - _StraightAlphaInput: 0 + m_Colors: + - : {r: 0, g: 2.018574, b: 1e-45, a: 0.000007110106} + - _Color: {r: 1, g: 1, b: 1, a: 1} diff --git a/box1/Assets/Spine/Runtime/spine-unity/SkeletonDataModifierAssets/BlendModeMaterials/SkeletonPMAAdditive.mat.meta b/box1/Assets/Spine/Runtime/spine-unity/SkeletonDataModifierAssets/BlendModeMaterials/SkeletonPMAAdditive.mat.meta new file mode 100644 index 00000000..e8edf094 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/SkeletonDataModifierAssets/BlendModeMaterials/SkeletonPMAAdditive.mat.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 4deba332d47209e4780b3c5fcf0e3745 +timeCreated: 1496447909 +licenseType: Free +NativeFormatImporter: + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/SkeletonDataModifierAssets/BlendModeMaterials/SkeletonPMAMultiply.mat b/box1/Assets/Spine/Runtime/spine-unity/SkeletonDataModifierAssets/BlendModeMaterials/SkeletonPMAMultiply.mat new file mode 100644 index 00000000..28c90c14 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/SkeletonDataModifierAssets/BlendModeMaterials/SkeletonPMAMultiply.mat @@ -0,0 +1,43 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 6 + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_Name: SkeletonPMAMultiply + m_Shader: {fileID: 4800000, guid: 8bdcdc7ee298e594a9c20c61d25c33b6, type: 3} + m_ShaderKeywords: + m_LightmapFlags: 4 + m_CustomRenderQueue: -1 + stringTagMap: {} + m_SavedProperties: + serializedVersion: 2 + m_TexEnvs: + - first: + name: + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - first: + name: _MainTex + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Floats: + - first: + name: + second: 0 + - first: + name: _Cutoff + second: 0.1 + m_Colors: + - first: + name: + second: {r: 0, g: 2.018574, b: 1e-45, a: 0.000007110106} + - first: + name: _Color + second: {r: 1, g: 1, b: 1, a: 1} diff --git a/box1/Assets/Spine/Runtime/spine-unity/SkeletonDataModifierAssets/BlendModeMaterials/SkeletonPMAMultiply.mat.meta b/box1/Assets/Spine/Runtime/spine-unity/SkeletonDataModifierAssets/BlendModeMaterials/SkeletonPMAMultiply.mat.meta new file mode 100644 index 00000000..c8c80384 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/SkeletonDataModifierAssets/BlendModeMaterials/SkeletonPMAMultiply.mat.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 53bf0ab317d032d418cf1252d68f51df +timeCreated: 1496447909 +licenseType: Free +NativeFormatImporter: + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/SkeletonDataModifierAssets/BlendModeMaterials/SkeletonPMAScreen.mat b/box1/Assets/Spine/Runtime/spine-unity/SkeletonDataModifierAssets/BlendModeMaterials/SkeletonPMAScreen.mat new file mode 100644 index 00000000..601f987e --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/SkeletonDataModifierAssets/BlendModeMaterials/SkeletonPMAScreen.mat @@ -0,0 +1,43 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 6 + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_Name: SkeletonPMAScreen + m_Shader: {fileID: 4800000, guid: 4e8caa36c07aacf4ab270da00784e4d9, type: 3} + m_ShaderKeywords: + m_LightmapFlags: 4 + m_CustomRenderQueue: -1 + stringTagMap: {} + m_SavedProperties: + serializedVersion: 2 + m_TexEnvs: + - first: + name: + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - first: + name: _MainTex + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Floats: + - first: + name: + second: 0 + - first: + name: _Cutoff + second: 0.1 + m_Colors: + - first: + name: + second: {r: 0, g: 2.018574, b: 1e-45, a: 0.000007121922} + - first: + name: _Color + second: {r: 1, g: 1, b: 1, a: 1} diff --git a/box1/Assets/Spine/Runtime/spine-unity/SkeletonDataModifierAssets/BlendModeMaterials/SkeletonPMAScreen.mat.meta b/box1/Assets/Spine/Runtime/spine-unity/SkeletonDataModifierAssets/BlendModeMaterials/SkeletonPMAScreen.mat.meta new file mode 100644 index 00000000..6a1a749d --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/SkeletonDataModifierAssets/BlendModeMaterials/SkeletonPMAScreen.mat.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 73f0f46d3177c614baf0fa48d646a9be +timeCreated: 1496447909 +licenseType: Free +NativeFormatImporter: + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/SpineAttributes.cs b/box1/Assets/Spine/Runtime/spine-unity/SpineAttributes.cs new file mode 100644 index 00000000..a0dd2e27 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/SpineAttributes.cs @@ -0,0 +1,298 @@ +/****************************************************************************** + * 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; +using System.Collections; + +namespace Spine.Unity { + + [AttributeUsage(AttributeTargets.Field, Inherited = true, AllowMultiple = false)] + public abstract class SpineAttributeBase : PropertyAttribute { + public string dataField = ""; + public string startsWith = ""; + public bool includeNone = true; + public bool fallbackToTextField = false; + } + + public class SpineBone : SpineAttributeBase { + /// + /// Smart popup menu for Spine Bones + /// + /// Filters popup results to elements that begin with supplied string. + /// If true, the dropdown list will include a "none" option which stored as an empty string. + /// If true, and an animation list source can't be found, the field will fall back to a normal text field. If false, it will show an error. + /// If specified, a locally scoped field with the name supplied by in dataField will be used to fill the popup results. + /// Valid types are SkeletonDataAsset and SkeletonRenderer (and derivatives) + /// If left empty and the script the attribute is applied to is derived from Component, GetComponent() will be called as a fallback. + /// + public SpineBone (string startsWith = "", string dataField = "", bool includeNone = true, bool fallbackToTextField = false) { + this.startsWith = startsWith; + this.dataField = dataField; + this.includeNone = includeNone; + this.fallbackToTextField = fallbackToTextField; + } + + public static Spine.Bone GetBone (string boneName, SkeletonRenderer renderer) { + return renderer.skeleton == null ? null : renderer.skeleton.FindBone(boneName); + } + + public static Spine.BoneData GetBoneData (string boneName, SkeletonDataAsset skeletonDataAsset) { + var data = skeletonDataAsset.GetSkeletonData(true); + return data.FindBone(boneName); + } + } + + public class SpineSlot : SpineAttributeBase { + public bool containsBoundingBoxes = false; + + /// + /// Smart popup menu for Spine Slots + /// + /// Filters popup results to elements that begin with supplied string. + /// Disables popup results that don't contain bounding box attachments when true. + /// If true, the dropdown list will include a "none" option which stored as an empty string. + /// If true, and an animation list source can't be found, the field will fall back to a normal text field. If false, it will show an error. + /// If specified, a locally scoped field with the name supplied by in dataField will be used to fill the popup results. + /// Valid types are SkeletonDataAsset and SkeletonRenderer (and derivatives). + /// If left empty and the script the attribute is applied to is derived from Component, GetComponent() will be called as a fallback. + /// + public SpineSlot (string startsWith = "", string dataField = "", bool containsBoundingBoxes = false, bool includeNone = true, bool fallbackToTextField = false) { + this.startsWith = startsWith; + this.dataField = dataField; + this.containsBoundingBoxes = containsBoundingBoxes; + this.includeNone = includeNone; + this.fallbackToTextField = fallbackToTextField; + } + } + + public class SpineAnimation : SpineAttributeBase { + /// + /// Smart popup menu for Spine Animations + /// + /// Filters popup results to elements that begin with supplied string. + /// If true, and an animation list source can't be found, the field will fall back to a normal text field. If false, it will show an error. + /// If true, the dropdown list will include a "none" option which stored as an empty string. + /// If specified, a locally scoped field with the name supplied by in dataField will be used to fill the popup results. + /// Valid types are SkeletonDataAsset and SkeletonRenderer (and derivatives) + /// If left empty and the script the attribute is applied to is derived from Component, GetComponent() will be called as a fallback. + /// + public SpineAnimation (string startsWith = "", string dataField = "", bool includeNone = true, bool fallbackToTextField = false) { + this.startsWith = startsWith; + this.dataField = dataField; + this.includeNone = includeNone; + this.fallbackToTextField = fallbackToTextField; + } + } + + public class SpineEvent : SpineAttributeBase { + /// + /// Smart popup menu for Spine Events (Spine.EventData) + /// + /// Filters popup results to elements that begin with supplied string. + /// If true, the dropdown list will include a "none" option which stored as an empty string. + /// If specified, a locally scoped field with the name supplied by in dataField will be used to fill the popup results. + /// Valid types are SkeletonDataAsset and SkeletonRenderer (and derivatives). + /// If left empty and the script the attribute is applied to is derived from Component, GetComponent(SkeletonRenderer)() will be called as a fallback. + /// + /// If true, and an animation list source can't be found, the field will fall back to a normal text field. If false, it will show an error. + + public bool audioOnly = false; + + public SpineEvent (string startsWith = "", string dataField = "", bool includeNone = true, bool fallbackToTextField = false, bool audioOnly = false) { + this.startsWith = startsWith; + this.dataField = dataField; + this.includeNone = includeNone; + this.fallbackToTextField = fallbackToTextField; + this.audioOnly = audioOnly; + } + } + + public class SpineIkConstraint : SpineAttributeBase { + /// + /// Smart popup menu for Spine IK Constraints (Spine.IkConstraint) + /// + /// Filters popup results to elements that begin with supplied string. + /// If true, the dropdown list will include a "none" option which stored as an empty string. + /// If specified, a locally scoped field with the name supplied by in dataField will be used to fill the popup results. + /// Valid types are SkeletonDataAsset and SkeletonRenderer (and derivatives). + /// If left empty and the script the attribute is applied to is derived from Component, GetComponent(SkeletonRenderer)() will be called as a fallback. + /// + /// If true, and an animation list source can't be found, the field will fall back to a normal text field. If false, it will show an error. + public SpineIkConstraint (string startsWith = "", string dataField = "", bool includeNone = true, bool fallbackToTextField = false) { + this.startsWith = startsWith; + this.dataField = dataField; + this.includeNone = includeNone; + this.fallbackToTextField = fallbackToTextField; + } + } + + public class SpineTransformConstraint : SpineAttributeBase { + /// + /// Smart popup menu for Spine Transform Constraints (Spine.TransformConstraint) + /// + /// Filters popup results to elements that begin with supplied string. + /// If true, the dropdown list will include a "none" option which stored as an empty string. + /// If true, and an animation list source can't be found, the field will fall back to a normal text field. If false, it will show an error. + /// If specified, a locally scoped field with the name supplied by in dataField will be used to fill the popup results. + /// Valid types are SkeletonDataAsset and SkeletonRenderer (and derivatives). + /// If left empty and the script the attribute is applied to is derived from Component, GetComponent() will be called as a fallback. + /// + public SpineTransformConstraint (string startsWith = "", string dataField = "", bool includeNone = true, bool fallbackToTextField = false) { + this.startsWith = startsWith; + this.dataField = dataField; + this.includeNone = includeNone; + this.fallbackToTextField = fallbackToTextField; + } + } + + public class SpinePathConstraint : SpineAttributeBase { + /// + /// Smart popup menu for Spine Events (Spine.PathConstraint) + /// + /// Filters popup results to elements that begin with supplied string. + /// If true, the dropdown list will include a "none" option which stored as an empty string. + /// If specified, a locally scoped field with the name supplied by in dataField will be used to fill the popup results. + /// Valid types are SkeletonDataAsset and SkeletonRenderer (and derivatives). + /// If left empty and the script the attribute is applied to is derived from Component, GetComponent(SkeletonRenderer)() will be called as a fallback. + /// + public SpinePathConstraint (string startsWith = "", string dataField = "", bool includeNone = true, bool fallbackToTextField = false) { + this.startsWith = startsWith; + this.dataField = dataField; + this.includeNone = includeNone; + this.fallbackToTextField = fallbackToTextField; + } + } + + public class SpineSkin : SpineAttributeBase { + /// + /// Smart popup menu for Spine Skins + /// + /// Filters popup results to elements that begin with supplied string. + /// If true, the dropdown list will include a "none" option which stored as an empty string. + /// If true, and an animation list source can't be found, the field will fall back to a normal text field. If false, it will show an error. + /// If true, the default choice will be serialized as an empty string. + /// If specified, a locally scoped field with the name supplied by in dataField will be used to fill the popup results. + /// Valid types are SkeletonDataAsset and SkeletonRenderer (and derivatives) + /// If left empty and the script the attribute is applied to is derived from Component, GetComponent() will be called as a fallback. + /// + + public bool defaultAsEmptyString = false; + + public SpineSkin (string startsWith = "", string dataField = "", bool includeNone = true, bool fallbackToTextField = false, bool defaultAsEmptyString = false) { + this.startsWith = startsWith; + this.dataField = dataField; + this.includeNone = includeNone; + this.fallbackToTextField = fallbackToTextField; + this.defaultAsEmptyString = defaultAsEmptyString; + } + } + + public class SpineAttachment : SpineAttributeBase { + public bool returnAttachmentPath = false; + public bool currentSkinOnly = false; + public bool placeholdersOnly = false; + public string skinField = ""; + public string slotField = ""; + + /// + /// Smart popup menu for Spine Attachments + /// + /// Filters popup results to only include the current Skin. Only valid when a SkeletonRenderer is the data source. + /// Returns a fully qualified path for an Attachment in the format "Skin/Slot/AttachmentName". This path format is only used by the SpineAttachment helper methods like SpineAttachment.GetAttachment and .GetHierarchy. Do not use full path anywhere else in Spine's system. + /// Filters popup results to exclude attachments that are not children of Skin Placeholders + /// If specified, a locally scoped field with the name supplied by in slotField will be used to limit the popup results to children of a named slot + /// If specified, a locally scoped field with the name supplied by in skinField will be used to limit the popup results to entries of the named skin + /// If true, the dropdown list will include a "none" option which stored as an empty string. + /// If true, and an animation list source can't be found, the field will fall back to a normal text field. If false, it will show an error. + /// If specified, a locally scoped field with the name supplied by in dataField will be used to fill the popup results. + /// Valid types are SkeletonDataAsset and SkeletonRenderer (and derivatives) + /// If left empty and the script the attribute is applied to is derived from Component, GetComponent() will be called as a fallback. + /// + public SpineAttachment (bool currentSkinOnly = true, bool returnAttachmentPath = false, bool placeholdersOnly = false, string slotField = "", string dataField = "", string skinField = "", bool includeNone = true, bool fallbackToTextField = false) { + this.currentSkinOnly = currentSkinOnly; + this.returnAttachmentPath = returnAttachmentPath; + this.placeholdersOnly = placeholdersOnly; + this.slotField = slotField; + this.dataField = dataField; + this.skinField = skinField; + this.includeNone = includeNone; + this.fallbackToTextField = fallbackToTextField; + } + + public static SpineAttachment.Hierarchy GetHierarchy (string fullPath) { + return new SpineAttachment.Hierarchy(fullPath); + } + + public static Spine.Attachment GetAttachment (string attachmentPath, Spine.SkeletonData skeletonData) { + var hierarchy = SpineAttachment.GetHierarchy(attachmentPath); + return string.IsNullOrEmpty(hierarchy.name) ? null : skeletonData.FindSkin(hierarchy.skin).GetAttachment(skeletonData.FindSlotIndex(hierarchy.slot), hierarchy.name); + } + + public static Spine.Attachment GetAttachment (string attachmentPath, SkeletonDataAsset skeletonDataAsset) { + return GetAttachment(attachmentPath, skeletonDataAsset.GetSkeletonData(true)); + } + + /// + /// A struct that represents 3 strings that help identify and locate an attachment in a skeleton. + public struct Hierarchy { + public string skin; + public string slot; + public string name; + + public Hierarchy (string fullPath) { + string[] chunks = fullPath.Split(new char[]{'/'}, System.StringSplitOptions.RemoveEmptyEntries); + if (chunks.Length == 0) { + skin = ""; + slot = ""; + name = ""; + return; + } + else if (chunks.Length < 2) { + throw new System.Exception("Cannot generate Attachment Hierarchy from string! Not enough components! [" + fullPath + "]"); + } + skin = chunks[0]; + slot = chunks[1]; + name = ""; + for (int i = 2; i < chunks.Length; i++) { + name += chunks[i]; + } + } + } + } + + public class SpineAtlasRegion : PropertyAttribute { + public string atlasAssetField; + + public SpineAtlasRegion (string atlasAssetField = "") { + this.atlasAssetField = atlasAssetField; + } + } + +} diff --git a/box1/Assets/Spine/Runtime/spine-unity/SpineAttributes.cs.meta b/box1/Assets/Spine/Runtime/spine-unity/SpineAttributes.cs.meta new file mode 100644 index 00000000..00a5090b --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/SpineAttributes.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: ce216f51ebc1d3f40929f4e58d1c65e5 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Utility.meta b/box1/Assets/Spine/Runtime/spine-unity/Utility.meta new file mode 100644 index 00000000..7098b07f --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Utility.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 52627c17e6dd4bf4dad4bdfc490ce823 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Utility/AtlasUtilities.cs b/box1/Assets/Spine/Runtime/spine-unity/Utility/AtlasUtilities.cs new file mode 100644 index 00000000..5abd195f --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Utility/AtlasUtilities.cs @@ -0,0 +1,754 @@ +/****************************************************************************** + * 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_2019_3_OR_NEWER +#define CONFIGURABLE_ENTER_PLAY_MODE +#endif + + +using UnityEngine; +using System.Collections.Generic; +using System; + + +namespace Spine.Unity.AttachmentTools { + + public static class AtlasUtilities { + internal const TextureFormat SpineTextureFormat = TextureFormat.RGBA32; + internal const float DefaultMipmapBias = -0.5f; + internal const bool UseMipMaps = false; + internal const float DefaultScale = 0.01f; + + const int NonrenderingRegion = -1; + + #if CONFIGURABLE_ENTER_PLAY_MODE + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] + static void Init () { + // handle disabled domain reload + AtlasUtilities.ClearCache(); + } + #endif + + public static AtlasRegion ToAtlasRegion (this Texture2D t, Material materialPropertySource, float scale = DefaultScale) { + return t.ToAtlasRegion(materialPropertySource.shader, scale, materialPropertySource); + } + + public static AtlasRegion ToAtlasRegion (this Texture2D t, Shader shader, float scale = DefaultScale, Material materialPropertySource = null) { + var material = new Material(shader); + if (materialPropertySource != null) { + material.CopyPropertiesFromMaterial(materialPropertySource); + material.shaderKeywords = materialPropertySource.shaderKeywords; + } + + material.mainTexture = t; + var page = material.ToSpineAtlasPage(); + + float width = t.width; + float height = t.height; + + var region = new AtlasRegion(); + region.name = t.name; + region.index = -1; + region.rotate = false; + + // World space units + Vector2 boundsMin = Vector2.zero, boundsMax = new Vector2(width, height) * scale; + + // Texture space/pixel units + region.width = (int)width; + region.originalWidth = (int)width; + region.height = (int)height; + region.originalHeight = (int)height; + region.offsetX = width * (0.5f - InverseLerp(boundsMin.x, boundsMax.x, 0)); + region.offsetY = height * (0.5f - InverseLerp(boundsMin.y, boundsMax.y, 0)); + + // Use the full area of the texture. + region.u = 0; + region.v = 1; + region.u2 = 1; + region.v2 = 0; + region.x = 0; + region.y = 0; + + region.page = page; + + return region; + } + + /// + /// Creates a Spine.AtlasRegion that uses a premultiplied alpha duplicate of the Sprite's texture data. + public static AtlasRegion ToAtlasRegionPMAClone (this Texture2D t, Material materialPropertySource, TextureFormat textureFormat = SpineTextureFormat, bool mipmaps = UseMipMaps) { + return t.ToAtlasRegionPMAClone(materialPropertySource.shader, textureFormat, mipmaps, materialPropertySource); + } + + /// + /// Creates a Spine.AtlasRegion that uses a premultiplied alpha duplicate of the Sprite's texture data. + public static AtlasRegion ToAtlasRegionPMAClone (this Texture2D t, Shader shader, TextureFormat textureFormat = SpineTextureFormat, bool mipmaps = UseMipMaps, Material materialPropertySource = null) { + var material = new Material(shader); + if (materialPropertySource != null) { + material.CopyPropertiesFromMaterial(materialPropertySource); + material.shaderKeywords = materialPropertySource.shaderKeywords; + } + var newTexture = t.GetClone(textureFormat, mipmaps, applyPMA : true); + + newTexture.name = t.name + "-pma-"; + material.name = t.name + shader.name; + + material.mainTexture = newTexture; + var page = material.ToSpineAtlasPage(); + + var region = newTexture.ToAtlasRegion(shader); + region.page = page; + + return region; + } + + /// + /// Creates a new Spine.AtlasPage from a UnityEngine.Material. If the material has a preassigned texture, the page width and height will be set. + public static AtlasPage ToSpineAtlasPage (this Material m) { + var newPage = new AtlasPage { + rendererObject = m, + name = m.name + }; + + var t = m.mainTexture; + if (t != null) { + newPage.width = t.width; + newPage.height = t.height; + } + + return newPage; + } + + /// + /// Creates a Spine.AtlasRegion from a UnityEngine.Sprite. + public static AtlasRegion ToAtlasRegion (this Sprite s, AtlasPage page) { + if (page == null) throw new System.ArgumentNullException("page", "page cannot be null. AtlasPage determines which texture region belongs and how it should be rendered. You can use material.ToSpineAtlasPage() to get a shareable AtlasPage from a Material, or use the sprite.ToAtlasRegion(material) overload."); + var region = s.ToAtlasRegion(); + region.page = page; + return region; + } + + /// + /// Creates a Spine.AtlasRegion from a UnityEngine.Sprite. This creates a new AtlasPage object for every AtlasRegion you create. You can centralize Material control by creating a shared atlas page using Material.ToSpineAtlasPage and using the sprite.ToAtlasRegion(AtlasPage) overload. + public static AtlasRegion ToAtlasRegion (this Sprite s, Material material) { + var region = s.ToAtlasRegion(); + region.page = material.ToSpineAtlasPage(); + return region; + } + + public static AtlasRegion ToAtlasRegionPMAClone (this Sprite s, Material materialPropertySource, TextureFormat textureFormat = SpineTextureFormat, bool mipmaps = UseMipMaps) { + return s.ToAtlasRegionPMAClone(materialPropertySource.shader, textureFormat, mipmaps, materialPropertySource); + } + + /// + /// Creates a Spine.AtlasRegion that uses a premultiplied alpha duplicate of the Sprite's texture data. + public static AtlasRegion ToAtlasRegionPMAClone (this Sprite s, Shader shader, TextureFormat textureFormat = SpineTextureFormat, bool mipmaps = UseMipMaps, Material materialPropertySource = null) { + var material = new Material(shader); + if (materialPropertySource != null) { + material.CopyPropertiesFromMaterial(materialPropertySource); + material.shaderKeywords = materialPropertySource.shaderKeywords; + } + + var tex = s.ToTexture(textureFormat, mipmaps, applyPMA : true); + tex.name = s.name + "-pma-"; + material.name = tex.name + shader.name; + + material.mainTexture = tex; + var page = material.ToSpineAtlasPage(); + + var region = s.ToAtlasRegion(true); + region.page = page; + + return region; + } + + internal static AtlasRegion ToAtlasRegion (this Sprite s, bool isolatedTexture = false) { + var region = new AtlasRegion(); + region.name = s.name; + region.index = -1; + region.rotate = s.packed && s.packingRotation != SpritePackingRotation.None; + + // World space units + Bounds bounds = s.bounds; + Vector2 boundsMin = bounds.min, boundsMax = bounds.max; + + // Texture space/pixel units + Rect spineRect = s.rect.SpineUnityFlipRect(s.texture.height); + region.width = (int)spineRect.width; + region.originalWidth = (int)spineRect.width; + region.height = (int)spineRect.height; + region.originalHeight = (int)spineRect.height; + region.offsetX = spineRect.width * (0.5f - InverseLerp(boundsMin.x, boundsMax.x, 0)); + region.offsetY = spineRect.height * (0.5f - InverseLerp(boundsMin.y, boundsMax.y, 0)); + + if (isolatedTexture) { + region.u = 0; + region.v = 1; + region.u2 = 1; + region.v2 = 0; + region.x = 0; + region.y = 0; + } else { + Texture2D tex = s.texture; + Rect uvRect = TextureRectToUVRect(s.textureRect, tex.width, tex.height); + region.u = uvRect.xMin; + region.v = uvRect.yMax; + region.u2 = uvRect.xMax; + region.v2 = uvRect.yMin; + region.x = (int)spineRect.x; + region.y = (int)spineRect.y; + } + + return region; + } + + #region Runtime Repacking + /// + /// Fills the outputAttachments list with new attachment objects based on the attachments in sourceAttachments, + /// but mapped to a new single texture using the same material. + /// Returned Material and Texture behave like new Texture2D(), thus you need to call Destroy() + /// to free resources. + /// The list of attachments to be repacked. + /// The List(Attachment) to populate with the newly created Attachment objects. + /// + /// May be null. If no Material property source is provided, no special + public static void GetRepackedAttachments (List sourceAttachments, List outputAttachments, Material materialPropertySource, out Material outputMaterial, out Texture2D outputTexture, int maxAtlasSize = 1024, int padding = 2, TextureFormat textureFormat = SpineTextureFormat, bool mipmaps = UseMipMaps, string newAssetName = "Repacked Attachments", bool clearCache = false, bool useOriginalNonrenderables = true) { + if (sourceAttachments == null) throw new System.ArgumentNullException("sourceAttachments"); + if (outputAttachments == null) throw new System.ArgumentNullException("outputAttachments"); + + // Use these to detect and use shared regions. + var existingRegions = new Dictionary(); + var regionIndexes = new List(); + var texturesToPack = new List(); + var originalRegions = new List(); + + outputAttachments.Clear(); + outputAttachments.AddRange(sourceAttachments); + + int newRegionIndex = 0; + for (int i = 0, n = sourceAttachments.Count; i < n; i++) { + var originalAttachment = sourceAttachments[i]; + + if (IsRenderable(originalAttachment)) { + var newAttachment = originalAttachment.GetCopy(true); + var region = newAttachment.GetRegion(); + int existingIndex; + if (existingRegions.TryGetValue(region, out existingIndex)) { + regionIndexes.Add(existingIndex); // Store the region index for the eventual new attachment. + } else { + originalRegions.Add(region); + texturesToPack.Add(region.ToTexture(textureFormat, mipmaps)); // Add the texture to the PackTextures argument + existingRegions.Add(region, newRegionIndex); // Add the region to the dictionary of known regions + regionIndexes.Add(newRegionIndex); // Store the region index for the eventual new attachment. + newRegionIndex++; + } + + outputAttachments[i] = newAttachment; + } else { + outputAttachments[i] = useOriginalNonrenderables ? originalAttachment : originalAttachment.GetCopy(true); + regionIndexes.Add(NonrenderingRegion); // Output attachments pairs with regionIndexes list 1:1. Pad with a sentinel if the attachment doesn't have a region. + } + } + + // Fill a new texture with the collected attachment textures. + var newTexture = new Texture2D(maxAtlasSize, maxAtlasSize, textureFormat, mipmaps); + newTexture.mipMapBias = AtlasUtilities.DefaultMipmapBias; + newTexture.name = newAssetName; + // Copy settings + if (texturesToPack.Count > 0) { + var sourceTexture = texturesToPack[0]; + newTexture.CopyTextureAttributesFrom(sourceTexture); + } + var rects = newTexture.PackTextures(texturesToPack.ToArray(), padding, maxAtlasSize); + + // Rehydrate the repacked textures as a Material, Spine atlas and Spine.AtlasAttachments + Shader shader = materialPropertySource == null ? Shader.Find("Spine/Skeleton") : materialPropertySource.shader; + var newMaterial = new Material(shader); + if (materialPropertySource != null) { + newMaterial.CopyPropertiesFromMaterial(materialPropertySource); + newMaterial.shaderKeywords = materialPropertySource.shaderKeywords; + } + + newMaterial.name = newAssetName; + newMaterial.mainTexture = newTexture; + var page = newMaterial.ToSpineAtlasPage(); + page.name = newAssetName; + + var repackedRegions = new List(); + for (int i = 0, n = originalRegions.Count; i < n; i++) { + var oldRegion = originalRegions[i]; + var newRegion = UVRectToAtlasRegion(rects[i], oldRegion, page); + repackedRegions.Add(newRegion); + } + + // Map the cloned attachments to the repacked atlas. + for (int i = 0, n = outputAttachments.Count; i < n; i++) { + var a = outputAttachments[i]; + if (IsRenderable(a)) + a.SetRegion(repackedRegions[regionIndexes[i]]); + } + + // Clean up. + if (clearCache) + AtlasUtilities.ClearCache(); + + outputTexture = newTexture; + outputMaterial = newMaterial; + } + + /// + /// Creates and populates a duplicate skin with cloned attachments that are backed by a new packed texture atlas + /// comprised of all the regions from the original skin. + /// GetRepackedSkin is an expensive operation, preferably call it at level load time. + /// No Spine.Atlas object is created so there is no way to find AtlasRegions except through the Attachments using them. + /// Returned Material and Texture behave like new Texture2D(), thus you need to call Destroy() + /// to free resources. + /// Optional additional textures (such as normal maps) to copy while repacking. + /// To copy e.g. the main texture and normal maps, pass 'new int[] { Shader.PropertyToID("_BumpMap") }' at this parameter. + /// When additionalTexturePropertyIDsToCopy is non-null, + /// this array will be filled with the resulting repacked texture for every property, + /// just as the main repacked texture is assigned to outputTexture. + /// When additionalTexturePropertyIDsToCopy is non-null, + /// this array will be used as TextureFormat at the Texture at the respective property. + /// When additionalTextureFormats is null or when its array size is smaller, + /// textureFormat is used where there exists no corresponding array item. + /// When additionalTexturePropertyIDsToCopy is non-null, + /// this array will be used to determine whether linear or sRGB color space is used at the + /// Texture at the respective property. When additionalTextureIsLinear is null, linear color space + /// is assumed at every additional Texture element. + /// When e.g. packing the main texture and normal maps, pass 'new bool[] { true }' at this parameter, because normal maps use + /// linear color space. + public static Skin GetRepackedSkin (this Skin o, string newName, Material materialPropertySource, out Material outputMaterial, out Texture2D outputTexture, + int maxAtlasSize = 1024, int padding = 2, TextureFormat textureFormat = SpineTextureFormat, bool mipmaps = UseMipMaps, + bool useOriginalNonrenderables = true, bool clearCache = false, + int[] additionalTexturePropertyIDsToCopy = null, Texture2D[] additionalOutputTextures = null, + TextureFormat[] additionalTextureFormats = null, bool[] additionalTextureIsLinear = null) { + + return GetRepackedSkin(o, newName, materialPropertySource.shader, out outputMaterial, out outputTexture, + maxAtlasSize, padding, textureFormat, mipmaps, materialPropertySource, + clearCache, useOriginalNonrenderables, additionalTexturePropertyIDsToCopy, additionalOutputTextures, + additionalTextureFormats, additionalTextureIsLinear); + } + + /// + /// Creates and populates a duplicate skin with cloned attachments that are backed by a new packed texture atlas + /// comprised of all the regions from the original skin. + /// GetRepackedSkin is an expensive operation, preferably call it at level load time. + /// No Spine.Atlas object is created so there is no way to find AtlasRegions except through the Attachments using them. + /// Returned Material and Texture behave like new Texture2D(), thus you need to call Destroy() + /// to free resources. + public static Skin GetRepackedSkin (this Skin o, string newName, Shader shader, out Material outputMaterial, out Texture2D outputTexture, + int maxAtlasSize = 1024, int padding = 2, TextureFormat textureFormat = SpineTextureFormat, bool mipmaps = UseMipMaps, + Material materialPropertySource = null, bool clearCache = false, bool useOriginalNonrenderables = true, + int[] additionalTexturePropertyIDsToCopy = null, Texture2D[] additionalOutputTextures = null, + TextureFormat[] additionalTextureFormats = null, bool[] additionalTextureIsLinear = null) { + + outputTexture = null; + if (additionalTexturePropertyIDsToCopy != null && additionalTextureIsLinear == null) { + additionalTextureIsLinear = new bool[additionalTexturePropertyIDsToCopy.Length]; + for (int i = 0; i < additionalTextureIsLinear.Length; ++i) { + additionalTextureIsLinear[i] = true; + } + } + + if (o == null) throw new System.NullReferenceException("Skin was null"); + var skinAttachments = o.Attachments; + var newSkin = new Skin(newName); + + newSkin.bones.AddRange(o.bones); + newSkin.constraints.AddRange(o.constraints); + + // Use these to detect and use shared regions. + var existingRegions = new Dictionary(); + var regionIndexes = new List(); + + // Collect all textures from the attachments of the original skin. + var repackedAttachments = new List(); + int numTextureParamsToRepack = 1 + (additionalTexturePropertyIDsToCopy == null ? 0 : additionalTexturePropertyIDsToCopy.Length); + additionalOutputTextures = (additionalTexturePropertyIDsToCopy == null ? null : new Texture2D[additionalTexturePropertyIDsToCopy.Length]); + List[] texturesToPackAtParam = new List[numTextureParamsToRepack]; + for (int i = 0; i < numTextureParamsToRepack; ++i) { + texturesToPackAtParam[i] = new List(); + } + var originalRegions = new List(); + int newRegionIndex = 0; + + foreach (var skinEntry in skinAttachments) { + var originalKey = skinEntry.Key; + var originalAttachment = skinEntry.Value; + + Attachment newAttachment; + if (IsRenderable(originalAttachment)) { + newAttachment = originalAttachment.GetCopy(true); + var region = newAttachment.GetRegion(); + int existingIndex; + if (existingRegions.TryGetValue(region, out existingIndex)) { + regionIndexes.Add(existingIndex); // Store the region index for the eventual new attachment. + } else { + originalRegions.Add(region); + for (int i = 0; i < numTextureParamsToRepack; ++i) { + Texture2D regionTexture = (i == 0 ? + region.ToTexture(textureFormat, mipmaps) : + region.ToTexture((additionalTextureFormats != null && i - 1 < additionalTextureFormats.Length) ? + additionalTextureFormats[i - 1] : textureFormat, + mipmaps, additionalTexturePropertyIDsToCopy[i - 1], additionalTextureIsLinear[i - 1])); + texturesToPackAtParam[i].Add(regionTexture); // Add the texture to the PackTextures argument + } + existingRegions.Add(region, newRegionIndex); // Add the region to the dictionary of known regions + regionIndexes.Add(newRegionIndex); // Store the region index for the eventual new attachment. + newRegionIndex++; + } + + repackedAttachments.Add(newAttachment); + newSkin.SetAttachment(originalKey.SlotIndex, originalKey.Name, newAttachment); + } else { + newSkin.SetAttachment(originalKey.SlotIndex, originalKey.Name, useOriginalNonrenderables ? originalAttachment : originalAttachment.GetCopy(true)); + } + } + + // Rehydrate the repacked textures as a Material, Spine atlas and Spine.AtlasAttachments + var newMaterial = new Material(shader); + if (materialPropertySource != null) { + newMaterial.CopyPropertiesFromMaterial(materialPropertySource); + newMaterial.shaderKeywords = materialPropertySource.shaderKeywords; + } + newMaterial.name = newName; + + Rect[] rects = null; + for (int i = 0; i < numTextureParamsToRepack; ++i) { + // Fill a new texture with the collected attachment textures. + var newTexture = new Texture2D(maxAtlasSize, maxAtlasSize, + (i > 0 && additionalTextureFormats != null && i - 1 < additionalTextureFormats.Length) ? + additionalTextureFormats[i - 1] : textureFormat, + mipmaps, + (i > 0) ? additionalTextureIsLinear[i - 1] : false); + newTexture.mipMapBias = AtlasUtilities.DefaultMipmapBias; + var texturesToPack = texturesToPackAtParam[i]; + if (texturesToPack.Count > 0) { + var sourceTexture = texturesToPack[0]; + newTexture.CopyTextureAttributesFrom(sourceTexture); + } + newTexture.name = newName; + var rectsForTexParam = newTexture.PackTextures(texturesToPack.ToArray(), padding, maxAtlasSize); + if (i == 0) { + rects = rectsForTexParam; + newMaterial.mainTexture = newTexture; + outputTexture = newTexture; + } + else { + newMaterial.SetTexture(additionalTexturePropertyIDsToCopy[i - 1], newTexture); + additionalOutputTextures[i - 1] = newTexture; + } + } + + var page = newMaterial.ToSpineAtlasPage(); + page.name = newName; + + var repackedRegions = new List(); + for (int i = 0, n = originalRegions.Count; i < n; i++) { + var oldRegion = originalRegions[i]; + var newRegion = UVRectToAtlasRegion(rects[i], oldRegion, page); + repackedRegions.Add(newRegion); + } + + // Map the cloned attachments to the repacked atlas. + for (int i = 0, n = repackedAttachments.Count; i < n; i++) { + var a = repackedAttachments[i]; + if (IsRenderable(a)) + a.SetRegion(repackedRegions[regionIndexes[i]]); + } + + // Clean up. + if (clearCache) + AtlasUtilities.ClearCache(); + + outputMaterial = newMaterial; + return newSkin; + } + + public static Sprite ToSprite (this AtlasRegion ar, float pixelsPerUnit = 100) { + return Sprite.Create(ar.GetMainTexture(), ar.GetUnityRect(), new Vector2(0.5f, 0.5f), pixelsPerUnit); + } + + struct IntAndAtlasRegionKey { + int i; + AtlasRegion region; + + public IntAndAtlasRegionKey(int i, AtlasRegion region) { + this.i = i; + this.region = region; + } + + public override int GetHashCode () { + return i.GetHashCode() * 23 ^ region.GetHashCode(); + } + } + static Dictionary CachedRegionTextures = new Dictionary(); + static List CachedRegionTexturesList = new List(); + + public static void ClearCache () { + foreach (var t in CachedRegionTexturesList) { + UnityEngine.Object.Destroy(t); + } + CachedRegionTextures.Clear(); + CachedRegionTexturesList.Clear(); + } + + /// Creates a new Texture2D object based on an AtlasRegion. + /// If applyImmediately is true, Texture2D.Apply is called immediately after the Texture2D is filled with data. + public static Texture2D ToTexture (this AtlasRegion ar, TextureFormat textureFormat = SpineTextureFormat, bool mipmaps = UseMipMaps, + int texturePropertyId = 0, bool linear = false, bool applyPMA = false) { + + Texture2D output; + + IntAndAtlasRegionKey cacheKey = new IntAndAtlasRegionKey(texturePropertyId, ar); + CachedRegionTextures.TryGetValue(cacheKey, out output); + if (output == null) { + Texture2D sourceTexture = texturePropertyId == 0 ? ar.GetMainTexture() : ar.GetTexture(texturePropertyId); + Rect r = ar.GetUnityRect(); + int width = (int)r.width; + int height = (int)r.height; + output = new Texture2D(width, height, textureFormat, mipmaps, linear) { name = ar.name }; + output.CopyTextureAttributesFrom(sourceTexture); + if (applyPMA) + AtlasUtilities.CopyTextureApplyPMA(sourceTexture, r, output); + else + AtlasUtilities.CopyTexture(sourceTexture, r, output); + CachedRegionTextures.Add(cacheKey, output); + CachedRegionTexturesList.Add(output); + } + + return output; + } + + static Texture2D ToTexture (this Sprite s, TextureFormat textureFormat = SpineTextureFormat, + bool mipmaps = UseMipMaps, bool linear = false, bool applyPMA = false) { + + var spriteTexture = s.texture; + Rect r; + if (!s.packed || s.packingMode == SpritePackingMode.Rectangle) { + r = s.textureRect; + } + else { + r = new Rect(); + r.xMin = Math.Min(s.uv[0].x, s.uv[1].x) * spriteTexture.width; + r.xMax = Math.Max(s.uv[0].x, s.uv[1].x) * spriteTexture.width; + r.yMin = Math.Min(s.uv[0].y, s.uv[2].y) * spriteTexture.height; + r.yMax = Math.Max(s.uv[0].y, s.uv[2].y) * spriteTexture.height; + #if UNITY_EDITOR + if (s.uv.Length > 4) { + Debug.LogError("When using a tightly packed SpriteAtlas with Spine, you may only access Sprites that are packed as 'FullRect' from it! " + + "You can either disable 'Tight Packing' at the whole SpriteAtlas, or change the single Sprite's TextureImporter Setting 'MeshType' to 'Full Rect'." + + "Sprite Asset: " + s.name, s); + } + #endif + } + var newTexture = new Texture2D((int)r.width, (int)r.height, textureFormat, mipmaps, linear); + newTexture.CopyTextureAttributesFrom(spriteTexture); + if (applyPMA) + AtlasUtilities.CopyTextureApplyPMA(spriteTexture, r, newTexture); + else + AtlasUtilities.CopyTexture(spriteTexture, r, newTexture); + return newTexture; + } + + static Texture2D GetClone (this Texture2D t, TextureFormat textureFormat = SpineTextureFormat, + bool mipmaps = UseMipMaps, bool linear = false, bool applyPMA = false) { + + var newTexture = new Texture2D((int)t.width, (int)t.height, textureFormat, mipmaps, linear); + newTexture.CopyTextureAttributesFrom(t); + if (applyPMA) + AtlasUtilities.CopyTextureApplyPMA(t, new Rect(0, 0, t.width, t.height), newTexture); + else + AtlasUtilities.CopyTexture(t, new Rect(0, 0, t.width, t.height), newTexture); + return newTexture; + } + + static void CopyTexture (Texture2D source, Rect sourceRect, Texture2D destination) { + if (SystemInfo.copyTextureSupport == UnityEngine.Rendering.CopyTextureSupport.None) { + // GetPixels fallback for old devices. + Color[] pixelBuffer = source.GetPixels((int)sourceRect.x, (int)sourceRect.y, (int)sourceRect.width, (int)sourceRect.height); + destination.SetPixels(pixelBuffer); + destination.Apply(); + } else { + Graphics.CopyTexture(source, 0, 0, (int)sourceRect.x, (int)sourceRect.y, (int)sourceRect.width, (int)sourceRect.height, destination, 0, 0, 0, 0); + } + } + + static void CopyTextureApplyPMA (Texture2D source, Rect sourceRect, Texture2D destination) { + Color[] pixelBuffer = source.GetPixels((int)sourceRect.x, (int)sourceRect.y, (int)sourceRect.width, (int)sourceRect.height); + for (int i = 0, n = pixelBuffer.Length; i < n; i++) { + Color p = pixelBuffer[i]; + float a = p.a; + p.r = p.r * a; + p.g = p.g * a; + p.b = p.b * a; + pixelBuffer[i] = p; + } + destination.SetPixels(pixelBuffer); + destination.Apply(); + } + + static bool IsRenderable (Attachment a) { + return a is IHasRendererObject; + } + + /// + /// Get a rect with flipped Y so that a Spine atlas rect gets converted to a Unity Sprite rect and vice versa. + static Rect SpineUnityFlipRect (this Rect rect, int textureHeight) { + rect.y = textureHeight - rect.y - rect.height; + return rect; + } + + /// + /// Gets the Rect of an AtlasRegion according to Unity texture coordinates (x-right, y-up). + /// This overload relies on region.page.height being correctly set. + static Rect GetUnityRect (this AtlasRegion region) { + return region.GetSpineAtlasRect().SpineUnityFlipRect(region.page.height); + } + + /// + /// Gets the Rect of an AtlasRegion according to Unity texture coordinates (x-right, y-up). + static Rect GetUnityRect (this AtlasRegion region, int textureHeight) { + return region.GetSpineAtlasRect().SpineUnityFlipRect(textureHeight); + } + + /// + /// Returns a Rect of the AtlasRegion according to Spine texture coordinates. (x-right, y-down) + static Rect GetSpineAtlasRect (this AtlasRegion region, bool includeRotate = true) { + if (includeRotate && region.rotate) + return new Rect(region.x, region.y, region.height, region.width); + else + return new Rect(region.x, region.y, region.width, region.height); + } + + /// + /// Denormalize a uvRect into a texture-space Rect. + static Rect UVRectToTextureRect (Rect uvRect, int texWidth, int texHeight) { + uvRect.x *= texWidth; + uvRect.width *= texWidth; + uvRect.y *= texHeight; + uvRect.height *= texHeight; + return uvRect; + } + + /// + /// Normalize a texture Rect into UV coordinates. + static Rect TextureRectToUVRect (Rect textureRect, int texWidth, int texHeight) { + textureRect.x = Mathf.InverseLerp(0, texWidth, textureRect.x); + textureRect.y = Mathf.InverseLerp(0, texHeight, textureRect.y); + textureRect.width = Mathf.InverseLerp(0, texWidth, textureRect.width); + textureRect.height = Mathf.InverseLerp(0, texHeight, textureRect.height); + return textureRect; + } + + /// + /// Creates a new Spine AtlasRegion according to a Unity UV Rect (x-right, y-up, uv-normalized). + static AtlasRegion UVRectToAtlasRegion (Rect uvRect, AtlasRegion referenceRegion, AtlasPage page) { + var tr = UVRectToTextureRect(uvRect, page.width, page.height); + var rr = tr.SpineUnityFlipRect(page.height); + + int x = (int)rr.x, y = (int)rr.y; + int w, h; + if (referenceRegion.rotate) { + w = (int)rr.height; + h = (int)rr.width; + } else { + w = (int)rr.width; + h = (int)rr.height; + } + + int originalW = Mathf.RoundToInt((float)w * ((float)referenceRegion.originalWidth / (float)referenceRegion.width)); + int originalH = Mathf.RoundToInt((float)h * ((float)referenceRegion.originalHeight / (float)referenceRegion.height)); + int offsetX = Mathf.RoundToInt((float)referenceRegion.offsetX * ((float)w / (float)referenceRegion.width)); + int offsetY = Mathf.RoundToInt((float)referenceRegion.offsetY * ((float)h / (float)referenceRegion.height)); + + return new AtlasRegion { + page = page, + name = referenceRegion.name, + + u = uvRect.xMin, + u2 = uvRect.xMax, + v = uvRect.yMax, + v2 = uvRect.yMin, + + index = -1, + + width = w, + originalWidth = originalW, + height = h, + originalHeight = originalH, + offsetX = offsetX, + offsetY = offsetY, + x = x, + y = y, + + rotate = referenceRegion.rotate + }; + } + + /// + /// Convenience method for getting the main texture of the material of the page of the region. + static Texture2D GetMainTexture (this AtlasRegion region) { + var material = (region.page.rendererObject as Material); + return material.mainTexture as Texture2D; + } + + /// + /// Convenience method for getting any texture of the material of the page of the region by texture property name. + static Texture2D GetTexture (this AtlasRegion region, string texturePropertyName) { + var material = (region.page.rendererObject as Material); + return material.GetTexture(texturePropertyName) as Texture2D; + } + + /// + /// Convenience method for getting any texture of the material of the page of the region by texture property id. + static Texture2D GetTexture (this AtlasRegion region, int texturePropertyId) { + var material = (region.page.rendererObject as Material); + return material.GetTexture(texturePropertyId) as Texture2D; + } + + static void CopyTextureAttributesFrom(this Texture2D destination, Texture2D source) { + destination.filterMode = source.filterMode; + destination.anisoLevel = source.anisoLevel; + #if UNITY_EDITOR + destination.alphaIsTransparency = source.alphaIsTransparency; + #endif + destination.wrapModeU = source.wrapModeU; + destination.wrapModeV = source.wrapModeV; + destination.wrapModeW = source.wrapModeW; + } + #endregion + + static float InverseLerp (float a, float b, float value) { + return (value - a) / (b - a); + } + } +} diff --git a/box1/Assets/Spine/Runtime/spine-unity/Utility/AtlasUtilities.cs.meta b/box1/Assets/Spine/Runtime/spine-unity/Utility/AtlasUtilities.cs.meta new file mode 100644 index 00000000..32d291e2 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Utility/AtlasUtilities.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 25ceef568a3dad448bf8a14fcc326964 +timeCreated: 1563321428 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Utility/AttachmentCloneExtensions.cs b/box1/Assets/Spine/Runtime/spine-unity/Utility/AttachmentCloneExtensions.cs new file mode 100644 index 00000000..ece990f3 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Utility/AttachmentCloneExtensions.cs @@ -0,0 +1,123 @@ +/****************************************************************************** + * 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.Generic; +using System.Collections; + +namespace Spine.Unity.AttachmentTools { + + public static class AttachmentCloneExtensions { + /// + /// Clones the attachment. + public static Attachment GetCopy (this Attachment o, bool cloneMeshesAsLinked) { + var meshAttachment = o as MeshAttachment; + if (meshAttachment != null && cloneMeshesAsLinked) + return meshAttachment.NewLinkedMesh(); + return o.Copy(); + } + + #region Runtime Linked MeshAttachments + /// + /// Returns a new linked mesh linked to this MeshAttachment. It will be mapped to the AtlasRegion provided. + public static MeshAttachment GetLinkedMesh (this MeshAttachment o, string newLinkedMeshName, AtlasRegion region) { + if (region == null) throw new System.ArgumentNullException("region"); + MeshAttachment mesh = o.NewLinkedMesh(); + mesh.SetRegion(region, false); + return mesh; + } + + /// + /// Returns a new linked mesh linked to this MeshAttachment. It will be mapped to an AtlasRegion generated from a Sprite. The AtlasRegion will be mapped to a new Material based on the shader. + /// For better caching and batching, use GetLinkedMesh(string, AtlasRegion, bool) + public static MeshAttachment GetLinkedMesh (this MeshAttachment o, Sprite sprite, Shader shader, Material materialPropertySource = null) { + var m = new Material(shader); + if (materialPropertySource != null) { + m.CopyPropertiesFromMaterial(materialPropertySource); + m.shaderKeywords = materialPropertySource.shaderKeywords; + } + return o.GetLinkedMesh(sprite.name, sprite.ToAtlasRegion()); + } + + /// + /// Returns a new linked mesh linked to this MeshAttachment. It will be mapped to an AtlasRegion generated from a Sprite. The AtlasRegion will be mapped to a new Material based on the shader. + /// For better caching and batching, use GetLinkedMesh(string, AtlasRegion, bool) + public static MeshAttachment GetLinkedMesh (this MeshAttachment o, Sprite sprite, Material materialPropertySource) { + return o.GetLinkedMesh(sprite, materialPropertySource.shader, materialPropertySource); + } + #endregion + + #region RemappedClone Convenience Methods + /// + /// Gets a clone of the attachment remapped with a sprite image. + /// The remapped clone. + /// The original attachment. + /// The sprite whose texture to use. + /// The source material used to copy the shader and material properties from. + /// If true, a premultiply alpha clone of the original texture will be created. + /// If true MeshAttachments will be cloned as linked meshes and will inherit animation from the original attachment. + /// If true the size of the original attachment will be followed, instead of using the Sprite size. + public static Attachment GetRemappedClone (this Attachment o, Sprite sprite, Material sourceMaterial, bool premultiplyAlpha = true, bool cloneMeshAsLinked = true, bool useOriginalRegionSize = false) { + var atlasRegion = premultiplyAlpha ? sprite.ToAtlasRegionPMAClone(sourceMaterial) : sprite.ToAtlasRegion(new Material(sourceMaterial) { mainTexture = sprite.texture } ); + return o.GetRemappedClone(atlasRegion, cloneMeshAsLinked, useOriginalRegionSize, 1f/sprite.pixelsPerUnit); + } + + /// + /// Gets a clone of the attachment remapped with an atlasRegion image. + /// The remapped clone. + /// The original attachment. + /// Atlas region. + /// If true MeshAttachments will be cloned as linked meshes and will inherit animation from the original attachment. + /// If true the size of the original attachment will be followed, instead of using the Sprite size. + /// Unity units per pixel scale used to scale the atlas region size when not using the original region size. + public static Attachment GetRemappedClone (this Attachment o, AtlasRegion atlasRegion, bool cloneMeshAsLinked = true, bool useOriginalRegionSize = false, float scale = 0.01f) { + var regionAttachment = o as RegionAttachment; + if (regionAttachment != null) { + RegionAttachment newAttachment = (RegionAttachment)regionAttachment.Copy(); + newAttachment.SetRegion(atlasRegion, false); + if (!useOriginalRegionSize) { + newAttachment.width = atlasRegion.width * scale; + newAttachment.height = atlasRegion.height * scale; + } + newAttachment.UpdateOffset(); + return newAttachment; + } else { + var meshAttachment = o as MeshAttachment; + if (meshAttachment != null) { + MeshAttachment newAttachment = cloneMeshAsLinked ? meshAttachment.NewLinkedMesh() : (MeshAttachment)meshAttachment.Copy(); + newAttachment.SetRegion(atlasRegion); + return newAttachment; + } + } + + return o.GetCopy(true); // Non-renderable Attachments will return as normal cloned attachments. + } + #endregion + } +} diff --git a/box1/Assets/Spine/Runtime/spine-unity/Utility/AttachmentCloneExtensions.cs.meta b/box1/Assets/Spine/Runtime/spine-unity/Utility/AttachmentCloneExtensions.cs.meta new file mode 100644 index 00000000..4d6580e6 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Utility/AttachmentCloneExtensions.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 3431ed563b2c62f4c8c974a99365ba52 +timeCreated: 1563321428 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Utility/AttachmentRegionExtensions.cs b/box1/Assets/Spine/Runtime/spine-unity/Utility/AttachmentRegionExtensions.cs new file mode 100644 index 00000000..580b0ae6 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Utility/AttachmentRegionExtensions.cs @@ -0,0 +1,207 @@ +/****************************************************************************** + * 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.Generic; +using System.Collections; + +namespace Spine.Unity.AttachmentTools { + public static class AttachmentRegionExtensions { + #region GetRegion + /// + /// Tries to get the region (image) of a renderable attachment. If the attachment is not renderable, it returns null. + public static AtlasRegion GetRegion (this Attachment attachment) { + var renderableAttachment = attachment as IHasRendererObject; + if (renderableAttachment != null) + return renderableAttachment.RendererObject as AtlasRegion; + + return null; + } + + /// Gets the region (image) of a RegionAttachment + public static AtlasRegion GetRegion (this RegionAttachment regionAttachment) { + return regionAttachment.RendererObject as AtlasRegion; + } + + /// Gets the region (image) of a MeshAttachment + public static AtlasRegion GetRegion (this MeshAttachment meshAttachment) { + return meshAttachment.RendererObject as AtlasRegion; + } + #endregion + #region SetRegion + /// + /// Tries to set the region (image) of a renderable attachment. If the attachment is not renderable, nothing is applied. + public static void SetRegion (this Attachment attachment, AtlasRegion region, bool updateOffset = true) { + var regionAttachment = attachment as RegionAttachment; + if (regionAttachment != null) + regionAttachment.SetRegion(region, updateOffset); + + var meshAttachment = attachment as MeshAttachment; + if (meshAttachment != null) + meshAttachment.SetRegion(region, updateOffset); + } + + /// Sets the region (image) of a RegionAttachment + public static void SetRegion (this RegionAttachment attachment, AtlasRegion region, bool updateOffset = true) { + if (region == null) throw new System.ArgumentNullException("region"); + + // (AtlasAttachmentLoader.cs) + attachment.RendererObject = region; + attachment.SetUVs(region.u, region.v, region.u2, region.v2, region.rotate); + attachment.regionOffsetX = region.offsetX; + attachment.regionOffsetY = region.offsetY; + attachment.regionWidth = region.width; + attachment.regionHeight = region.height; + attachment.regionOriginalWidth = region.originalWidth; + attachment.regionOriginalHeight = region.originalHeight; + + if (updateOffset) attachment.UpdateOffset(); + } + + /// Sets the region (image) of a MeshAttachment + public static void SetRegion (this MeshAttachment attachment, AtlasRegion region, bool updateUVs = true) { + if (region == null) throw new System.ArgumentNullException("region"); + + // (AtlasAttachmentLoader.cs) + attachment.RendererObject = region; + attachment.RegionU = region.u; + attachment.RegionV = region.v; + attachment.RegionU2 = region.u2; + attachment.RegionV2 = region.v2; + attachment.RegionRotate = region.rotate; + attachment.regionOffsetX = region.offsetX; + attachment.regionOffsetY = region.offsetY; + attachment.regionWidth = region.width; + attachment.regionHeight = region.height; + attachment.regionOriginalWidth = region.originalWidth; + attachment.regionOriginalHeight = region.originalHeight; + + if (updateUVs) attachment.UpdateUVs(); + } + #endregion + + #region Runtime RegionAttachments + /// + /// Creates a RegionAttachment based on a sprite. This method creates a real, usable AtlasRegion. That AtlasRegion uses a new AtlasPage with the Material provided./// + public static RegionAttachment ToRegionAttachment (this Sprite sprite, Material material, float rotation = 0f) { + return sprite.ToRegionAttachment(material.ToSpineAtlasPage(), rotation); + } + + /// + /// Creates a RegionAttachment based on a sprite. This method creates a real, usable AtlasRegion. That AtlasRegion uses the AtlasPage provided./// + public static RegionAttachment ToRegionAttachment (this Sprite sprite, AtlasPage page, float rotation = 0f) { + if (sprite == null) throw new System.ArgumentNullException("sprite"); + if (page == null) throw new System.ArgumentNullException("page"); + var region = sprite.ToAtlasRegion(page); + var unitsPerPixel = 1f / sprite.pixelsPerUnit; + return region.ToRegionAttachment(sprite.name, unitsPerPixel, rotation); + } + + /// + /// Creates a Spine.AtlasRegion that uses a premultiplied alpha duplicate texture of the Sprite's texture data. Returns a RegionAttachment that uses it. Use this if you plan to use a premultiply alpha shader such as "Spine/Skeleton" + public static RegionAttachment ToRegionAttachmentPMAClone (this Sprite sprite, Shader shader, TextureFormat textureFormat = AtlasUtilities.SpineTextureFormat, bool mipmaps = AtlasUtilities.UseMipMaps, Material materialPropertySource = null, float rotation = 0f) { + if (sprite == null) throw new System.ArgumentNullException("sprite"); + if (shader == null) throw new System.ArgumentNullException("shader"); + var region = sprite.ToAtlasRegionPMAClone(shader, textureFormat, mipmaps, materialPropertySource); + var unitsPerPixel = 1f / sprite.pixelsPerUnit; + return region.ToRegionAttachment(sprite.name, unitsPerPixel, rotation); + } + + public static RegionAttachment ToRegionAttachmentPMAClone (this Sprite sprite, Material materialPropertySource, TextureFormat textureFormat = AtlasUtilities.SpineTextureFormat, bool mipmaps = AtlasUtilities.UseMipMaps, float rotation = 0f) { + return sprite.ToRegionAttachmentPMAClone(materialPropertySource.shader, textureFormat, mipmaps, materialPropertySource, rotation); + } + + /// + /// Creates a new RegionAttachment from a given AtlasRegion. + public static RegionAttachment ToRegionAttachment (this AtlasRegion region, string attachmentName, float scale = 0.01f, float rotation = 0f) { + if (string.IsNullOrEmpty(attachmentName)) throw new System.ArgumentException("attachmentName can't be null or empty.", "attachmentName"); + if (region == null) throw new System.ArgumentNullException("region"); + + // (AtlasAttachmentLoader.cs) + var attachment = new RegionAttachment(attachmentName); + + attachment.RendererObject = region; + attachment.SetUVs(region.u, region.v, region.u2, region.v2, region.rotate); + attachment.regionOffsetX = region.offsetX; + attachment.regionOffsetY = region.offsetY; + attachment.regionWidth = region.width; + attachment.regionHeight = region.height; + attachment.regionOriginalWidth = region.originalWidth; + attachment.regionOriginalHeight = region.originalHeight; + + attachment.Path = region.name; + attachment.scaleX = 1; + attachment.scaleY = 1; + attachment.rotation = rotation; + + attachment.r = 1; + attachment.g = 1; + attachment.b = 1; + attachment.a = 1; + + // pass OriginalWidth and OriginalHeight because UpdateOffset uses it in its calculation. + attachment.width = attachment.regionOriginalWidth * scale; + attachment.height = attachment.regionOriginalHeight * scale; + + attachment.SetColor(Color.white); + attachment.UpdateOffset(); + return attachment; + } + + /// Sets the scale. Call regionAttachment.UpdateOffset to apply the change. + public static void SetScale (this RegionAttachment regionAttachment, Vector2 scale) { + regionAttachment.scaleX = scale.x; + regionAttachment.scaleY = scale.y; + } + + /// Sets the scale. Call regionAttachment.UpdateOffset to apply the change. + public static void SetScale (this RegionAttachment regionAttachment, float x, float y) { + regionAttachment.scaleX = x; + regionAttachment.scaleY = y; + } + + /// Sets the position offset. Call regionAttachment.UpdateOffset to apply the change. + public static void SetPositionOffset (this RegionAttachment regionAttachment, Vector2 offset) { + regionAttachment.x = offset.x; + regionAttachment.y = offset.y; + } + + /// Sets the position offset. Call regionAttachment.UpdateOffset to apply the change. + public static void SetPositionOffset (this RegionAttachment regionAttachment, float x, float y) { + regionAttachment.x = x; + regionAttachment.y = y; + } + + /// Sets the rotation. Call regionAttachment.UpdateOffset to apply the change. + public static void SetRotation (this RegionAttachment regionAttachment, float rotation) { + regionAttachment.rotation = rotation; + } + #endregion + } +} diff --git a/box1/Assets/Spine/Runtime/spine-unity/Utility/AttachmentRegionExtensions.cs.meta b/box1/Assets/Spine/Runtime/spine-unity/Utility/AttachmentRegionExtensions.cs.meta new file mode 100644 index 00000000..58262113 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Utility/AttachmentRegionExtensions.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 7e7eac783deea004e9bc403eca68a7dc +timeCreated: 1563321428 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Utility/MaterialChecks.cs b/box1/Assets/Spine/Runtime/spine-unity/Utility/MaterialChecks.cs new file mode 100644 index 00000000..0e1174a7 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Utility/MaterialChecks.cs @@ -0,0 +1,190 @@ +/****************************************************************************** + * 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.Collections.Generic; +using UnityEngine; + +#if UNITY_EDITOR + +namespace Spine.Unity { + /// Utility class providing methods to check material settings for incorrect combinations. + public class MaterialChecks { + + static readonly int STRAIGHT_ALPHA_PARAM_ID = Shader.PropertyToID("_StraightAlphaInput"); + static readonly string ALPHAPREMULTIPLY_ON_KEYWORD = "_ALPHAPREMULTIPLY_ON"; + static readonly string STRAIGHT_ALPHA_KEYWORD = "_STRAIGHT_ALPHA_INPUT"; + + public static readonly string kPMANotSupportedLinearMessage = + "Warning: Premultiply-alpha atlas textures not supported in Linear color space!\n\nPlease\n" + + "a) re-export atlas as straight alpha texture with 'premultiply alpha' unchecked\n" + + " (if you have already done this, please set the 'Straight Alpha Texture' Material parameter to 'true') or\n" + + "b) switch to Gamma color space via\nProject Settings - Player - Other Settings - Color Space.\n"; + public static readonly string kZSpacingRequiredMessage = + "Warning: Z Spacing required on selected shader! Otherwise you will receive incorrect results.\n\nPlease\n" + + "1) make sure at least minimal 'Z Spacing' is set at the SkeletonRenderer/SkeletonAnimation component under 'Advanced' and\n" + + "2) ensure that the skeleton has overlapping parts on different Z depth. You can adjust this in Spine via draw order.\n"; + public static readonly string kZSpacingRecommendedMessage = + "Warning: Z Spacing recommended on selected shader configuration!\n\nPlease\n" + + "1) make sure at least minimal 'Z Spacing' is set at the SkeletonRenderer/SkeletonAnimation component under 'Advanced' and\n" + + "2) ensure that the skeleton has overlapping parts on different Z depth. You can adjust this in Spine via draw order.\n"; + public static readonly string kAddNormalsRequiredMessage = + "Warning: 'Add Normals' required on URP shader to receive shadows!\n\nPlease\n" + + "a) enable 'Add Normals' at the SkeletonRenderer/SkeletonAnimation component under 'Advanced' or\n" + + "b) disable 'Receive Shadows' at the Material."; + + public static bool IsMaterialSetupProblematic (SkeletonRenderer renderer, ref string errorMessage) { + var materials = renderer.GetComponent().sharedMaterials; + bool isProblematic = false; + foreach (var material in materials) { + if (material == null) continue; + isProblematic |= IsMaterialSetupProblematic(material, ref errorMessage); + if (renderer.zSpacing == 0) { + isProblematic |= IsZSpacingRequired(material, ref errorMessage); + } + if (IsURPMaterial(material) && !AreShadowsDisabled(material) && renderer.addNormals == false) { + isProblematic = true; + errorMessage += kAddNormalsRequiredMessage; + } + } + return isProblematic; + } + + public static bool IsMaterialSetupProblematic(Material material, ref string errorMessage) { + return !IsColorSpaceSupported(material, ref errorMessage); + } + + public static bool IsZSpacingRequired(Material material, ref string errorMessage) { + bool hasForwardAddPass = material.FindPass("FORWARD_DELTA") >= 0; + if (hasForwardAddPass) { + errorMessage += kZSpacingRequiredMessage; + return true; + } + bool zWrite = material.HasProperty("_ZWrite") && material.GetFloat("_ZWrite") > 0.0f; + if (zWrite) { + errorMessage += kZSpacingRecommendedMessage; + return true; + } + return false; + } + + public static bool IsColorSpaceSupported (Material material, ref string errorMessage) { + if (QualitySettings.activeColorSpace == ColorSpace.Linear) { + if (IsPMAMaterial(material)) { + errorMessage += kPMANotSupportedLinearMessage; + return false; + } + } + return true; + } + + + public static bool UsesSpineShader (Material material) { + return material.shader.name.Contains("Spine/"); + } + + public static bool IsTextureSetupProblematic (Material material, ColorSpace colorSpace, + bool sRGBTexture, bool mipmapEnabled, bool alphaIsTransparency, + string texturePath, string materialPath, + ref string errorMessage) { + + if (material == null || !UsesSpineShader(material)) { + return false; + } + + bool isProblematic = false; + if (IsPMAMaterial(material)) { + // 'sRGBTexture = true' generates incorrectly weighted mipmaps at PMA textures, + // causing white borders due to undesired custom weighting. + if (sRGBTexture && mipmapEnabled && colorSpace == ColorSpace.Gamma) { + errorMessage += string.Format("`{0}` : Problematic Texture Settings found: " + + "When enabling `Generate Mip Maps` in Gamma color space, it is recommended " + + "to disable `sRGB (Color Texture)` on `Premultiply alpha` textures. Otherwise " + + "you will receive white border artifacts on an atlas exported with default " + + "`Premultiply alpha` settings.\n" + + "(You can disable this warning in `Edit - Preferences - Spine`)\n", texturePath); + isProblematic = true; + } + if (alphaIsTransparency) { + string materialName = System.IO.Path.GetFileName(materialPath); + errorMessage += string.Format("`{0}` and material `{1}` : Problematic " + + "Texture / Material Settings found: It is recommended to disable " + + "`Alpha Is Transparency` on `Premultiply alpha` textures.\n" + + "Assuming `Premultiply alpha` texture because `Straight Alpha Texture` " + + "is disabled at material). " + + "(You can disable this warning in `Edit - Preferences - Spine`)\n", texturePath, materialName); + isProblematic = true; + } + } + else { // straight alpha texture + if (!alphaIsTransparency) { + string materialName = System.IO.Path.GetFileName(materialPath); + errorMessage += string.Format("`{0}` and material `{1}` : Incorrect" + + "Texture / Material Settings found: It is strongly recommended " + + "to enable `Alpha Is Transparency` on `Straight alpha` textures.\n" + + "Assuming `Straight alpha` texture because `Straight Alpha Texture` " + + "is enabled at material). " + + "(You can disable this warning in `Edit - Preferences - Spine`)\n", texturePath, materialName); + isProblematic = true; + } + } + return isProblematic; + } + + public static void EnablePMAAtMaterial (Material material, bool enablePMA) { + if (material.HasProperty(STRAIGHT_ALPHA_PARAM_ID)) { + material.SetInt(STRAIGHT_ALPHA_PARAM_ID, enablePMA ? 0 : 1); + if (enablePMA) + material.DisableKeyword(STRAIGHT_ALPHA_KEYWORD); + else + material.EnableKeyword(STRAIGHT_ALPHA_KEYWORD); + } + else { + if (enablePMA) + material.EnableKeyword(ALPHAPREMULTIPLY_ON_KEYWORD); + else + material.DisableKeyword(ALPHAPREMULTIPLY_ON_KEYWORD); + } + } + + static bool IsPMAMaterial (Material material) { + return (material.HasProperty(STRAIGHT_ALPHA_PARAM_ID) && material.GetInt(STRAIGHT_ALPHA_PARAM_ID) == 0) || + material.IsKeywordEnabled(ALPHAPREMULTIPLY_ON_KEYWORD); + } + + static bool IsURPMaterial (Material material) { + return material.shader.name.Contains("Universal Render Pipeline"); + } + + static bool AreShadowsDisabled (Material material) { + return material.IsKeywordEnabled("_RECEIVE_SHADOWS_OFF"); + } + } +} + +#endif // UNITY_EDITOR diff --git a/box1/Assets/Spine/Runtime/spine-unity/Utility/MaterialChecks.cs.meta b/box1/Assets/Spine/Runtime/spine-unity/Utility/MaterialChecks.cs.meta new file mode 100644 index 00000000..7535c40d --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Utility/MaterialChecks.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e68fa8db689084946adce454b83e6d4a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Utility/SkeletonExtensions.cs b/box1/Assets/Spine/Runtime/spine-unity/Utility/SkeletonExtensions.cs new file mode 100644 index 00000000..4ca34def --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Utility/SkeletonExtensions.cs @@ -0,0 +1,614 @@ +/****************************************************************************** + * 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; + +namespace Spine.Unity { + public static class SkeletonExtensions { + + #region Colors + const float ByteToFloat = 1f / 255f; + public static Color GetColor (this Skeleton s) { return new Color(s.r, s.g, s.b, s.a); } + public static Color GetColor (this RegionAttachment a) { return new Color(a.r, a.g, a.b, a.a); } + public static Color GetColor (this MeshAttachment a) { return new Color(a.r, a.g, a.b, a.a); } + public static Color GetColor (this Slot s) { return new Color(s.r, s.g, s.b, s.a); } + public static Color GetColorTintBlack (this Slot s) { return new Color(s.r2, s.g2, s.b2, 1f); } + + public static void SetColor (this Skeleton skeleton, Color color) { + skeleton.A = color.a; + skeleton.R = color.r; + skeleton.G = color.g; + skeleton.B = color.b; + } + + public static void SetColor (this Skeleton skeleton, Color32 color) { + skeleton.A = color.a * ByteToFloat; + skeleton.R = color.r * ByteToFloat; + skeleton.G = color.g * ByteToFloat; + skeleton.B = color.b * ByteToFloat; + } + + public static void SetColor (this Slot slot, Color color) { + slot.A = color.a; + slot.R = color.r; + slot.G = color.g; + slot.B = color.b; + } + + public static void SetColor (this Slot slot, Color32 color) { + slot.A = color.a * ByteToFloat; + slot.R = color.r * ByteToFloat; + slot.G = color.g * ByteToFloat; + slot.B = color.b * ByteToFloat; + } + + public static void SetColor (this RegionAttachment attachment, Color color) { + attachment.A = color.a; + attachment.R = color.r; + attachment.G = color.g; + attachment.B = color.b; + } + + public static void SetColor (this RegionAttachment attachment, Color32 color) { + attachment.A = color.a * ByteToFloat; + attachment.R = color.r * ByteToFloat; + attachment.G = color.g * ByteToFloat; + attachment.B = color.b * ByteToFloat; + } + + public static void SetColor (this MeshAttachment attachment, Color color) { + attachment.A = color.a; + attachment.R = color.r; + attachment.G = color.g; + attachment.B = color.b; + } + + public static void SetColor (this MeshAttachment attachment, Color32 color) { + attachment.A = color.a * ByteToFloat; + attachment.R = color.r * ByteToFloat; + attachment.G = color.g * ByteToFloat; + attachment.B = color.b * ByteToFloat; + } + #endregion + + #region Skeleton + /// Sets the Skeleton's local scale using a UnityEngine.Vector2. If only individual components need to be set, set Skeleton.ScaleX or Skeleton.ScaleY. + public static void SetLocalScale (this Skeleton skeleton, Vector2 scale) { + skeleton.ScaleX = scale.x; + skeleton.ScaleY = scale.y; + } + + /// Gets the internal bone matrix as a Unity bonespace-to-skeletonspace transformation matrix. + public static Matrix4x4 GetMatrix4x4 (this Bone bone) { + return new Matrix4x4 { + m00 = bone.a, + m01 = bone.b, + m03 = bone.worldX, + m10 = bone.c, + m11 = bone.d, + m13 = bone.worldY, + m33 = 1 + }; + } + #endregion + + #region Bone + /// Sets the bone's (local) X and Y according to a Vector2 + public static void SetLocalPosition (this Bone bone, Vector2 position) { + bone.X = position.x; + bone.Y = position.y; + } + + /// Sets the bone's (local) X and Y according to a Vector3. The z component is ignored. + public static void SetLocalPosition (this Bone bone, Vector3 position) { + bone.X = position.x; + bone.Y = position.y; + } + + /// Gets the bone's local X and Y as a Vector2. + public static Vector2 GetLocalPosition (this Bone bone) { + return new Vector2(bone.x, bone.y); + } + + /// Gets the position of the bone in Skeleton-space. + public static Vector2 GetSkeletonSpacePosition (this Bone bone) { + return new Vector2(bone.worldX, bone.worldY); + } + + /// Gets a local offset from the bone and converts it into Skeleton-space. + public static Vector2 GetSkeletonSpacePosition (this Bone bone, Vector2 boneLocal) { + Vector2 o; + bone.LocalToWorld(boneLocal.x, boneLocal.y, out o.x, out o.y); + return o; + } + + /// Gets the bone's Unity World position using its Spine GameObject Transform. UpdateWorldTransform needs to have been called for this to return the correct, updated value. + public static Vector3 GetWorldPosition (this Bone bone, UnityEngine.Transform spineGameObjectTransform) { + return spineGameObjectTransform.TransformPoint(new Vector3(bone.worldX, bone.worldY)); + } + + public static Vector3 GetWorldPosition (this Bone bone, UnityEngine.Transform spineGameObjectTransform, float positionScale) { + return spineGameObjectTransform.TransformPoint(new Vector3(bone.worldX * positionScale, bone.worldY * positionScale)); + } + + /// Gets a skeleton space UnityEngine.Quaternion representation of bone.WorldRotationX. + public static Quaternion GetQuaternion (this Bone bone) { + var halfRotation = Mathf.Atan2(bone.c, bone.a) * 0.5f; + return new Quaternion(0, 0, Mathf.Sin(halfRotation), Mathf.Cos(halfRotation)); + } + + /// Gets a bone-local space UnityEngine.Quaternion representation of bone.rotation. + public static Quaternion GetLocalQuaternion (this Bone bone) { + var halfRotation = bone.rotation * Mathf.Deg2Rad * 0.5f; + return new Quaternion(0, 0, Mathf.Sin(halfRotation), Mathf.Cos(halfRotation)); + } + + /// Returns the Skeleton's local scale as a UnityEngine.Vector2. If only individual components are needed, use Skeleton.ScaleX or Skeleton.ScaleY. + public static Vector2 GetLocalScale (this Skeleton skeleton) { + return new Vector2(skeleton.ScaleX, skeleton.ScaleY); + } + + /// Calculates a 2x2 Transformation Matrix that can convert a skeleton-space position to a bone-local position. + public static void GetWorldToLocalMatrix (this Bone bone, out float ia, out float ib, out float ic, out float id) { + float a = bone.a, b = bone.b, c = bone.c, d = bone.d; + float invDet = 1 / (a * d - b * c); + ia = invDet * d; + ib = invDet * -b; + ic = invDet * -c; + id = invDet * a; + } + + /// UnityEngine.Vector2 override of Bone.WorldToLocal. This converts a skeleton-space position into a bone local position. + public static Vector2 WorldToLocal (this Bone bone, Vector2 worldPosition) { + Vector2 o; + bone.WorldToLocal(worldPosition.x, worldPosition.y, out o.x, out o.y); + return o; + } + + /// Sets the skeleton-space position of a bone. + /// The local position in its parent bone space, or in skeleton space if it is the root bone. + public static Vector2 SetPositionSkeletonSpace (this Bone bone, Vector2 skeletonSpacePosition) { + if (bone.parent == null) { // root bone + bone.SetLocalPosition(skeletonSpacePosition); + return skeletonSpacePosition; + } else { + var parent = bone.parent; + Vector2 parentLocal = parent.WorldToLocal(skeletonSpacePosition); + bone.SetLocalPosition(parentLocal); + return parentLocal; + } + } + #endregion + + #region Attachments + public static Material GetMaterial (this Attachment a) { + object rendererObject = null; + var renderableAttachment = a as IHasRendererObject; + if (renderableAttachment != null) + rendererObject = renderableAttachment.RendererObject; + + if (rendererObject == null) + return null; + + #if SPINE_TK2D + return (rendererObject.GetType() == typeof(Material)) ? (Material)rendererObject : (Material)((AtlasRegion)rendererObject).page.rendererObject; + #else + return (Material)((AtlasRegion)rendererObject).page.rendererObject; + #endif + } + + /// Fills a Vector2 buffer with local vertices. + /// The VertexAttachment + /// Slot where the attachment belongs. + /// Correctly-sized buffer. Use attachment's .WorldVerticesLength to get the correct size. If null, a new Vector2[] of the correct size will be allocated. + public static Vector2[] GetLocalVertices (this VertexAttachment va, Slot slot, Vector2[] buffer) { + int floatsCount = va.worldVerticesLength; + int bufferTargetSize = floatsCount >> 1; + buffer = buffer ?? new Vector2[bufferTargetSize]; + if (buffer.Length < bufferTargetSize) throw new System.ArgumentException(string.Format("Vector2 buffer too small. {0} requires an array of size {1}. Use the attachment's .WorldVerticesLength to get the correct size.", va.Name, floatsCount), "buffer"); + + if (va.bones == null) { + var localVerts = va.vertices; + for (int i = 0; i < bufferTargetSize; i++) { + int j = i * 2; + buffer[i] = new Vector2(localVerts[j], localVerts[j+1]); + } + } else { + var floats = new float[floatsCount]; + va.ComputeWorldVertices(slot, floats); + + Bone sb = slot.bone; + float ia, ib, ic, id, bwx = sb.worldX, bwy = sb.worldY; + sb.GetWorldToLocalMatrix(out ia, out ib, out ic, out id); + + for (int i = 0; i < bufferTargetSize; i++) { + int j = i * 2; + float x = floats[j] - bwx, y = floats[j+1] - bwy; + buffer[i] = new Vector2(x * ia + y * ib, x * ic + y * id); + } + } + + return buffer; + } + + /// Calculates world vertices and fills a Vector2 buffer. + /// The VertexAttachment + /// Slot where the attachment belongs. + /// Correctly-sized buffer. Use attachment's .WorldVerticesLength to get the correct size. If null, a new Vector2[] of the correct size will be allocated. + public static Vector2[] GetWorldVertices (this VertexAttachment a, Slot slot, Vector2[] buffer) { + int worldVertsLength = a.worldVerticesLength; + int bufferTargetSize = worldVertsLength >> 1; + buffer = buffer ?? new Vector2[bufferTargetSize]; + if (buffer.Length < bufferTargetSize) throw new System.ArgumentException(string.Format("Vector2 buffer too small. {0} requires an array of size {1}. Use the attachment's .WorldVerticesLength to get the correct size.", a.Name, worldVertsLength), "buffer"); + + var floats = new float[worldVertsLength]; + a.ComputeWorldVertices(slot, floats); + + for (int i = 0, n = worldVertsLength >> 1; i < n; i++) { + int j = i * 2; + buffer[i] = new Vector2(floats[j], floats[j + 1]); + } + + return buffer; + } + + /// Gets the PointAttachment's Unity World position using its Spine GameObject Transform. + public static Vector3 GetWorldPosition (this PointAttachment attachment, Slot slot, Transform spineGameObjectTransform) { + Vector3 skeletonSpacePosition; + skeletonSpacePosition.z = 0; + attachment.ComputeWorldPosition(slot.bone, out skeletonSpacePosition.x, out skeletonSpacePosition.y); + return spineGameObjectTransform.TransformPoint(skeletonSpacePosition); + } + + /// Gets the PointAttachment's Unity World position using its Spine GameObject Transform. + public static Vector3 GetWorldPosition (this PointAttachment attachment, Bone bone, Transform spineGameObjectTransform) { + Vector3 skeletonSpacePosition; + skeletonSpacePosition.z = 0; + attachment.ComputeWorldPosition(bone, out skeletonSpacePosition.x, out skeletonSpacePosition.y); + return spineGameObjectTransform.TransformPoint(skeletonSpacePosition); + } + #endregion + } +} + +namespace Spine { + using System; + using System.Collections.Generic; + + public struct BoneMatrix { + public float a, b, c, d, x, y; + + /// Recursively calculates a worldspace bone matrix based on BoneData. + public static BoneMatrix CalculateSetupWorld (BoneData boneData) { + if (boneData == null) + return default(BoneMatrix); + + // End condition: isRootBone + if (boneData.parent == null) + return GetInheritedInternal(boneData, default(BoneMatrix)); + + BoneMatrix result = CalculateSetupWorld(boneData.parent); + return GetInheritedInternal(boneData, result); + } + + static BoneMatrix GetInheritedInternal (BoneData boneData, BoneMatrix parentMatrix) { + var parent = boneData.parent; + if (parent == null) return new BoneMatrix(boneData); // isRootBone + + float pa = parentMatrix.a, pb = parentMatrix.b, pc = parentMatrix.c, pd = parentMatrix.d; + BoneMatrix result = default(BoneMatrix); + result.x = pa * boneData.x + pb * boneData.y + parentMatrix.x; + result.y = pc * boneData.x + pd * boneData.y + parentMatrix.y; + + switch (boneData.transformMode) { + case TransformMode.Normal: { + float rotationY = boneData.rotation + 90 + boneData.shearY; + float la = MathUtils.CosDeg(boneData.rotation + boneData.shearX) * boneData.scaleX; + float lb = MathUtils.CosDeg(rotationY) * boneData.scaleY; + float lc = MathUtils.SinDeg(boneData.rotation + boneData.shearX) * boneData.scaleX; + float ld = MathUtils.SinDeg(rotationY) * boneData.scaleY; + result.a = pa * la + pb * lc; + result.b = pa * lb + pb * ld; + result.c = pc * la + pd * lc; + result.d = pc * lb + pd * ld; + break; + } + case TransformMode.OnlyTranslation: { + float rotationY = boneData.rotation + 90 + boneData.shearY; + result.a = MathUtils.CosDeg(boneData.rotation + boneData.shearX) * boneData.scaleX; + result.b = MathUtils.CosDeg(rotationY) * boneData.scaleY; + result.c = MathUtils.SinDeg(boneData.rotation + boneData.shearX) * boneData.scaleX; + result.d = MathUtils.SinDeg(rotationY) * boneData.scaleY; + break; + } + case TransformMode.NoRotationOrReflection: { + float s = pa * pa + pc * pc, prx; + if (s > 0.0001f) { + s = Math.Abs(pa * pd - pb * pc) / s; + pb = pc * s; + pd = pa * s; + prx = MathUtils.Atan2(pc, pa) * MathUtils.RadDeg; + } else { + pa = 0; + pc = 0; + prx = 90 - MathUtils.Atan2(pd, pb) * MathUtils.RadDeg; + } + float rx = boneData.rotation + boneData.shearX - prx; + float ry = boneData.rotation + boneData.shearY - prx + 90; + float la = MathUtils.CosDeg(rx) * boneData.scaleX; + float lb = MathUtils.CosDeg(ry) * boneData.scaleY; + float lc = MathUtils.SinDeg(rx) * boneData.scaleX; + float ld = MathUtils.SinDeg(ry) * boneData.scaleY; + result.a = pa * la - pb * lc; + result.b = pa * lb - pb * ld; + result.c = pc * la + pd * lc; + result.d = pc * lb + pd * ld; + break; + } + case TransformMode.NoScale: + case TransformMode.NoScaleOrReflection: { + float cos = MathUtils.CosDeg(boneData.rotation), sin = MathUtils.SinDeg(boneData.rotation); + float za = pa * cos + pb * sin; + float zc = pc * cos + pd * sin; + float s = (float)Math.Sqrt(za * za + zc * zc); + if (s > 0.00001f) + s = 1 / s; + za *= s; + zc *= s; + s = (float)Math.Sqrt(za * za + zc * zc); + float r = MathUtils.PI / 2 + MathUtils.Atan2(zc, za); + float zb = MathUtils.Cos(r) * s; + float zd = MathUtils.Sin(r) * s; + float la = MathUtils.CosDeg(boneData.shearX) * boneData.scaleX; + float lb = MathUtils.CosDeg(90 + boneData.shearY) * boneData.scaleY; + float lc = MathUtils.SinDeg(boneData.shearX) * boneData.scaleX; + float ld = MathUtils.SinDeg(90 + boneData.shearY) * boneData.scaleY; + if (boneData.transformMode != TransformMode.NoScaleOrReflection ? pa * pd - pb * pc < 0 : false) { + zb = -zb; + zd = -zd; + } + result.a = za * la + zb * lc; + result.b = za * lb + zb * ld; + result.c = zc * la + zd * lc; + result.d = zc * lb + zd * ld; + break; + } + } + + return result; + } + + /// Constructor for a local bone matrix based on Setup Pose BoneData. + public BoneMatrix (BoneData boneData) { + float rotationY = boneData.rotation + 90 + boneData.shearY; + float rotationX = boneData.rotation + boneData.shearX; + + a = MathUtils.CosDeg(rotationX) * boneData.scaleX; + c = MathUtils.SinDeg(rotationX) * boneData.scaleX; + b = MathUtils.CosDeg(rotationY) * boneData.scaleY; + d = MathUtils.SinDeg(rotationY) * boneData.scaleY; + x = boneData.x; + y = boneData.y; + } + + /// Constructor for a local bone matrix based on a bone instance's current pose. + public BoneMatrix (Bone bone) { + float rotationY = bone.rotation + 90 + bone.shearY; + float rotationX = bone.rotation + bone.shearX; + + a = MathUtils.CosDeg(rotationX) * bone.scaleX; + c = MathUtils.SinDeg(rotationX) * bone.scaleX; + b = MathUtils.CosDeg(rotationY) * bone.scaleY; + d = MathUtils.SinDeg(rotationY) * bone.scaleY; + x = bone.x; + y = bone.y; + } + + public BoneMatrix TransformMatrix (BoneMatrix local) { + return new BoneMatrix { + a = this.a * local.a + this.b * local.c, + b = this.a * local.b + this.b * local.d, + c = this.c * local.a + this.d * local.c, + d = this.c * local.b + this.d * local.d, + x = this.a * local.x + this.b * local.y + this.x, + y = this.c * local.x + this.d * local.y + this.y + }; + } + } + + public static class SpineSkeletonExtensions { + public static bool IsWeighted (this VertexAttachment va) { + return va.bones != null && va.bones.Length > 0; + } + + public static bool IsRenderable (this Attachment a) { + return a is IHasRendererObject; + } + + #region Transform Modes + public static bool InheritsRotation (this TransformMode mode) { + const int RotationBit = 0; + return ((int)mode & (1U << RotationBit)) == 0; + } + + public static bool InheritsScale (this TransformMode mode) { + const int ScaleBit = 1; + return ((int)mode & (1U << ScaleBit)) == 0; + } + #endregion + + #region Posing + internal static void SetPropertyToSetupPose (this Skeleton skeleton, int propertyID) { + int tt = propertyID >> 24; + var timelineType = (TimelineType)tt; + int i = propertyID - (tt << 24); + + Bone bone; + IkConstraint ikc; + PathConstraint pc; + + switch (timelineType) { + // Bone + case TimelineType.Rotate: + bone = skeleton.bones.Items[i]; + bone.rotation = bone.data.rotation; + break; + case TimelineType.Translate: + bone = skeleton.bones.Items[i]; + bone.x = bone.data.x; + bone.y = bone.data.y; + break; + case TimelineType.Scale: + bone = skeleton.bones.Items[i]; + bone.scaleX = bone.data.scaleX; + bone.scaleY = bone.data.scaleY; + break; + case TimelineType.Shear: + bone = skeleton.bones.Items[i]; + bone.shearX = bone.data.shearX; + bone.shearY = bone.data.shearY; + break; + + // Slot + case TimelineType.Attachment: + skeleton.SetSlotAttachmentToSetupPose(i); + break; + case TimelineType.Color: + skeleton.slots.Items[i].SetColorToSetupPose(); + break; + case TimelineType.TwoColor: + skeleton.slots.Items[i].SetColorToSetupPose(); + break; + case TimelineType.Deform: + skeleton.slots.Items[i].Deform.Clear(); + break; + + // Skeleton + case TimelineType.DrawOrder: + skeleton.SetDrawOrderToSetupPose(); + break; + + // IK Constraint + case TimelineType.IkConstraint: + ikc = skeleton.ikConstraints.Items[i]; + ikc.mix = ikc.data.mix; + ikc.softness = ikc.data.softness; + ikc.bendDirection = ikc.data.bendDirection; + ikc.stretch = ikc.data.stretch; + break; + + // TransformConstraint + case TimelineType.TransformConstraint: + var tc = skeleton.transformConstraints.Items[i]; + var tcData = tc.data; + tc.rotateMix = tcData.rotateMix; + tc.translateMix = tcData.translateMix; + tc.scaleMix = tcData.scaleMix; + tc.shearMix = tcData.shearMix; + break; + + // Path Constraint + case TimelineType.PathConstraintPosition: + pc = skeleton.pathConstraints.Items[i]; + pc.position = pc.data.position; + break; + case TimelineType.PathConstraintSpacing: + pc = skeleton.pathConstraints.Items[i]; + pc.spacing = pc.data.spacing; + break; + case TimelineType.PathConstraintMix: + pc = skeleton.pathConstraints.Items[i]; + pc.rotateMix = pc.data.rotateMix; + pc.translateMix = pc.data.translateMix; + break; + } + } + + /// Resets the DrawOrder to the Setup Pose's draw order + public static void SetDrawOrderToSetupPose (this Skeleton skeleton) { + var slotsItems = skeleton.slots.Items; + int n = skeleton.slots.Count; + + var drawOrder = skeleton.drawOrder; + drawOrder.Clear(false); + drawOrder.EnsureCapacity(n); + drawOrder.Count = n; + System.Array.Copy(slotsItems, drawOrder.Items, n); + } + + /// Resets all the slots on the skeleton to their Setup Pose attachments but does not reset slot colors. + public static void SetSlotAttachmentsToSetupPose (this Skeleton skeleton) { + var slotsItems = skeleton.slots.Items; + for (int i = 0; i < skeleton.slots.Count; i++) { + Slot slot = slotsItems[i]; + string attachmentName = slot.data.attachmentName; + slot.Attachment = string.IsNullOrEmpty(attachmentName) ? null : skeleton.GetAttachment(i, attachmentName); + } + } + + /// Resets the color of a slot to Setup Pose value. + public static void SetColorToSetupPose (this Slot slot) { + slot.r = slot.data.r; + slot.g = slot.data.g; + slot.b = slot.data.b; + slot.a = slot.data.a; + slot.r2 = slot.data.r2; + slot.g2 = slot.data.g2; + slot.b2 = slot.data.b2; + } + + /// Sets a slot's attachment to setup pose. If you have the slotIndex, Skeleton.SetSlotAttachmentToSetupPose is faster. + public static void SetAttachmentToSetupPose (this Slot slot) { + var slotData = slot.data; + slot.Attachment = slot.bone.skeleton.GetAttachment(slotData.name, slotData.attachmentName); + } + + /// Resets the attachment of slot at a given slotIndex to setup pose. This is faster than Slot.SetAttachmentToSetupPose. + public static void SetSlotAttachmentToSetupPose (this Skeleton skeleton, int slotIndex) { + var slot = skeleton.slots.Items[slotIndex]; + string attachmentName = slot.data.attachmentName; + if (string.IsNullOrEmpty(attachmentName)) { + slot.Attachment = null; + } else { + var attachment = skeleton.GetAttachment(slotIndex, attachmentName); + slot.Attachment = attachment; + } + } + + /// Resets Skeleton parts to Setup Pose according to a Spine.Animation's keyed items. + public static void SetKeyedItemsToSetupPose (this Animation animation, Skeleton skeleton) { + animation.Apply(skeleton, 0, 0, false, null, 0, MixBlend.Setup, MixDirection.Out); + } + + public static void AllowImmediateQueue (this TrackEntry trackEntry) { + if (trackEntry.nextTrackLast < 0) trackEntry.nextTrackLast = 0; + } + #endregion + } +} diff --git a/box1/Assets/Spine/Runtime/spine-unity/Utility/SkeletonExtensions.cs.meta b/box1/Assets/Spine/Runtime/spine-unity/Utility/SkeletonExtensions.cs.meta new file mode 100644 index 00000000..427cdd10 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Utility/SkeletonExtensions.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: ea85c8f6a91a6ab45881b0dbdaabb7d0 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Utility/SkinUtilities.cs b/box1/Assets/Spine/Runtime/spine-unity/Utility/SkinUtilities.cs new file mode 100644 index 00000000..7da11829 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Utility/SkinUtilities.cs @@ -0,0 +1,168 @@ +/****************************************************************************** + * 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.Generic; +using System.Collections; + +namespace Spine.Unity.AttachmentTools { + + public static class SkinUtilities { + + #region Skeleton Skin Extensions + /// + /// Convenience method for duplicating a skeleton's current active skin so changes to it will not affect other skeleton instances. . + public static Skin UnshareSkin (this Skeleton skeleton, bool includeDefaultSkin, bool unshareAttachments, AnimationState state = null) { + // 1. Copy the current skin and set the skeleton's skin to the new one. + var newSkin = skeleton.GetClonedSkin("cloned skin", includeDefaultSkin, unshareAttachments, true); + skeleton.SetSkin(newSkin); + + // 2. Apply correct attachments: skeleton.SetToSetupPose + animationState.Apply + if (state != null) { + skeleton.SetToSetupPose(); + state.Apply(skeleton); + } + + // 3. Return unshared skin. + return newSkin; + } + + public static Skin GetClonedSkin (this Skeleton skeleton, string newSkinName, bool includeDefaultSkin = false, bool cloneAttachments = false, bool cloneMeshesAsLinked = true) { + var newSkin = new Skin(newSkinName); // may have null name. Harmless. + var defaultSkin = skeleton.data.DefaultSkin; + var activeSkin = skeleton.skin; + + if (includeDefaultSkin) + defaultSkin.CopyTo(newSkin, true, cloneAttachments, cloneMeshesAsLinked); + + if (activeSkin != null) + activeSkin.CopyTo(newSkin, true, cloneAttachments, cloneMeshesAsLinked); + + return newSkin; + } + #endregion + + /// + /// Gets a shallow copy of the skin. The cloned skin's attachments are shared with the original skin. + public static Skin GetClone (this Skin original) { + var newSkin = new Skin(original.name + " clone"); + var newSkinAttachments = newSkin.Attachments; + var newSkinBones = newSkin.Bones; + var newSkinConstraints = newSkin.Constraints; + + foreach (var a in original.Attachments) + newSkinAttachments[a.Key] = a.Value; + + newSkinBones.AddRange(original.bones); + newSkinConstraints.AddRange(original.constraints); + return newSkin; + } + + /// Adds an attachment to the skin for the specified slot index and name. If the name already exists for the slot, the previous value is replaced. + public static void SetAttachment (this Skin skin, string slotName, string keyName, Attachment attachment, Skeleton skeleton) { + int slotIndex = skeleton.FindSlotIndex(slotName); + if (skeleton == null) throw new System.ArgumentNullException("skeleton", "skeleton cannot be null."); + if (slotIndex == -1) throw new System.ArgumentException(string.Format("Slot '{0}' does not exist in skeleton.", slotName), "slotName"); + skin.SetAttachment(slotIndex, keyName, attachment); + } + + /// Adds skin items from another skin. For items that already exist, the previous values are replaced. + public static void AddAttachments (this Skin skin, Skin otherSkin) { + if (otherSkin == null) return; + otherSkin.CopyTo(skin, true, false); + } + + /// Gets an attachment from the skin for the specified slot index and name. + public static Attachment GetAttachment (this Skin skin, string slotName, string keyName, Skeleton skeleton) { + int slotIndex = skeleton.FindSlotIndex(slotName); + if (skeleton == null) throw new System.ArgumentNullException("skeleton", "skeleton cannot be null."); + if (slotIndex == -1) throw new System.ArgumentException(string.Format("Slot '{0}' does not exist in skeleton.", slotName), "slotName"); + return skin.GetAttachment(slotIndex, keyName); + } + + /// Adds an attachment to the skin for the specified slot index and name. If the name already exists for the slot, the previous value is replaced. + public static void SetAttachment (this Skin skin, int slotIndex, string keyName, Attachment attachment) { + skin.SetAttachment(slotIndex, keyName, attachment); + } + + public static void RemoveAttachment (this Skin skin, string slotName, string keyName, SkeletonData skeletonData) { + int slotIndex = skeletonData.FindSlotIndex(slotName); + if (skeletonData == null) throw new System.ArgumentNullException("skeletonData", "skeletonData cannot be null."); + if (slotIndex == -1) throw new System.ArgumentException(string.Format("Slot '{0}' does not exist in skeleton.", slotName), "slotName"); + skin.RemoveAttachment(slotIndex, keyName); + } + + public static void Clear (this Skin skin) { + skin.Attachments.Clear(); + } + + //[System.Obsolete] + public static void Append (this Skin destination, Skin source) { + source.CopyTo(destination, true, false); + } + + public static void CopyTo (this Skin source, Skin destination, bool overwrite, bool cloneAttachments, bool cloneMeshesAsLinked = true) { + var sourceAttachments = source.Attachments; + var destinationAttachments = destination.Attachments; + var destinationBones = destination.Bones; + var destinationConstraints = destination.Constraints; + + if (cloneAttachments) { + if (overwrite) { + foreach (var e in sourceAttachments) { + Attachment clonedAttachment = e.Value.GetCopy(cloneMeshesAsLinked); + destinationAttachments[new Skin.SkinEntry(e.Key.SlotIndex, e.Key.Name, clonedAttachment)] = clonedAttachment; + } + } else { + foreach (var e in sourceAttachments) { + if (destinationAttachments.ContainsKey(e.Key)) continue; + Attachment clonedAttachment = e.Value.GetCopy(cloneMeshesAsLinked); + destinationAttachments.Add(new Skin.SkinEntry(e.Key.SlotIndex, e.Key.Name, clonedAttachment), clonedAttachment); + } + } + } else { + if (overwrite) { + foreach (var e in sourceAttachments) + destinationAttachments[e.Key] = e.Value; + } else { + foreach (var e in sourceAttachments) { + if (destinationAttachments.ContainsKey(e.Key)) continue; + destinationAttachments.Add(e.Key, e.Value); + } + } + } + + foreach (BoneData data in source.bones) + if (!destinationBones.Contains(data)) destinationBones.Add(data); + + foreach (ConstraintData data in source.constraints) + if (!destinationConstraints.Contains(data)) destinationConstraints.Add(data); + } + } +} diff --git a/box1/Assets/Spine/Runtime/spine-unity/Utility/SkinUtilities.cs.meta b/box1/Assets/Spine/Runtime/spine-unity/Utility/SkinUtilities.cs.meta new file mode 100644 index 00000000..5ac1f297 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Utility/SkinUtilities.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: f4692b9527684d048862210ba3f9834e +timeCreated: 1563321428 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Utility/TimelineExtensions.cs b/box1/Assets/Spine/Runtime/spine-unity/Utility/TimelineExtensions.cs new file mode 100644 index 00000000..03f14aa5 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Utility/TimelineExtensions.cs @@ -0,0 +1,91 @@ +/****************************************************************************** + * 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.Generic; +using System.Collections; + +namespace Spine.Unity.AnimationTools { + public static class TimelineExtensions { + + /// Evaluates the resulting value of a TranslateTimeline at a given time. + /// SkeletonData can be accessed from Skeleton.Data or from SkeletonDataAsset.GetSkeletonData. + /// If no SkeletonData is given, values are computed relative to setup pose instead of local-absolute. + public static Vector2 Evaluate (this TranslateTimeline timeline, float time, SkeletonData skeletonData = null) { + const int PREV_TIME = -3, PREV_X = -2, PREV_Y = -1; + const int X = 1, Y = 2; + + var frames = timeline.frames; + if (time < frames[0]) return Vector2.zero; + + float x, y; + if (time >= frames[frames.Length - TranslateTimeline.ENTRIES]) { // Time is after last frame. + x = frames[frames.Length + PREV_X]; + y = frames[frames.Length + PREV_Y]; + } + else { + // Interpolate between the previous frame and the current frame. + int frame = Animation.BinarySearch(frames, time, TranslateTimeline.ENTRIES); + x = frames[frame + PREV_X]; + y = frames[frame + PREV_Y]; + float frameTime = frames[frame]; + float percent = timeline.GetCurvePercent(frame / TranslateTimeline.ENTRIES - 1, + 1 - (time - frameTime) / (frames[frame + PREV_TIME] - frameTime)); + + x += (frames[frame + X] - x) * percent; + y += (frames[frame + Y] - y) * percent; + } + + Vector2 xy = new Vector2(x, y); + if (skeletonData == null) { + return xy; + } + else { + var boneData = skeletonData.bones.Items[timeline.boneIndex]; + return xy + new Vector2(boneData.x, boneData.y); + } + } + + /// Gets the translate timeline for a given boneIndex. + /// You can get the boneIndex using SkeletonData.FindBoneIndex. + /// The root bone is always boneIndex 0. + /// This will return null if a TranslateTimeline is not found. + public static TranslateTimeline FindTranslateTimelineForBone (this Animation a, int boneIndex) { + foreach (var timeline in a.timelines) { + if (timeline.GetType().IsSubclassOf(typeof(TranslateTimeline))) + continue; + + var translateTimeline = timeline as TranslateTimeline; + if (translateTimeline != null && translateTimeline.boneIndex == boneIndex) + return translateTimeline; + } + return null; + } + } +} diff --git a/box1/Assets/Spine/Runtime/spine-unity/Utility/TimelineExtensions.cs.meta b/box1/Assets/Spine/Runtime/spine-unity/Utility/TimelineExtensions.cs.meta new file mode 100644 index 00000000..6198f84a --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Utility/TimelineExtensions.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 07807fefbff25484ba41b1d16911fb0e +timeCreated: 1591974498 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Utility/YieldInstructions.meta b/box1/Assets/Spine/Runtime/spine-unity/Utility/YieldInstructions.meta new file mode 100644 index 00000000..903af3e8 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Utility/YieldInstructions.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 15ac4befbee15d845ac289de3ab6d3d4 +folderAsset: yes +timeCreated: 1455486167 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Utility/YieldInstructions/WaitForSpineAnimation.cs b/box1/Assets/Spine/Runtime/spine-unity/Utility/YieldInstructions/WaitForSpineAnimation.cs new file mode 100644 index 00000000..644ceed9 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Utility/YieldInstructions/WaitForSpineAnimation.cs @@ -0,0 +1,108 @@ +/****************************************************************************** + * 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 System; + +namespace Spine.Unity { + /// + /// Use this as a condition-blocking yield instruction for Unity Coroutines. + /// The routine will pause until the AnimationState.TrackEntry fires any of the + /// configured events. + ///

+ /// See the Spine Unity Events documentation page + /// and + /// for more information on when track events will be triggered.

+ public class WaitForSpineAnimation : IEnumerator { + + [Flags] + public enum AnimationEventTypes + { + Start = 1, + Interrupt = 2, + End = 4, + Dispose = 8, + Complete = 16 + } + + bool m_WasFired = false; + + public WaitForSpineAnimation (Spine.TrackEntry trackEntry, AnimationEventTypes eventsToWaitFor) { + SafeSubscribe(trackEntry, eventsToWaitFor); + } + + #region Reuse + /// + /// One optimization high-frequency YieldInstruction returns is to cache instances to minimize GC pressure. + /// Use NowWaitFor to reuse the same instance of WaitForSpineAnimationComplete. + public WaitForSpineAnimation NowWaitFor (Spine.TrackEntry trackEntry, AnimationEventTypes eventsToWaitFor) { + SafeSubscribe(trackEntry, eventsToWaitFor); + return this; + } + #endregion + + #region IEnumerator + bool IEnumerator.MoveNext () { + if (m_WasFired) { + ((IEnumerator)this).Reset(); // auto-reset for YieldInstruction reuse + return false; + } + + return true; + } + void IEnumerator.Reset () { m_WasFired = false; } + object IEnumerator.Current { get { return null; } } + #endregion + + protected void SafeSubscribe (Spine.TrackEntry trackEntry, AnimationEventTypes eventsToWaitFor) { + if (trackEntry == null) { + // Break immediately if trackEntry is null. + Debug.LogWarning("TrackEntry was null. Coroutine will continue immediately."); + m_WasFired = true; + } + else { + if ((eventsToWaitFor & AnimationEventTypes.Start) != 0) + trackEntry.Start += HandleComplete; + if ((eventsToWaitFor & AnimationEventTypes.Interrupt) != 0) + trackEntry.Interrupt += HandleComplete; + if ((eventsToWaitFor & AnimationEventTypes.End) != 0) + trackEntry.End += HandleComplete; + if ((eventsToWaitFor & AnimationEventTypes.Dispose) != 0) + trackEntry.Dispose += HandleComplete; + if ((eventsToWaitFor & AnimationEventTypes.Complete) != 0) + trackEntry.Complete += HandleComplete; + } + } + + void HandleComplete (TrackEntry trackEntry) { + m_WasFired = true; + } + } +} diff --git a/box1/Assets/Spine/Runtime/spine-unity/Utility/YieldInstructions/WaitForSpineAnimation.cs.meta b/box1/Assets/Spine/Runtime/spine-unity/Utility/YieldInstructions/WaitForSpineAnimation.cs.meta new file mode 100644 index 00000000..ac946e63 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Utility/YieldInstructions/WaitForSpineAnimation.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: d9be5adcaf0003849a1d181173c19635 +timeCreated: 1566289729 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Utility/YieldInstructions/WaitForSpineAnimationComplete.cs b/box1/Assets/Spine/Runtime/spine-unity/Utility/YieldInstructions/WaitForSpineAnimationComplete.cs new file mode 100644 index 00000000..39cf16a9 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Utility/YieldInstructions/WaitForSpineAnimationComplete.cs @@ -0,0 +1,62 @@ +/****************************************************************************** + * 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; + +namespace Spine.Unity { + /// + /// Use this as a condition-blocking yield instruction for Unity Coroutines. + /// The routine will pause until the AnimationState.TrackEntry fires its Complete event. + /// It can be configured to trigger on the End event as well to cover interruption. + ///

+ /// See the Spine Unity Events documentation page + /// and + /// for more information on when track events will be triggered.

+ public class WaitForSpineAnimationComplete : WaitForSpineAnimation, IEnumerator { + + public WaitForSpineAnimationComplete (Spine.TrackEntry trackEntry, bool includeEndEvent = false) : + base(trackEntry, + includeEndEvent ? (AnimationEventTypes.Complete | AnimationEventTypes.End) : AnimationEventTypes.Complete) + { + } + + #region Reuse + /// + /// One optimization high-frequency YieldInstruction returns is to cache instances to minimize GC pressure. + /// Use NowWaitFor to reuse the same instance of WaitForSpineAnimationComplete. + public WaitForSpineAnimationComplete NowWaitFor (Spine.TrackEntry trackEntry, bool includeEndEvent = false) { + SafeSubscribe(trackEntry, + includeEndEvent ? (AnimationEventTypes.Complete | AnimationEventTypes.End) : AnimationEventTypes.Complete); + return this; + } + #endregion + } +} diff --git a/box1/Assets/Spine/Runtime/spine-unity/Utility/YieldInstructions/WaitForSpineAnimationComplete.cs.meta b/box1/Assets/Spine/Runtime/spine-unity/Utility/YieldInstructions/WaitForSpineAnimationComplete.cs.meta new file mode 100644 index 00000000..0aabc3b4 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Utility/YieldInstructions/WaitForSpineAnimationComplete.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: a807dd9fb79db3545b6c2859a2bbfc0b +timeCreated: 1449704018 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Utility/YieldInstructions/WaitForSpineAnimationEnd.cs b/box1/Assets/Spine/Runtime/spine-unity/Utility/YieldInstructions/WaitForSpineAnimationEnd.cs new file mode 100644 index 00000000..dbafcc6c --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Utility/YieldInstructions/WaitForSpineAnimationEnd.cs @@ -0,0 +1,59 @@ +/****************************************************************************** + * 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; + +namespace Spine.Unity { + /// + /// Use this as a condition-blocking yield instruction for Unity Coroutines. + /// The routine will pause until the AnimationState.TrackEntry fires its End event. + ///

+ /// See the Spine Unity Events documentation page + /// and + /// for more information on when track events will be triggered.

+ public class WaitForSpineAnimationEnd : WaitForSpineAnimation, IEnumerator { + + public WaitForSpineAnimationEnd (Spine.TrackEntry trackEntry) : + base(trackEntry, AnimationEventTypes.End) + { + } + + #region Reuse + /// + /// One optimization high-frequency YieldInstruction returns is to cache instances to minimize GC pressure. + /// Use NowWaitFor to reuse the same instance of WaitForSpineAnimationComplete. + public WaitForSpineAnimationEnd NowWaitFor (Spine.TrackEntry trackEntry) { + SafeSubscribe(trackEntry, AnimationEventTypes.End); + return this; + } + #endregion + } +} diff --git a/box1/Assets/Spine/Runtime/spine-unity/Utility/YieldInstructions/WaitForSpineAnimationEnd.cs.meta b/box1/Assets/Spine/Runtime/spine-unity/Utility/YieldInstructions/WaitForSpineAnimationEnd.cs.meta new file mode 100644 index 00000000..472b1f96 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Utility/YieldInstructions/WaitForSpineAnimationEnd.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 3c5a5fe930d1ab24da154d76b24c2747 +timeCreated: 1566288961 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Utility/YieldInstructions/WaitForSpineEvent.cs b/box1/Assets/Spine/Runtime/spine-unity/Utility/YieldInstructions/WaitForSpineEvent.cs new file mode 100644 index 00000000..1da2bcb6 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Utility/YieldInstructions/WaitForSpineEvent.cs @@ -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 UnityEngine; +using System.Collections; +using Spine; + +namespace Spine.Unity { + /// + /// Use this as a condition-blocking yield instruction for Unity Coroutines. + /// The routine will pause until the AnimationState fires an event matching the given event name or EventData reference. + public class WaitForSpineEvent : IEnumerator { + + Spine.EventData m_TargetEvent; + string m_EventName; + Spine.AnimationState m_AnimationState; + + bool m_WasFired = false; + bool m_unsubscribeAfterFiring = false; + + #region Constructors + void Subscribe (Spine.AnimationState state, Spine.EventData eventDataReference, bool unsubscribe) { + if (state == null) { + Debug.LogWarning("AnimationState argument was null. Coroutine will continue immediately."); + m_WasFired = true; + return; + } else if (eventDataReference == null) { + Debug.LogWarning("eventDataReference argument was null. Coroutine will continue immediately."); + m_WasFired = true; + return; + } + + m_AnimationState = state; + m_TargetEvent = eventDataReference; + state.Event += HandleAnimationStateEvent; + + m_unsubscribeAfterFiring = unsubscribe; + + } + + void SubscribeByName (Spine.AnimationState state, string eventName, bool unsubscribe) { + if (state == null) { + Debug.LogWarning("AnimationState argument was null. Coroutine will continue immediately."); + m_WasFired = true; + return; + } else if (string.IsNullOrEmpty(eventName)) { + Debug.LogWarning("eventName argument was null. Coroutine will continue immediately."); + m_WasFired = true; + return; + } + + m_AnimationState = state; + m_EventName = eventName; + state.Event += HandleAnimationStateEventByName; + + m_unsubscribeAfterFiring = unsubscribe; + } + + public WaitForSpineEvent (Spine.AnimationState state, Spine.EventData eventDataReference, bool unsubscribeAfterFiring = true) { + Subscribe(state, eventDataReference, unsubscribeAfterFiring); + } + + public WaitForSpineEvent (SkeletonAnimation skeletonAnimation, Spine.EventData eventDataReference, bool unsubscribeAfterFiring = true) { + // If skeletonAnimation is invalid, its state will be null. Subscribe handles null states just fine. + Subscribe(skeletonAnimation.state, eventDataReference, unsubscribeAfterFiring); + } + + public WaitForSpineEvent (Spine.AnimationState state, string eventName, bool unsubscribeAfterFiring = true) { + SubscribeByName(state, eventName, unsubscribeAfterFiring); + } + + public WaitForSpineEvent (SkeletonAnimation skeletonAnimation, string eventName, bool unsubscribeAfterFiring = true) { + // If skeletonAnimation is invalid, its state will be null. Subscribe handles null states just fine. + SubscribeByName(skeletonAnimation.state, eventName, unsubscribeAfterFiring); + } + #endregion + + #region Event Handlers + void HandleAnimationStateEventByName (Spine.TrackEntry trackEntry, Spine.Event e) { + m_WasFired |= (e.Data.Name == m_EventName); // Check event name string match. + if (m_WasFired && m_unsubscribeAfterFiring) + m_AnimationState.Event -= HandleAnimationStateEventByName; // Unsubscribe after correct event fires. + } + + void HandleAnimationStateEvent (Spine.TrackEntry trackEntry, Spine.Event e) { + m_WasFired |= (e.Data == m_TargetEvent); // Check event data reference match. + if (m_WasFired && m_unsubscribeAfterFiring) + m_AnimationState.Event -= HandleAnimationStateEvent; // Usubscribe after correct event fires. + } + #endregion + + #region Reuse + /// + /// By default, WaitForSpineEvent will unsubscribe from the event immediately after it fires a correct matching event. + /// If you want to reuse this WaitForSpineEvent instance on the same event, you can set this to false. + public bool WillUnsubscribeAfterFiring { get { return m_unsubscribeAfterFiring; } set { m_unsubscribeAfterFiring = value; } } + + public WaitForSpineEvent NowWaitFor (Spine.AnimationState state, Spine.EventData eventDataReference, bool unsubscribeAfterFiring = true) { + ((IEnumerator)this).Reset(); + Clear(state); + Subscribe(state, eventDataReference, unsubscribeAfterFiring); + + return this; + } + + public WaitForSpineEvent NowWaitFor (Spine.AnimationState state, string eventName, bool unsubscribeAfterFiring = true) { + ((IEnumerator)this).Reset(); + Clear(state); + SubscribeByName(state, eventName, unsubscribeAfterFiring); + + return this; + } + + void Clear (Spine.AnimationState state) { + state.Event -= HandleAnimationStateEvent; + state.Event -= HandleAnimationStateEventByName; + } + #endregion + + #region IEnumerator + bool IEnumerator.MoveNext () { + if (m_WasFired) { + ((IEnumerator)this).Reset(); // auto-reset for YieldInstruction reuse + return false; + } + + return true; + } + void IEnumerator.Reset () { m_WasFired = false; } + object IEnumerator.Current { get { return null; } } + #endregion + } +} diff --git a/box1/Assets/Spine/Runtime/spine-unity/Utility/YieldInstructions/WaitForSpineEvent.cs.meta b/box1/Assets/Spine/Runtime/spine-unity/Utility/YieldInstructions/WaitForSpineEvent.cs.meta new file mode 100644 index 00000000..72bbef73 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Utility/YieldInstructions/WaitForSpineEvent.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: fc166d883db083e469872998172f2d38 +timeCreated: 1449701857 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/Runtime/spine-unity/Utility/YieldInstructions/WaitForSpineTrackEntryEnd.cs b/box1/Assets/Spine/Runtime/spine-unity/Utility/YieldInstructions/WaitForSpineTrackEntryEnd.cs new file mode 100644 index 00000000..dc62d435 --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Utility/YieldInstructions/WaitForSpineTrackEntryEnd.cs @@ -0,0 +1,85 @@ +/****************************************************************************** + * 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; + +namespace Spine.Unity { + /// + /// Use this as a condition-blocking yield instruction for Unity Coroutines. + /// The routine will pause until the AnimationState.TrackEntry fires its End event. + public class WaitForSpineTrackEntryEnd : IEnumerator { + + bool m_WasFired = false; + + public WaitForSpineTrackEntryEnd (Spine.TrackEntry trackEntry) { + SafeSubscribe(trackEntry); + } + + void HandleEnd (TrackEntry trackEntry) { + m_WasFired = true; + } + + void SafeSubscribe (Spine.TrackEntry trackEntry) { + if (trackEntry == null) { + // Break immediately if trackEntry is null. + Debug.LogWarning("TrackEntry was null. Coroutine will continue immediately."); + m_WasFired = true; + } else { + trackEntry.End += HandleEnd; + } + } + + #region Reuse + /// + /// One optimization high-frequency YieldInstruction returns is to cache instances to minimize GC pressure. + /// Use NowWaitFor to reuse the same instance of WaitForSpineAnimationEnd. + public WaitForSpineTrackEntryEnd NowWaitFor (Spine.TrackEntry trackEntry) { + SafeSubscribe(trackEntry); + return this; + } + #endregion + + #region IEnumerator + bool IEnumerator.MoveNext () { + if (m_WasFired) { + ((IEnumerator)this).Reset(); // auto-reset for YieldInstruction reuse + return false; + } + + return true; + } + void IEnumerator.Reset () { m_WasFired = false; } + object IEnumerator.Current { get { return null; } } + #endregion + + } + +} diff --git a/box1/Assets/Spine/Runtime/spine-unity/Utility/YieldInstructions/WaitForSpineTrackEntryEnd.cs.meta b/box1/Assets/Spine/Runtime/spine-unity/Utility/YieldInstructions/WaitForSpineTrackEntryEnd.cs.meta new file mode 100644 index 00000000..afd6031f --- /dev/null +++ b/box1/Assets/Spine/Runtime/spine-unity/Utility/YieldInstructions/WaitForSpineTrackEntryEnd.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 8036c6c2897d2764db92f632d2aef568 +timeCreated: 1480672707 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/package.json b/box1/Assets/Spine/package.json new file mode 100644 index 00000000..6fac1264 --- /dev/null +++ b/box1/Assets/Spine/package.json @@ -0,0 +1,19 @@ +{ + "name": "com.esotericsoftware.spine.spine-unity", + "displayName": "spine-unity Runtime", + "description": "This plugin provides the spine-unity runtime core.", + "version": "3.8.0", + "unity": "2018.3", + "author": { + "name": "Esoteric Software", + "email": "contact@esotericsoftware.com", + "url": "http://esotericsoftware.com/" + }, + "dependencies": { + }, + "keywords": [ + "spine", + "spine-unity", + "core" + ] +} diff --git a/box1/Assets/Spine/package.json.meta b/box1/Assets/Spine/package.json.meta new file mode 100644 index 00000000..d0000cca --- /dev/null +++ b/box1/Assets/Spine/package.json.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 09478c42aa0375347898d942d287a819 +PackageManifestImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/Assets/Spine/version.txt b/box1/Assets/Spine/version.txt new file mode 100644 index 00000000..5a46579c --- /dev/null +++ b/box1/Assets/Spine/version.txt @@ -0,0 +1,2 @@ +This Spine-Unity runtime works with data exported from Spine Editor version: 3.8.xx +Package version: spine-unity-3.8-2020-09-11.unitypackage diff --git a/box1/Assets/Spine/version.txt.meta b/box1/Assets/Spine/version.txt.meta new file mode 100644 index 00000000..d34c5b7d --- /dev/null +++ b/box1/Assets/Spine/version.txt.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 80c06a67282e71043a4b1fad3e0c5654 +timeCreated: 1485965987 +licenseType: Free +TextScriptImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/box1/ProjectSettings/GraphicsSettings.asset b/box1/ProjectSettings/GraphicsSettings.asset index be851a42..424e6a38 100644 --- a/box1/ProjectSettings/GraphicsSettings.asset +++ b/box1/ProjectSettings/GraphicsSettings.asset @@ -57,7 +57,7 @@ GraphicsSettings: m_FogKeepExp: 1 m_FogKeepExp2: 1 m_AlbedoSwatchInfos: [] - m_LightsUseLinearIntensity: 1 + m_LightsUseLinearIntensity: 0 m_LightsUseColorTemperature: 1 m_DefaultRenderingLayerMask: 1 m_LogWhenShaderIsCompiled: 0 diff --git a/box1/ProjectSettings/ProjectSettings.asset b/box1/ProjectSettings/ProjectSettings.asset index a06b4a85..fbc7c046 100644 --- a/box1/ProjectSettings/ProjectSettings.asset +++ b/box1/ProjectSettings/ProjectSettings.asset @@ -47,7 +47,7 @@ PlayerSettings: defaultScreenWidthWeb: 960 defaultScreenHeightWeb: 600 m_StereoRenderingPath: 0 - m_ActiveColorSpace: 1 + m_ActiveColorSpace: 0 unsupportedMSAAFallback: 0 m_SpriteBatchVertexThreshold: 300 m_MTRendering: 1 @@ -283,7 +283,99 @@ PlayerSettings: AndroidValidateAppBundleSize: 1 AndroidAppBundleSizeToValidate: 150 m_BuildTargetIcons: [] - m_BuildTargetPlatformIcons: [] + m_BuildTargetPlatformIcons: + - m_BuildTarget: Android + m_Icons: + - m_Textures: [] + m_Width: 432 + m_Height: 432 + m_Kind: 2 + m_SubKind: + - m_Textures: [] + m_Width: 324 + m_Height: 324 + m_Kind: 2 + m_SubKind: + - m_Textures: [] + m_Width: 216 + m_Height: 216 + m_Kind: 2 + m_SubKind: + - m_Textures: [] + m_Width: 162 + m_Height: 162 + m_Kind: 2 + m_SubKind: + - m_Textures: [] + m_Width: 108 + m_Height: 108 + m_Kind: 2 + m_SubKind: + - m_Textures: [] + m_Width: 81 + m_Height: 81 + m_Kind: 2 + m_SubKind: + - m_Textures: [] + m_Width: 192 + m_Height: 192 + m_Kind: 1 + m_SubKind: + - m_Textures: [] + m_Width: 144 + m_Height: 144 + m_Kind: 1 + m_SubKind: + - m_Textures: [] + m_Width: 96 + m_Height: 96 + m_Kind: 1 + m_SubKind: + - m_Textures: [] + m_Width: 72 + m_Height: 72 + m_Kind: 1 + m_SubKind: + - m_Textures: [] + m_Width: 48 + m_Height: 48 + m_Kind: 1 + m_SubKind: + - m_Textures: [] + m_Width: 36 + m_Height: 36 + m_Kind: 1 + m_SubKind: + - m_Textures: [] + m_Width: 192 + m_Height: 192 + m_Kind: 0 + m_SubKind: + - m_Textures: [] + m_Width: 144 + m_Height: 144 + m_Kind: 0 + m_SubKind: + - m_Textures: [] + m_Width: 96 + m_Height: 96 + m_Kind: 0 + m_SubKind: + - m_Textures: [] + m_Width: 72 + m_Height: 72 + m_Kind: 0 + m_SubKind: + - m_Textures: [] + m_Width: 48 + m_Height: 48 + m_Kind: 0 + m_SubKind: + - m_Textures: [] + m_Width: 36 + m_Height: 36 + m_Kind: 0 + m_SubKind: m_BuildTargetBatching: [] m_BuildTargetShaderSettings: [] m_BuildTargetGraphicsJobs: [] diff --git a/box1/ProjectSettings/SceneTemplateSettings.json b/box1/ProjectSettings/SceneTemplateSettings.json new file mode 100644 index 00000000..5e97f839 --- /dev/null +++ b/box1/ProjectSettings/SceneTemplateSettings.json @@ -0,0 +1,121 @@ +{ + "templatePinStates": [], + "dependencyTypeInfos": [ + { + "userAdded": false, + "type": "UnityEngine.AnimationClip", + "defaultInstantiationMode": 0 + }, + { + "userAdded": false, + "type": "UnityEditor.Animations.AnimatorController", + "defaultInstantiationMode": 0 + }, + { + "userAdded": false, + "type": "UnityEngine.AnimatorOverrideController", + "defaultInstantiationMode": 0 + }, + { + "userAdded": false, + "type": "UnityEditor.Audio.AudioMixerController", + "defaultInstantiationMode": 0 + }, + { + "userAdded": false, + "type": "UnityEngine.ComputeShader", + "defaultInstantiationMode": 1 + }, + { + "userAdded": false, + "type": "UnityEngine.Cubemap", + "defaultInstantiationMode": 0 + }, + { + "userAdded": false, + "type": "UnityEngine.GameObject", + "defaultInstantiationMode": 0 + }, + { + "userAdded": false, + "type": "UnityEditor.LightingDataAsset", + "defaultInstantiationMode": 0 + }, + { + "userAdded": false, + "type": "UnityEngine.LightingSettings", + "defaultInstantiationMode": 0 + }, + { + "userAdded": false, + "type": "UnityEngine.Material", + "defaultInstantiationMode": 0 + }, + { + "userAdded": false, + "type": "UnityEditor.MonoScript", + "defaultInstantiationMode": 1 + }, + { + "userAdded": false, + "type": "UnityEngine.PhysicMaterial", + "defaultInstantiationMode": 0 + }, + { + "userAdded": false, + "type": "UnityEngine.PhysicsMaterial2D", + "defaultInstantiationMode": 0 + }, + { + "userAdded": false, + "type": "UnityEngine.Rendering.PostProcessing.PostProcessProfile", + "defaultInstantiationMode": 0 + }, + { + "userAdded": false, + "type": "UnityEngine.Rendering.PostProcessing.PostProcessResources", + "defaultInstantiationMode": 0 + }, + { + "userAdded": false, + "type": "UnityEngine.Rendering.VolumeProfile", + "defaultInstantiationMode": 0 + }, + { + "userAdded": false, + "type": "UnityEditor.SceneAsset", + "defaultInstantiationMode": 1 + }, + { + "userAdded": false, + "type": "UnityEngine.Shader", + "defaultInstantiationMode": 1 + }, + { + "userAdded": false, + "type": "UnityEngine.ShaderVariantCollection", + "defaultInstantiationMode": 1 + }, + { + "userAdded": false, + "type": "UnityEngine.Texture", + "defaultInstantiationMode": 0 + }, + { + "userAdded": false, + "type": "UnityEngine.Texture2D", + "defaultInstantiationMode": 0 + }, + { + "userAdded": false, + "type": "UnityEngine.Timeline.TimelineAsset", + "defaultInstantiationMode": 0 + } + ], + "defaultDependencyTypeInfo": { + "userAdded": false, + "type": "", + "defaultInstantiationMode": 1 + }, + "newSceneOverride": 0 +} \ No newline at end of file diff --git a/box1/ProjectSettings/ShaderGraphSettings.asset b/box1/ProjectSettings/ShaderGraphSettings.asset new file mode 100644 index 00000000..59c4647f --- /dev/null +++ b/box1/ProjectSettings/ShaderGraphSettings.asset @@ -0,0 +1,17 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &1 +MonoBehaviour: + m_ObjectHideFlags: 53 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: de02f9e1d18f588468e474319d09a723, type: 3} + m_Name: + m_EditorClassIdentifier: + shaderVariantLimit: 2048 + customInterpolatorErrorThreshold: 32 + customInterpolatorWarningThreshold: 16 diff --git a/box1/UserSettings/Layouts/default-2022.dwlt b/box1/UserSettings/Layouts/default-2022.dwlt new file mode 100644 index 00000000..c93e34d0 --- /dev/null +++ b/box1/UserSettings/Layouts/default-2022.dwlt @@ -0,0 +1,1279 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &1 +MonoBehaviour: + m_ObjectHideFlags: 52 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 12004, guid: 0000000000000000e000000000000000, type: 0} + m_Name: + m_EditorClassIdentifier: + m_PixelRect: + serializedVersion: 2 + x: 2059 + y: 92 + width: 1331 + height: 914 + m_ShowMode: 0 + m_Title: Game + m_RootView: {fileID: 4} + m_MinSize: {x: 100, y: 121} + m_MaxSize: {x: 4000, y: 4021} + m_Maximized: 0 +--- !u!114 &2 +MonoBehaviour: + m_ObjectHideFlags: 52 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 1 + m_Script: {fileID: 12004, guid: 0000000000000000e000000000000000, type: 0} + m_Name: + m_EditorClassIdentifier: + m_PixelRect: + serializedVersion: 2 + x: 0 + y: 43 + width: 1920 + height: 989 + m_ShowMode: 4 + m_Title: Inspector + m_RootView: {fileID: 9} + m_MinSize: {x: 875, y: 300} + m_MaxSize: {x: 10000, y: 10000} + m_Maximized: 1 +--- !u!114 &3 +MonoBehaviour: + m_ObjectHideFlags: 52 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 12006, guid: 0000000000000000e000000000000000, type: 0} + m_Name: GameView + m_EditorClassIdentifier: + m_Children: [] + m_Position: + serializedVersion: 2 + x: 0 + y: 0 + width: 1331 + height: 914 + m_MinSize: {x: 100, y: 121} + m_MaxSize: {x: 4000, y: 4021} + m_ActualView: {fileID: 16} + m_Panes: + - {fileID: 16} + m_Selected: 0 + m_LastSelected: 0 +--- !u!114 &4 +MonoBehaviour: + m_ObjectHideFlags: 52 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 12010, guid: 0000000000000000e000000000000000, type: 0} + m_Name: + m_EditorClassIdentifier: + m_Children: + - {fileID: 3} + m_Position: + serializedVersion: 2 + x: 0 + y: 0 + width: 1331 + height: 914 + m_MinSize: {x: 100, y: 121} + m_MaxSize: {x: 4000, y: 4021} + vertical: 0 + controlID: 14 + draggingID: 0 +--- !u!114 &5 +MonoBehaviour: + m_ObjectHideFlags: 52 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 1 + m_Script: {fileID: 12010, guid: 0000000000000000e000000000000000, type: 0} + m_Name: + m_EditorClassIdentifier: + m_Children: + - {fileID: 12} + - {fileID: 6} + m_Position: + serializedVersion: 2 + x: 0 + y: 30 + width: 1920 + height: 939 + m_MinSize: {x: 300, y: 100} + m_MaxSize: {x: 24288, y: 16192} + vertical: 0 + controlID: 130 + draggingID: 0 +--- !u!114 &6 +MonoBehaviour: + m_ObjectHideFlags: 52 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 1 + m_Script: {fileID: 12006, guid: 0000000000000000e000000000000000, type: 0} + m_Name: + m_EditorClassIdentifier: + m_Children: [] + m_Position: + serializedVersion: 2 + x: 1448 + y: 0 + width: 472 + height: 939 + m_MinSize: {x: 276, y: 71} + m_MaxSize: {x: 4001, y: 4021} + m_ActualView: {fileID: 18} + m_Panes: + - {fileID: 18} + m_Selected: 0 + m_LastSelected: 0 +--- !u!114 &7 +MonoBehaviour: + m_ObjectHideFlags: 52 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 1 + m_Script: {fileID: 12006, guid: 0000000000000000e000000000000000, type: 0} + m_Name: + m_EditorClassIdentifier: + m_Children: [] + m_Position: + serializedVersion: 2 + x: 0 + y: 0 + width: 352 + height: 587 + m_MinSize: {x: 201, y: 221} + m_MaxSize: {x: 4001, y: 4021} + m_ActualView: {fileID: 19} + m_Panes: + - {fileID: 19} + m_Selected: 0 + m_LastSelected: 0 +--- !u!114 &8 +MonoBehaviour: + m_ObjectHideFlags: 52 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 1 + m_Script: {fileID: 12006, guid: 0000000000000000e000000000000000, type: 0} + m_Name: ProjectBrowser + m_EditorClassIdentifier: + m_Children: [] + m_Position: + serializedVersion: 2 + x: 0 + y: 587 + width: 1448 + height: 352 + m_MinSize: {x: 231, y: 271} + m_MaxSize: {x: 10001, y: 10021} + m_ActualView: {fileID: 17} + m_Panes: + - {fileID: 17} + - {fileID: 21} + m_Selected: 0 + m_LastSelected: 1 +--- !u!114 &9 +MonoBehaviour: + m_ObjectHideFlags: 52 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 1 + m_Script: {fileID: 12008, guid: 0000000000000000e000000000000000, type: 0} + m_Name: + m_EditorClassIdentifier: + m_Children: + - {fileID: 10} + - {fileID: 5} + - {fileID: 11} + m_Position: + serializedVersion: 2 + x: 0 + y: 0 + width: 1920 + height: 989 + m_MinSize: {x: 875, y: 300} + m_MaxSize: {x: 10000, y: 10000} + m_UseTopView: 1 + m_TopViewHeight: 30 + m_UseBottomView: 1 + m_BottomViewHeight: 20 +--- !u!114 &10 +MonoBehaviour: + m_ObjectHideFlags: 52 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 1 + m_Script: {fileID: 12011, guid: 0000000000000000e000000000000000, type: 0} + m_Name: + m_EditorClassIdentifier: + m_Children: [] + m_Position: + serializedVersion: 2 + x: 0 + y: 0 + width: 1920 + height: 30 + m_MinSize: {x: 0, y: 0} + m_MaxSize: {x: 0, y: 0} + m_LastLoadedLayoutName: +--- !u!114 &11 +MonoBehaviour: + m_ObjectHideFlags: 52 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 1 + m_Script: {fileID: 12042, guid: 0000000000000000e000000000000000, type: 0} + m_Name: + m_EditorClassIdentifier: + m_Children: [] + m_Position: + serializedVersion: 2 + x: 0 + y: 969 + width: 1920 + height: 20 + m_MinSize: {x: 0, y: 0} + m_MaxSize: {x: 0, y: 0} +--- !u!114 &12 +MonoBehaviour: + m_ObjectHideFlags: 52 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 1 + m_Script: {fileID: 12010, guid: 0000000000000000e000000000000000, type: 0} + m_Name: + m_EditorClassIdentifier: + m_Children: + - {fileID: 13} + - {fileID: 8} + m_Position: + serializedVersion: 2 + x: 0 + y: 0 + width: 1448 + height: 939 + m_MinSize: {x: 200, y: 100} + m_MaxSize: {x: 16192, y: 16192} + vertical: 1 + controlID: 63 + draggingID: 0 +--- !u!114 &13 +MonoBehaviour: + m_ObjectHideFlags: 52 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 1 + m_Script: {fileID: 12010, guid: 0000000000000000e000000000000000, type: 0} + m_Name: + m_EditorClassIdentifier: + m_Children: + - {fileID: 7} + - {fileID: 14} + m_Position: + serializedVersion: 2 + x: 0 + y: 0 + width: 1448 + height: 587 + m_MinSize: {x: 200, y: 50} + m_MaxSize: {x: 16192, y: 8096} + vertical: 0 + controlID: 64 + draggingID: 0 +--- !u!114 &14 +MonoBehaviour: + m_ObjectHideFlags: 52 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 1 + m_Script: {fileID: 12006, guid: 0000000000000000e000000000000000, type: 0} + m_Name: SceneView + m_EditorClassIdentifier: + m_Children: [] + m_Position: + serializedVersion: 2 + x: 352 + y: 0 + width: 1096 + height: 587 + m_MinSize: {x: 202, y: 221} + m_MaxSize: {x: 4002, y: 4021} + m_ActualView: {fileID: 20} + m_Panes: + - {fileID: 20} + - {fileID: 15} + m_Selected: 0 + m_LastSelected: 1 +--- !u!114 &15 +MonoBehaviour: + m_ObjectHideFlags: 52 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 13855, guid: 0000000000000000e000000000000000, type: 0} + m_Name: + m_EditorClassIdentifier: + m_MinSize: {x: 310, y: 200} + m_MaxSize: {x: 4000, y: 4000} + m_TitleContent: + m_Text: Preferences + m_Image: {fileID: -5712115415447495865, guid: 0000000000000000d000000000000000, type: 0} + m_Tooltip: + m_Pos: + serializedVersion: 2 + x: 352 + y: 73 + width: 1094 + height: 566 + m_SerializedDataModeController: + m_DataMode: 0 + m_PreferredDataMode: 0 + m_SupportedDataModes: + isAutomatic: 1 + m_ViewDataDictionary: {fileID: 0} + m_OverlayCanvas: + m_LastAppliedPresetName: Default + m_SaveData: [] + m_OverlaysVisible: 1 + m_PosLeft: {x: 0, y: 0} + m_PosRight: {x: 0, y: 0} + m_Scope: 0 + m_SplitterFlex: 0.2 + m_SearchText: + m_TreeViewState: + scrollPos: {x: 0, y: 0} + m_SelectedIDs: 71137e95 + m_LastClickedID: -1786899599 + m_ExpandedIDs: 2956c29689577ec10000000001fecd114886f92e + m_RenameOverlay: + m_UserAcceptedRename: 0 + m_Name: + m_OriginalName: + m_EditFieldRect: + serializedVersion: 2 + x: 0 + y: 0 + width: 0 + height: 0 + m_UserData: 0 + m_IsWaitingForDelay: 0 + m_IsRenaming: 0 + m_OriginalEventType: 11 + m_IsRenamingFilename: 0 + m_ClientGUIView: {fileID: 0} + m_SearchString: +--- !u!114 &16 +MonoBehaviour: + m_ObjectHideFlags: 52 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 12015, guid: 0000000000000000e000000000000000, type: 0} + m_Name: + m_EditorClassIdentifier: + m_MinSize: {x: 100, y: 100} + m_MaxSize: {x: 4000, y: 4000} + m_TitleContent: + m_Text: Game + m_Image: {fileID: -6423792434712278376, guid: 0000000000000000d000000000000000, type: 0} + m_Tooltip: + m_Pos: + serializedVersion: 2 + x: 2059 + y: 92 + width: 1331 + height: 893 + m_SerializedDataModeController: + m_DataMode: 0 + m_PreferredDataMode: 0 + m_SupportedDataModes: + isAutomatic: 1 + m_ViewDataDictionary: {fileID: 0} + m_OverlayCanvas: + m_LastAppliedPresetName: Default + m_SaveData: [] + m_OverlaysVisible: 1 + m_SerializedViewNames: [] + m_SerializedViewValues: [] + m_PlayModeViewName: GameView + m_ShowGizmos: 0 + m_TargetDisplay: 0 + m_ClearColor: {r: 0, g: 0, b: 0, a: 0} + m_TargetSize: {x: 1080, y: 1920} + m_TextureFilterMode: 0 + m_TextureHideFlags: 61 + m_RenderIMGUI: 1 + m_EnterPlayModeBehavior: 0 + m_UseMipMap: 0 + m_VSyncEnabled: 0 + m_Gizmos: 0 + m_Stats: 0 + m_SelectedSizes: 07000000000000000000000000000000000000000000000000000000000000000000000000000000 + m_ZoomArea: + m_HRangeLocked: 0 + m_VRangeLocked: 0 + hZoomLockedByDefault: 0 + vZoomLockedByDefault: 0 + m_HBaseRangeMin: -540 + m_HBaseRangeMax: 540 + m_VBaseRangeMin: -960 + m_VBaseRangeMax: 960 + m_HAllowExceedBaseRangeMin: 1 + m_HAllowExceedBaseRangeMax: 1 + m_VAllowExceedBaseRangeMin: 1 + m_VAllowExceedBaseRangeMax: 1 + m_ScaleWithWindow: 0 + m_HSlider: 0 + m_VSlider: 0 + m_IgnoreScrollWheelUntilClicked: 0 + m_EnableMouseInput: 1 + m_EnableSliderZoomHorizontal: 0 + m_EnableSliderZoomVertical: 0 + m_UniformScale: 1 + m_UpDirection: 1 + m_DrawArea: + serializedVersion: 2 + x: 0 + y: 21 + width: 1331 + height: 872 + m_Scale: {x: 0.45416668, y: 0.45416668} + m_Translation: {x: 665.5, y: 436} + m_MarginLeft: 0 + m_MarginRight: 0 + m_MarginTop: 0 + m_MarginBottom: 0 + m_LastShownAreaInsideMargins: + serializedVersion: 2 + x: -1465.321 + y: -960 + width: 2930.642 + height: 1920 + m_MinimalGUI: 1 + m_defaultScale: 0.45416668 + m_LastWindowPixelSize: {x: 1331, y: 893} + m_ClearInEditMode: 1 + m_NoCameraWarning: 1 + m_LowResolutionForAspectRatios: 01000000000000000000 + m_XRRenderMode: 0 + m_RenderTexture: {fileID: 0} +--- !u!114 &17 +MonoBehaviour: + m_ObjectHideFlags: 52 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 1 + m_Script: {fileID: 12014, guid: 0000000000000000e000000000000000, type: 0} + m_Name: + m_EditorClassIdentifier: + m_MinSize: {x: 230, y: 250} + m_MaxSize: {x: 10000, y: 10000} + m_TitleContent: + m_Text: Project + m_Image: {fileID: -5467254957812901981, guid: 0000000000000000d000000000000000, type: 0} + m_Tooltip: + m_Pos: + serializedVersion: 2 + x: 0 + y: 660 + width: 1447 + height: 331 + m_SerializedDataModeController: + m_DataMode: 0 + m_PreferredDataMode: 0 + m_SupportedDataModes: + isAutomatic: 1 + m_ViewDataDictionary: {fileID: 0} + m_OverlayCanvas: + m_LastAppliedPresetName: Default + m_SaveData: [] + m_OverlaysVisible: 1 + m_SearchFilter: + m_NameFilter: + m_ClassNames: [] + m_AssetLabels: [] + m_AssetBundleNames: [] + m_ReferencingInstanceIDs: + m_SceneHandles: + m_ShowAllHits: 0 + m_SkipHidden: 0 + m_SearchArea: 1 + m_Folders: + - Assets + m_Globs: [] + m_OriginalText: + m_ImportLogFlags: 0 + m_FilterByTypeIntersection: 0 + m_ViewMode: 1 + m_StartGridSize: 16 + m_LastFolders: + - Assets/Editor + m_LastFoldersGridSize: 16 + m_LastProjectPath: E:\Project\WXGame\box1 + m_LockTracker: + m_IsLocked: 0 + m_FolderTreeState: + scrollPos: {x: 0, y: 45} + m_SelectedIDs: 6ec10000 + m_LastClickedID: 49518 + m_ExpandedIDs: 000000006ec1000000ca9a3bffffff7f + m_RenameOverlay: + m_UserAcceptedRename: 0 + m_Name: + m_OriginalName: + m_EditFieldRect: + serializedVersion: 2 + x: 0 + y: 0 + width: 0 + height: 0 + m_UserData: 0 + m_IsWaitingForDelay: 0 + m_IsRenaming: 0 + m_OriginalEventType: 11 + m_IsRenamingFilename: 1 + m_ClientGUIView: {fileID: 8} + m_SearchString: + m_CreateAssetUtility: + m_EndAction: {fileID: 0} + m_InstanceID: 0 + m_Path: + m_Icon: {fileID: 0} + m_ResourceFile: + m_AssetTreeState: + scrollPos: {x: 0, y: 0} + m_SelectedIDs: + m_LastClickedID: 0 + m_ExpandedIDs: 000000006ec10000 + m_RenameOverlay: + m_UserAcceptedRename: 0 + m_Name: + m_OriginalName: + m_EditFieldRect: + serializedVersion: 2 + x: 0 + y: 0 + width: 0 + height: 0 + m_UserData: 0 + m_IsWaitingForDelay: 0 + m_IsRenaming: 0 + m_OriginalEventType: 11 + m_IsRenamingFilename: 1 + m_ClientGUIView: {fileID: 0} + m_SearchString: + m_CreateAssetUtility: + m_EndAction: {fileID: 0} + m_InstanceID: 0 + m_Path: + m_Icon: {fileID: 0} + m_ResourceFile: + m_ListAreaState: + m_SelectedInstanceIDs: + m_LastClickedInstanceID: 0 + m_HadKeyboardFocusLastEvent: 1 + m_ExpandedInstanceIDs: c6230000 + m_RenameOverlay: + m_UserAcceptedRename: 0 + m_Name: + m_OriginalName: + m_EditFieldRect: + serializedVersion: 2 + x: 0 + y: 0 + width: 0 + height: 0 + m_UserData: 0 + m_IsWaitingForDelay: 0 + m_IsRenaming: 0 + m_OriginalEventType: 11 + m_IsRenamingFilename: 1 + m_ClientGUIView: {fileID: 8} + m_CreateAssetUtility: + m_EndAction: {fileID: 0} + m_InstanceID: 0 + m_Path: + m_Icon: {fileID: 0} + m_ResourceFile: + m_NewAssetIndexInList: -1 + m_ScrollPosition: {x: 0, y: 0} + m_GridSize: 16 + m_SkipHiddenPackages: 0 + m_DirectoriesAreaWidth: 207 +--- !u!114 &18 +MonoBehaviour: + m_ObjectHideFlags: 52 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 1 + m_Script: {fileID: 12019, guid: 0000000000000000e000000000000000, type: 0} + m_Name: + m_EditorClassIdentifier: + m_MinSize: {x: 275, y: 50} + m_MaxSize: {x: 4000, y: 4000} + m_TitleContent: + m_Text: Inspector + m_Image: {fileID: -2667387946076563598, guid: 0000000000000000d000000000000000, type: 0} + m_Tooltip: + m_Pos: + serializedVersion: 2 + x: 1448 + y: 73 + width: 471 + height: 918 + m_SerializedDataModeController: + m_DataMode: 0 + m_PreferredDataMode: 0 + m_SupportedDataModes: + isAutomatic: 1 + m_ViewDataDictionary: {fileID: 0} + m_OverlayCanvas: + m_LastAppliedPresetName: Default + m_SaveData: [] + m_OverlaysVisible: 1 + m_ObjectsLockedBeforeSerialization: [] + m_InstanceIDsLockedBeforeSerialization: + m_PreviewResizer: + m_CachedPref: 270 + m_ControlHash: -371814159 + m_PrefName: Preview_InspectorPreview + m_LastInspectedObjectInstanceID: -1 + m_LastVerticalScrollValue: 0 + m_GlobalObjectId: + m_InspectorMode: 0 + m_LockTracker: + m_IsLocked: 0 + m_PreviewWindow: {fileID: 0} +--- !u!114 &19 +MonoBehaviour: + m_ObjectHideFlags: 52 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 1 + m_Script: {fileID: 12061, guid: 0000000000000000e000000000000000, type: 0} + m_Name: + m_EditorClassIdentifier: + m_MinSize: {x: 200, y: 200} + m_MaxSize: {x: 4000, y: 4000} + m_TitleContent: + m_Text: Hierarchy + m_Image: {fileID: 7966133145522015247, guid: 0000000000000000d000000000000000, type: 0} + m_Tooltip: + m_Pos: + serializedVersion: 2 + x: 0 + y: 73 + width: 351 + height: 566 + m_SerializedDataModeController: + m_DataMode: 0 + m_PreferredDataMode: 0 + m_SupportedDataModes: + isAutomatic: 1 + m_ViewDataDictionary: {fileID: 0} + m_OverlayCanvas: + m_LastAppliedPresetName: Default + m_SaveData: [] + m_OverlaysVisible: 1 + m_SceneHierarchy: + m_TreeViewState: + scrollPos: {x: 0, y: 0} + m_SelectedIDs: 00e3feff + m_LastClickedID: 0 + m_ExpandedIDs: f6fcfefff0fefeffb80bffff + m_RenameOverlay: + m_UserAcceptedRename: 0 + m_Name: + m_OriginalName: + m_EditFieldRect: + serializedVersion: 2 + x: 0 + y: 0 + width: 0 + height: 0 + m_UserData: 0 + m_IsWaitingForDelay: 0 + m_IsRenaming: 0 + m_OriginalEventType: 11 + m_IsRenamingFilename: 0 + m_ClientGUIView: {fileID: 7} + m_SearchString: + m_ExpandedScenes: [] + m_CurrenRootInstanceID: 0 + m_LockTracker: + m_IsLocked: 0 + m_CurrentSortingName: TransformSorting + m_WindowGUID: 4c969a2b90040154d917609493e03593 +--- !u!114 &20 +MonoBehaviour: + m_ObjectHideFlags: 52 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 1 + m_Script: {fileID: 12013, guid: 0000000000000000e000000000000000, type: 0} + m_Name: + m_EditorClassIdentifier: + m_MinSize: {x: 200, y: 200} + m_MaxSize: {x: 4000, y: 4000} + m_TitleContent: + m_Text: Scene + m_Image: {fileID: 2593428753322112591, guid: 0000000000000000d000000000000000, type: 0} + m_Tooltip: + m_Pos: + serializedVersion: 2 + x: 352 + y: 73 + width: 1094 + height: 566 + m_SerializedDataModeController: + m_DataMode: 0 + m_PreferredDataMode: 0 + m_SupportedDataModes: + isAutomatic: 1 + m_ViewDataDictionary: {fileID: 0} + m_OverlayCanvas: + m_LastAppliedPresetName: Default + m_SaveData: + - dockPosition: 0 + containerId: overlay-toolbar__top + floating: 0 + collapsed: 0 + displayed: 1 + snapOffset: {x: -174, y: -26} + snapOffsetDelta: {x: 0, y: 0} + snapCorner: 3 + id: Tool Settings + index: 0 + layout: 1 + size: {x: 0, y: 0} + sizeOverriden: 0 + - dockPosition: 0 + containerId: overlay-toolbar__top + floating: 0 + collapsed: 0 + displayed: 1 + snapOffset: {x: -141, y: 149} + snapOffsetDelta: {x: 0, y: 0} + snapCorner: 1 + id: unity-grid-and-snap-toolbar + index: 1 + layout: 1 + size: {x: 0, y: 0} + sizeOverriden: 0 + - dockPosition: 1 + containerId: overlay-toolbar__top + floating: 0 + collapsed: 0 + displayed: 1 + snapOffset: {x: 0, y: 0} + snapOffsetDelta: {x: 0, y: 0} + snapCorner: 0 + id: unity-scene-view-toolbar + index: 0 + layout: 1 + size: {x: 0, y: 0} + sizeOverriden: 0 + - dockPosition: 1 + containerId: overlay-toolbar__top + floating: 0 + collapsed: 0 + displayed: 0 + snapOffset: {x: 0, y: 0} + snapOffsetDelta: {x: 0, y: 0} + snapCorner: 1 + id: unity-search-toolbar + index: 1 + layout: 1 + size: {x: 0, y: 0} + sizeOverriden: 0 + - dockPosition: 0 + containerId: overlay-container--left + floating: 0 + collapsed: 0 + displayed: 1 + snapOffset: {x: 0, y: 0} + snapOffsetDelta: {x: 0, y: 0} + snapCorner: 0 + id: unity-transform-toolbar + index: 0 + layout: 2 + size: {x: 0, y: 0} + sizeOverriden: 0 + - dockPosition: 0 + containerId: overlay-container--left + floating: 0 + collapsed: 0 + displayed: 1 + snapOffset: {x: 0, y: 197} + snapOffsetDelta: {x: 0, y: 0} + snapCorner: 0 + id: unity-component-tools + index: 1 + layout: 2 + size: {x: 0, y: 0} + sizeOverriden: 0 + - dockPosition: 0 + containerId: overlay-container--right + floating: 0 + collapsed: 0 + displayed: 1 + snapOffset: {x: 67.5, y: 86} + snapOffsetDelta: {x: 0, y: 0} + snapCorner: 0 + id: Orientation + index: 0 + layout: 4 + size: {x: 0, y: 0} + sizeOverriden: 0 + - dockPosition: 1 + containerId: overlay-container--right + floating: 0 + collapsed: 0 + displayed: 0 + snapOffset: {x: 0, y: 0} + snapOffsetDelta: {x: 0, y: 0} + snapCorner: 0 + id: Scene View/Light Settings + index: 1 + layout: 4 + size: {x: 0, y: 0} + sizeOverriden: 0 + - dockPosition: 1 + containerId: overlay-container--right + floating: 0 + collapsed: 0 + displayed: 0 + snapOffset: {x: 0, y: 0} + snapOffsetDelta: {x: 0, y: 0} + snapCorner: 0 + id: Scene View/Camera + index: 1 + layout: 4 + size: {x: 0, y: 0} + sizeOverriden: 0 + - dockPosition: 1 + containerId: overlay-container--right + floating: 0 + collapsed: 0 + displayed: 0 + snapOffset: {x: 0, y: 0} + snapOffsetDelta: {x: 0, y: 0} + snapCorner: 0 + id: Scene View/Cloth Constraints + index: 2 + layout: 4 + size: {x: 0, y: 0} + sizeOverriden: 0 + - dockPosition: 1 + containerId: overlay-container--right + floating: 0 + collapsed: 0 + displayed: 0 + snapOffset: {x: 0, y: 0} + snapOffsetDelta: {x: 0, y: 0} + snapCorner: 0 + id: Scene View/Cloth Collisions + index: 4 + layout: 4 + size: {x: 0, y: 0} + sizeOverriden: 0 + - dockPosition: 1 + containerId: overlay-container--right + floating: 0 + collapsed: 0 + displayed: 0 + snapOffset: {x: 0, y: 0} + snapOffsetDelta: {x: 0, y: 0} + snapCorner: 0 + id: Scene View/Navmesh Display + index: 4 + layout: 4 + size: {x: 0, y: 0} + sizeOverriden: 0 + - dockPosition: 1 + containerId: overlay-container--right + floating: 0 + collapsed: 0 + displayed: 0 + snapOffset: {x: 0, y: 0} + snapOffsetDelta: {x: 0, y: 0} + snapCorner: 0 + id: Scene View/Agent Display + index: 5 + layout: 4 + size: {x: 0, y: 0} + sizeOverriden: 0 + - dockPosition: 1 + containerId: overlay-container--right + floating: 0 + collapsed: 0 + displayed: 0 + snapOffset: {x: 0, y: 0} + snapOffsetDelta: {x: 0, y: 0} + snapCorner: 0 + id: Scene View/Obstacle Display + index: 6 + layout: 4 + size: {x: 0, y: 0} + sizeOverriden: 0 + - dockPosition: 1 + containerId: overlay-container--right + floating: 0 + collapsed: 0 + displayed: 0 + snapOffset: {x: 0, y: 0} + snapOffsetDelta: {x: 0, y: 0} + snapCorner: 0 + id: Scene View/Occlusion Culling + index: 5 + layout: 4 + size: {x: 0, y: 0} + sizeOverriden: 0 + - dockPosition: 1 + containerId: overlay-container--right + floating: 0 + collapsed: 0 + displayed: 0 + snapOffset: {x: 0, y: 0} + snapOffsetDelta: {x: 0, y: 0} + snapCorner: 0 + id: Scene View/Physics Debugger + index: 6 + layout: 4 + size: {x: 0, y: 0} + sizeOverriden: 0 + - dockPosition: 1 + containerId: overlay-container--right + floating: 0 + collapsed: 0 + displayed: 0 + snapOffset: {x: 0, y: 0} + snapOffsetDelta: {x: 0, y: 0} + snapCorner: 0 + id: Scene View/Scene Visibility + index: 7 + layout: 4 + size: {x: 0, y: 0} + sizeOverriden: 0 + - dockPosition: 1 + containerId: overlay-container--right + floating: 0 + collapsed: 0 + displayed: 0 + snapOffset: {x: 0, y: 0} + snapOffsetDelta: {x: 0, y: 0} + snapCorner: 0 + id: Scene View/Particles + index: 8 + layout: 4 + size: {x: 0, y: 0} + sizeOverriden: 0 + - dockPosition: 1 + containerId: overlay-container--right + floating: 0 + collapsed: 0 + displayed: 0 + snapOffset: {x: 0, y: 0} + snapOffsetDelta: {x: 0, y: 0} + snapCorner: 0 + id: Scene View/Tilemap + index: 11 + layout: 4 + size: {x: 0, y: 0} + sizeOverriden: 0 + - dockPosition: 1 + containerId: overlay-container--right + floating: 0 + collapsed: 0 + displayed: 0 + snapOffset: {x: 0, y: 0} + snapOffsetDelta: {x: 0, y: 0} + snapCorner: 0 + id: Scene View/Tilemap Palette Helper + index: 12 + layout: 4 + size: {x: 0, y: 0} + sizeOverriden: 0 + - dockPosition: 1 + containerId: overlay-container--right + floating: 0 + collapsed: 0 + displayed: 0 + snapOffset: {x: 48, y: 48} + snapOffsetDelta: {x: 0, y: 0} + snapCorner: 0 + id: Scene View/Open Tile Palette + index: 0 + layout: 4 + size: {x: 0, y: 0} + sizeOverriden: 0 + - dockPosition: 1 + containerId: overlay-container--right + floating: 0 + collapsed: 0 + displayed: 0 + snapOffset: {x: 48, y: 48} + snapOffsetDelta: {x: 0, y: 0} + snapCorner: 0 + id: Scene View/Tilemap Focus + index: 3 + layout: 4 + size: {x: 0, y: 0} + sizeOverriden: 0 + - dockPosition: 1 + containerId: overlay-container--right + floating: 0 + collapsed: 0 + displayed: 0 + snapOffset: {x: 48, y: 48} + snapOffsetDelta: {x: 0, y: 0} + snapCorner: 0 + id: Scene View/Path + index: 10 + layout: 4 + size: {x: 0, y: 0} + sizeOverriden: 0 + - dockPosition: 1 + containerId: overlay-container--right + floating: 0 + collapsed: 0 + displayed: 0 + snapOffset: {x: 48, y: 48} + snapOffsetDelta: {x: 0, y: 0} + snapCorner: 0 + id: Scene View/TrailRenderer + index: 9 + layout: 4 + size: {x: 0, y: 0} + sizeOverriden: 0 + - dockPosition: 1 + containerId: overlay-container--right + floating: 0 + collapsed: 0 + displayed: 1 + snapOffset: {x: 48, y: 10} + snapOffsetDelta: {x: 0, y: 0} + snapCorner: 0 + id: UnityEditor.SceneViewCameraOverlay + index: 12 + layout: 4 + size: {x: 0, y: 0} + sizeOverriden: 0 + - dockPosition: 1 + containerId: overlay-container--right + floating: 0 + collapsed: 0 + displayed: 1 + snapOffset: {x: 48, y: 48} + snapOffsetDelta: {x: 0, y: 0} + snapCorner: 0 + id: AINavigationOverlay + index: 11 + layout: 4 + size: {x: 0, y: 0} + sizeOverriden: 0 + - dockPosition: 1 + containerId: overlay-container--right + floating: 0 + collapsed: 0 + displayed: 0 + snapOffset: {x: 48, y: 48} + snapOffsetDelta: {x: 0, y: 0} + snapCorner: 0 + id: APV Overlay + index: 11 + layout: 4 + size: {x: 0, y: 0} + sizeOverriden: 0 + m_OverlaysVisible: 1 + m_WindowGUID: cc27987af1a868c49b0894db9c0f5429 + m_Gizmos: 1 + m_OverrideSceneCullingMask: 6917529027641081856 + m_SceneIsLit: 1 + m_SceneLighting: 1 + m_2DMode: 1 + m_isRotationLocked: 0 + m_PlayAudio: 0 + m_AudioPlay: 0 + m_Position: + m_Target: {x: -0.55690366, y: 0.69230556, z: -0.016894879} + speed: 2 + m_Value: {x: -0.55690366, y: 0.69230556, z: -0.016894879} + m_RenderMode: 0 + m_CameraMode: + drawMode: 0 + name: Shaded + section: Shading Mode + m_ValidateTrueMetals: 0 + m_DoValidateTrueMetals: 0 + m_SceneViewState: + m_AlwaysRefresh: 0 + showFog: 1 + showSkybox: 1 + showFlares: 1 + showImageEffects: 1 + showParticleSystems: 1 + showVisualEffectGraphs: 1 + m_FxEnabled: 1 + m_Grid: + xGrid: + m_Fade: + m_Target: 0 + speed: 2 + m_Value: 0 + m_Color: {r: 0.5, g: 0.5, b: 0.5, a: 0.4} + m_Pivot: {x: 0, y: 0, z: 0} + m_Size: {x: 0, y: 0} + yGrid: + m_Fade: + m_Target: 0 + speed: 2 + m_Value: 0 + m_Color: {r: 0.5, g: 0.5, b: 0.5, a: 0.4} + m_Pivot: {x: 0, y: 0, z: 0} + m_Size: {x: 1, y: 1} + zGrid: + m_Fade: + m_Target: 1 + speed: 2 + m_Value: 1 + m_Color: {r: 0.5, g: 0.5, b: 0.5, a: 0.4} + m_Pivot: {x: 0, y: 0, z: 0} + m_Size: {x: 1, y: 1} + m_ShowGrid: 1 + m_GridAxis: 1 + m_gridOpacity: 0.5 + m_Rotation: + m_Target: {x: 0, y: 0, z: 0, w: 1} + speed: 2 + m_Value: {x: 0, y: 0, z: 0, w: 1} + m_Size: + m_Target: 2.403626 + speed: 2 + m_Value: 2.403626 + m_Ortho: + m_Target: 1 + speed: 2 + m_Value: 1 + m_CameraSettings: + m_Speed: 1 + m_SpeedNormalized: 0.5 + m_SpeedMin: 0.001 + m_SpeedMax: 2 + m_EasingEnabled: 1 + m_EasingDuration: 0.4 + m_AccelerationEnabled: 1 + m_FieldOfViewHorizontalOrVertical: 60 + m_NearClip: 0.03 + m_FarClip: 10000 + m_DynamicClip: 1 + m_OcclusionCulling: 0 + m_LastSceneViewRotation: {x: -0.08717229, y: 0.89959055, z: -0.21045254, w: -0.3726226} + m_LastSceneViewOrtho: 0 + m_ReplacementShader: {fileID: 0} + m_ReplacementString: + m_SceneVisActive: 1 + m_LastLockedObject: {fileID: 0} + m_ViewIsLockedToObject: 0 +--- !u!114 &21 +MonoBehaviour: + m_ObjectHideFlags: 52 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 1 + m_Script: {fileID: 12003, guid: 0000000000000000e000000000000000, type: 0} + m_Name: + m_EditorClassIdentifier: + m_MinSize: {x: 100, y: 100} + m_MaxSize: {x: 4000, y: 4000} + m_TitleContent: + m_Text: Console + m_Image: {fileID: -4327648978806127646, guid: 0000000000000000d000000000000000, type: 0} + m_Tooltip: + m_Pos: + serializedVersion: 2 + x: 0 + y: 660 + width: 1447 + height: 331 + m_SerializedDataModeController: + m_DataMode: 0 + m_PreferredDataMode: 0 + m_SupportedDataModes: + isAutomatic: 1 + m_ViewDataDictionary: {fileID: 0} + m_OverlayCanvas: + m_LastAppliedPresetName: Default + m_SaveData: [] + m_OverlaysVisible: 1 diff --git a/d2/.vsconfig b/d2/.vsconfig new file mode 100644 index 00000000..f019fd0a --- /dev/null +++ b/d2/.vsconfig @@ -0,0 +1,6 @@ +{ + "version": "1.0", + "components": [ + "Microsoft.VisualStudio.Workload.ManagedGame" + ] +}