diff --git a/AGENTS.md b/AGENTS.md index bba26ec9..8ed3dfbd 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,82 +1,100 @@ -# AGENTS GUIDE — Assets/AirConsole Focus - -The `airconsole-unity-plugin` project targets Unity 2022.3.x and ships the full AirConsole runtime, editor tooling, Android TV helpers, and WebGL controller templates. This guide is tailored to the contents under `Assets/AirConsole`. - -## What Lives in Assets/AirConsole - -- `scripts/Runtime`: Core API surface (`AirConsole.cs`), websocket/webview bridges (`WebsocketListener.cs`, `WebViewManager.cs`), runtime settings (`Settings.cs`, `AirconsoleRuntimeSettings.cs`, `NativeGameSizingSettings.cs`), logging (`AirConsoleLogger.cs`, `DebugLevel.cs`), platform runtime configurators, and Android plugin wrappers under `Runtime/Plugin/Android`. -- `scripts/Editor`: Custom inspectors/windows (`Inspector.cs`, `SettingWindow.cs`, `PlayMode.cs`, `SafeAreaTester.cs`, `WebListener.cs`), build automation (`BuildAutomation/*`), project maintenance checks (`ProjectMaintenance/*`), and plugin developer helpers (`PluginDevelopment/*`). -- `scripts/SupportCheck`: Unity version/platform validator ASMDEF used in-editor. -- `scripts/Tests`: ASMDEF-scoped EditMode, PlayMode, and Editor tests. -- `examples`: Sample scenes (`basic`, `pong`, `platformer`, `swipe`, `game-states`, `safe-area`, `translations`) for manual validation. -- `extras`: Controller template HTML and `HighScoreHelper.cs`. -- `plugins`: Managed dependencies (`Newtonsoft.Json.dll`, `websocket-sharp.dll`) plus Android native plugin payload under `plugins/Android`. -- `unity-webview`: Embedded WebView plugin with runtime/editor asmdefs and native binaries under `Plugins`. -- `unity-webview` is an imported external dependency. You are not allowed to alter it. -- Docs and misc: `Documentation_1.7.pdf`, `Documentation for AndroidTV.pdf`, `Upgrade_Plugin_Version.md`, `README.txt`, `airconsole.prefs`, and the distributable `airconsole-code.unitypackage`. - -## Runtime Essentials - -- **API + bridge**: `AirConsole.cs` exposes the public API; `WebsocketListener` routes JSON actions/events; `WebViewManager` coordinates the embedded webview. Add new events in both the listener and the API surface. -- **Config assets**: `AirconsoleRuntimeSettings.asset` and `NativeGameSizingSettings.asset` (in `scripts/Runtime/Resources`) hold defaults for ports, safe-area sizing, etc. Adjust via the editor UI instead of hardcoding. -- **Platform setup**: Implementations of `IRuntimeConfigurator` (`AndroidRuntimeConfigurator`, `WebGLRuntimeConfigurator`, `EditorRuntimeConfigurator`) handle platform-specific initialization. Extend these rather than branching deep in the API. -- **Android plugin wrappers**: `PluginManager`, `AndroidUnityUtils`, and callback helpers (`UnityPluginExecutionCallback`, `UnityPluginStringCallback`, `GenericUnityPluginCallback`, `UnityAndroidObjectProvider`) encapsulate Java bridge calls. Keep new native hooks consistent with these wrappers. -- **Logging & diagnostics**: Use `AirConsoleLogger` with `DebugLevel` enums to respect runtime debug settings. - -## Editor & Build Tooling - -- **UI/inspectors**: `SettingWindow`, `Inspector`, `PlayMode`, `SafeAreaTester`, and `WebListener` provide editor UI and simulator hooks. Prefer extending these instead of adding ad-hoc windows. -- **Build automation** (`scripts/Editor/BuildAutomation`): - - `PreBuildProcessing` and `PostBuildProcess` wrap pre/post hooks; post steps validate WebGL template AirConsole JS versions. - - `AndroidManifestProcessor`, `AndroidGradleProcessor`, `AndroidProjectProcessor`, `AndroidManifest`, and `AndroidXMLDocument` mutate generated Android projects/manifests. Use these helpers instead of manual IO. -- **Project maintenance** (`ProjectMaintenance`): `ProjectDependencyCheck`, `SemVerCheck`, and `ProjectConfigurationCheck` enforce Unity version and project settings; `ProjectPreferenceManager/ProjectPreferences` manage stored preferences; `ProjectUpgradeEditor` supports upgrade flows. -- **Plugin development helpers** (`PluginDevelopment`): `BuildHelper` hosts build/packaging entry points (Web/Android) and can auto-zip or auto-commit; `DevelopmentTools` includes additional packager utilities. - -## Tests, Samples, Validation - -- Tests live under `scripts/Tests` (EditMode/PlayMode/Editor asmdefs). Run via Unity Test Runner; some PlayMode tests expect Android as the active build target. -- Manual checks: leverage sample scenes in `examples` to verify controller flows, safe-area behavior, translations, and Android TV input. -- WebGL validation: keep `PostBuildProcess` version checks aligned with the AirConsole JS used in `Assets/WebGLTemplates/AirConsole-*`. - -## Dependencies & Third-Party - -- Managed DLLs: `Newtonsoft.Json.dll` and `websocket-sharp.dll` are under `plugins/` and referenced by runtime asmdefs. -- Embedded webview: `unity-webview` includes runtime/editor code plus native libs under `unity-webview/Plugins`. -- Android native pieces are under `plugins/Android`; ensure gradle/manifest processors remain compatible when updating them. - -## Common Workflows - -- **Add/extend an API event**: Update `WebsocketListener` to parse/route the action, expose it in `AirConsole`, and wire through logging; add tests where possible. -- **Adjust runtime defaults**: Modify `AirconsoleRuntimeSettings.asset` or `NativeGameSizingSettings.asset` (via editor windows). Avoid hardcoded constants in code. -- **Android manifest/Gradle edits**: Implement changes in `AndroidManifestProcessor`/`AndroidGradleProcessor`/`AndroidProjectProcessor`; ensure `useCustomMainManifest` stays enabled. -- **WebGL template/JS version bumps**: Update constants/regex in `PostBuildProcess`, refresh `Settings.RequiredMinimumVersion` if needed, and sync HTML in `Assets/WebGLTemplates/AirConsole-*`. -- **Packaging/exports**: Use `BuildHelper.BuildWeb()`, `BuildHelper.BuildAndroid()`, or `BuildHelper.BuildAndroidInternal()`; they run configuration checks and can zip outputs. - -## Guardrails & Gotchas - -- Conditional compilation is heavily used: `#if !DISABLE_AIRCONSOLE`, `UNITY_ANDROID`, `UNITY_EDITOR`, `UNITY_WEBGL`. Keep new code behind appropriate defines and asmdefs. -- Respect asmdef boundaries (`AirConsole.Runtime`, `AirConsole.Editor`, `AirConsole.SupportCheck`, `AirConsole.Examples`, `unity-webview`); place new files in matching folders. -- Embedded websocket/webview server underpins editor play; avoid breaking `WebsocketListener`/`WebViewManager` interactions (ports come from runtime settings). -- Safe-area handling is central for Android TV/Automotive—maintain `OnSafeAreaChanged` flows and avoid state changes before safe-area readiness. -- Build helper may auto-commit with `build: TIMESTAMP` when uncommitted changes exist; be mindful when running locally. - -## Event Queue Architecture (Thread-Safe Callbacks) - -The WebView plugin uses a thread-safe event queue to handle callbacks from native code (Android only at this point): - -### Event Processing Lifecycle - -Events are processed at multiple points to ensure timely delivery: - -1. **`Update()`**: Primary drain point (every frame) -2. **`LateUpdate()`**: Secondary drain (end of frame) -3. **`FixedUpdate()`**: Tertiary drain (physics frame / fixed timestep / before rendering) -4. **`OnApplicationPause(false)`**: Flush on resume -5. **`OnDisable()`**: Flush before component teardown -6. **`OnApplicationQuit()`**: Final flush before app exit - -## Additional References - -- `Documentation_1.7.pdf` (setup/examples), `Documentation for AndroidTV.pdf`, and `Upgrade_Plugin_Version.md` for upgrade flows. -- Controller HTML template: `extras/controller-template.html`. -- Quick intro: `Assets/AirConsole/README.txt`; preferences file `airconsole.prefs`. +# airconsole-unity-plugin +## OVERVIEW +AirConsole SDK for Unity. +C# wrapper around the AirConsole browser API. +Android native bridge for Android builds. +WebGL JavaScript generation for browser builds. +Main targets: Android and WebGL. +Bridge languages: C#, Java or Kotlin, JavaScript. +Two message patterns exist. +Old pattern: polling through `GetMessage()`. +New pattern: queue based event delivery. +Prefer queue based delivery for new Android bridge behavior. +## ENTRY POINT +Main SDK entry: `Assets/AirConsole/scripts/Runtime/AirConsole.cs`. +`AirConsole.cs` owns the singleton. +The singleton is the main public API surface. +Unity scenes call this API for connection state, messages, device data, and platform actions. +Android bridge entry uses `AndroidJavaProxy`. +Native callbacks enter Unity through proxy handlers. +WebGL entry uses generated JavaScript. +Generated JS exposes the runtime browser interface for Unity WebGL builds. +## ARCHITECTURE +Old Android message path: +1. Native side stores incoming messages. +2. Unity polls with `GetMessage()`. +3. `UnitySendMessageDispatcher` forwards payloads into Unity. +4. C# parses payloads and raises SDK callbacks. +New Android message path: +1. Native side calls an `AndroidJavaProxy` callback. +2. Proxy receives payloads off the Unity main thread. +3. Proxy writes work items into a `ConcurrentQueue`. +4. Unity main thread drains the queue. +5. SDK events fire during main thread processing. +WebGL message path: +1. Build postprocess generates JS from C# reflection. +2. Runtime JS binds Unity calls to AirConsole browser API calls. +3. Browser callbacks route back into Unity. +## ANDROID BRIDGE +Android bridge code lives under `Assets/AirConsole/plugins/Android/`. +`PluginManager` initializes native bridge state. +`PluginManager` connects Unity runtime and Android plugin code. +`AndroidJavaProxy` handles messages from native code. +Proxy handlers must stay small. +Proxy handlers must not call Unity APIs directly from background threads. +Use the main thread queue for message delivery. +Use `ConcurrentQueue` for thread safe handoff. +Drain queued actions or messages from Unity main thread update flow. +Preserve payload shape when moving between native and C#. +## WEBGL EXPORT +Build postprocess generates `airconsole-unity-plugin.js`. +Generation uses C# reflection. +Generated JS mirrors the callable SDK surface needed by WebGL builds. +Runtime JS interface talks to the AirConsole browser API. +Unity WebGL calls route through generated JS functions. +Browser events route back into Unity objects. +Change the generator or C# source instead of hand editing generated JS. +## STRUCTURE +`Assets/AirConsole/` contains the main SDK. +`Assets/AirConsole/scripts/Runtime/AirConsole.cs` contains the singleton and main public API. +`Assets/AirConsole/plugins/Android/` contains native bridge code and Android plugin assets. +`Assets/AirConsole/scripts/Editor/` contains editor tooling and build postprocessing. +`Assets/AirConsole/scripts/Editor/BuildAutomation/` is the build generation area. +Sample scenes live under the AirConsole assets tree. +## WHERE TO LOOK +Main SDK: `Assets/AirConsole/scripts/Runtime/AirConsole.cs`. +Android bridge: `Assets/AirConsole/plugins/Android/`. +Build generation: `Assets/AirConsole/scripts/Editor/BuildAutomation/`. +Generated WebGL interface and sample integration: `airconsole-unity-plugin.js`, sample scenes. +## BUILD POSTPROCESSING +Unity build postprocess auto runs after supported builds. +It generates Android manifests when needed. +It handles AndroidX setup. +It copies Android AAR files into the build output. +It links iOS frameworks for supported exports. +It generates WebGL JavaScript interface files. +It can export `.unitypackage` distribution packages. +## TESTING +Automated tests are limited. +Use Unity Test Runner when relevant. +Most confidence comes from integration testing. +Run sample scenes for message flow checks. +Test Android bridge behavior on Android builds. +Test WebGL behavior in exported WebGL builds. +Verify old polling behavior when touching legacy paths. +Verify queue based behavior when touching new bridge paths. +## EXPORTS +Distribution output is a `.unitypackage`. +The package includes AirConsole `Assets` and all required `Plugins` content. +The package must include Android bridge assets and WebGL runtime generation support. +## COMMANDS +Unity build: run from Unity Editor or configured Unity batchmode build. +PostprocessBuild auto runs during Unity build. +Export package: use Unity export package workflow for `.unitypackage`. +Run tests: use Unity Test Runner for EditMode and PlayMode suites. +## FORBIDDEN +NEVER hardcode device IDs. +NO platform specific code outside `plugins/`. +Do not bypass the main thread queue for Android callbacks. +Do not call Unity APIs directly from Android background callbacks. +Do not edit generated WebGL JS when generator changes are required. diff --git a/Assets/AirConsole/AGENTS.md b/Assets/AirConsole/AGENTS.md new file mode 100644 index 00000000..e8103c4f --- /dev/null +++ b/Assets/AirConsole/AGENTS.md @@ -0,0 +1,26 @@ +# Assets/AirConsole + +This subtree contains the shipped Unity runtime, editor tooling, examples, and native wrappers. + +## Local Focus Areas + +- Runtime API and bridges: `scripts/Runtime/` +- Editor tooling and build processors: `scripts/Editor/` +- Automated tests: `scripts/Tests/` +- Examples and manual smoke scenes: `examples/` + +## Local Invariants + +- Extend platform-specific behavior through the existing configurators and Android wrapper classes instead of scattering `#if UNITY_*` checks. +- Keep asmdef boundaries intact (`AirConsole.Runtime`, `AirConsole.Editor`, `AirConsole.SupportCheck`, examples/tests). +- Preserve safe-area and main-thread callback behavior when touching Android or WebView flows. +- Treat `unity-webview/` as vendored unless the task explicitly belongs there. + +## Common Checks + +- Add matching runtime/editor tests where feasible. +- For manifest or Gradle output changes, use the existing build processors in `scripts/Editor/BuildAutomation/`. + +## Learnings + +- _None yet._ diff --git a/Assets/AirConsole/AGENTS.md.meta b/Assets/AirConsole/AGENTS.md.meta new file mode 100644 index 00000000..88282192 --- /dev/null +++ b/Assets/AirConsole/AGENTS.md.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 1e07dd5d100a14e25911f3b3990b5e78 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/AirConsole/examples/AirConsole.Examples.asmdef b/Assets/AirConsole/examples/AirConsole.Examples.asmdef index 48fa51e6..b8c0d637 100644 --- a/Assets/AirConsole/examples/AirConsole.Examples.asmdef +++ b/Assets/AirConsole/examples/AirConsole.Examples.asmdef @@ -1,24 +1,25 @@ { - "name": "AirConsole.Examples", - "rootNamespace": "NDream.AirConsole.Examples", - "references": [ - "AirConsole.Runtime" - ], - "includePlatforms": [ - "Android", - "Editor", - "WebGL" - ], - "excludePlatforms": [], - "allowUnsafeCode": false, - "overrideReferences": true, - "precompiledReferences": [ - "Newtonsoft.Json.dll" - ], - "autoReferenced": true, - "defineConstraints": [ - "UNITY_2022_3_OR_NEWER" - ], - "versionDefines": [], - "noEngineReferences": false + "name": "AirConsole.Examples", + "rootNamespace": "NDream.AirConsole.Examples", + "references": [ + "AirConsole.Runtime", + "Unity.TextMeshPro" + ], + "includePlatforms": [ + "Android", + "Editor", + "WebGL" + ], + "excludePlatforms": [], + "allowUnsafeCode": false, + "overrideReferences": true, + "precompiledReferences": [ + "Newtonsoft.Json.dll" + ], + "autoReferenced": true, + "defineConstraints": [ + "UNITY_2022_3_OR_NEWER" + ], + "versionDefines": [], + "noEngineReferences": false } \ No newline at end of file diff --git a/Assets/AirConsole/examples/basic/controller.html b/Assets/AirConsole/examples/basic/controller.html index e4b24401..dc7dee90 100644 --- a/Assets/AirConsole/examples/basic/controller.html +++ b/Assets/AirConsole/examples/basic/controller.html @@ -2,7 +2,7 @@ - + + + + + + +
Look at the screen!
+ + diff --git a/Assets/AirConsole/examples/configuration/configuration-controller.html.meta b/Assets/AirConsole/examples/configuration/configuration-controller.html.meta new file mode 100644 index 00000000..f9816aae --- /dev/null +++ b/Assets/AirConsole/examples/configuration/configuration-controller.html.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 2c64a934739fb451987dd00162fe35f8 +timeCreated: 1437829347 +licenseType: Store +TextScriptImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/AirConsole/examples/configuration/configuration.unity b/Assets/AirConsole/examples/configuration/configuration.unity new file mode 100644 index 00000000..c2c4013b --- /dev/null +++ b/Assets/AirConsole/examples/configuration/configuration.unity @@ -0,0 +1,808 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!29 &1 +OcclusionCullingSettings: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_OcclusionBakeSettings: + smallestOccluder: 5 + smallestHole: 0.25 + backfaceThreshold: 100 + m_SceneGUID: 00000000000000000000000000000000 + m_OcclusionCullingData: {fileID: 0} +--- !u!104 &2 +RenderSettings: + m_ObjectHideFlags: 0 + serializedVersion: 9 + m_Fog: 0 + m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} + m_FogMode: 3 + m_FogDensity: 0.01 + m_LinearFogStart: 0 + m_LinearFogEnd: 300 + m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} + m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} + m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} + m_AmbientIntensity: 1 + m_AmbientMode: 3 + m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} + m_SkyboxMaterial: {fileID: 0} + m_HaloStrength: 0.5 + m_FlareStrength: 1 + m_FlareFadeSpeed: 3 + m_HaloTexture: {fileID: 0} + m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} + m_DefaultReflectionMode: 0 + m_DefaultReflectionResolution: 128 + m_ReflectionBounces: 1 + m_ReflectionIntensity: 1 + m_CustomReflection: {fileID: 0} + m_Sun: {fileID: 0} + m_UseRadianceAmbientProbe: 0 +--- !u!157 &4 +LightmapSettings: + m_ObjectHideFlags: 0 + serializedVersion: 12 + m_GIWorkflowMode: 1 + m_GISettings: + serializedVersion: 2 + m_BounceScale: 1 + m_IndirectOutputScale: 1 + m_AlbedoBoost: 1 + m_EnvironmentLightingMode: 0 + m_EnableBakedLightmaps: 0 + m_EnableRealtimeLightmaps: 0 + m_LightmapEditorSettings: + serializedVersion: 12 + m_Resolution: 2 + m_BakeResolution: 40 + m_AtlasSize: 1024 + m_AO: 0 + m_AOMaxDistance: 1 + m_CompAOExponent: 0 + m_CompAOExponentDirect: 0 + m_ExtractAmbientOcclusion: 0 + m_Padding: 2 + m_LightmapParameters: {fileID: 0} + m_LightmapsBakeMode: 1 + m_TextureCompression: 1 + m_FinalGather: 0 + m_FinalGatherFiltering: 1 + m_FinalGatherRayCount: 1024 + m_ReflectionCompression: 2 + m_MixedBakeMode: 1 + m_BakeBackend: 0 + m_PVRSampling: 1 + m_PVRDirectSampleCount: 32 + m_PVRSampleCount: 500 + m_PVRBounces: 2 + m_PVREnvironmentSampleCount: 500 + m_PVREnvironmentReferencePointCount: 2048 + m_PVRFilteringMode: 2 + m_PVRDenoiserTypeDirect: 0 + m_PVRDenoiserTypeIndirect: 0 + m_PVRDenoiserTypeAO: 0 + m_PVRFilterTypeDirect: 0 + m_PVRFilterTypeIndirect: 0 + m_PVRFilterTypeAO: 0 + m_PVREnvironmentMIS: 0 + m_PVRCulling: 1 + m_PVRFilteringGaussRadiusDirect: 1 + m_PVRFilteringGaussRadiusIndirect: 5 + m_PVRFilteringGaussRadiusAO: 2 + m_PVRFilteringAtrousPositionSigmaDirect: 0.5 + m_PVRFilteringAtrousPositionSigmaIndirect: 2 + m_PVRFilteringAtrousPositionSigmaAO: 1 + m_ExportTrainingData: 0 + m_TrainingDataDestination: TrainingData + m_LightProbeSampleCountMultiplier: 4 + m_LightingDataAsset: {fileID: 0} + m_LightingSettings: {fileID: 0} +--- !u!196 &5 +NavMeshSettings: + serializedVersion: 2 + m_ObjectHideFlags: 0 + m_BuildSettings: + serializedVersion: 3 + agentTypeID: 0 + agentRadius: 0.5 + agentHeight: 2 + agentSlope: 45 + agentClimb: 0.4 + ledgeDropHeight: 0 + maxJumpAcrossDistance: 0 + minRegionArea: 2 + manualCellSize: 0 + cellSize: 0.16666667 + manualTileSize: 0 + tileSize: 256 + buildHeightMesh: 0 + maxJobWorkers: 0 + preserveTilesOutsideBounds: 0 + debug: + m_Flags: 0 + m_NavMeshData: {fileID: 0} +--- !u!1 &702535399 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 702535401} + - component: {fileID: 702535402} + m_Layer: 0 + m_Name: Logic + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &702535401 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 702535399} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &702535402 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 702535399} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 1d0351a4bff3410fbf54067d3ca4a69d, type: 3} + m_Name: + m_EditorClassIdentifier: + logWindow: {fileID: 1591857828} +--- !u!1 &841124340 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 841124342} + - component: {fileID: 841124341} + - component: {fileID: 841124343} + m_Layer: 0 + m_Name: AirConsole + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &841124341 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 841124340} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: e37d83ebce05ad74683fd3228dde9e7d, type: 3} + m_Name: + m_EditorClassIdentifier: + controllerHtml: {fileID: 4900000, guid: 2c64a934739fb451987dd00162fe35f8, type: 3} + autoScaleCanvas: 1 + androidGameVersion: 2025-10-14-07-07-52 + androidUIResizeMode: 0 + webViewLoadingSprite: {fileID: 0} + nativeGameSizingSupported: 0 + browserStartMode: 0 + devGameId: com.airconsole.plugin.unity + devLanguage: + LocalIpOverride: +--- !u!4 &841124342 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 841124340} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &841124343 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 841124340} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f8eacf087b9954b9bab975cd1a0e968c, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!1 &1158769760 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1158769765} + - component: {fileID: 1158769764} + - component: {fileID: 1158769762} + - component: {fileID: 1158769761} + - component: {fileID: 1158769766} + m_Layer: 0 + m_Name: Main Camera + m_TagString: MainCamera + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!81 &1158769761 +AudioListener: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1158769760} + m_Enabled: 1 +--- !u!124 &1158769762 +Behaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1158769760} + m_Enabled: 1 +--- !u!20 &1158769764 +Camera: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1158769760} + m_Enabled: 1 + serializedVersion: 2 + m_ClearFlags: 1 + m_BackGroundColor: {r: 0.18039216, g: 0.18039216, b: 0.18039216, a: 1} + 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_NormalizedViewPortRect: + serializedVersion: 2 + x: 0 + y: 0 + width: 1 + height: 1 + near clip plane: 0 + far clip plane: 1000 + field of view: 60 + orthographic: 1 + orthographic size: 5 + m_Depth: -1 + m_CullingMask: + serializedVersion: 2 + m_Bits: 4294967295 + m_RenderingPath: -1 + m_TargetTexture: {fileID: 0} + m_TargetDisplay: 0 + m_TargetEye: 3 + m_HDR: 0 + m_AllowMSAA: 1 + m_AllowDynamicResolution: 0 + m_ForceIntoRT: 0 + m_OcclusionCulling: 1 + m_StereoConvergence: 10 + m_StereoSeparation: 0.022 +--- !u!4 &1158769765 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1158769760} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: -10} + m_LocalScale: {x: 0.72806513, y: 0.72806513, z: 0.72806513} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &1158769766 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1158769760} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: a1b5c6dd8de3e4b4fafb3c384af7e1d2, type: 3} + m_Name: + m_EditorClassIdentifier: + targetCamera: {fileID: 1158769764} +--- !u!1 &1179297375 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1179297379} + - component: {fileID: 1179297378} + - component: {fileID: 1179297377} + - component: {fileID: 1179297376} + m_Layer: 0 + m_Name: EventSystem + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1179297376 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1179297375} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 2d49b7c1bcd2e07499844da127be038d, type: 3} + m_Name: + m_EditorClassIdentifier: + m_SendPointerHoverToParent: 1 + m_ForceModuleActive: 0 +--- !u!114 &1179297377 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1179297375} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4f231c4fb786f3946a6b90b886c48677, type: 3} + m_Name: + m_EditorClassIdentifier: + m_SendPointerHoverToParent: 1 + m_HorizontalAxis: Horizontal + m_VerticalAxis: Vertical + m_SubmitButton: Submit + m_CancelButton: Cancel + m_InputActionsPerSecond: 10 + m_RepeatDelay: 0.5 + m_ForceModuleActive: 0 +--- !u!114 &1179297378 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1179297375} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 76c392e42b5098c458856cdf6ecaaaa1, type: 3} + m_Name: + m_EditorClassIdentifier: + m_FirstSelected: {fileID: 0} + m_sendNavigationEvents: 1 + m_DragThreshold: 5 +--- !u!4 &1179297379 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1179297375} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1506040750 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1506040753} + - component: {fileID: 1506040752} + m_Layer: 0 + m_Name: AudioPlayer + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!82 &1506040752 +AudioSource: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1506040750} + m_Enabled: 1 + serializedVersion: 4 + OutputAudioMixerGroup: {fileID: 0} + m_audioClip: {fileID: 8300000, guid: 804632e1e46684476b4ea5f752e8df15, type: 3} + m_PlayOnAwake: 1 + m_Volume: 1 + m_Pitch: 1 + Loop: 1 + Mute: 0 + Spatialize: 0 + SpatializePostEffects: 0 + Priority: 128 + DopplerLevel: 1 + MinDistance: 1 + MaxDistance: 500 + Pan2D: 0 + rolloffMode: 0 + BypassEffects: 0 + BypassListenerEffects: 0 + BypassReverbZones: 0 + rolloffCustomCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 3 + time: 0 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + weightedMode: 0 + inWeight: 0.33333334 + outWeight: 0.33333334 + - serializedVersion: 3 + time: 1 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + weightedMode: 0 + inWeight: 0.33333334 + outWeight: 0.33333334 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + panLevelCustomCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 3 + time: 0 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + weightedMode: 0 + inWeight: 0.33333334 + outWeight: 0.33333334 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + spreadCustomCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 3 + time: 0 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + weightedMode: 0 + inWeight: 0.33333334 + outWeight: 0.33333334 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + reverbZoneMixCustomCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 3 + time: 0 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + weightedMode: 0 + inWeight: 0.33333334 + outWeight: 0.33333334 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 +--- !u!4 &1506040753 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1506040750} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0.36577117, y: -0.17775297, z: 0.030780792} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1591857826 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1591857827} + - component: {fileID: 1591857829} + - component: {fileID: 1591857828} + m_Layer: 5 + m_Name: Text (TMP) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1591857827 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1591857826} + 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: 1727224451} + 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 &1591857828 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1591857826} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, 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_text: New Text + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4294967295 + m_fontColor: {r: 1, g: 1, b: 1, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 60 + m_fontSizeBase: 60 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 512 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 1 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 1 + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &1591857829 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1591857826} + m_CullTransparentMesh: 1 +--- !u!1 &1727224447 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1727224451} + - component: {fileID: 1727224450} + - component: {fileID: 1727224449} + - component: {fileID: 1727224448} + m_Layer: 5 + m_Name: Canvas + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1727224448 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1727224447} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: dc42784cf147c0c48a680349fa168899, type: 3} + m_Name: + m_EditorClassIdentifier: + m_IgnoreReversedGraphics: 1 + m_BlockingObjects: 0 + m_BlockingMask: + serializedVersion: 2 + m_Bits: 4294967295 +--- !u!114 &1727224449 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1727224447} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 0cd44c1031e13a943bb63640046fad76, type: 3} + m_Name: + m_EditorClassIdentifier: + m_UiScaleMode: 0 + m_ReferencePixelsPerUnit: 100 + m_ScaleFactor: 1 + m_ReferenceResolution: {x: 800, y: 600} + m_ScreenMatchMode: 0 + m_MatchWidthOrHeight: 0 + m_PhysicalUnit: 3 + m_FallbackScreenDPI: 96 + m_DefaultSpriteDPI: 96 + m_DynamicPixelsPerUnit: 1 + m_PresetInfoIsWorld: 0 +--- !u!223 &1727224450 +Canvas: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1727224447} + m_Enabled: 1 + serializedVersion: 3 + m_RenderMode: 0 + m_Camera: {fileID: 0} + m_PlaneDistance: 100 + m_PixelPerfect: 0 + m_ReceivesEvents: 1 + m_OverrideSorting: 0 + m_OverridePixelPerfect: 0 + m_SortingBucketNormalizedSize: 0 + m_VertexColorAlwaysGammaSpace: 0 + m_AdditionalShaderChannelsFlag: 25 + m_UpdateRectTransformForStandalone: 0 + m_SortingLayerID: 0 + m_SortingOrder: 0 + m_TargetDisplay: 0 +--- !u!224 &1727224451 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1727224447} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 0, y: 0, z: 0} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 1591857827} + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0, y: 0} +--- !u!1660057539 &9223372036854775807 +SceneRoots: + m_ObjectHideFlags: 0 + m_Roots: + - {fileID: 841124342} + - {fileID: 702535401} + - {fileID: 1158769765} + - {fileID: 1179297379} + - {fileID: 1506040753} + - {fileID: 1727224451} diff --git a/Assets/AirConsole/examples/configuration/configuration.unity.meta b/Assets/AirConsole/examples/configuration/configuration.unity.meta new file mode 100644 index 00000000..4a88cd73 --- /dev/null +++ b/Assets/AirConsole/examples/configuration/configuration.unity.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: bf34c2a42d02941118132d2cadf62b5d +timeCreated: 1435580098 +licenseType: Store +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/AirConsole/examples/game-states/controller-game-states.html b/Assets/AirConsole/examples/game-states/controller-game-states.html index d5c82e7e..fb0c97d8 100644 --- a/Assets/AirConsole/examples/game-states/controller-game-states.html +++ b/Assets/AirConsole/examples/game-states/controller-game-states.html @@ -2,7 +2,7 @@ Controller - Game states - + +