Compare commits

...
Author SHA1 Message Date
admin 3be710d4f5 Document iOS Unity 6.5 launch findings 2026-06-22 07:38:27 -07:00
admin 67ce4bdb2d Add iOS forced render probe 2026-06-22 07:32:34 -07:00
admin cf9e31c486 Try Metal display link for iOS rendering 2026-06-22 07:24:29 -07:00
admin 478228773d Disable iOS multithreaded rendering for diagnosis 2026-06-22 07:19:39 -07:00
admin bf438f4d2f Add iOS launch render layer markers 2026-06-22 07:12:10 -07:00
admin e8603eecd7 Expand iOS render diagnostics 2026-06-22 05:39:41 -07:00
admin ab23553415 Sample iOS framebuffer diagnostics 2026-06-21 19:48:44 -07:00
admin e408aae17e Expand iOS UI visibility diagnostics 2026-06-21 19:43:05 -07:00
admin 561e246515 Restore Unity UI canvas scales 2026-06-21 15:09:21 -07:00
admin 114e59aca8 Route iOS managed launch logs through os_log 2026-06-21 14:37:28 -07:00
admin 2bb85c27ef Expand iOS gray screen diagnostics 2026-06-21 14:32:47 -07:00
admin ad3508a74e Keep iOS sign-in flow fullscreen 2026-06-21 14:24:47 -07:00
admin bd429e2ffe Make iOS launch diagnostics public in Console 2026-06-21 14:10:22 -07:00
admin 56de80ee0f Commit Unity 6.5 rendering settings migration 2026-06-21 13:25:07 -07:00
admin 716c2d1dc0 Avoid cross-target iOS diagnostics symbol 2026-06-21 13:09:12 -07:00
admin 143fc4b33e Improve iOS launch diagnostics for Xcode 2026-06-21 11:41:36 -07:00
admin 4d448bea69 Broaden iOS generated launch diagnostics 2026-06-21 10:35:57 -07:00
admin 3d7f99d93c Add iOS main launch diagnostics 2026-06-21 10:03:51 -07:00
admin 03e69b004e Revert "Preserve Unity iOS scene manifest"
This reverts commit 8cb8884c5f.
2026-06-21 10:02:10 -07:00
admin 8cb8884c5f Preserve Unity iOS scene manifest 2026-06-21 09:31:30 -07:00
admin 08eba56309 Clear Unity generated state for TestFlight builds 2026-06-21 09:02:05 -07:00
admin 70b49e5f49 Compile iOS launch diagnostics in editor builds 2026-06-21 09:02:05 -07:00
admin 38c8763dc8 Patch iOS AppController launch diagnostics 2026-06-21 09:02:05 -07:00
admin 59df601b7d Add iOS launch diagnostics 2026-06-21 09:02:05 -07:00
admin 6fc2c95725 Isolate TestFlight Xcode DerivedData 2026-06-21 09:02:04 -07:00
admin db93ecf922 Clear TestFlight Library on Unity version changes 2026-06-21 09:02:04 -07:00
admin 0bea072cb0 Reset tracked files before TestFlight Unity builds 2026-06-21 09:02:04 -07:00
21 changed files with 2095 additions and 57 deletions
+44 -2
View File
@@ -10,6 +10,11 @@ on:
required: false
default: 'false'
type: boolean
clean_unity_generated_state:
description: 'Clear Unity generated project state before building'
required: false
default: 'true'
type: boolean
permissions:
contents: read
@@ -144,13 +149,44 @@ jobs:
with:
persist-credentials: false
lfs: false # Fetch LFS after checkout to avoid stale ref issues
clean: false # Library/ persists between runs on self-hosted runners
clean: false # Preserve ignored files until our explicit cleanup step
fetch-depth: 0
- name: Clean stale files
env:
CLEAN_UNITY_GENERATED_STATE: ${{ github.event.inputs.clean_unity_generated_state != 'false' }}
run: |
# actions/checkout with clean:false preserves ignored Unity caches, but
# it can leave tracked files modified on self-hosted runners.
git reset --hard HEAD
git clean -ffd
rm -rf src/main/csharp/net/eagle0/clients/unity/eagle0/Library/Bee/
UNITY_PROJECT_DIR="src/main/csharp/net/eagle0/clients/unity/eagle0"
LIBRARY_DIR="$UNITY_PROJECT_DIR/Library"
VERSION_CACHE="$LIBRARY_DIR/.last_unity_version"
PROJECT_VERSION_FILE="$UNITY_PROJECT_DIR/ProjectSettings/ProjectVersion.txt"
CURRENT_VERSION=$(grep "m_EditorVersion:" "$PROJECT_VERSION_FILE" | head -1 | sed 's/m_EditorVersion: //')
# TestFlight currently favors correctness over incremental import speed:
# clear all ignored Unity-generated project state unless explicitly disabled.
if [ "$CLEAN_UNITY_GENERATED_STATE" = "true" ]; then
echo "Clearing Unity generated project state before TestFlight build"
rm -rf "$LIBRARY_DIR"
rm -rf "$UNITY_PROJECT_DIR/Temp"
rm -rf "$UNITY_PROJECT_DIR/Obj"
rm -rf "$UNITY_PROJECT_DIR/Logs"
rm -rf "$UNITY_PROJECT_DIR/UserSettings"
rm -rf "$UNITY_PROJECT_DIR/ServerData"
fi
# Nuke Library/ when Unity version changes to avoid stale imports
if [ -f "$VERSION_CACHE" ]; then
CACHED_VERSION=$(cat "$VERSION_CACHE")
if [ "$CACHED_VERSION" != "$CURRENT_VERSION" ]; then
echo "Unity version changed ($CACHED_VERSION -> $CURRENT_VERSION) -- clearing Library/"
rm -rf "$LIBRARY_DIR"
fi
fi
rm -rf "$LIBRARY_DIR/Bee/"
- name: Fetch LFS files
env:
@@ -165,6 +201,12 @@ jobs:
run: |
./ci/github_actions/build_unity_ios.sh "$EAGLE0_BUILD_DIR/eagle0iOS"
- name: Save Unity version for Library/ cache invalidation
if: success()
run: |
mkdir -p src/main/csharp/net/eagle0/clients/unity/eagle0/Library
grep "m_EditorVersion:" src/main/csharp/net/eagle0/clients/unity/eagle0/ProjectSettings/ProjectVersion.txt | head -1 | sed 's/m_EditorVersion: //' > src/main/csharp/net/eagle0/clients/unity/eagle0/Library/.last_unity_version
- name: Upload Addressables to CDN
if: success() && github.event.inputs.skip_upload != 'true'
env:
+9
View File
@@ -14,14 +14,22 @@ PROFILE_UUID=${4:?Missing provisioning profile UUID}
ARCHIVE_PATH="$OUTPUT_PATH/eagle0.xcarchive"
EXPORT_PATH="$OUTPUT_PATH"
DERIVED_DATA_PATH="$OUTPUT_PATH/DerivedData"
echo "Archiving iOS app..."
echo " Xcode project: $XCODE_PROJECT_PATH"
echo " Archive path: $ARCHIVE_PATH"
echo " DerivedData path: $DERIVED_DATA_PATH"
echo " Team ID: $TEAM_ID"
mkdir -p "$OUTPUT_PATH"
# Avoid reusing stale Xcode build products from previous Unity-iPhone archives
# on the self-hosted signing runner.
echo "Cleaning stale Unity-iPhone DerivedData before archive..."
find ~/Library/Developer/Xcode/DerivedData -maxdepth 1 -name 'Unity-iPhone-*' -type d -exec rm -rf {} + 2>/dev/null || true
rm -rf "$DERIVED_DATA_PATH"
# Find the .xcodeproj file
XCODEPROJ=$(find "$XCODE_PROJECT_PATH" -name "*.xcodeproj" -maxdepth 1 | head -1)
if [ -z "$XCODEPROJ" ]; then
@@ -65,6 +73,7 @@ xcodebuild archive \
-project "$XCODEPROJ" \
-scheme "$SCHEME" \
-archivePath "$ARCHIVE_PATH" \
-derivedDataPath "$DERIVED_DATA_PATH" \
-destination "generic/platform=iOS" \
CODE_SIGN_IDENTITY="-" \
CODE_SIGNING_REQUIRED=NO \
+100
View File
@@ -0,0 +1,100 @@
# iOS Unity 6.5 Launch Investigation
Date: 2026-06-22
## Problem
iOS builds made from the Unity 6.5 upgrade launch, show the Unity/native startup path, then settle on a flat black or gray screen instead of the Eagle sign-in UX. The process remains alive.
The current diagnostic branch is:
`codex/ios-testflight-clean-checkout`
## What We Know
- Unity is starting successfully on iOS with Unity `6000.5.0f1`.
- The app is entering the expected scene. Diagnostics show `activeScene=Main`, later with `Main`, `Shared`, and `Connection` loaded.
- The native iOS window hierarchy looks valid:
- one key `UIWindow`
- root view controller `UnityDefaultViewController`
- root view `UnityView`
- backing layer `CAMetalLayer`
- Native UIKit drawing works. The native diagnostic overlay appears above Unity.
- Unity-side managed code is running. `Update` continues and frame count advances.
- Addressables are not the current launch blocker. `Data/Raw/aa/settings.json` exists in the iOS player, and the connection/sign-in scene objects are present.
- The sign-in UI exists in memory. Diagnostics find active `ScreenSpaceOverlay` canvases with visible graphics that are not culled:
- `ConnectionCanvas`
- `PersistentCanvas`
- `ErrorCanvas`
- The framebuffer readback remains flat gray:
- repeated samples around `RGBA(0.510, 0.502, 0.502, 1.000)`
- this stays true even when visible UI graphics exist
- The Unity IMGUI marker and the diagnostic screen-clearing camera do not appear visually.
- Disabling iOS multithreaded rendering did not help.
- Enabling `metalUseMetalDisplayLink` did not help and was reverted.
## Latest Forced Render Probe
Commit `67ce4bdb2d` added a forced render probe. The latest test showed:
```text
FrameProbe +20s forcedRender glClear=RGBA(1.000, 0.000, 1.000, 1.000) cameraRender=RGBA(1.000, 0.000, 1.000, 1.000)
```
Interpretation:
- Offscreen `RenderTexture` readback works at least for a direct `GL.Clear`.
- The manual camera part of the probe is currently malformed for URP Render Graph because the temporary render texture was created with no depth buffer.
- Unity logs this while running the manual camera probe:
```text
In the render graph API, the output Render Texture must have a depth buffer.
RenderPass: Fake or uninitialized surface is not supported for attachment 0.
EndRenderPass: Not inside a Renderpass
```
So this probe does not yet prove whether camera rendering to an offscreen target works. It does prove that a basic offscreen render target can be cleared and read back.
## Important Render Callback Observation
The only `BeginFrameRendering` and `BeginCameraRendering` entries seen in the latest logs are caused by the manual `Camera.Render()` diagnostic probe. There is still no clear evidence that Unity's ordinary per-frame camera/render pipeline is presenting the Main camera, overlay canvases, or the diagnostic display camera into the app's screen backbuffer.
That is the strongest current clue: the app logic and UI object graph are alive, but normal screen presentation appears not to happen.
## Current Hypotheses
Most likely:
- Unity 6.5 iOS + URP + Metal presentation/backbuffer path is broken for this project.
- A migrated project setting or generated iOS player setting is preventing normal screen camera rendering.
- URP Render Graph is failing to produce/present the normal camera frame on iOS, despite the app and scene being alive.
Less likely now:
- Wrong scene.
- Addressables missing from the player.
- OAuth/sign-in code path hiding UI.
- iOS native window/view hierarchy problem.
- iOS multithreaded rendering alone.
- Metal display link alone.
## Recommended Next Step
Create a separate throwaway branch from current `origin/main` that downgrades only the Unity/editor-related state back to Unity 6.4, then trigger a full TestFlight build from that branch.
The comparison question is deliberately narrow:
Does current `origin/main` content launch successfully on iOS when built with Unity 6.4?
Expected outcomes:
- If Unity 6.4 launches successfully: this strongly points to a Unity 6.5 iOS/URP/Metal presentation regression or a 6.5 migration setting issue.
- If Unity 6.4 also fails: the breakage is probably from another recent project/content/build-system change, and the Unity 6.5 timing was misleading.
Do not merge the downgrade branch. It is only a comparison artifact.
## If Continuing Diagnostics Instead
The next useful diagnostic patch would be to fix the forced camera render probe by creating the temporary render texture with a depth buffer or explicit depth/stencil format, then check whether `camera.Render()` can turn the offscreen texture green.
If that works while the screen stays gray, the failure is likely in screen backbuffer/presentation. If it fails too, the failure is broader in URP camera rendering on iOS.
@@ -307,8 +307,10 @@ public class ConnectionHandler : MonoBehaviour, ILobbySubscriber, IDisposable {
TutorialManager.Instance?.OnGameEvent("auth_panel_shown");
// Show hint for users coming from invitation flow
SetOAuthStatusText(InvitationSignInHint);
// Exit fullscreen so user can see browser with the sign-in link
if (Screen.fullScreen) {
// Exit fullscreen on desktop so the external browser is visible.
// Mobile platforms do not have a useful windowed mode, and forcing
// one during iOS startup can leave Unity presenting only a blank surface.
if (Screen.fullScreen && !Application.isMobilePlatform) {
_exitedFullscreenForNewUser = true;
_previousFullScreenMode = Screen.fullScreenMode;
_previousWidth = Screen.width;
@@ -1,5 +1,523 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &-8602469092812045411
MonoBehaviour:
m_ObjectHideFlags: 3
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: 899c54efeace73346a0a16faa3afe726, type: 3}
m_Name: Vignette
m_EditorClassIdentifier: Unity.RenderPipelines.Universal.Runtime::UnityEngine.Rendering.Universal.Vignette
active: 1
color:
m_OverrideState: 1
m_Value: {r: 0, g: 0, b: 0, a: 1}
center:
m_OverrideState: 1
m_Value: {x: 0.5, y: 0.5}
intensity:
m_OverrideState: 1
m_Value: 0
smoothness:
m_OverrideState: 1
m_Value: 0.2
rounded:
m_OverrideState: 1
m_Value: 0
--- !u!114 &-7437140395906876790
MonoBehaviour:
m_ObjectHideFlags: 3
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: 221518ef91623a7438a71fef23660601, type: 3}
m_Name: WhiteBalance
m_EditorClassIdentifier: Unity.RenderPipelines.Universal.Runtime::UnityEngine.Rendering.Universal.WhiteBalance
active: 1
temperature:
m_OverrideState: 1
m_Value: 0
tint:
m_OverrideState: 1
m_Value: 0
--- !u!114 &-6317230708989453511
MonoBehaviour:
m_ObjectHideFlags: 3
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: 81180773991d8724ab7f2d216912b564, type: 3}
m_Name: ChromaticAberration
m_EditorClassIdentifier: Unity.RenderPipelines.Universal.Runtime::UnityEngine.Rendering.Universal.ChromaticAberration
active: 1
intensity:
m_OverrideState: 1
m_Value: 0
--- !u!114 &-6307998228487220772
MonoBehaviour:
m_ObjectHideFlags: 3
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: 29fa0085f50d5e54f8144f766051a691, type: 3}
m_Name: FilmGrain
m_EditorClassIdentifier: Unity.RenderPipelines.Universal.Runtime::UnityEngine.Rendering.Universal.FilmGrain
active: 1
type:
m_OverrideState: 1
m_Value: 0
intensity:
m_OverrideState: 1
m_Value: 0
response:
m_OverrideState: 1
m_Value: 0.8
texture:
m_OverrideState: 1
m_Value: {fileID: 0}
--- !u!114 &-5689078660742997338
MonoBehaviour:
m_ObjectHideFlags: 3
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: c5e1dc532bcb41949b58bc4f2abfbb7e, type: 3}
m_Name: LensDistortion
m_EditorClassIdentifier: Unity.RenderPipelines.Universal.Runtime::UnityEngine.Rendering.Universal.LensDistortion
active: 1
intensity:
m_OverrideState: 1
m_Value: 0
xMultiplier:
m_OverrideState: 1
m_Value: 1
yMultiplier:
m_OverrideState: 1
m_Value: 1
center:
m_OverrideState: 1
m_Value: {x: 0.5, y: 0.5}
scale:
m_OverrideState: 1
m_Value: 1
--- !u!114 &-4799771996309553576
MonoBehaviour:
m_ObjectHideFlags: 3
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: 3eb4b772797da9440885e8bd939e9560, type: 3}
m_Name: ColorCurves
m_EditorClassIdentifier: Unity.RenderPipelines.Universal.Runtime::UnityEngine.Rendering.Universal.ColorCurves
active: 1
master:
m_OverrideState: 1
m_Value:
<length>k__BackingField: 2
m_Loop: 0
m_ZeroValue: 0
m_Range: 1
m_Curve:
serializedVersion: 2
m_Curve:
- serializedVersion: 3
time: 0
value: 0
inSlope: 1
outSlope: 1
tangentMode: 0
weightedMode: 0
inWeight: 0
outWeight: 0
- serializedVersion: 3
time: 1
value: 1
inSlope: 1
outSlope: 1
tangentMode: 0
weightedMode: 0
inWeight: 0
outWeight: 0
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
red:
m_OverrideState: 1
m_Value:
<length>k__BackingField: 2
m_Loop: 0
m_ZeroValue: 0
m_Range: 1
m_Curve:
serializedVersion: 2
m_Curve:
- serializedVersion: 3
time: 0
value: 0
inSlope: 1
outSlope: 1
tangentMode: 0
weightedMode: 0
inWeight: 0
outWeight: 0
- serializedVersion: 3
time: 1
value: 1
inSlope: 1
outSlope: 1
tangentMode: 0
weightedMode: 0
inWeight: 0
outWeight: 0
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
green:
m_OverrideState: 1
m_Value:
<length>k__BackingField: 2
m_Loop: 0
m_ZeroValue: 0
m_Range: 1
m_Curve:
serializedVersion: 2
m_Curve:
- serializedVersion: 3
time: 0
value: 0
inSlope: 1
outSlope: 1
tangentMode: 0
weightedMode: 0
inWeight: 0
outWeight: 0
- serializedVersion: 3
time: 1
value: 1
inSlope: 1
outSlope: 1
tangentMode: 0
weightedMode: 0
inWeight: 0
outWeight: 0
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
blue:
m_OverrideState: 1
m_Value:
<length>k__BackingField: 2
m_Loop: 0
m_ZeroValue: 0
m_Range: 1
m_Curve:
serializedVersion: 2
m_Curve:
- serializedVersion: 3
time: 0
value: 0
inSlope: 1
outSlope: 1
tangentMode: 0
weightedMode: 0
inWeight: 0
outWeight: 0
- serializedVersion: 3
time: 1
value: 1
inSlope: 1
outSlope: 1
tangentMode: 0
weightedMode: 0
inWeight: 0
outWeight: 0
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
hueVsHue:
m_OverrideState: 1
m_Value:
<length>k__BackingField: 0
m_Loop: 1
m_ZeroValue: 0.5
m_Range: 1
m_Curve:
serializedVersion: 2
m_Curve: []
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
hueVsSat:
m_OverrideState: 1
m_Value:
<length>k__BackingField: 0
m_Loop: 1
m_ZeroValue: 0.5
m_Range: 1
m_Curve:
serializedVersion: 2
m_Curve: []
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
satVsSat:
m_OverrideState: 1
m_Value:
<length>k__BackingField: 0
m_Loop: 0
m_ZeroValue: 0.5
m_Range: 1
m_Curve:
serializedVersion: 2
m_Curve: []
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
lumVsSat:
m_OverrideState: 1
m_Value:
<length>k__BackingField: 0
m_Loop: 0
m_ZeroValue: 0.5
m_Range: 1
m_Curve:
serializedVersion: 2
m_Curve: []
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
--- !u!114 &-3746391180291394380
MonoBehaviour:
m_ObjectHideFlags: 3
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: c01700fd266d6914ababb731e09af2eb, type: 3}
m_Name: DepthOfField
m_EditorClassIdentifier: Unity.RenderPipelines.Universal.Runtime::UnityEngine.Rendering.Universal.DepthOfField
active: 1
mode:
m_OverrideState: 1
m_Value: 0
gaussianStart:
m_OverrideState: 1
m_Value: 10
gaussianEnd:
m_OverrideState: 1
m_Value: 30
gaussianMaxRadius:
m_OverrideState: 1
m_Value: 1
highQualitySampling:
m_OverrideState: 1
m_Value: 0
focusDistance:
m_OverrideState: 1
m_Value: 10
aperture:
m_OverrideState: 1
m_Value: 5.6
focalLength:
m_OverrideState: 1
m_Value: 50
bladeCount:
m_OverrideState: 1
m_Value: 5
bladeCurvature:
m_OverrideState: 1
m_Value: 1
bladeRotation:
m_OverrideState: 1
m_Value: 0
--- !u!114 &-1543782473584419305
MonoBehaviour:
m_ObjectHideFlags: 3
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: 558a8e2b6826cf840aae193990ba9f2e, type: 3}
m_Name: ShadowsMidtonesHighlights
m_EditorClassIdentifier: Unity.RenderPipelines.Universal.Runtime::UnityEngine.Rendering.Universal.ShadowsMidtonesHighlights
active: 1
shadows:
m_OverrideState: 1
m_Value: {x: 1, y: 1, z: 1, w: 0}
midtones:
m_OverrideState: 1
m_Value: {x: 1, y: 1, z: 1, w: 0}
highlights:
m_OverrideState: 1
m_Value: {x: 1, y: 1, z: 1, w: 0}
shadowsStart:
m_OverrideState: 1
m_Value: 0
shadowsEnd:
m_OverrideState: 1
m_Value: 0.3
highlightsStart:
m_OverrideState: 1
m_Value: 0.55
highlightsEnd:
m_OverrideState: 1
m_Value: 1
--- !u!114 &-1498567658803252609
MonoBehaviour:
m_ObjectHideFlags: 3
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: 6bd486065ce11414fa40e631affc4900, type: 3}
m_Name: ProbeVolumesOptions
m_EditorClassIdentifier: Unity.RenderPipelines.Core.Runtime::UnityEngine.Rendering.ProbeVolumesOptions
active: 1
normalBias:
m_OverrideState: 1
m_Value: 0.05
viewBias:
m_OverrideState: 1
m_Value: 0.1
scaleBiasWithMinProbeDistance:
m_OverrideState: 1
m_Value: 0
samplingNoise:
m_OverrideState: 1
m_Value: 0.1
animateSamplingNoise:
m_OverrideState: 1
m_Value: 1
leakReductionMode:
m_OverrideState: 1
m_Value: 2
minValidDotProductValue:
m_OverrideState: 1
m_Value: 0.1
occlusionOnlyReflectionNormalization:
m_OverrideState: 1
m_Value: 1
intensityMultiplier:
m_OverrideState: 1
m_Value: 1
skyOcclusionIntensityMultiplier:
m_OverrideState: 1
m_Value: 1
worldOffset:
m_OverrideState: 1
m_Value: {x: 0, y: 0, z: 0}
--- !u!114 &-1164001390101786740
MonoBehaviour:
m_ObjectHideFlags: 3
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: 66f335fb1ffd8684294ad653bf1c7564, type: 3}
m_Name: ColorAdjustments
m_EditorClassIdentifier: Unity.RenderPipelines.Universal.Runtime::UnityEngine.Rendering.Universal.ColorAdjustments
active: 1
postExposure:
m_OverrideState: 1
m_Value: 0
contrast:
m_OverrideState: 1
m_Value: 0
colorFilter:
m_OverrideState: 1
m_Value: {r: 1, g: 1, b: 1, a: 1}
hueShift:
m_OverrideState: 1
m_Value: 0
saturation:
m_OverrideState: 1
m_Value: 0
--- !u!114 &-582628798280521535
MonoBehaviour:
m_ObjectHideFlags: 3
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: 97c23e3b12dc18c42a140437e53d3951, type: 3}
m_Name: Tonemapping
m_EditorClassIdentifier: Unity.RenderPipelines.Universal.Runtime::UnityEngine.Rendering.Universal.Tonemapping
active: 1
mode:
m_OverrideState: 1
m_Value: 0
neutralHDRRangeReductionMode:
m_OverrideState: 1
m_Value: 2
acesPreset:
m_OverrideState: 1
m_Value: 3
hueShiftAmount:
m_OverrideState: 1
m_Value: 0
detectPaperWhite:
m_OverrideState: 1
m_Value: 0
paperWhite:
m_OverrideState: 1
m_Value: 300
detectBrightnessLimits:
m_OverrideState: 1
m_Value: 1
minNits:
m_OverrideState: 1
m_Value: 0.005
maxNits:
m_OverrideState: 1
m_Value: 1000
--- !u!114 &-328865088572219810
MonoBehaviour:
m_ObjectHideFlags: 3
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: fb60a22f311433c4c962b888d1393f88, type: 3}
m_Name: PaniniProjection
m_EditorClassIdentifier: Unity.RenderPipelines.Universal.Runtime::UnityEngine.Rendering.Universal.PaniniProjection
active: 1
distance:
m_OverrideState: 1
m_Value: 0
cropToFit:
m_OverrideState: 1
m_Value: 1
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
@@ -12,4 +530,269 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: d7fd9488000d3734a9e00ee676215985, type: 3}
m_Name: DefaultVolumeProfile
m_EditorClassIdentifier: Unity.RenderPipelines.Core.Runtime::UnityEngine.Rendering.VolumeProfile
components: []
components:
- {fileID: 8145226663738208909}
- {fileID: -4799771996309553576}
- {fileID: -8602469092812045411}
- {fileID: -6307998228487220772}
- {fileID: 1187344733919894786}
- {fileID: 5904656700679825604}
- {fileID: 490749192378758693}
- {fileID: -6317230708989453511}
- {fileID: -3746391180291394380}
- {fileID: 7983480714356308405}
- {fileID: -7437140395906876790}
- {fileID: -5689078660742997338}
- {fileID: -1164001390101786740}
- {fileID: -582628798280521535}
- {fileID: 6080956283843308041}
- {fileID: 5258935138529682999}
- {fileID: -328865088572219810}
- {fileID: -1543782473584419305}
- {fileID: -1498567658803252609}
--- !u!114 &490749192378758693
MonoBehaviour:
m_ObjectHideFlags: 3
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: ccf1aba9553839d41ae37dd52e9ebcce, type: 3}
m_Name: MotionBlur
m_EditorClassIdentifier: Unity.RenderPipelines.Universal.Runtime::UnityEngine.Rendering.Universal.MotionBlur
active: 1
mode:
m_OverrideState: 1
m_Value: 0
quality:
m_OverrideState: 1
m_Value: 0
intensity:
m_OverrideState: 1
m_Value: 0
clamp:
m_OverrideState: 1
m_Value: 0.05
--- !u!114 &1187344733919894786
MonoBehaviour:
m_ObjectHideFlags: 3
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: 5485954d14dfb9a4c8ead8edb0ded5b1, type: 3}
m_Name: LiftGammaGain
m_EditorClassIdentifier: Unity.RenderPipelines.Universal.Runtime::UnityEngine.Rendering.Universal.LiftGammaGain
active: 1
lift:
m_OverrideState: 1
m_Value: {x: 1, y: 1, z: 1, w: 0}
gamma:
m_OverrideState: 1
m_Value: {x: 1, y: 1, z: 1, w: 0}
gain:
m_OverrideState: 1
m_Value: {x: 1, y: 1, z: 1, w: 0}
--- !u!114 &5258935138529682999
MonoBehaviour:
m_ObjectHideFlags: 3
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: e021b4c809a781e468c2988c016ebbea, type: 3}
m_Name: ColorLookup
m_EditorClassIdentifier: Unity.RenderPipelines.Universal.Runtime::UnityEngine.Rendering.Universal.ColorLookup
active: 1
texture:
m_OverrideState: 1
m_Value: {fileID: 0}
dimension: 1
contribution:
m_OverrideState: 1
m_Value: 0
--- !u!114 &5904656700679825604
MonoBehaviour:
m_ObjectHideFlags: 3
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: 0b2db86121404754db890f4c8dfe81b2, type: 3}
m_Name: Bloom
m_EditorClassIdentifier: Unity.RenderPipelines.Universal.Runtime::UnityEngine.Rendering.Universal.Bloom
active: 1
skipIterations:
m_OverrideState: 1
m_Value: 1
threshold:
m_OverrideState: 1
m_Value: 0.9
intensity:
m_OverrideState: 1
m_Value: 0
scatter:
m_OverrideState: 1
m_Value: 0.7
clamp:
m_OverrideState: 1
m_Value: 65472
tint:
m_OverrideState: 1
m_Value: {r: 1, g: 1, b: 1, a: 1}
highQualityFiltering:
m_OverrideState: 1
m_Value: 0
filter:
m_OverrideState: 1
m_Value: 0
downscale:
m_OverrideState: 1
m_Value: 0
maxIterations:
m_OverrideState: 1
m_Value: 6
dirtTexture:
m_OverrideState: 1
m_Value: {fileID: 0}
dimension: 1
dirtIntensity:
m_OverrideState: 1
m_Value: 0
--- !u!114 &6080956283843308041
MonoBehaviour:
m_ObjectHideFlags: 3
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: 70afe9e12c7a7ed47911bb608a23a8ff, type: 3}
m_Name: SplitToning
m_EditorClassIdentifier: Unity.RenderPipelines.Universal.Runtime::UnityEngine.Rendering.Universal.SplitToning
active: 1
shadows:
m_OverrideState: 1
m_Value: {r: 0.5, g: 0.5, b: 0.5, a: 1}
highlights:
m_OverrideState: 1
m_Value: {r: 0.5, g: 0.5, b: 0.5, a: 1}
balance:
m_OverrideState: 1
m_Value: 0
--- !u!114 &7983480714356308405
MonoBehaviour:
m_ObjectHideFlags: 3
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: 06437c1ff663d574d9447842ba0a72e4, type: 3}
m_Name: ScreenSpaceLensFlare
m_EditorClassIdentifier: Unity.RenderPipelines.Universal.Runtime::UnityEngine.Rendering.Universal.ScreenSpaceLensFlare
active: 1
intensity:
m_OverrideState: 1
m_Value: 0
tintColor:
m_OverrideState: 1
m_Value: {r: 1, g: 1, b: 1, a: 1}
bloomMip:
m_OverrideState: 1
m_Value: 1
firstFlareIntensity:
m_OverrideState: 1
m_Value: 1
secondaryFlareIntensity:
m_OverrideState: 1
m_Value: 1
warpedFlareIntensity:
m_OverrideState: 1
m_Value: 1
warpedFlareScale:
m_OverrideState: 1
m_Value: {x: 1, y: 1}
samples:
m_OverrideState: 1
m_Value: 1
sampleDimmer:
m_OverrideState: 1
m_Value: 0.5
vignetteEffect:
m_OverrideState: 1
m_Value: 1
startingPosition:
m_OverrideState: 1
m_Value: 1.25
scale:
m_OverrideState: 1
m_Value: 1.5
streaksIntensity:
m_OverrideState: 1
m_Value: 0
streaksLength:
m_OverrideState: 1
m_Value: 0.5
streaksOrientation:
m_OverrideState: 1
m_Value: 0
streaksThreshold:
m_OverrideState: 1
m_Value: 0.25
resolution:
m_OverrideState: 1
m_Value: 4
chromaticAbberationIntensity:
m_OverrideState: 1
m_Value: 0.5
--- !u!114 &8145226663738208909
MonoBehaviour:
m_ObjectHideFlags: 3
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: cdfbdbb87d3286943a057f7791b43141, type: 3}
m_Name: ChannelMixer
m_EditorClassIdentifier: Unity.RenderPipelines.Universal.Runtime::UnityEngine.Rendering.Universal.ChannelMixer
active: 1
redOutRedIn:
m_OverrideState: 1
m_Value: 100
redOutGreenIn:
m_OverrideState: 1
m_Value: 0
redOutBlueIn:
m_OverrideState: 1
m_Value: 0
greenOutRedIn:
m_OverrideState: 1
m_Value: 0
greenOutGreenIn:
m_OverrideState: 1
m_Value: 100
greenOutBlueIn:
m_OverrideState: 1
m_Value: 0
blueOutRedIn:
m_OverrideState: 1
m_Value: 0
blueOutGreenIn:
m_OverrideState: 1
m_Value: 0
blueOutBlueIn:
m_OverrideState: 1
m_Value: 100
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 6640b9dbf5ca47f69742262e25473798
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,428 @@
#if UNITY_IOS && !UNITY_EDITOR
using System.IO;
using System.Runtime.InteropServices;
using System.Collections;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
public static class iOSLaunchDiagnostics {
private const string Prefix = "[Eagle0Launch]";
private static bool _sawFirstCameraRender;
private static bool _sawFirstFrameRender;
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
private static void SubsystemRegistration() {
Log("SubsystemRegistration");
_sawFirstCameraRender = false;
_sawFirstFrameRender = false;
}
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterAssembliesLoaded)]
private static void AfterAssembliesLoaded() { Log("AfterAssembliesLoaded"); }
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSplashScreen)]
private static void BeforeSplashScreen() {
Log("BeforeSplashScreen");
Application.logMessageReceived += OnLogMessageReceived;
}
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
private static void BeforeSceneLoad() {
Log("BeforeSceneLoad");
SceneManager.sceneLoaded += OnSceneLoaded;
RenderPipelineManager.beginContextRendering += OnBeginContextRendering;
RenderPipelineManager.beginFrameRendering += OnBeginFrameRendering;
RenderPipelineManager.beginCameraRendering += OnBeginCameraRendering;
Camera.onPreCull += OnCameraPreCull;
LogEnvironment();
ShowNativeOverlay("BeforeSceneLoad");
InstallFrameProbe();
}
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterSceneLoad)]
private static void AfterSceneLoad() {
Log("AfterSceneLoad");
LogRuntimeState("AfterSceneLoad");
}
private static void OnSceneLoaded(Scene scene, LoadSceneMode mode) {
Log($"SceneLoaded name={scene.name} path={scene.path} mode={mode}");
}
private static void OnBeginContextRendering(
ScriptableRenderContext context,
System.Collections.Generic.List<Camera> cameras) {
Log($"BeginContextRendering cameraCount={cameras?.Count ?? 0}");
RenderPipelineManager.beginContextRendering -= OnBeginContextRendering;
}
private static void OnBeginFrameRendering(ScriptableRenderContext context, Camera[] cameras) {
if (_sawFirstFrameRender) { return; }
_sawFirstFrameRender = true;
Log($"BeginFrameRendering cameraCount={cameras?.Length ?? 0}");
}
private static void OnBeginCameraRendering(ScriptableRenderContext context, Camera camera) {
if (_sawFirstCameraRender) { return; }
_sawFirstCameraRender = true;
Log($"BeginCameraRendering camera={DescribeCamera(camera)}");
}
private static void OnCameraPreCull(Camera camera) {
Log($"CameraPreCull camera={DescribeCamera(camera)}");
Camera.onPreCull -= OnCameraPreCull;
}
private static void OnLogMessageReceived(string condition, string stackTrace, LogType type) {
if (type != LogType.Exception && type != LogType.Error) { return; }
Debug.Log($"{Prefix} observed {type}: {condition}");
}
private static void InstallFrameProbe() {
var probe = new GameObject("iOSLaunchDiagnosticsFrameProbe");
Object.DontDestroyOnLoad(probe);
probe.hideFlags = HideFlags.HideAndDontSave;
probe.AddComponent<FrameProbe>();
Log("FrameProbe installed");
}
private static void LogEnvironment() {
var settingsPath = Path.Combine(Application.streamingAssetsPath, "aa/settings.json");
Log($"Build={BuildInfo.GitCommitShort} timestamp={BuildInfo.BuildTimestamp}");
Log($"Unity={Application.unityVersion} platform={Application.platform} device={SystemInfo.deviceModel}");
Log($"GraphicsDevice={SystemInfo.graphicsDeviceType} graphicsName={SystemInfo.graphicsDeviceName}");
Log($"RenderPipeline.current={GraphicsSettings.currentRenderPipeline?.name ?? "null"}");
Log($"Quality.renderPipeline={QualitySettings.renderPipeline?.name ?? "null"}");
Log($"Screen={Screen.width}x{Screen.height} dpi={Screen.dpi} fullScreen={Screen.fullScreen} mode={Screen.fullScreenMode}");
Log($"StreamingAssets={Application.streamingAssetsPath}");
Log($"AddressablesSettingsExists={File.Exists(settingsPath)} path={settingsPath}");
}
private static void LogRuntimeState(string reason) {
Log($"{reason} frame={Time.frameCount} realtime={Time.realtimeSinceStartup:F2} focused={Application.isFocused} targetFrameRate={Application.targetFrameRate} vSync={QualitySettings.vSyncCount}");
Log($"{reason} activeScene={SceneManager.GetActiveScene().name} loadedScenes={DescribeLoadedScenes()}");
Log($"{reason} cameras={DescribeCameras()}");
Log($"{reason} canvases={DescribeCanvases()}");
}
private static string DescribeLoadedScenes() {
var description = "";
for (var i = 0; i < SceneManager.sceneCount; i++) {
var scene = SceneManager.GetSceneAt(i);
if (description.Length > 0) { description += ","; }
description += $"{scene.name}(loaded={scene.isLoaded},roots={scene.rootCount})";
}
return description.Length == 0 ? "none" : description;
}
private static string DescribeCameras() {
var cameras = Object.FindObjectsByType<Camera>(FindObjectsSortMode.None);
if (cameras.Length == 0) { return "none"; }
var description = "";
foreach (var camera in cameras) {
if (description.Length > 0) { description += " | "; }
description += DescribeCamera(camera);
}
return description;
}
private static string DescribeCamera(Camera camera) {
if (camera == null) { return "null"; }
return $"{camera.name} active={camera.gameObject.activeInHierarchy} enabled={camera.enabled} depth={camera.depth} rect={camera.rect} clear={camera.clearFlags} bg={camera.backgroundColor} target={(camera.targetTexture == null ? "screen" : camera.targetTexture.name)}";
}
private static string DescribeCanvases() {
var canvases = Object.FindObjectsByType<Canvas>(
FindObjectsInactive.Include,
FindObjectsSortMode.None);
if (canvases.Length == 0) { return "none"; }
var description = "";
foreach (var canvas in canvases) {
if (description.Length > 0) { description += " | "; }
description += DescribeCanvas(canvas);
}
return description;
}
private static string DescribeCanvas(Canvas canvas) {
var rectTransform = canvas.GetComponent<RectTransform>();
var scaler = canvas.GetComponent<CanvasScaler>();
var graphics = canvas.GetComponentsInChildren<Graphic>(true);
var enabledGraphics = 0;
var visibleGraphics = 0;
var sample = "";
foreach (var graphic in graphics) {
if (graphic.enabled) { enabledGraphics++; }
var graphicRect = graphic.transform as RectTransform;
var rect = graphicRect == null ? Rect.zero : graphicRect.rect;
var hasRect = Mathf.Abs(rect.width) > 0.01f && Mathf.Abs(rect.height) > 0.01f;
var visible = graphic.gameObject.activeInHierarchy && graphic.enabled &&
graphic.canvasRenderer.GetAlpha() > 0.001f && hasRect;
if (visible) { visibleGraphics++; }
if (sample.Length < 900 &&
(visible || graphic.name.Contains("Sign") || graphic.name.Contains("OAuth"))) {
if (sample.Length > 0) { sample += ","; }
sample +=
$"{GetPath(graphic.transform)}:{graphic.GetType().Name} active={graphic.gameObject.activeInHierarchy} enabled={graphic.enabled} cull={graphic.canvasRenderer.cull} alpha={graphic.canvasRenderer.GetAlpha():F2} colorAlpha={graphic.color.a:F2} shader={DescribeMaterial(graphic.materialForRendering)} texture={DescribeTexture(graphic.mainTexture)} rect={DescribeRectTransform(graphicRect)}";
}
}
var scalerDescription =
scaler == null
? "none"
: $"mode={scaler.uiScaleMode} scaleFactor={scaler.scaleFactor:F3} ref={scaler.referenceResolution} match={scaler.matchWidthOrHeight:F2}";
return $"{canvas.name} active={canvas.gameObject.activeInHierarchy} selfActive={canvas.gameObject.activeSelf} enabled={canvas.enabled} mode={canvas.renderMode} sorting={canvas.sortingOrder} scale={canvas.transform.localScale} lossyScale={canvas.transform.lossyScale} pixelRect={canvas.pixelRect} rect={DescribeRectTransform(rectTransform)} scaler={scalerDescription} groups={DescribeCanvasGroups(canvas)} graphics={graphics.Length} enabledGraphics={enabledGraphics} visibleGraphics={visibleGraphics} sample=[{(sample.Length == 0 ? "none" : sample)}]";
}
private static string DescribeMaterial(Material material) {
if (material == null) { return "null"; }
return material.shader == null ? $"{material.name}/shader=null"
: $"{material.name}/{material.shader.name}";
}
private static string DescribeTexture(Texture texture) {
if (texture == null) { return "null"; }
return $"{texture.name}:{texture.width}x{texture.height}";
}
private static string DescribeFramebufferSamples(string reason) {
var width = Screen.width;
var height = Screen.height;
if (width <= 0 || height <= 0) {
return $"{reason} framebuffer unavailable Screen={width}x{height}";
}
var texture = new Texture2D(1, 1, TextureFormat.RGBA32, false);
var samples = "";
SampleFramebuffer(texture, "center", width * 0.5f, height * 0.5f, ref samples);
SampleFramebuffer(texture, "upperLeft", width * 0.25f, height * 0.75f, ref samples);
SampleFramebuffer(texture, "upperRight", width * 0.75f, height * 0.75f, ref samples);
SampleFramebuffer(texture, "lowerLeft", width * 0.25f, height * 0.25f, ref samples);
SampleFramebuffer(texture, "lowerRight", width * 0.75f, height * 0.25f, ref samples);
Object.Destroy(texture);
return $"{reason} framebuffer Screen={width}x{height} samples={samples}";
}
private static void
SampleFramebuffer(Texture2D texture, string label, float x, float y, ref string samples) {
var sampleX = Mathf.Clamp(Mathf.RoundToInt(x), 0, Screen.width - 1);
var sampleY = Mathf.Clamp(Mathf.RoundToInt(y), 0, Screen.height - 1);
texture.ReadPixels(new Rect(sampleX, sampleY, 1, 1), 0, 0);
texture.Apply(false);
var color = texture.GetPixel(0, 0);
if (samples.Length > 0) { samples += " | "; }
samples += $"{label}@({sampleX},{sampleY})={color}";
}
private static string DescribeCanvasGroups(Canvas canvas) {
var groups = canvas.GetComponentsInChildren<CanvasGroup>(true);
if (groups.Length == 0) { return "none"; }
var description = "";
foreach (var group in groups) {
if (description.Length > 0) { description += ","; }
description +=
$"{GetPath(group.transform)}:active={group.gameObject.activeInHierarchy} alpha={group.alpha:F2} interactable={group.interactable}";
}
return description;
}
private static string DescribeRectTransform(RectTransform rectTransform) {
if (rectTransform == null) { return "none"; }
return $"rect={rectTransform.rect} anchors=({rectTransform.anchorMin},{rectTransform.anchorMax}) pivot={rectTransform.pivot} anchored={rectTransform.anchoredPosition} sizeDelta={rectTransform.sizeDelta} localScale={rectTransform.localScale} lossyScale={rectTransform.lossyScale}";
}
private static string GetPath(Transform transform) {
var path = transform.name;
while (transform.parent != null) {
transform = transform.parent;
path = $"{transform.name}/{path}";
}
return path;
}
[DllImport("__Internal")]
private static extern void Eagle0NativeLaunchDiagnosticsCheckpoint(string message);
[DllImport("__Internal")]
private static extern void Eagle0NativeShowLaunchDiagnosticsOverlay(string message);
private static void ShowNativeOverlay(string reason) {
try {
Eagle0NativeShowLaunchDiagnosticsOverlay(
$"{Prefix} native overlay {reason} build={BuildInfo.GitCommitShort}");
} catch (System.Exception exception) {
Log($"Native overlay failed: {exception.GetType().Name}: {exception.Message}");
}
}
private static void Log(string message) {
var line = $"{Prefix} {message}";
Eagle0NativeLaunchDiagnosticsCheckpoint(line);
Debug.Log(line);
}
private sealed class FrameProbe : MonoBehaviour {
private readonly float[] _snapshotTimes = { 1.0f, 3.0f, 5.0f, 10.0f, 20.0f };
private int _nextSnapshot;
private bool _loggedFirstUpdate;
private bool _loggedFirstOnGui;
private Camera _diagnosticDisplayCamera;
private GUIStyle _overlayStyle;
private void Awake() { Log("FrameProbe Awake"); }
private void Start() {
InstallDiagnosticDisplayCamera();
LogRuntimeState("FrameProbe Start");
}
private void Update() {
if (!_loggedFirstUpdate) {
_loggedFirstUpdate = true;
LogRuntimeState("FrameProbe first Update");
}
if (_nextSnapshot >= _snapshotTimes.Length ||
Time.realtimeSinceStartup < _snapshotTimes[_nextSnapshot]) {
return;
}
LogRuntimeState($"FrameProbe +{_snapshotTimes[_nextSnapshot]:F0}s");
StartCoroutine(
LogFramebufferAfterFrame($"FrameProbe +{_snapshotTimes[_nextSnapshot]:F0}s"));
StartCoroutine(
LogForcedRenderAfterFrame($"FrameProbe +{_snapshotTimes[_nextSnapshot]:F0}s"));
_nextSnapshot++;
}
private void InstallDiagnosticDisplayCamera() {
if (_diagnosticDisplayCamera != null) { return; }
var cameraObject = new GameObject("iOSLaunchDiagnosticsDisplayCamera");
Object.DontDestroyOnLoad(cameraObject);
cameraObject.hideFlags = HideFlags.HideAndDontSave;
_diagnosticDisplayCamera = cameraObject.AddComponent<Camera>();
_diagnosticDisplayCamera.clearFlags = CameraClearFlags.SolidColor;
_diagnosticDisplayCamera.backgroundColor = new Color(1.0f, 0.0f, 1.0f, 1.0f);
_diagnosticDisplayCamera.cullingMask = 0;
_diagnosticDisplayCamera.depth = 10000.0f;
_diagnosticDisplayCamera.rect = new Rect(0.0f, 0.0f, 1.0f, 1.0f);
_diagnosticDisplayCamera.orthographic = true;
_diagnosticDisplayCamera.nearClipPlane = 0.01f;
_diagnosticDisplayCamera.farClipPlane = 10.0f;
_diagnosticDisplayCamera.enabled = true;
Log($"Diagnostic display camera installed camera={DescribeCamera(_diagnosticDisplayCamera)}");
}
private IEnumerator LogFramebufferAfterFrame(string reason) {
yield return new WaitForEndOfFrame();
Log(DescribeFramebufferSamples(reason));
}
private IEnumerator LogForcedRenderAfterFrame(string reason) {
yield return new WaitForEndOfFrame();
Log(DescribeForcedRenderProbe(reason));
}
private static string DescribeForcedRenderProbe(string reason) {
var renderTexture = RenderTexture.GetTemporary(64, 64, 0, RenderTextureFormat.ARGB32);
var previous = RenderTexture.active;
var cameraObject = new GameObject("iOSLaunchDiagnosticsManualCamera");
cameraObject.hideFlags = HideFlags.HideAndDontSave;
try {
RenderTexture.active = renderTexture;
GL.Clear(true, true, new Color(1.0f, 0.0f, 1.0f, 1.0f));
var glSample = SampleActiveRenderTexture();
var camera = cameraObject.AddComponent<Camera>();
camera.enabled = false;
camera.clearFlags = CameraClearFlags.SolidColor;
camera.backgroundColor = new Color(0.0f, 1.0f, 0.0f, 1.0f);
camera.cullingMask = 0;
camera.targetTexture = renderTexture;
camera.orthographic = true;
camera.nearClipPlane = 0.01f;
camera.farClipPlane = 10.0f;
camera.Render();
RenderTexture.active = renderTexture;
var cameraSample = SampleActiveRenderTexture();
return $"{reason} forcedRender glClear={glSample} cameraRender={cameraSample}";
} catch (System.Exception exception) {
return $"{reason} forcedRender exception={exception.GetType().Name}: {exception.Message}";
} finally {
RenderTexture.active = previous;
RenderTexture.ReleaseTemporary(renderTexture);
Object.Destroy(cameraObject);
}
}
private static Color SampleActiveRenderTexture() {
var texture = new Texture2D(1, 1, TextureFormat.RGBA32, false);
texture.ReadPixels(new Rect(32, 32, 1, 1), 0, 0);
texture.Apply(false);
var color = texture.GetPixel(0, 0);
Object.Destroy(texture);
return color;
}
private void OnGUI() {
if (!_loggedFirstOnGui) {
_loggedFirstOnGui = true;
Log("FrameProbe OnGUI");
}
if (_overlayStyle == null) {
_overlayStyle = new GUIStyle(GUI.skin.label) {
fontSize = 32,
fontStyle = FontStyle.Bold,
alignment = TextAnchor.MiddleLeft,
};
_overlayStyle.normal.textColor = Color.white;
}
var oldColor = GUI.color;
var oldDepth = GUI.depth;
GUI.depth = -10000;
GUI.color = Color.magenta;
GUI.DrawTexture(new Rect(24, 24, 128, 128), Texture2D.whiteTexture);
GUI.color = Color.green;
GUI.DrawTexture(new Rect(168, 24, 128, 128), Texture2D.whiteTexture);
GUI.color = new Color(0.0f, 0.0f, 0.0f, 0.78f);
GUI.DrawTexture(new Rect(24, 168, 760, 72), Texture2D.whiteTexture);
GUI.color = Color.white;
GUI.Label(
new Rect(40, 168, 728, 72),
$"Eagle0 Unity IMGUI marker frame={Time.frameCount}",
_overlayStyle);
GUI.depth = oldDepth;
GUI.color = oldColor;
}
}
}
#endif
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 8b96578711c040cc8a9be926a2a13795
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,271 @@
#if UNITY_EDITOR
using System.IO;
using UnityEditor;
using UnityEditor.Callbacks;
public static class iOSLaunchDiagnosticsPostprocessor {
[PostProcessBuild(1000)]
public static void AddNativeLaunchDiagnostics(BuildTarget target, string pathToBuiltProject) {
if (target != BuildTarget.iOS) { return; }
AddMainDiagnostics(pathToBuiltProject);
AddAppControllerDiagnostics(pathToBuiltProject);
}
private static void AddMainDiagnostics(string pathToBuiltProject) {
var mainPaths =
Directory.GetFiles(pathToBuiltProject, "main.mm", SearchOption.AllDirectories);
if (mainPaths.Length == 0) {
UnityEngine.Debug.LogWarning(
$"iOS launch diagnostics: missing main.mm under {pathToBuiltProject}");
return;
}
foreach (var mainPath in mainPaths) { AddMainDiagnosticsToFile(mainPath); }
}
private static void AddMainDiagnosticsToFile(string mainPath) {
var source = File.ReadAllText(mainPath);
var relativePath = Path.GetFileName(Path.GetDirectoryName(mainPath)) + "/main.mm";
var marker = $"[Eagle0LaunchNative] {relativePath} main entered";
if (source.Contains(marker)) {
UnityEngine.Debug.Log($"iOS launch diagnostics already installed in {relativePath}");
return;
}
if (!source.Contains("#import <Foundation/Foundation.h>")) {
source = "#import <Foundation/Foundation.h>\n" + source;
}
source = EnsureNativeCheckpointDeclaration(source);
source = InsertAfterFirstBrace(
source,
"int main(",
" Eagle0GeneratedLaunchDiagnosticsLog(\"" + marker + "\");\n");
source = InsertBeforeLineContainingAfter(
source,
"int main(",
"UIApplicationMain(",
" Eagle0GeneratedLaunchDiagnosticsLog(\"[Eagle0LaunchNative] " + relativePath +
" before UIApplicationMain\");\n");
source = InsertBeforeLineContainingAfter(
source,
"int main(",
"runUIApplicationMainWithArgc(",
" Eagle0GeneratedLaunchDiagnosticsLog(\"[Eagle0LaunchNative] " + relativePath +
" before runUIApplicationMainWithArgc\");\n");
File.WriteAllText(mainPath, source);
UnityEngine.Debug.Log($"Installed iOS launch diagnostics in {relativePath}");
}
private static void AddAppControllerDiagnostics(string pathToBuiltProject) {
var appControllerPath = Path.Combine(pathToBuiltProject, "Classes/UnityAppController.mm");
if (!File.Exists(appControllerPath)) {
UnityEngine.Debug.LogWarning(
$"iOS launch diagnostics: missing UnityAppController.mm at {appControllerPath}");
return;
}
var source = File.ReadAllText(appControllerPath);
const string marker = "[Eagle0LaunchNative] UnityAppController diagnostics installed";
if (source.Contains(marker)) {
UnityEngine.Debug.Log(
"iOS launch diagnostics already installed in UnityAppController.mm");
return;
}
source = source.Replace(
"#include \"PluginBase/AppDelegateListener.h\"",
"#include \"PluginBase/AppDelegateListener.h\"\n#import <Foundation/Foundation.h>");
source = EnsureNativeCheckpointDeclaration(source);
source = InsertAfter(
source,
"- (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions\n{",
" Eagle0GeneratedLaunchDiagnosticsLog(\"" + marker + "\");\n");
source = InsertAfter(
source,
"- (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions\n{",
" Eagle0GeneratedLaunchDiagnosticsLog([[NSString stringWithFormat:@\"[Eagle0LaunchNative] AppController delegate=%@ launchOptions=%@\", NSStringFromClass([[UIApplication sharedApplication].delegate class]), launchOptions] UTF8String]);\n");
source = InsertAfter(
source,
"- (void)applicationDidBecomeActive:(UIApplication*)application\n{",
" Eagle0GeneratedLaunchDiagnosticsLog(\"[Eagle0LaunchNative] UnityAppController applicationDidBecomeActive\");\n");
File.WriteAllText(appControllerPath, source);
UnityEngine.Debug.Log("Installed iOS launch diagnostics in UnityAppController.mm");
AddGeneratedLifecycleDiagnostics(pathToBuiltProject);
}
private static void AddGeneratedLifecycleDiagnostics(string pathToBuiltProject) {
foreach (var sourcePath in Directory
.GetFiles(pathToBuiltProject, "*.mm", SearchOption.AllDirectories)) {
var fileName = Path.GetFileName(sourcePath);
if (!fileName.Contains("AppDelegate") && !fileName.Contains("SceneDelegate")) {
continue;
}
AddGeneratedLifecycleDiagnosticsToFile(sourcePath);
}
}
private static void AddGeneratedLifecycleDiagnosticsToFile(string sourcePath) {
var source = File.ReadAllText(sourcePath);
var relativePath = Path.GetFileName(Path.GetDirectoryName(sourcePath)) + "/" +
Path.GetFileName(sourcePath);
var marker = $"[Eagle0LaunchNative] {relativePath} diagnostics installed";
if (source.Contains(marker)) {
UnityEngine.Debug.Log($"iOS launch diagnostics already installed in {relativePath}");
return;
}
if (!source.Contains("#import <Foundation/Foundation.h>")) {
source = "#import <Foundation/Foundation.h>\n" + source;
}
source = EnsureNativeCheckpointDeclaration(source);
var installed = false;
source = InsertAfterOptional(
source,
"- (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions\n{",
" Eagle0GeneratedLaunchDiagnosticsLog(\"" + marker + "\");\n",
ref installed);
source = InsertAfterOptional(
source,
"- (void)applicationDidBecomeActive:(UIApplication*)application\n{",
" Eagle0GeneratedLaunchDiagnosticsLog(\"[Eagle0LaunchNative] " + relativePath +
" applicationDidBecomeActive\");\n",
ref installed);
source = InsertAfterOptional(
source,
"- (UISceneConfiguration*)application:(UIApplication*)application configurationForConnectingSceneSession:(UISceneSession*)connectingSceneSession options:(UISceneConnectionOptions*)options\n{",
" Eagle0GeneratedLaunchDiagnosticsLog([[NSString stringWithFormat:@\"[Eagle0LaunchNative] " +
relativePath +
" configurationForConnectingSceneSession role=%@\", connectingSceneSession.role] UTF8String]);\n",
ref installed);
source = InsertAfterOptional(
source,
"- (void)scene:(UIScene*)scene willConnectToSession:(UISceneSession*)session options:(UISceneConnectionOptions*)connectionOptions\n{",
" Eagle0GeneratedLaunchDiagnosticsLog([[NSString stringWithFormat:@\"[Eagle0LaunchNative] " +
relativePath +
" scene willConnect role=%@\", session.role] UTF8String]);\n",
ref installed);
source = InsertAfterOptional(
source,
"- (void)sceneDidBecomeActive:(UIScene*)scene\n{",
" Eagle0GeneratedLaunchDiagnosticsLog(\"[Eagle0LaunchNative] " + relativePath +
" sceneDidBecomeActive\");\n",
ref installed);
if (!installed) {
UnityEngine.Debug.LogWarning(
$"iOS launch diagnostics: no lifecycle hooks found in {relativePath}");
return;
}
File.WriteAllText(sourcePath, source);
UnityEngine.Debug.Log($"Installed iOS launch diagnostics in {relativePath}");
}
private static string InsertAfter(string source, string needle, string insertion) {
var index = source.IndexOf(needle, System.StringComparison.Ordinal);
if (index < 0) {
UnityEngine.Debug.LogWarning(
$"iOS launch diagnostics: could not find native hook: {needle}");
return source;
}
var insertAt = index + needle.Length;
return source.Insert(insertAt, "\n" + insertion);
}
private static string
InsertAfterOptional(string source, string needle, string insertion, ref bool inserted) {
var index = source.IndexOf(needle, System.StringComparison.Ordinal);
if (index < 0) { return source; }
inserted = true;
var insertAt = index + needle.Length;
return source.Insert(insertAt, "\n" + insertion);
}
private static string EnsureNativeCheckpointDeclaration(string source) {
const string functionName = "Eagle0GeneratedLaunchDiagnosticsLog";
if (source.Contains(functionName)) { return source; }
const string helper =
"\n#import <os/log.h>\n" + "#include <stdio.h>\n" +
"static void Eagle0GeneratedLaunchDiagnosticsLog(const char *message) {\n" +
" NSString *checkpoint = message == nullptr ? @\"generated checkpoint: null\" : [NSString stringWithUTF8String:message];\n" +
" if ([checkpoint hasPrefix:@\"[Eagle0LaunchNative] \"]) {\n" +
" checkpoint = [checkpoint substringFromIndex:[@\"[Eagle0LaunchNative] \" length]];\n" +
" }\n" +
" NSString *line = [NSString stringWithFormat:@\"[Eagle0LaunchNative] %@\", checkpoint];\n" +
" os_log(OS_LOG_DEFAULT, \"%{public}s\", [line UTF8String]);\n" +
" NSLog(@\"%@\", line);\n" +
" fprintf(stderr, \"%s\\n\", [line UTF8String]);\n" +
" NSString *path = [NSTemporaryDirectory() stringByAppendingPathComponent:@\"eagle0-launch.log\"];\n" +
" NSString *entry = [line stringByAppendingString:@\"\\n\"];\n" +
" NSFileHandle *handle = [NSFileHandle fileHandleForWritingAtPath:path];\n" +
" if (handle == nil) {\n" +
" [entry writeToFile:path atomically:YES encoding:NSUTF8StringEncoding error:nil];\n" +
" return;\n" + " }\n" + " [handle seekToEndOfFile];\n" +
" [handle writeData:[entry dataUsingEncoding:NSUTF8StringEncoding]];\n" +
" [handle closeFile];\n" + "}\n";
var foundationImport = "#import <Foundation/Foundation.h>";
var importIndex = source.IndexOf(foundationImport, System.StringComparison.Ordinal);
if (importIndex >= 0) {
return source.Insert(importIndex + foundationImport.Length, helper);
}
return "#import <Foundation/Foundation.h>" + helper + source;
}
private static string InsertAfterFirstBrace(string source, string prefix, string insertion) {
var prefixIndex = source.IndexOf(prefix, System.StringComparison.Ordinal);
if (prefixIndex < 0) {
UnityEngine.Debug.LogWarning(
$"iOS launch diagnostics: could not find native hook prefix: {prefix}");
return source;
}
var braceIndex = source.IndexOf('{', prefixIndex);
if (braceIndex < 0) {
UnityEngine.Debug.LogWarning(
$"iOS launch diagnostics: could not find native hook brace after: {prefix}");
return source;
}
return source.Insert(braceIndex + 1, "\n" + insertion);
}
private static string InsertBeforeLineContainingAfter(
string source,
string afterPrefix,
string needle,
string insertion) {
var startIndex = source.IndexOf(afterPrefix, System.StringComparison.Ordinal);
if (startIndex < 0) {
UnityEngine.Debug.LogWarning(
$"iOS launch diagnostics: could not find native hook prefix: {afterPrefix}");
return source;
}
var index = source.IndexOf(needle, startIndex, System.StringComparison.Ordinal);
if (index < 0) {
UnityEngine.Debug.LogWarning(
$"iOS launch diagnostics: could not find native hook line after {afterPrefix}: {needle}");
return source;
}
var lineStart = source.LastIndexOf('\n', index);
lineStart = lineStart < 0 ? 0 : lineStart + 1;
return source.Insert(lineStart, insertion);
}
}
#endif
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 95c6c9ab620a4e60a996bb04e4b16ec6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 7d31306224d7441cb8d9e2e641c47ae7
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,332 @@
#import <Foundation/Foundation.h>
#import <QuartzCore/QuartzCore.h>
#import <UIKit/UIKit.h>
#import <os/log.h>
#include <stdio.h>
static UIWindow *Eagle0DiagnosticWindow = nil;
static UILabel *Eagle0DiagnosticLabel = nil;
static void Eagle0Log(NSString *message) {
NSString *line = [NSString stringWithFormat:@"[Eagle0LaunchNative] %@", message];
os_log(OS_LOG_DEFAULT, "%{public}s", [line UTF8String]);
NSLog(@"%@", line);
fprintf(stderr, "%s\n", [line UTF8String]);
NSString *path = [NSTemporaryDirectory() stringByAppendingPathComponent:@"eagle0-launch.log"];
NSString *entry = [line stringByAppendingString:@"\n"];
NSFileHandle *handle = [NSFileHandle fileHandleForWritingAtPath:path];
if (handle == nil) {
[entry writeToFile:path atomically:YES encoding:NSUTF8StringEncoding error:nil];
return;
}
[handle seekToEndOfFile];
[handle writeData:[entry dataUsingEncoding:NSUTF8StringEncoding]];
[handle closeFile];
}
static NSString *Eagle0DescribeColor(UIColor *color) {
if (color == nil) {
return @"nil";
}
CGFloat red = 0;
CGFloat green = 0;
CGFloat blue = 0;
CGFloat alpha = 0;
if ([color getRed:&red green:&green blue:&blue alpha:&alpha]) {
return [NSString stringWithFormat:@"rgba=%.3f,%.3f,%.3f,%.3f", red, green, blue, alpha];
}
return [color description];
}
static void Eagle0LogViewTree(UIView *view, NSString *indent, NSInteger depth) {
if (view == nil) {
Eagle0Log([NSString stringWithFormat:@"%@view=nil", indent]);
return;
}
Eagle0Log([NSString stringWithFormat:
@"%@view=%@ frame=%@ bounds=%@ hidden=%d alpha=%.3f opaque=%d bg=%@ layer=%@ layerFrame=%@ layerHidden=%d subviews=%lu",
indent,
NSStringFromClass([view class]),
NSStringFromCGRect(view.frame),
NSStringFromCGRect(view.bounds),
view.hidden,
view.alpha,
view.opaque,
Eagle0DescribeColor(view.backgroundColor),
NSStringFromClass([view.layer class]),
NSStringFromCGRect(view.layer.frame),
view.layer.hidden,
(unsigned long)view.subviews.count]);
if (depth <= 0) {
return;
}
NSString *childIndent = [indent stringByAppendingString:@" "];
for (UIView *subview in view.subviews) {
Eagle0LogViewTree(subview, childIndent, depth - 1);
}
}
static NSString *Eagle0DescribeWindowScene(UIWindow *window) {
if (window == nil) {
return @"nil";
}
if (@available(iOS 13.0, *)) {
UIWindowScene *scene = window.windowScene;
if (scene == nil) {
return @"nil";
}
return [NSString stringWithFormat:@"%@ state=%ld",
scene.session.persistentIdentifier,
(long)scene.activationState];
}
return @"unavailable";
}
static void Eagle0LogWindow(UIWindow *window, NSUInteger index, NSString *reason) {
if (window == nil) {
Eagle0Log([NSString stringWithFormat:@"%@ window[%lu]=nil",
reason,
(unsigned long)index]);
return;
}
Eagle0Log([NSString stringWithFormat:
@"%@ window[%lu]=%@ key=%d level=%.3f frame=%@ bounds=%@ hidden=%d alpha=%.3f opaque=%d rootViewController=%@ rootView=%@ scene=%@",
reason,
(unsigned long)index,
window,
window.isKeyWindow,
window.windowLevel,
NSStringFromCGRect(window.frame),
NSStringFromCGRect(window.bounds),
window.hidden,
window.alpha,
window.opaque,
NSStringFromClass([window.rootViewController class]),
NSStringFromClass([window.rootViewController.view class]),
Eagle0DescribeWindowScene(window)]);
Eagle0LogViewTree(window, [NSString stringWithFormat:@"%@ window[%lu] ",
reason,
(unsigned long)index],
4);
}
static UIWindowScene *Eagle0FindActiveWindowScene() {
if (@available(iOS 13.0, *)) {
UIApplication *application = [UIApplication sharedApplication];
for (UIScene *scene in application.connectedScenes) {
if (![scene isKindOfClass:[UIWindowScene class]]) {
continue;
}
UIWindowScene *windowScene = (UIWindowScene *)scene;
if (windowScene.activationState == UISceneActivationStateForegroundActive ||
windowScene.activationState == UISceneActivationStateForegroundInactive) {
return windowScene;
}
}
}
return nil;
}
static void Eagle0InstallDiagnosticOverlay(NSString *message, NSInteger retriesRemaining) {
dispatch_async(dispatch_get_main_queue(), ^{
if (Eagle0DiagnosticWindow != nil) {
Eagle0DiagnosticLabel.text = message;
Eagle0Log([NSString stringWithFormat:@"diagnostic overlay updated: %@", message]);
return;
}
CGRect screenBounds = [UIScreen mainScreen].bounds;
UIWindow *window = nil;
if (@available(iOS 13.0, *)) {
UIWindowScene *windowScene = Eagle0FindActiveWindowScene();
if (windowScene == nil) {
if (retriesRemaining > 0) {
Eagle0Log(@"diagnostic overlay waiting for UIWindowScene");
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)),
dispatch_get_main_queue(), ^{
Eagle0InstallDiagnosticOverlay(message, retriesRemaining - 1);
});
} else {
Eagle0Log(@"diagnostic overlay failed: no UIWindowScene");
}
return;
}
window = [[UIWindow alloc] initWithWindowScene:windowScene];
screenBounds = windowScene.screen.bounds;
} else {
window = [[UIWindow alloc] initWithFrame:screenBounds];
}
UIViewController *controller = [[UIViewController alloc] init];
controller.view = [[UIView alloc] initWithFrame:screenBounds];
controller.view.backgroundColor = [UIColor clearColor];
controller.view.userInteractionEnabled = NO;
UIView *marker = [[UIView alloc] initWithFrame:CGRectMake(16, 16, 520, 118)];
marker.backgroundColor = [UIColor colorWithRed:1.0 green:0.0 blue:1.0 alpha:0.88];
marker.userInteractionEnabled = NO;
[controller.view addSubview:marker];
UIView *greenPatch = [[UIView alloc] initWithFrame:CGRectMake(536, 16, 118, 118)];
greenPatch.backgroundColor = [UIColor colorWithRed:0.0 green:1.0 blue:0.0 alpha:0.88];
greenPatch.userInteractionEnabled = NO;
[controller.view addSubview:greenPatch];
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(32, 28, 488, 94)];
label.text = message;
label.numberOfLines = 3;
label.textColor = [UIColor whiteColor];
label.font = [UIFont boldSystemFontOfSize:22];
label.backgroundColor = [UIColor clearColor];
label.userInteractionEnabled = NO;
[controller.view addSubview:label];
window.frame = screenBounds;
window.rootViewController = controller;
window.backgroundColor = [UIColor clearColor];
window.opaque = NO;
window.hidden = NO;
window.userInteractionEnabled = NO;
window.windowLevel = UIWindowLevelAlert + 100.0;
Eagle0DiagnosticWindow = window;
Eagle0DiagnosticLabel = label;
Eagle0Log([NSString stringWithFormat:@"diagnostic overlay installed: %@", message]);
});
}
extern "C" void Eagle0NativeLaunchDiagnosticsCheckpoint(const char *message) {
NSString *checkpoint = message == nil ? @"native checkpoint: null"
: [NSString stringWithUTF8String:message];
if ([checkpoint hasPrefix:@"[Eagle0LaunchNative] "]) {
checkpoint = [checkpoint substringFromIndex:[@"[Eagle0LaunchNative] " length]];
}
Eagle0Log(checkpoint);
}
extern "C" void Eagle0NativeShowLaunchDiagnosticsOverlay(const char *message) {
NSString *overlayMessage = message == nil ? @"Eagle0 native overlay"
: [NSString stringWithUTF8String:message];
Eagle0InstallDiagnosticOverlay(overlayMessage, 5);
}
static void Eagle0LogApplicationState(NSString *reason) {
UIApplication *application = [UIApplication sharedApplication];
Eagle0Log([NSString stringWithFormat:@"%@ appState=%ld delegate=%@ keyWindow=%@ windowCount=%lu",
reason,
(long)application.applicationState,
NSStringFromClass([application.delegate class]),
application.keyWindow,
(unsigned long)application.windows.count]);
if (@available(iOS 13.0, *)) {
Eagle0Log([NSString stringWithFormat:@"%@ connectedScenes=%lu",
reason,
(unsigned long)application.connectedScenes.count]);
for (UIScene *scene in application.connectedScenes) {
Eagle0Log([NSString stringWithFormat:@"%@ scene=%@ state=%ld delegate=%@",
reason,
scene.session.persistentIdentifier,
(long)scene.activationState,
NSStringFromClass([scene.delegate class])]);
}
}
UIScreen *screen = [UIScreen mainScreen];
Eagle0Log([NSString stringWithFormat:@"%@ screenBounds=%@ nativeBounds=%@ scale=%.3f nativeScale=%.3f brightness=%.3f",
reason,
NSStringFromCGRect(screen.bounds),
NSStringFromCGRect(screen.nativeBounds),
screen.scale,
screen.nativeScale,
screen.brightness]);
NSArray<UIWindow *> *windows = application.windows;
for (NSUInteger i = 0; i < windows.count; i++) {
Eagle0LogWindow(windows[i], i, reason);
}
}
__attribute__((constructor))
static void Eagle0InstallLaunchDiagnostics() {
Eagle0Log(@"native constructor");
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
[center addObserverForName:UIApplicationDidFinishLaunchingNotification
object:nil
queue:[NSOperationQueue mainQueue]
usingBlock:^(__unused NSNotification *notification) {
Eagle0Log(@"UIApplicationDidFinishLaunchingNotification");
}];
[center addObserverForName:UIApplicationDidBecomeActiveNotification
object:nil
queue:[NSOperationQueue mainQueue]
usingBlock:^(__unused NSNotification *notification) {
Eagle0Log(@"UIApplicationDidBecomeActiveNotification");
}];
[center addObserverForName:UIApplicationDidEnterBackgroundNotification
object:nil
queue:[NSOperationQueue mainQueue]
usingBlock:^(__unused NSNotification *notification) {
Eagle0Log(@"UIApplicationDidEnterBackgroundNotification");
}];
[center addObserverForName:UIApplicationDidBecomeActiveNotification
object:nil
queue:[NSOperationQueue mainQueue]
usingBlock:^(__unused NSNotification *notification) {
Eagle0LogApplicationState(@"didBecomeActive state dump");
}];
if (@available(iOS 13.0, *)) {
[center addObserverForName:UISceneWillEnterForegroundNotification
object:nil
queue:[NSOperationQueue mainQueue]
usingBlock:^(__unused NSNotification *notification) {
Eagle0Log(@"UISceneWillEnterForegroundNotification");
}];
[center addObserverForName:UISceneDidActivateNotification
object:nil
queue:[NSOperationQueue mainQueue]
usingBlock:^(__unused NSNotification *notification) {
Eagle0Log(@"UISceneDidActivateNotification");
Eagle0LogApplicationState(@"sceneDidActivate state dump");
}];
}
dispatch_async(dispatch_get_main_queue(), ^{
Eagle0LogApplicationState(@"constructor async state dump");
});
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)),
dispatch_get_main_queue(), ^{
Eagle0LogApplicationState(@"constructor +1s state dump");
});
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)),
dispatch_get_main_queue(), ^{
Eagle0LogApplicationState(@"constructor +3s state dump");
});
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)),
dispatch_get_main_queue(), ^{
Eagle0LogApplicationState(@"constructor +5s state dump");
});
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(10 * NSEC_PER_SEC)),
dispatch_get_main_queue(), ^{
Eagle0LogApplicationState(@"constructor +10s state dump");
});
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(20 * NSEC_PER_SEC)),
dispatch_get_main_queue(), ^{
Eagle0LogApplicationState(@"constructor +20s state dump");
});
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: a50bb990d8595476db94c5f937032712
@@ -11291,7 +11291,7 @@ RectTransform:
m_GameObject: {fileID: 1124833187}
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_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 1113003747}
@@ -45525,7 +45525,7 @@ RectTransform:
m_GameObject: {fileID: 333844760}
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_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 424602577}
@@ -8146,7 +8146,7 @@ RectTransform:
m_GameObject: {fileID: 789446545}
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_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 898871943}
@@ -12990,7 +12990,7 @@ RectTransform:
m_GameObject: {fileID: 1121876563}
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_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 1901323898}
@@ -17896,7 +17896,7 @@ RectTransform:
m_GameObject: {fileID: 1579523265}
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_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 2077202251}
@@ -19970,7 +19970,7 @@ RectTransform:
m_GameObject: {fileID: 1700355199}
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_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 1750698845}
@@ -74,7 +74,6 @@ MonoBehaviour:
m_MixedLightingSupported: 1
m_SupportsLightCookies: 1
m_SupportsLightLayers: 0
m_DebugLevel: 0
m_StoreActionsOptimization: 0
m_UseAdaptivePerformance: 1
m_ColorGradingMode: 0
@@ -100,43 +99,43 @@ MonoBehaviour:
obsoleteHasProbeVolumes:
m_Keys: []
m_Values:
m_PrefilteringModeMainLightShadows: 1
m_PrefilteringModeAdditionalLight: 4
m_PrefilteringModeAdditionalLightShadows: 1
m_PrefilterXRKeywords: 0
m_PrefilteringModeForwardPlus: 1
m_PrefilteringModeDeferredRendering: 1
m_PrefilteringModeScreenSpaceOcclusion: 1
m_PrefilterDebugKeywords: 0
m_PrefilterWriteRenderingLayers: 0
m_PrefilterHDROutput: 0
m_PrefilterAlphaOutput: 0
m_PrefilterSSAODepthNormals: 0
m_PrefilterSSAOSourceDepthLow: 0
m_PrefilterSSAOSourceDepthMedium: 0
m_PrefilterSSAOSourceDepthHigh: 0
m_PrefilterSSAOInterleaved: 0
m_PrefilterSSAOBlueNoise: 0
m_PrefilterSSAOSampleCountLow: 0
m_PrefilterSSAOSampleCountMedium: 0
m_PrefilterSSAOSampleCountHigh: 0
m_PrefilterDBufferMRT1: 0
m_PrefilterDBufferMRT2: 0
m_PrefilterDBufferMRT3: 0
m_PrefilterSoftShadowsQualityLow: 0
m_PrefilterSoftShadowsQualityMedium: 0
m_PrefilterSoftShadowsQualityHigh: 0
m_PrefilteringModeMainLightShadows: 3
m_PrefilteringModeAdditionalLight: 3
m_PrefilteringModeAdditionalLightShadows: 0
m_PrefilterXRKeywords: 1
m_PrefilteringModeForwardPlus: 0
m_PrefilteringModeDeferredRendering: 0
m_PrefilteringModeScreenSpaceOcclusion: 0
m_PrefilterDebugKeywords: 1
m_PrefilterWriteRenderingLayers: 1
m_PrefilterHDROutput: 1
m_PrefilterAlphaOutput: 1
m_PrefilterSSAODepthNormals: 1
m_PrefilterSSAOSourceDepthLow: 1
m_PrefilterSSAOSourceDepthMedium: 1
m_PrefilterSSAOSourceDepthHigh: 1
m_PrefilterSSAOInterleaved: 1
m_PrefilterSSAOBlueNoise: 1
m_PrefilterSSAOSampleCountLow: 1
m_PrefilterSSAOSampleCountMedium: 1
m_PrefilterSSAOSampleCountHigh: 1
m_PrefilterDBufferMRT1: 1
m_PrefilterDBufferMRT2: 1
m_PrefilterDBufferMRT3: 1
m_PrefilterSoftShadowsQualityLow: 1
m_PrefilterSoftShadowsQualityMedium: 1
m_PrefilterSoftShadowsQualityHigh: 1
m_PrefilterSoftShadows: 0
m_PrefilterScreenCoord: 0
m_PrefilterScreenSpaceIrradiance: 0
m_PrefilterNativeRenderPass: 0
m_PrefilterScreenCoord: 1
m_PrefilterScreenSpaceIrradiance: 1
m_PrefilterNativeRenderPass: 1
m_PrefilterUseLegacyLightmaps: 0
m_PrefilterBicubicLightmapSampling: 0
m_PrefilterBicubicLightmapSampling: 1
m_PrefilterReflectionProbeRotation: 0
m_PrefilterReflectionProbeBlending: 0
m_PrefilterReflectionProbeBoxProjection: 0
m_PrefilterReflectionProbeAtlas: 0
m_PrefilterPointSamplingUpsampling: 0
m_PrefilterReflectionProbeBlending: 1
m_PrefilterReflectionProbeBoxProjection: 1
m_PrefilterReflectionProbeAtlas: 1
m_PrefilterPointSamplingUpsampling: 1
m_ShaderVariantLogLevel: 0
m_ShadowCascades: 0
m_Textures:
@@ -68,7 +68,20 @@ MonoBehaviour:
- rid: 8550040182798417953
- rid: 8550040182798417954
m_RuntimeSettings:
m_List: []
m_List:
- rid: 8550040182798417924
- rid: 8550040182798417929
- rid: 8550040182798417930
- rid: 8550040182798417931
- rid: 8550040182798417933
- rid: 8550040182798417934
- rid: 8550040182798417936
- rid: 8550040182798417939
- rid: 8550040182798417942
- rid: 8550040182798417945
- rid: 8550040182798417946
- rid: 8550040182798417949
- rid: 8550040182798417952
m_AssetVersion: 10
m_ObsoleteDefaultVolumeProfile: {fileID: 0}
m_RenderingLayerNames:
@@ -47,6 +47,15 @@ GraphicsSettings:
- {fileID: 4800000, guid: 0406db5a14f94604a8c57ccfbc9f3b46, type: 3}
m_PreloadedShaders: []
m_PreloadShadersBatchTimeLimit: -1
m_GraphicsStateCollection: {fileID: 0}
m_CollectionStartupAction: 0
m_TraceSavePath: TracedCollection
m_TraceSendToEditor: 1
m_AdditionalWarmupCollections: []
m_WarmupAsync: 1
m_EnableCacheMissTracing: 0
m_WarmupProgressivelyLimit: -1
m_CacheMissCollectionPath: CacheMissCollection
m_SpritesDefaultMaterial: {fileID: 10754, guid: 0000000000000000f000000000000000,
type: 0}
m_CustomRenderPipeline: {fileID: 11400000, guid: fb010f72d164b4ab08ce7d5a889c2d54,
@@ -109,6 +118,8 @@ GraphicsSettings:
type: 2}
m_ShaderBuildSettings:
keywordDeclarationOverrides: []
numInternalDefines: 0
defines: []
m_LightsUseLinearIntensity: 0
m_LightsUseColorTemperature: 1
m_LogWhenShaderIsCompiled: 0
@@ -3,7 +3,7 @@
--- !u!129 &1
PlayerSettings:
m_ObjectHideFlags: 0
serializedVersion: 28
serializedVersion: 29
productGUID: 3506591d5c717d84b84696960944eb8b
AndroidProfiler: 0
AndroidFilterTouchesWhenObscured: 0
@@ -43,7 +43,6 @@ PlayerSettings:
- logo: {fileID: 21300000, guid: 7dbcf0ac797c34eb0b03d1c5aef66bb1, type: 3}
duration: 2
m_VirtualRealitySplashScreen: {fileID: 0}
m_HolographicTrackingLossScreen: {fileID: 0}
defaultScreenWidth: 1024
defaultScreenHeight: 768
defaultScreenWidthWeb: 960
@@ -68,10 +67,15 @@ PlayerSettings:
useOSAutorotation: 1
use32BitDisplayBuffer: 1
preserveFramebufferAlpha: 0
adjustIOSFPSUsingThermalState: 1
thermalStateSeriousIOSFPS: 30
thermalStateCriticalIOSFPS: 15
disableDepthAndStencilBuffers: 0
androidStartInFullscreen: 1
androidRenderOutsideSafeArea: 0
androidUseSwappy: 0
androidRequestedVisibleInsets: 1
androidSystemBarsBehavior: 2
androidDisplayOptions: 1
androidBlitType: 0
androidResizeableActivity: 0
@@ -115,7 +119,8 @@ PlayerSettings:
xboxEnableHeadOrientation: 0
xboxEnableGuest: 0
xboxEnablePIXSampling: 0
metalFramebufferOnly: 1
metalFramebufferOnly: 0
metalUseMetalDisplayLink: 0
xboxOneResolution: 0
xboxOneSResolution: 0
xboxOneXResolution: 3
@@ -149,12 +154,10 @@ PlayerSettings:
preloadedAssets: []
metroInputSource: 0
wsaTransparentSwapchain: 0
m_HolographicPauseOnTrackingLoss: 1
xboxOneDisableKinectGpuReservation: 0
xboxOneEnable7thCore: 0
vrSettings:
enable360StereoCapture: 0
isWsaHolographicRemotingEnabled: 0
enableFrameTimingStats: 0
enableOpenGLProfilerGPURecorders: 1
allowHDRDisplaySupport: 0
@@ -177,7 +180,7 @@ PlayerSettings:
tvOS: 0
overrideDefaultApplicationIdentifier: 1
AndroidBundleVersionCode: 1
AndroidMinSdkVersion: 25
AndroidMinSdkVersion: 26
AndroidTargetSdkVersion: 0
AndroidPreferredInstallLocation: 1
AndroidPreferredDataLocation: 1
@@ -202,6 +205,7 @@ PlayerSettings:
tvOSTargetOSVersionString: 15.0
VisionOSSdkVersion: 0
VisionOSTargetOSVersionString: 1.0
xcodeProjectType: 0
uIPrerenderedIcon: 0
uIRequiresPersistentWiFi: 0
uIRequiresFullScreen: 1
@@ -271,7 +275,6 @@ PlayerSettings:
useCustomGradleSettingsTemplate: 0
useCustomProguardFile: 0
AndroidTargetArchitectures: 5
AndroidAllowedArchitectures: -1
AndroidSplashScreenScale: 0
androidSplashScreen: {fileID: 0}
AndroidKeystoreName: '{inproject}: '
@@ -405,7 +408,10 @@ PlayerSettings:
m_Height: 1024
m_Kind: 4
m_SubKind: App Store
m_BuildTargetBatching: []
m_BuildTargetBatching:
- m_BuildTarget: iPhone
m_StaticBatching: 1
m_DynamicBatching: 0
m_BuildTargetShaderSettings: []
m_BuildTargetGraphicsJobs:
- m_BuildTarget: MacStandaloneSupport
@@ -449,7 +455,6 @@ PlayerSettings:
- m_BuildTarget: AndroidPlayer
m_APIs: 0b000000
m_Automatic: 0
m_BuildTargetVRSettings: []
m_DefaultShaderChunkSizeInMB: 16
m_DefaultShaderChunkCount: 0
openGLRequireES31: 0
@@ -644,6 +649,8 @@ PlayerSettings:
switchMicroSleepForYieldTime: 25
switchRamDiskSpaceSize: 12
switchUpgradedPlayerSettingsToNMETA: 0
switchCaStoreSource: 0
switchCaStoreFilePath:
ps4NPAgeRating: 12
ps4NPTitleSecret:
ps4NPTrophyPackPath:
@@ -775,6 +782,7 @@ PlayerSettings:
Standalone: 1
il2cppCompilerConfiguration: {}
il2cppCodeGeneration: {}
il2cppLTOMode: {}
il2cppStacktraceInformation: {}
managedStrippingLevel:
EmbeddedLinux: 1
@@ -861,7 +869,6 @@ PlayerSettings:
XboxOneXTitleMemory: 8
XboxOneOverrideIdentityName:
XboxOneOverrideIdentityPublisher:
vrEditorSettings: {}
cloudServicesEnabled:
UNet: 1
luminIcon:
@@ -885,6 +892,7 @@ PlayerSettings:
captureStartupLogs: {}
activeInputHandler: 1
windowsGamepadBackendHint: 0
enableDirectStorage: 0
cloudProjectId: 34326edd-6b91-4774-9c79-e04218c750da
framebufferDepthMemorylessMode: 0
qualitySettingsNames: []