diff --git a/CHANGELOG.md b/CHANGELOG.md
index 435f04582..7d2a423dd 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,7 @@
### Fixes
+- Fixed an issue where screenshot capture triggered on a burst job would crash the game. The SDK can now also capture screenshots on events that occur outside of the main thread ([#2392](https://github.com/getsentry/sentry-unity/pull/2392))
- Structured logs now have the `origin` and `sdk` attributes correctly set ([#2390](https://github.com/getsentry/sentry-unity/pull/2390))
- Resolved possible startup crashes on Android VR platforms like the Oculus Quest. The SDK no longer natively subscribes to interaction hooks for automatic tracing and breadcrumb creation. ([#2393](https://github.com/getsentry/sentry-unity/pull/2393))
diff --git a/samples/unity-of-bugs/Assets/Scenes/3_AdditionalSamples.unity b/samples/unity-of-bugs/Assets/Scenes/3_AdditionalSamples.unity
index df0951bed..85086bcb6 100644
--- a/samples/unity-of-bugs/Assets/Scenes/3_AdditionalSamples.unity
+++ b/samples/unity-of-bugs/Assets/Scenes/3_AdditionalSamples.unity
@@ -13,7 +13,7 @@ OcclusionCullingSettings:
--- !u!104 &2
RenderSettings:
m_ObjectHideFlags: 0
- serializedVersion: 10
+ serializedVersion: 9
m_Fog: 0
m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1}
m_FogMode: 3
@@ -42,8 +42,8 @@ RenderSettings:
--- !u!157 &3
LightmapSettings:
m_ObjectHideFlags: 0
- serializedVersion: 13
- m_BakeOnSceneLoad: 0
+ serializedVersion: 12
+ m_GIWorkflowMode: 1
m_GISettings:
serializedVersion: 2
m_BounceScale: 1
@@ -66,6 +66,9 @@ LightmapSettings:
m_LightmapParameters: {fileID: 0}
m_LightmapsBakeMode: 1
m_TextureCompression: 1
+ m_FinalGather: 0
+ m_FinalGatherFiltering: 1
+ m_FinalGatherRayCount: 256
m_ReflectionCompression: 2
m_MixedBakeMode: 2
m_BakeBackend: 0
@@ -100,7 +103,7 @@ NavMeshSettings:
serializedVersion: 2
m_ObjectHideFlags: 0
m_BuildSettings:
- serializedVersion: 3
+ serializedVersion: 2
agentTypeID: 0
agentRadius: 0.5
agentHeight: 2
@@ -113,7 +116,7 @@ NavMeshSettings:
cellSize: 0.16666667
manualTileSize: 0
tileSize: 256
- buildHeightMesh: 0
+ accuratePlacement: 0
maxJobWorkers: 0
preserveTilesOutsideBounds: 0
debug:
@@ -153,7 +156,9 @@ RectTransform:
- {fileID: 1326160953}
- {fileID: 1983589452}
- {fileID: 978406552}
+ - {fileID: 2066465601}
m_Father: {fileID: 1665572489}
+ m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 1}
m_AnchorMax: {x: 1, y: 1}
@@ -229,17 +234,9 @@ 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
@@ -273,13 +270,13 @@ 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_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
+ m_RootOrder: 2
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &582054325
GameObject:
@@ -321,13 +318,13 @@ Transform:
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 582054325}
- 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!114 &582054329
MonoBehaviour:
@@ -370,6 +367,7 @@ RectTransform:
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 5216638424148094703}
+ m_RootOrder: 5
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
@@ -407,6 +405,7 @@ RectTransform:
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 978406552}
+ m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
@@ -488,6 +487,7 @@ RectTransform:
m_Children:
- {fileID: 834374186}
m_Father: {fileID: 253040315}
+ m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
@@ -619,6 +619,7 @@ RectTransform:
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 802360430}
+ m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
@@ -698,6 +699,7 @@ RectTransform:
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 1983589452}
+ m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
@@ -779,6 +781,7 @@ RectTransform:
m_Children:
- {fileID: 765642146}
m_Father: {fileID: 253040315}
+ m_RootOrder: 3
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
@@ -912,6 +915,7 @@ RectTransform:
m_Children:
- {fileID: 1857152829}
m_Father: {fileID: 253040315}
+ m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
@@ -1012,6 +1016,86 @@ CanvasRenderer:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1326160952}
m_CullTransparentMesh: 0
+--- !u!1 &1583546086
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 1583546087}
+ - component: {fileID: 1583546089}
+ - component: {fileID: 1583546088}
+ m_Layer: 5
+ m_Name: Text
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!224 &1583546087
+RectTransform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1583546086}
+ 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: 2066465601}
+ m_RootOrder: 0
+ 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 &1583546088
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1583546086}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ m_Material: {fileID: 0}
+ m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
+ m_RaycastTarget: 1
+ m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
+ m_Maskable: 1
+ m_OnCullStateChanged:
+ m_PersistentCalls:
+ m_Calls: []
+ m_FontData:
+ m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
+ m_FontSize: 14
+ m_FontStyle: 0
+ m_BestFit: 0
+ m_MinSize: 0
+ m_MaxSize: 40
+ m_Alignment: 4
+ m_AlignByGeometry: 0
+ m_RichText: 1
+ m_HorizontalOverflow: 1
+ m_VerticalOverflow: 0
+ m_LineSpacing: 1
+ m_Text: LogError in Burst Job
+--- !u!222 &1583546089
+CanvasRenderer:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1583546086}
+ m_CullTransparentMesh: 0
--- !u!1 &1665572488
GameObject:
m_ObjectHideFlags: 0
@@ -1047,6 +1131,7 @@ RectTransform:
- {fileID: 253040315}
- {fileID: 5216638424148094703}
m_Father: {fileID: 0}
+ m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
@@ -1112,7 +1197,6 @@ Canvas:
m_SortingBucketNormalizedSize: 0
m_VertexColorAlwaysGammaSpace: 0
m_AdditionalShaderChannelsFlag: 0
- m_UpdateRectTransformForStandalone: 0
m_SortingLayerID: 0
m_SortingOrder: 0
m_TargetDisplay: 0
@@ -1147,6 +1231,7 @@ RectTransform:
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 1326160953}
+ m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
@@ -1228,6 +1313,7 @@ RectTransform:
m_Children:
- {fileID: 908640125}
m_Father: {fileID: 253040315}
+ m_RootOrder: 2
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
@@ -1328,6 +1414,140 @@ CanvasRenderer:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1983589451}
m_CullTransparentMesh: 0
+--- !u!1 &2066465600
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 2066465601}
+ - component: {fileID: 2066465604}
+ - component: {fileID: 2066465603}
+ - component: {fileID: 2066465602}
+ m_Layer: 5
+ m_Name: Burst Job
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!224 &2066465601
+RectTransform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 2066465600}
+ 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: 1583546087}
+ m_Father: {fileID: 253040315}
+ m_RootOrder: 4
+ 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: 200, y: 30}
+ m_Pivot: {x: 0.5, y: 0.5}
+--- !u!114 &2066465602
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 2066465600}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ m_Navigation:
+ m_Mode: 3
+ m_WrapAround: 0
+ m_SelectOnUp: {fileID: 0}
+ m_SelectOnDown: {fileID: 0}
+ m_SelectOnLeft: {fileID: 0}
+ m_SelectOnRight: {fileID: 0}
+ m_Transition: 1
+ m_Colors:
+ m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
+ m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
+ m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
+ m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
+ m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
+ m_ColorMultiplier: 1
+ m_FadeDuration: 0.1
+ m_SpriteState:
+ m_HighlightedSprite: {fileID: 0}
+ m_PressedSprite: {fileID: 0}
+ m_SelectedSprite: {fileID: 0}
+ m_DisabledSprite: {fileID: 0}
+ m_AnimationTriggers:
+ m_NormalTrigger: Normal
+ m_HighlightedTrigger: Highlighted
+ m_PressedTrigger: Pressed
+ m_SelectedTrigger: Selected
+ m_DisabledTrigger: Disabled
+ m_Interactable: 1
+ m_TargetGraphic: {fileID: 2066465603}
+ m_OnClick:
+ m_PersistentCalls:
+ m_Calls:
+ - m_Target: {fileID: 253040317}
+ m_TargetAssemblyTypeName: AdditionalSampleButtons, Assembly-CSharp
+ m_MethodName: StartBuggyBurstJob
+ m_Mode: 1
+ m_Arguments:
+ m_ObjectArgument: {fileID: 0}
+ m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
+ m_IntArgument: 0
+ m_FloatArgument: 0
+ m_StringArgument:
+ m_BoolArgument: 0
+ m_CallState: 1
+--- !u!114 &2066465603
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 2066465600}
+ 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: 1}
+ m_RaycastTarget: 1
+ m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
+ m_Maskable: 1
+ m_OnCullStateChanged:
+ m_PersistentCalls:
+ m_Calls: []
+ m_Sprite: {fileID: 10905, 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 &2066465604
+CanvasRenderer:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 2066465600}
+ m_CullTransparentMesh: 0
--- !u!1 &5216638424148094696
GameObject:
m_ObjectHideFlags: 0
@@ -1403,6 +1623,7 @@ RectTransform:
- {fileID: 5216638425317031111}
- {fileID: 735359052}
m_Father: {fileID: 1665572489}
+ m_RootOrder: 2
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0}
m_AnchorMax: {x: 0.5, y: 0}
@@ -1482,6 +1703,7 @@ RectTransform:
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 5216638425317031111}
+ m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
@@ -1543,6 +1765,7 @@ RectTransform:
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 5216638425882040144}
+ m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
@@ -1614,6 +1837,7 @@ RectTransform:
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 5216638424148094703}
+ m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
@@ -1773,6 +1997,7 @@ RectTransform:
m_Children:
- {fileID: 5216638424536828319}
m_Father: {fileID: 5216638424148094703}
+ m_RootOrder: 4
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
@@ -1887,6 +2112,7 @@ RectTransform:
m_Children:
- {fileID: 5216638426142319615}
m_Father: {fileID: 5216638424148094703}
+ m_RootOrder: 2
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
@@ -1926,6 +2152,7 @@ RectTransform:
m_Children:
- {fileID: 5216638425035397373}
m_Father: {fileID: 5216638424148094703}
+ m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
@@ -2074,6 +2301,7 @@ RectTransform:
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 5216638424148094703}
+ m_RootOrder: 3
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
@@ -2153,6 +2381,7 @@ RectTransform:
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 5216638425805414493}
+ m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
@@ -2224,6 +2453,7 @@ RectTransform:
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 7152012675849339084}
+ m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5}
@@ -2253,6 +2483,7 @@ RectTransform:
- {fileID: 7152012675148913643}
- {fileID: 7152012676968016302}
m_Father: {fileID: 1665572489}
+ m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 1}
m_AnchorMax: {x: 1, y: 1}
@@ -2330,6 +2561,7 @@ RectTransform:
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 7152012675849339084}
+ m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5}
@@ -2354,10 +2586,3 @@ GameObject:
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
---- !u!1660057539 &9223372036854775807
-SceneRoots:
- m_ObjectHideFlags: 0
- m_Roots:
- - {fileID: 519420032}
- - {fileID: 582054328}
- - {fileID: 1665572489}
diff --git a/samples/unity-of-bugs/Assets/Scripts/AdditionalSampleButtons.cs b/samples/unity-of-bugs/Assets/Scripts/AdditionalSampleButtons.cs
index cfde60315..0bfac1503 100644
--- a/samples/unity-of-bugs/Assets/Scripts/AdditionalSampleButtons.cs
+++ b/samples/unity-of-bugs/Assets/Scripts/AdditionalSampleButtons.cs
@@ -1,6 +1,9 @@
-using System.Threading;
+using System;
+using System.Threading;
using Sentry;
using Sentry.Unity;
+using Unity.Burst;
+using Unity.Jobs;
using UnityEngine;
public class AdditionalSampleButtons : MonoBehaviour
@@ -50,4 +53,22 @@ public void ApplicationNotResponding()
}
public void Assert() => UnityEngine.Assertions.Assert.IsTrue(false);
+
+
+ [BurstCompile]
+ private struct BuggyBurstJob : IJob
+ {
+ public void Execute()
+ {
+ Debug.LogError("Bursting with bugs! 💥");
+ }
+ }
+
+ public void StartBuggyBurstJob()
+ {
+ Debug.Log("Starting Burst job filled with bugs! 💥");
+ var job = new BuggyBurstJob();
+ var handle = job.Schedule();
+ handle.Complete();
+ }
}
diff --git a/samples/unity-of-bugs/Packages/manifest.json b/samples/unity-of-bugs/Packages/manifest.json
index b591aa1ff..727dc350f 100644
--- a/samples/unity-of-bugs/Packages/manifest.json
+++ b/samples/unity-of-bugs/Packages/manifest.json
@@ -1,6 +1,7 @@
{
"dependencies": {
- "com.unity.collab-proxy": "2.9.3",
+ "com.unity.burst": "1.8.25",
+ "com.unity.collab-proxy": "2.10.1",
"com.unity.feature.development": "1.0.1",
"com.unity.ide.rider": "3.0.38",
"com.unity.ide.visualstudio": "2.0.23",
@@ -10,7 +11,7 @@
"com.unity.textmeshpro": "3.0.9",
"com.unity.timeline": "1.6.5",
"com.unity.ugui": "1.0.0",
- "com.unity.visualscripting": "1.9.8",
+ "com.unity.visualscripting": "1.9.9",
"io.sentry.unity.dev": "file:../../../package-dev",
"com.unity.modules.ai": "1.0.0",
"com.unity.modules.androidjni": "1.0.0",
diff --git a/samples/unity-of-bugs/Packages/packages-lock.json b/samples/unity-of-bugs/Packages/packages-lock.json
index d2fca6059..fbe6f3c53 100644
--- a/samples/unity-of-bugs/Packages/packages-lock.json
+++ b/samples/unity-of-bugs/Packages/packages-lock.json
@@ -1,7 +1,17 @@
{
"dependencies": {
+ "com.unity.burst": {
+ "version": "1.8.25",
+ "depth": 0,
+ "source": "registry",
+ "dependencies": {
+ "com.unity.mathematics": "1.2.1",
+ "com.unity.modules.jsonserialize": "1.0.0"
+ },
+ "url": "https://packages.unity.com"
+ },
"com.unity.collab-proxy": {
- "version": "2.9.3",
+ "version": "2.10.1",
"depth": 0,
"source": "registry",
"dependencies": {},
@@ -27,10 +37,10 @@
"source": "builtin",
"dependencies": {
"com.unity.ide.visualstudio": "2.0.22",
- "com.unity.ide.rider": "3.0.31",
+ "com.unity.ide.rider": "3.0.38",
"com.unity.ide.vscode": "1.2.5",
"com.unity.editorcoroutines": "1.0.0",
- "com.unity.performance.profile-analyzer": "1.2.2",
+ "com.unity.performance.profile-analyzer": "1.2.3",
"com.unity.test-framework": "1.1.33",
"com.unity.testtools.codecoverage": "1.2.6"
}
@@ -60,6 +70,13 @@
"dependencies": {},
"url": "https://packages.unity.com"
},
+ "com.unity.mathematics": {
+ "version": "1.2.6",
+ "depth": 1,
+ "source": "registry",
+ "dependencies": {},
+ "url": "https://packages.unity.com"
+ },
"com.unity.mobile.android-logcat": {
"version": "1.4.6",
"depth": 0,
@@ -68,7 +85,7 @@
"url": "https://packages.unity.com"
},
"com.unity.performance.profile-analyzer": {
- "version": "1.2.2",
+ "version": "1.2.3",
"depth": 1,
"source": "registry",
"dependencies": {},
@@ -133,7 +150,7 @@
}
},
"com.unity.visualscripting": {
- "version": "1.9.8",
+ "version": "1.9.9",
"depth": 0,
"source": "registry",
"dependencies": {
diff --git a/samples/unity-of-bugs/ProjectSettings/ProjectVersion.txt b/samples/unity-of-bugs/ProjectSettings/ProjectVersion.txt
index 1a62a673a..d8cedffba 100644
--- a/samples/unity-of-bugs/ProjectSettings/ProjectVersion.txt
+++ b/samples/unity-of-bugs/ProjectSettings/ProjectVersion.txt
@@ -1,2 +1,2 @@
-m_EditorVersion: 2021.3.45f2
-m_EditorVersionWithRevision: 2021.3.45f2 (88f88f591b2e)
+m_EditorVersion: 2021.3.58f1
+m_EditorVersionWithRevision: 2021.3.58f1 (2c36cafeeccf)
diff --git a/scripts/ci-env.ps1 b/scripts/ci-env.ps1
index f80b7e23d..60255bf79 100644
--- a/scripts/ci-env.ps1
+++ b/scripts/ci-env.ps1
@@ -5,7 +5,7 @@ param (
switch ($name) {
"unity2021.3" {
- return "2021.3.45f2"
+ return "2021.3.58f1"
}
"unity2022.3" {
return "2022.3.62f3"
diff --git a/src/Sentry.Unity/ScreenshotEventProcessor.cs b/src/Sentry.Unity/ScreenshotEventProcessor.cs
index 57a22093a..0e1150c55 100644
--- a/src/Sentry.Unity/ScreenshotEventProcessor.cs
+++ b/src/Sentry.Unity/ScreenshotEventProcessor.cs
@@ -26,7 +26,8 @@ public SentryEvent Process(SentryEvent @event)
// Only ever capture one screenshot per frame
if (Interlocked.CompareExchange(ref _isCapturingScreenshot, 1, 0) == 0)
{
- _sentryMonoBehaviour.StartCoroutine(CaptureScreenshotCoroutine(@event.EventId));
+ _options.LogDebug("Starting coroutine to capture a screenshot.");
+ _sentryMonoBehaviour.QueueCoroutine(CaptureScreenshotCoroutine(@event.EventId));
}
return @event;
diff --git a/src/Sentry.Unity/SentryMonoBehaviour.cs b/src/Sentry.Unity/SentryMonoBehaviour.cs
index 4b1ff5f88..cb6a3d611 100644
--- a/src/Sentry.Unity/SentryMonoBehaviour.cs
+++ b/src/Sentry.Unity/SentryMonoBehaviour.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections;
+using System.Collections.Concurrent;
using Sentry.Unity.Integrations;
using UnityEngine;
@@ -9,6 +10,7 @@ internal interface ISentryMonoBehaviour
{
event Action? ApplicationResuming;
public Coroutine StartCoroutine(IEnumerator routine);
+ public void QueueCoroutine(IEnumerator routine);
}
///
@@ -51,6 +53,30 @@ public void StartAwakeSpan(MonoBehaviour monoBehaviour) =>
///
public partial class SentryMonoBehaviour
{
+ // Unbounded queue - used by the ScreenshotEventProcessor where capture is already limited by Interlocked to 1/frame
+ private readonly ConcurrentQueue _coroutineQueue = new();
+
+ public void QueueCoroutine(IEnumerator routine)
+ {
+ if (MainThreadData.IsMainThread())
+ {
+ StartCoroutine(routine);
+ }
+ else
+ {
+ // On background thread (e.g., Burst job) - queue for next Update()
+ _coroutineQueue.Enqueue(routine);
+ }
+ }
+
+ private void Update()
+ {
+ while (_coroutineQueue.TryDequeue(out var coroutine))
+ {
+ StartCoroutine(coroutine);
+ }
+ }
+
///
/// Hook to receive an event when the application gains focus.
///
diff --git a/test/Scripts.Integration.Test/Scripts/SmokeTester.cs b/test/Scripts.Integration.Test/Scripts/SmokeTester.cs
index 8e7f76a16..ead8d2d87 100644
--- a/test/Scripts.Integration.Test/Scripts/SmokeTester.cs
+++ b/test/Scripts.Integration.Test/Scripts/SmokeTester.cs
@@ -214,7 +214,33 @@ private IEnumerator SmokeTestCoroutine()
t.ExpectMessage(currentMessage, "'filename':'screenshot.jpg','attachment_type':'event.attachment'");
t.ExpectMessageNot(currentMessage, "'length':0");
-
+
+#if !UNITY_WEBGL
+ // Test screenshot capture from background thread
+ var backgroundThreadGuid = Guid.NewGuid().ToString();
+ var backgroundThreadTask = Task.Run(() =>
+ {
+ Debug.Log($"Background thread: Capturing exception with GUID={backgroundThreadGuid}");
+ Debug.LogError($"BackgroundThreadException(GUID)={backgroundThreadGuid}");
+ });
+ backgroundThreadTask.Wait();
+
+ // Wait for screenshot capture to complete
+ yield return null;
+ // The capture coroutine gets queued up to be started in the next Update(), wait for that
+ yield return null;
+
+ currentMessage++; // The background thread exception event
+
+ t.ExpectMessage(currentMessage, "'type':'event'");
+ t.ExpectMessage(currentMessage, $"BackgroundThreadException(GUID)={backgroundThreadGuid}");
+ t.ExpectMessageNot(currentMessage, "'length':0");
+
+ currentMessage++; // The screenshot envelope from background thread
+
+ t.ExpectMessage(currentMessage, "'filename':'screenshot.jpg','attachment_type':'event.attachment'");
+ t.ExpectMessageNot(currentMessage, "'length':0");
+#endif
Debug.Log("Finished checking messages.");
t.Pass();
diff --git a/test/Sentry.Unity.Tests/SentryMonoBehaviourTests.cs b/test/Sentry.Unity.Tests/SentryMonoBehaviourTests.cs
index 8b7e6ed45..586b1dea1 100644
--- a/test/Sentry.Unity.Tests/SentryMonoBehaviourTests.cs
+++ b/test/Sentry.Unity.Tests/SentryMonoBehaviourTests.cs
@@ -1,4 +1,6 @@
using System.Collections;
+using System.Threading;
+using System.Threading.Tasks;
using NUnit.Framework;
using Sentry.Unity.Tests.Stubs;
using UnityEngine;
@@ -81,4 +83,49 @@ public void UpdatePauseStatus_ResumedTwice_ApplicationResumingInvokedOnlyOnce()
Assert.AreEqual(1, counter);
}
+ [Test]
+ public void QueueCoroutine_CalledOnMainThread_StartsCoroutineImmediately()
+ {
+ var sut = _fixture.GetSut();
+ var coroutineExecuted = false;
+
+ IEnumerator TestCoroutine()
+ {
+ coroutineExecuted = true;
+ yield return null;
+ }
+
+ sut.QueueCoroutine(TestCoroutine());
+
+ Assert.IsTrue(coroutineExecuted);
+ }
+
+ [UnityTest]
+ public IEnumerator QueueCoroutine_QueuedOnBackgroundThread_StartsInUpdate()
+ {
+ var sut = _fixture.GetSut();
+ var coroutineExecuted = false;
+
+ IEnumerator TestCoroutine()
+ {
+ coroutineExecuted = true;
+ yield return null;
+ }
+
+ var thread = new Thread(() =>
+ {
+ sut.QueueCoroutine(TestCoroutine());
+ });
+
+ thread.Start();
+ thread.Join();
+
+ // Coroutine should not have started yet
+ Assert.IsFalse(coroutineExecuted);
+
+ // Wait for the coroutine to execute - trigger `Update`
+ yield return null;
+
+ Assert.IsTrue(coroutineExecuted);
+ }
}
diff --git a/test/Sentry.Unity.Tests/Stubs/SentryTestMonoBehaviour.cs b/test/Sentry.Unity.Tests/Stubs/SentryTestMonoBehaviour.cs
index 12ffb5add..f911d21b9 100644
--- a/test/Sentry.Unity.Tests/Stubs/SentryTestMonoBehaviour.cs
+++ b/test/Sentry.Unity.Tests/Stubs/SentryTestMonoBehaviour.cs
@@ -16,4 +16,10 @@ internal class TestSentryMonoBehaviour : MonoBehaviour, ISentryMonoBehaviour
StartCoroutineCalled = true;
return base.StartCoroutine(routine);
}
+
+ public void QueueCoroutine(IEnumerator routine)
+ {
+ // For tests, assume we're on the main thread and start immediately
+ StartCoroutine(routine);
+ }
}