First steps with camera framing
This commit is contained in:
1
Assets/Resources/PerformanceTestRunInfo.json
Normal file
1
Assets/Resources/PerformanceTestRunInfo.json
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{"TestSuite":"","Date":0,"Player":{"Development":false,"ScreenWidth":0,"ScreenHeight":0,"ScreenRefreshRate":0,"Fullscreen":false,"Vsync":0,"AntiAliasing":0,"Batchmode":false,"RenderThreadingMode":"MultiThreaded","GpuSkinning":false,"Platform":"","ColorSpace":"","AnisotropicFiltering":"","BlendWeights":"","GraphicsApi":"","ScriptingBackend":"IL2CPP","AndroidTargetSdkVersion":"AndroidApiLevelAuto","AndroidBuildSystem":"Gradle","BuildTarget":"Android","StereoRenderingPath":"MultiPass"},"Hardware":{"OperatingSystem":"","DeviceModel":"","DeviceName":"","ProcessorType":"","ProcessorCount":0,"GraphicsDeviceName":"","SystemMemorySizeMB":0},"Editor":{"Version":"6000.2.6f1","Branch":"6000.2/staging","Changeset":"cc51a95c0300","Date":1758053328},"Dependencies":["com.unity.2d.sprite@1.0.0","com.unity.2d.spriteshape@12.0.1","com.unity.addressables@2.7.3","com.unity.addressables.android@1.0.7","com.unity.cinemachine@3.1.4","com.unity.device-simulator.devices@1.0.0","com.unity.feature.2d@2.0.1","com.unity.film-internal-utilities@0.18.4-preview","com.unity.graphtoolkit@0.4.0-exp.2","com.unity.ide.rider@3.0.38","com.unity.ide.visualstudio@2.0.23","com.unity.inputsystem@1.14.2","com.unity.multiplayer.center@1.0.0","com.unity.render-pipelines.universal@17.2.0","com.unity.timeline@1.8.9","com.unity.ugui@2.0.0","com.unity.modules.accessibility@1.0.0","com.unity.modules.ai@1.0.0","com.unity.modules.androidjni@1.0.0","com.unity.modules.animation@1.0.0","com.unity.modules.assetbundle@1.0.0","com.unity.modules.audio@1.0.0","com.unity.modules.cloth@1.0.0","com.unity.modules.director@1.0.0","com.unity.modules.imageconversion@1.0.0","com.unity.modules.imgui@1.0.0","com.unity.modules.jsonserialize@1.0.0","com.unity.modules.particlesystem@1.0.0","com.unity.modules.physics@1.0.0","com.unity.modules.physics2d@1.0.0","com.unity.modules.screencapture@1.0.0","com.unity.modules.terrain@1.0.0","com.unity.modules.terrainphysics@1.0.0","com.unity.modules.tilemap@1.0.0","com.unity.modules.ui@1.0.0","com.unity.modules.uielements@1.0.0","com.unity.modules.umbra@1.0.0","com.unity.modules.unityanalytics@1.0.0","com.unity.modules.unitywebrequest@1.0.0","com.unity.modules.unitywebrequestassetbundle@1.0.0","com.unity.modules.unitywebrequestaudio@1.0.0","com.unity.modules.unitywebrequesttexture@1.0.0","com.unity.modules.unitywebrequestwww@1.0.0","com.unity.modules.vehicles@1.0.0","com.unity.modules.video@1.0.0","com.unity.modules.vr@1.0.0","com.unity.modules.wind@1.0.0","com.unity.modules.xr@1.0.0","com.unity.modules.subsystems@1.0.0","com.unity.modules.hierarchycore@1.0.0","com.unity.render-pipelines.core@17.2.0","com.unity.shadergraph@17.2.0","com.unity.render-pipelines.universal-config@17.0.3","com.unity.test-framework@1.6.0","com.unity.ext.nunit@2.0.5","com.unity.2d.animation@12.0.2","com.unity.2d.pixel-perfect@5.1.0","com.unity.2d.psdimporter@11.0.1","com.unity.2d.tilemap@1.0.0","com.unity.2d.tilemap.extras@5.0.1","com.unity.2d.aseprite@2.0.1","com.unity.splines@2.8.2","com.unity.profiling.core@1.0.2","com.unity.scriptablebuildpipeline@2.4.2","com.unity.2d.common@11.0.1","com.unity.mathematics@1.3.2","com.unity.searcher@4.9.3","com.unity.burst@1.8.24","com.unity.collections@2.5.7","com.unity.rendering.light-transport@1.0.1","com.unity.settings-manager@2.1.0","com.unity.nuget.mono-cecil@1.11.5","com.unity.test-framework.performance@3.1.0"],"Results":[]}
|
||||||
7
Assets/Resources/PerformanceTestRunInfo.json.meta
Normal file
7
Assets/Resources/PerformanceTestRunInfo.json.meta
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: cb4b04b706692c14ab819cb590863198
|
||||||
|
TextScriptImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
1
Assets/Resources/PerformanceTestRunSettings.json
Normal file
1
Assets/Resources/PerformanceTestRunSettings.json
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{"MeasurementCount":-1}
|
||||||
7
Assets/Resources/PerformanceTestRunSettings.json.meta
Normal file
7
Assets/Resources/PerformanceTestRunSettings.json.meta
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 4fcd6892d10380341866ac1c8a8c0ed9
|
||||||
|
TextScriptImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -342,16 +342,16 @@ LineRenderer:
|
|||||||
m_SortingLayer: 0
|
m_SortingLayer: 0
|
||||||
m_SortingOrder: 0
|
m_SortingOrder: 0
|
||||||
m_Positions:
|
m_Positions:
|
||||||
- {x: -0.15602553, y: 3.8573277, z: 0}
|
- {x: -0.15602553, y: 7.6274276, z: 0}
|
||||||
- {x: -0.1566351, y: 3.753693, z: 0}
|
- {x: -0.33293986, y: 6.2028694, z: 0}
|
||||||
- {x: -0.1572447, y: 3.6518767, z: 0}
|
- {x: -0.47067532, y: 4.9898887, z: 0}
|
||||||
- {x: -0.15785426, y: 3.5518785, z: 0}
|
- {x: -0.569232, y: 3.988484, z: 0}
|
||||||
- {x: -0.15846384, y: 3.453699, z: 0}
|
- {x: -0.6286098, y: 3.1986566, z: 0}
|
||||||
- {x: -0.15907341, y: 3.3573375, z: 0}
|
- {x: -0.6488087, y: 2.6204057, z: 0}
|
||||||
- {x: -0.15968299, y: 3.2627945, z: 0}
|
- {x: -0.62982893, y: 2.2537322, z: 0}
|
||||||
- {x: -0.16029257, y: 3.1700697, z: 0}
|
- {x: -0.57167023, y: 2.0986352, z: 0}
|
||||||
- {x: -0.16090216, y: 3.0791638, z: 0}
|
- {x: -0.47433275, y: 2.1551156, z: 0}
|
||||||
- {x: -0.16151173, y: 2.9900756, z: 0}
|
- {x: -0.33781648, y: 2.4231722, z: 0}
|
||||||
- {x: -0.16212131, y: 2.9028063, z: 0}
|
- {x: -0.16212131, y: 2.9028063, z: 0}
|
||||||
m_Parameters:
|
m_Parameters:
|
||||||
serializedVersion: 3
|
serializedVersion: 3
|
||||||
@@ -454,6 +454,7 @@ GameObject:
|
|||||||
- component: {fileID: 224729333}
|
- component: {fileID: 224729333}
|
||||||
- component: {fileID: 224729332}
|
- component: {fileID: 224729332}
|
||||||
- component: {fileID: 224729334}
|
- component: {fileID: 224729334}
|
||||||
|
- component: {fileID: 224729335}
|
||||||
m_Layer: 0
|
m_Layer: 0
|
||||||
m_Name: CinemachineCamera
|
m_Name: CinemachineCamera
|
||||||
m_TagString: Untagged
|
m_TagString: Untagged
|
||||||
@@ -541,6 +542,21 @@ Animator:
|
|||||||
m_AllowConstantClipSamplingOptimization: 1
|
m_AllowConstantClipSamplingOptimization: 1
|
||||||
m_KeepAnimatorStateOnDisable: 0
|
m_KeepAnimatorStateOnDisable: 0
|
||||||
m_WriteDefaultValuesOnDisable: 0
|
m_WriteDefaultValuesOnDisable: 0
|
||||||
|
--- !u!114 &224729335
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 224729330}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 8a71a21143bd4f4992d08829084d1e3b, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier: AppleHillsScripts::AppleHillsCamera.CameraScreenAdapter
|
||||||
|
referenceMarker: {fileID: 1651034645}
|
||||||
|
adjustOnStart: 1
|
||||||
|
adjustOnScreenResize: 1
|
||||||
--- !u!1 &323864663
|
--- !u!1 &323864663
|
||||||
GameObject:
|
GameObject:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
@@ -882,6 +898,7 @@ GameObject:
|
|||||||
- component: {fileID: 747976404}
|
- component: {fileID: 747976404}
|
||||||
- component: {fileID: 747976405}
|
- component: {fileID: 747976405}
|
||||||
- component: {fileID: 747976406}
|
- component: {fileID: 747976406}
|
||||||
|
- component: {fileID: 747976407}
|
||||||
m_Layer: 0
|
m_Layer: 0
|
||||||
m_Name: BottleMarine
|
m_Name: BottleMarine
|
||||||
m_TagString: Player
|
m_TagString: Player
|
||||||
@@ -898,7 +915,7 @@ Transform:
|
|||||||
m_GameObject: {fileID: 747976396}
|
m_GameObject: {fileID: 747976396}
|
||||||
serializedVersion: 2
|
serializedVersion: 2
|
||||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||||
m_LocalPosition: {x: 0, y: 2.9799, z: 0}
|
m_LocalPosition: {x: 0, y: 6.75, z: 0}
|
||||||
m_LocalScale: {x: 0.57574, y: 0.57574, z: 0.57574}
|
m_LocalScale: {x: 0.57574, y: 0.57574, z: 0.57574}
|
||||||
m_ConstrainProportionsScale: 0
|
m_ConstrainProportionsScale: 0
|
||||||
m_Children:
|
m_Children:
|
||||||
@@ -1089,6 +1106,27 @@ MonoBehaviour:
|
|||||||
m_Name:
|
m_Name:
|
||||||
m_EditorClassIdentifier: AppleHillsScripts::Minigames.DivingForPictures.Utilities.BottlePauser
|
m_EditorClassIdentifier: AppleHillsScripts::Minigames.DivingForPictures.Utilities.BottlePauser
|
||||||
wobbleReference: {fileID: 747976399}
|
wobbleReference: {fileID: 747976399}
|
||||||
|
--- !u!114 &747976407
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 747976396}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: ed380d10e1e04ae7990e5c726c929063, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier: AppleHillsScripts::AppleHillsCamera.EdgeAnchor
|
||||||
|
referenceMarker: {fileID: 1651034645}
|
||||||
|
anchorEdge: 0
|
||||||
|
useReferenceMargin: 0
|
||||||
|
customMargin: 0
|
||||||
|
adjustOnStart: 1
|
||||||
|
adjustOnScreenResize: 1
|
||||||
|
preserveOtherAxes: 1
|
||||||
|
showVisualization: 1
|
||||||
|
visualizationColor: {r: 1, g: 0, b: 0, a: 0.8}
|
||||||
--- !u!1 &824396214
|
--- !u!1 &824396214
|
||||||
GameObject:
|
GameObject:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
@@ -1324,16 +1362,16 @@ LineRenderer:
|
|||||||
m_SortingLayer: 0
|
m_SortingLayer: 0
|
||||||
m_SortingOrder: 0
|
m_SortingOrder: 0
|
||||||
m_Positions:
|
m_Positions:
|
||||||
- {x: -0.15602553, y: 3.8573277, z: 0}
|
- {x: -0.15602553, y: 7.6274276, z: 0}
|
||||||
- {x: -0.11662118, y: 3.66006, z: 0}
|
- {x: -0.29288492, y: 6.2025185, z: 0}
|
||||||
- {x: -0.07721684, y: 3.4853156, z: 0}
|
- {x: -0.39057457, y: 4.9891615, z: 0}
|
||||||
- {x: -0.03781248, y: 3.3330944, z: 0}
|
- {x: -0.44909453, y: 3.9873564, z: 0}
|
||||||
- {x: 0.0015918687, y: 3.2033968, z: 0}
|
- {x: -0.4684448, y: 3.197105, z: 0}
|
||||||
- {x: 0.040996216, y: 3.0962222, z: 0}
|
- {x: -0.44862524, y: 2.6184058, z: 0}
|
||||||
- {x: 0.08040057, y: 3.011571, z: 0}
|
- {x: -0.389636, y: 2.2512593, z: 0}
|
||||||
- {x: 0.11980491, y: 2.9494433, z: 0}
|
- {x: -0.2914771, y: 2.0956657, z: 0}
|
||||||
- {x: 0.15920927, y: 2.9098392, z: 0}
|
- {x: -0.15414846, y: 2.1516247, z: 0}
|
||||||
- {x: 0.1986136, y: 2.892758, z: 0}
|
- {x: 0.022349834, y: 2.419136, z: 0}
|
||||||
- {x: 0.23801796, y: 2.8982003, z: 0}
|
- {x: 0.23801796, y: 2.8982003, z: 0}
|
||||||
m_Parameters:
|
m_Parameters:
|
||||||
serializedVersion: 3
|
serializedVersion: 3
|
||||||
@@ -1867,16 +1905,16 @@ LineRenderer:
|
|||||||
m_SortingLayer: 0
|
m_SortingLayer: 0
|
||||||
m_SortingOrder: 0
|
m_SortingOrder: 0
|
||||||
m_Positions:
|
m_Positions:
|
||||||
- {x: -0.15602553, y: 3.8573277, z: 0}
|
- {x: -0.15602553, y: 7.6274276, z: 0}
|
||||||
- {x: -0.18956745, y: 3.6568341, z: 0}
|
- {x: -0.36587217, y: 6.20166, z: 0}
|
||||||
- {x: -0.22310936, y: 3.479415, z: 0}
|
- {x: -0.53654, y: 4.98747, z: 0}
|
||||||
- {x: -0.25665125, y: 3.3250687, z: 0}
|
- {x: -0.66802895, y: 3.984856, z: 0}
|
||||||
- {x: -0.29019317, y: 3.193797, z: 0}
|
- {x: -0.76033914, y: 3.1938195, z: 0}
|
||||||
- {x: -0.32373506, y: 3.0855987, z: 0}
|
- {x: -0.81347036, y: 2.6143596, z: 0}
|
||||||
- {x: -0.35727698, y: 3.0004745, z: 0}
|
- {x: -0.82742286, y: 2.2464767, z: 0}
|
||||||
- {x: -0.39081886, y: 2.938424, z: 0}
|
- {x: -0.80219656, y: 2.090171, z: 0}
|
||||||
- {x: -0.4243608, y: 2.8994474, z: 0}
|
- {x: -0.7377914, y: 2.1454425, z: 0}
|
||||||
- {x: -0.45790267, y: 2.8835444, z: 0}
|
- {x: -0.6342074, y: 2.4122903, z: 0}
|
||||||
- {x: -0.4914446, y: 2.8907156, z: 0}
|
- {x: -0.4914446, y: 2.8907156, z: 0}
|
||||||
m_Parameters:
|
m_Parameters:
|
||||||
serializedVersion: 3
|
serializedVersion: 3
|
||||||
@@ -1968,6 +2006,59 @@ MonoBehaviour:
|
|||||||
ropeDamping: 0.3
|
ropeDamping: 0.3
|
||||||
initialSeparationDistance: 0.1
|
initialSeparationDistance: 0.1
|
||||||
initialFallImpulse: 2
|
initialFallImpulse: 2
|
||||||
|
--- !u!1 &1651034644
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 1651034646}
|
||||||
|
- component: {fileID: 1651034645}
|
||||||
|
m_Layer: 0
|
||||||
|
m_Name: ScreenReferenceMarker
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!114 &1651034645
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1651034644}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 3058fe4801134fea916ad685f924668f, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier: AppleHillsScripts::AppleHillsCamera.ScreenReferenceMarker
|
||||||
|
targetWidth: 6.2
|
||||||
|
topMargin: 0.2
|
||||||
|
bottomMargin: 0.2
|
||||||
|
leftMargin: 0.2
|
||||||
|
rightMargin: 0.2
|
||||||
|
gizmoColor: {r: 0, g: 1, b: 0, a: 0.5}
|
||||||
|
screenEdgeColor: {r: 1, g: 1, b: 0, a: 0.3}
|
||||||
|
showVerticalMargins: 1
|
||||||
|
showHorizontalMargins: 1
|
||||||
|
--- !u!4 &1651034646
|
||||||
|
Transform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1651034644}
|
||||||
|
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 &1679185997
|
--- !u!1 &1679185997
|
||||||
GameObject:
|
GameObject:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
@@ -2031,6 +2122,7 @@ MonoBehaviour:
|
|||||||
- {fileID: 2956826569642009690, guid: b3501bc08c6afbf4f868bc7b6c2a2d92, type: 3}
|
- {fileID: 2956826569642009690, guid: b3501bc08c6afbf4f868bc7b6c2a2d92, type: 3}
|
||||||
- {fileID: 2956826569642009690, guid: 4f9c8bd3fb844484492a54a2998b9b3b, type: 3}
|
- {fileID: 2956826569642009690, guid: 4f9c8bd3fb844484492a54a2998b9b3b, type: 3}
|
||||||
- {fileID: 2956826569642009690, guid: 16ad8a46d2c7c534982f4ee943e06f74, type: 3}
|
- {fileID: 2956826569642009690, guid: 16ad8a46d2c7c534982f4ee943e06f74, type: 3}
|
||||||
|
initialTilePrefab: {fileID: 0}
|
||||||
onTileSpawned:
|
onTileSpawned:
|
||||||
m_PersistentCalls:
|
m_PersistentCalls:
|
||||||
m_Calls: []
|
m_Calls: []
|
||||||
@@ -2040,6 +2132,22 @@ MonoBehaviour:
|
|||||||
onLastTileLeft:
|
onLastTileLeft:
|
||||||
m_PersistentCalls:
|
m_PersistentCalls:
|
||||||
m_Calls: []
|
m_Calls: []
|
||||||
|
depthDifficultyRanges:
|
||||||
|
- minDepth: 0
|
||||||
|
maxDepth: 10
|
||||||
|
difficulty: 1
|
||||||
|
- minDepth: 11
|
||||||
|
maxDepth: 20
|
||||||
|
difficulty: 2
|
||||||
|
- minDepth: 21
|
||||||
|
maxDepth: 30
|
||||||
|
difficulty: 3
|
||||||
|
- minDepth: 31
|
||||||
|
maxDepth: 40
|
||||||
|
difficulty: 4
|
||||||
|
- minDepth: 41
|
||||||
|
maxDepth: 2147483647
|
||||||
|
difficulty: 5
|
||||||
--- !u!1 &1787733334
|
--- !u!1 &1787733334
|
||||||
GameObject:
|
GameObject:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
@@ -2410,3 +2518,4 @@ SceneRoots:
|
|||||||
- {fileID: 1679185998}
|
- {fileID: 1679185998}
|
||||||
- {fileID: 323864665}
|
- {fileID: 323864665}
|
||||||
- {fileID: 424805726}
|
- {fileID: 424805726}
|
||||||
|
- {fileID: 1651034646}
|
||||||
|
|||||||
3
Assets/Scripts/AppleHillsCamera.meta
Normal file
3
Assets/Scripts/AppleHillsCamera.meta
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 95f834c9cbc34cff9490c5582d66e463
|
||||||
|
timeCreated: 1760359480
|
||||||
111
Assets/Scripts/AppleHillsCamera/CameraScreenAdapter.cs
Normal file
111
Assets/Scripts/AppleHillsCamera/CameraScreenAdapter.cs
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
using UnityEngine;
|
||||||
|
using Unity.Cinemachine;
|
||||||
|
|
||||||
|
namespace AppleHillsCamera
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Adjusts the camera's orthographic size to match the target width from a ScreenReferenceMarker.
|
||||||
|
/// Works with both regular cameras and Cinemachine virtual cameras.
|
||||||
|
/// </summary>
|
||||||
|
public class CameraScreenAdapter : MonoBehaviour
|
||||||
|
{
|
||||||
|
[Tooltip("Reference that defines the target width to match")]
|
||||||
|
public ScreenReferenceMarker referenceMarker;
|
||||||
|
|
||||||
|
[Tooltip("Whether to adjust the camera automatically on Start")]
|
||||||
|
public bool adjustOnStart = true;
|
||||||
|
|
||||||
|
[Tooltip("Whether to adjust the camera automatically when the screen size changes")]
|
||||||
|
public bool adjustOnScreenResize = true;
|
||||||
|
|
||||||
|
private Camera _regularCamera;
|
||||||
|
private CinemachineCamera _virtualCamera;
|
||||||
|
private int _lastScreenWidth;
|
||||||
|
private int _lastScreenHeight;
|
||||||
|
private bool _usingCinemachine;
|
||||||
|
|
||||||
|
private void Awake()
|
||||||
|
{
|
||||||
|
// Try to get regular camera first
|
||||||
|
_regularCamera = GetComponent<Camera>();
|
||||||
|
|
||||||
|
// Try to get Cinemachine camera if no regular camera or if both exist
|
||||||
|
_virtualCamera = GetComponent<CinemachineCamera>();
|
||||||
|
|
||||||
|
// Determine which camera type we're using
|
||||||
|
_usingCinemachine = _virtualCamera != null;
|
||||||
|
|
||||||
|
_lastScreenWidth = Screen.width;
|
||||||
|
_lastScreenHeight = Screen.height;
|
||||||
|
|
||||||
|
if (!_usingCinemachine && _regularCamera == null)
|
||||||
|
{
|
||||||
|
Debug.LogError("CameraScreenAdapter: No camera component found. Add this script to a GameObject with either Camera or CinemachineCamera component.");
|
||||||
|
enabled = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Start()
|
||||||
|
{
|
||||||
|
if (adjustOnStart)
|
||||||
|
{
|
||||||
|
AdjustCamera();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Update()
|
||||||
|
{
|
||||||
|
if (adjustOnScreenResize &&
|
||||||
|
(Screen.width != _lastScreenWidth || Screen.height != _lastScreenHeight))
|
||||||
|
{
|
||||||
|
AdjustCamera();
|
||||||
|
_lastScreenWidth = Screen.width;
|
||||||
|
_lastScreenHeight = Screen.height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Manually trigger camera adjustment to match the reference width.
|
||||||
|
/// </summary>
|
||||||
|
public void AdjustCamera()
|
||||||
|
{
|
||||||
|
if (referenceMarker == null)
|
||||||
|
{
|
||||||
|
Debug.LogWarning("CameraScreenAdapter: Missing reference marker.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate the orthographic size based on the target width and screen aspect ratio
|
||||||
|
float targetWidth = referenceMarker.targetWidth;
|
||||||
|
float screenAspect = (float)Screen.height / Screen.width;
|
||||||
|
|
||||||
|
// Orthographic size is half the height, so we calculate:
|
||||||
|
// orthoSize = (targetWidth / 2) * (screenHeight / screenWidth)
|
||||||
|
float orthoSize = (targetWidth / 2f) * screenAspect;
|
||||||
|
|
||||||
|
// Apply the calculated size to the camera
|
||||||
|
if (_usingCinemachine)
|
||||||
|
{
|
||||||
|
// Apply to Cinemachine virtual camera
|
||||||
|
var lens = _virtualCamera.Lens;
|
||||||
|
lens.OrthographicSize = orthoSize;
|
||||||
|
_virtualCamera.Lens = lens;
|
||||||
|
Debug.Log($"Cinemachine Camera adapted: Width={targetWidth}, Aspect={screenAspect:F2}, OrthoSize={orthoSize:F2}");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Apply to regular camera
|
||||||
|
if (_regularCamera.orthographic)
|
||||||
|
{
|
||||||
|
_regularCamera.orthographicSize = orthoSize;
|
||||||
|
Debug.Log($"Camera adapted: Width={targetWidth}, Aspect={screenAspect:F2}, OrthoSize={orthoSize:F2}");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.LogWarning("CameraScreenAdapter: Regular camera is not in orthographic mode.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 8a71a21143bd4f4992d08829084d1e3b
|
||||||
|
timeCreated: 1760359498
|
||||||
310
Assets/Scripts/AppleHillsCamera/EdgeAnchor.cs
Normal file
310
Assets/Scripts/AppleHillsCamera/EdgeAnchor.cs
Normal file
@@ -0,0 +1,310 @@
|
|||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace AppleHillsCamera
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Anchors a game object at a fixed distance from a screen edge.
|
||||||
|
/// </summary>
|
||||||
|
[ExecuteInEditMode] // Make it run in the editor
|
||||||
|
public class EdgeAnchor : MonoBehaviour
|
||||||
|
{
|
||||||
|
public enum AnchorEdge
|
||||||
|
{
|
||||||
|
Top,
|
||||||
|
Bottom,
|
||||||
|
Left,
|
||||||
|
Right
|
||||||
|
}
|
||||||
|
|
||||||
|
[Tooltip("Reference marker that defines the screen edges and margins")]
|
||||||
|
public ScreenReferenceMarker referenceMarker;
|
||||||
|
|
||||||
|
[Tooltip("Which screen edge to anchor to")]
|
||||||
|
public AnchorEdge anchorEdge = AnchorEdge.Top;
|
||||||
|
|
||||||
|
[Tooltip("Whether to use the predefined margin from the reference marker")]
|
||||||
|
public bool useReferenceMargin = true;
|
||||||
|
|
||||||
|
[Tooltip("Custom margin to use if not using the reference margin")]
|
||||||
|
public float customMargin = 1f;
|
||||||
|
|
||||||
|
[Tooltip("Whether to adjust the position automatically on Start")]
|
||||||
|
public bool adjustOnStart = true;
|
||||||
|
|
||||||
|
[Tooltip("Whether to adjust the position when the screen size changes")]
|
||||||
|
public bool adjustOnScreenResize = true;
|
||||||
|
|
||||||
|
[Tooltip("Whether to preserve the object's position on other axes")]
|
||||||
|
public bool preserveOtherAxes = true;
|
||||||
|
|
||||||
|
[Header("Visualization")]
|
||||||
|
[Tooltip("Whether to show the anchor visualization in the editor")]
|
||||||
|
public bool showVisualization = true;
|
||||||
|
|
||||||
|
[Tooltip("Color for the anchor visualization line")]
|
||||||
|
public Color visualizationColor = new Color(1f, 0f, 0f, 0.8f);
|
||||||
|
|
||||||
|
private Camera _camera;
|
||||||
|
private int _lastScreenWidth;
|
||||||
|
private int _lastScreenHeight;
|
||||||
|
private Vector3 _originalPosition;
|
||||||
|
private bool _initialized = false;
|
||||||
|
|
||||||
|
#if UNITY_EDITOR
|
||||||
|
private void OnDrawGizmos()
|
||||||
|
{
|
||||||
|
if (!showVisualization || referenceMarker == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Draw a line from the object to its anchor point
|
||||||
|
Vector3 anchorPoint = GetAnchorPoint();
|
||||||
|
|
||||||
|
// Save original color
|
||||||
|
Color originalColor = Gizmos.color;
|
||||||
|
|
||||||
|
// Draw line to anchor point
|
||||||
|
Gizmos.color = visualizationColor;
|
||||||
|
Gizmos.DrawLine(gameObject.transform.position, anchorPoint);
|
||||||
|
|
||||||
|
// Draw a small sphere at the anchor point
|
||||||
|
Gizmos.DrawSphere(anchorPoint, 0.1f);
|
||||||
|
|
||||||
|
// Restore original color
|
||||||
|
Gizmos.color = originalColor;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
private void Awake()
|
||||||
|
{
|
||||||
|
_originalPosition = transform.position;
|
||||||
|
FindCamera();
|
||||||
|
_lastScreenWidth = Screen.width;
|
||||||
|
_lastScreenHeight = Screen.height;
|
||||||
|
_initialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnEnable()
|
||||||
|
{
|
||||||
|
if (!_initialized)
|
||||||
|
{
|
||||||
|
_originalPosition = transform.position;
|
||||||
|
FindCamera();
|
||||||
|
_lastScreenWidth = Screen.width;
|
||||||
|
_lastScreenHeight = Screen.height;
|
||||||
|
_initialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adjust position immediately when enabled in editor
|
||||||
|
#if UNITY_EDITOR
|
||||||
|
if (!Application.isPlaying)
|
||||||
|
{
|
||||||
|
UpdatePosition();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Start()
|
||||||
|
{
|
||||||
|
if (adjustOnStart && Application.isPlaying)
|
||||||
|
{
|
||||||
|
UpdatePosition();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Update()
|
||||||
|
{
|
||||||
|
bool shouldUpdate = false;
|
||||||
|
|
||||||
|
// Update if screen size has changed
|
||||||
|
if (adjustOnScreenResize &&
|
||||||
|
(Screen.width != _lastScreenWidth || Screen.height != _lastScreenHeight))
|
||||||
|
{
|
||||||
|
shouldUpdate = true;
|
||||||
|
_lastScreenWidth = Screen.width;
|
||||||
|
_lastScreenHeight = Screen.height;
|
||||||
|
}
|
||||||
|
|
||||||
|
// In editor, check for reference marker changes or inspector changes
|
||||||
|
#if UNITY_EDITOR
|
||||||
|
if (!Application.isPlaying)
|
||||||
|
{
|
||||||
|
shouldUpdate = true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Update position if needed
|
||||||
|
if (shouldUpdate)
|
||||||
|
{
|
||||||
|
UpdatePosition();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void FindCamera()
|
||||||
|
{
|
||||||
|
// Look for the main camera
|
||||||
|
_camera = Camera.main;
|
||||||
|
|
||||||
|
// If no main camera found, try to find any camera
|
||||||
|
if (_camera == null)
|
||||||
|
{
|
||||||
|
_camera = FindAnyObjectByType<Camera>();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_camera == null)
|
||||||
|
{
|
||||||
|
Debug.LogError("EdgeAnchor: No camera found in the scene.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Manually trigger position adjustment based on the anchor settings.
|
||||||
|
/// </summary>
|
||||||
|
public void UpdatePosition()
|
||||||
|
{
|
||||||
|
if (referenceMarker == null)
|
||||||
|
{
|
||||||
|
Debug.LogWarning("EdgeAnchor: Missing reference marker.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_camera == null)
|
||||||
|
{
|
||||||
|
FindCamera();
|
||||||
|
if (_camera == null) return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the margin value to use
|
||||||
|
float margin = GetMarginValue();
|
||||||
|
|
||||||
|
// Calculate the new position based on anchor edge
|
||||||
|
Vector3 newPosition = CalculateAnchoredPosition(margin);
|
||||||
|
|
||||||
|
// If preserving other axes, keep their original values
|
||||||
|
if (preserveOtherAxes)
|
||||||
|
{
|
||||||
|
switch (anchorEdge)
|
||||||
|
{
|
||||||
|
case AnchorEdge.Top:
|
||||||
|
case AnchorEdge.Bottom:
|
||||||
|
newPosition.x = transform.position.x;
|
||||||
|
newPosition.z = transform.position.z;
|
||||||
|
break;
|
||||||
|
case AnchorEdge.Left:
|
||||||
|
case AnchorEdge.Right:
|
||||||
|
newPosition.y = transform.position.y;
|
||||||
|
newPosition.z = transform.position.z;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply the new position
|
||||||
|
transform.position = newPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
private float GetMarginValue()
|
||||||
|
{
|
||||||
|
if (!useReferenceMargin)
|
||||||
|
{
|
||||||
|
return customMargin;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (anchorEdge)
|
||||||
|
{
|
||||||
|
case AnchorEdge.Top:
|
||||||
|
return referenceMarker.topMargin;
|
||||||
|
case AnchorEdge.Bottom:
|
||||||
|
return referenceMarker.bottomMargin;
|
||||||
|
case AnchorEdge.Left:
|
||||||
|
return referenceMarker.leftMargin;
|
||||||
|
case AnchorEdge.Right:
|
||||||
|
return referenceMarker.rightMargin;
|
||||||
|
default:
|
||||||
|
return customMargin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Vector3 CalculateAnchoredPosition(float margin)
|
||||||
|
{
|
||||||
|
// Get the screen edges in world coordinates
|
||||||
|
float cameraOrthoSize = _camera.orthographicSize;
|
||||||
|
float screenAspect = (float)Screen.width / Screen.height;
|
||||||
|
float screenHeight = cameraOrthoSize * 2f;
|
||||||
|
float screenWidth = screenHeight * screenAspect;
|
||||||
|
|
||||||
|
Vector3 cameraPosition = _camera.transform.position;
|
||||||
|
|
||||||
|
Vector3 newPosition = transform.position;
|
||||||
|
|
||||||
|
switch (anchorEdge)
|
||||||
|
{
|
||||||
|
case AnchorEdge.Top:
|
||||||
|
// Position from the top of the screen
|
||||||
|
newPosition.y = cameraPosition.y + cameraOrthoSize - margin;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AnchorEdge.Bottom:
|
||||||
|
// Position from the bottom of the screen
|
||||||
|
newPosition.y = cameraPosition.y - cameraOrthoSize + margin;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AnchorEdge.Left:
|
||||||
|
// Position from the left of the screen
|
||||||
|
newPosition.x = cameraPosition.x - (screenWidth / 2f) + margin;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AnchorEdge.Right:
|
||||||
|
// Position from the right of the screen
|
||||||
|
newPosition.x = cameraPosition.x + (screenWidth / 2f) - margin;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return newPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the anchor point on the edge for visualization
|
||||||
|
/// </summary>
|
||||||
|
private Vector3 GetAnchorPoint()
|
||||||
|
{
|
||||||
|
if (_camera == null)
|
||||||
|
{
|
||||||
|
FindCamera();
|
||||||
|
if (_camera == null) return transform.position;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the screen edges in world coordinates
|
||||||
|
float cameraOrthoSize = _camera.orthographicSize;
|
||||||
|
float screenAspect = (float)Screen.width / Screen.height;
|
||||||
|
float screenHeight = cameraOrthoSize * 2f;
|
||||||
|
float screenWidth = screenHeight * screenAspect;
|
||||||
|
|
||||||
|
Vector3 cameraPosition = _camera.transform.position;
|
||||||
|
Vector3 anchorPoint = transform.position;
|
||||||
|
|
||||||
|
switch (anchorEdge)
|
||||||
|
{
|
||||||
|
case AnchorEdge.Top:
|
||||||
|
// Anchor at top edge with same X as the object
|
||||||
|
anchorPoint.y = cameraPosition.y + cameraOrthoSize;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AnchorEdge.Bottom:
|
||||||
|
// Anchor at bottom edge with same X as the object
|
||||||
|
anchorPoint.y = cameraPosition.y - cameraOrthoSize;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AnchorEdge.Left:
|
||||||
|
// Anchor at left edge with same Y as the object
|
||||||
|
anchorPoint.x = cameraPosition.x - (screenWidth / 2f);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AnchorEdge.Right:
|
||||||
|
// Anchor at right edge with same Y as the object
|
||||||
|
anchorPoint.x = cameraPosition.x + (screenWidth / 2f);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return anchorPoint;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
3
Assets/Scripts/AppleHillsCamera/EdgeAnchor.cs.meta
Normal file
3
Assets/Scripts/AppleHillsCamera/EdgeAnchor.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: ed380d10e1e04ae7990e5c726c929063
|
||||||
|
timeCreated: 1760359522
|
||||||
142
Assets/Scripts/AppleHillsCamera/ScreenReferenceMarker.cs
Normal file
142
Assets/Scripts/AppleHillsCamera/ScreenReferenceMarker.cs
Normal file
@@ -0,0 +1,142 @@
|
|||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace AppleHillsCamera
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Defines reference sizes and distances for screen adaptation.
|
||||||
|
/// Used by CameraScreenAdapter and EdgeAnchor components.
|
||||||
|
/// </summary>
|
||||||
|
public class ScreenReferenceMarker : MonoBehaviour
|
||||||
|
{
|
||||||
|
[Header("Horizontal Reference")]
|
||||||
|
[Tooltip("The target width that should match the screen width")]
|
||||||
|
public float targetWidth = 10f;
|
||||||
|
|
||||||
|
[Header("Vertical References")]
|
||||||
|
[Tooltip("Distance from top of screen to use for anchoring")]
|
||||||
|
public float topMargin = 1f;
|
||||||
|
|
||||||
|
[Tooltip("Distance from bottom of screen to use for anchoring")]
|
||||||
|
public float bottomMargin = 1f;
|
||||||
|
|
||||||
|
[Tooltip("Distance from left of screen to use for anchoring")]
|
||||||
|
public float leftMargin = 1f;
|
||||||
|
|
||||||
|
[Tooltip("Distance from right of screen to use for anchoring")]
|
||||||
|
public float rightMargin = 1f;
|
||||||
|
|
||||||
|
[Header("Visualization")]
|
||||||
|
[Tooltip("Color to use for gizmo visualization")]
|
||||||
|
public Color gizmoColor = new Color(0f, 1f, 0f, 0.5f);
|
||||||
|
|
||||||
|
[Tooltip("Color to use for screen edge visualization")]
|
||||||
|
public Color screenEdgeColor = new Color(1f, 1f, 0f, 0.3f);
|
||||||
|
|
||||||
|
[Tooltip("Show the vertical margins in scene view")]
|
||||||
|
public bool showVerticalMargins = true;
|
||||||
|
|
||||||
|
[Tooltip("Show the horizontal margins in scene view")]
|
||||||
|
public bool showHorizontalMargins = true;
|
||||||
|
|
||||||
|
#if UNITY_EDITOR
|
||||||
|
private void OnDrawGizmos()
|
||||||
|
{
|
||||||
|
// Save original color
|
||||||
|
Color originalColor = Gizmos.color;
|
||||||
|
|
||||||
|
// Set the color for our gizmos
|
||||||
|
Gizmos.color = gizmoColor;
|
||||||
|
|
||||||
|
Vector3 position = transform.position;
|
||||||
|
|
||||||
|
// Draw the width reference
|
||||||
|
Vector3 left = position + Vector3.left * (targetWidth / 2f);
|
||||||
|
Vector3 right = position + Vector3.right * (targetWidth / 2f);
|
||||||
|
Gizmos.DrawLine(left, right);
|
||||||
|
|
||||||
|
// Draw vertical endpoints
|
||||||
|
float endCapSize = 0.5f;
|
||||||
|
Gizmos.DrawLine(left, left + Vector3.up * endCapSize);
|
||||||
|
Gizmos.DrawLine(left, left + Vector3.down * endCapSize);
|
||||||
|
Gizmos.DrawLine(right, right + Vector3.up * endCapSize);
|
||||||
|
Gizmos.DrawLine(right, right + Vector3.down * endCapSize);
|
||||||
|
|
||||||
|
// Calculate visual screen edges based on actual camera viewport
|
||||||
|
float halfWidth = targetWidth / 2f;
|
||||||
|
float halfHeight;
|
||||||
|
|
||||||
|
// Try to get camera references in the preferred order
|
||||||
|
|
||||||
|
// 1. Try to find the main camera in the scene (highest priority)
|
||||||
|
Camera mainCamera = Camera.main;
|
||||||
|
if (mainCamera != null && mainCamera.orthographic)
|
||||||
|
{
|
||||||
|
// Use the main camera's actual orthographic size for the height
|
||||||
|
halfHeight = mainCamera.orthographicSize;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// 2. Use Game/Simulator window resolution
|
||||||
|
float gameViewAspect = (float)Screen.height / Screen.width;
|
||||||
|
halfHeight = halfWidth * gameViewAspect;
|
||||||
|
|
||||||
|
// 3. Fallback to the scene view camera if needed
|
||||||
|
UnityEditor.SceneView sceneView = UnityEditor.SceneView.lastActiveSceneView;
|
||||||
|
if (sceneView != null && sceneView.camera != null && sceneView.camera.orthographic)
|
||||||
|
{
|
||||||
|
// Use the scene view camera's aspect ratio instead
|
||||||
|
float sceneAspect = sceneView.camera.pixelHeight / (float)sceneView.camera.pixelWidth;
|
||||||
|
halfHeight = halfWidth * sceneAspect;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Screen edge positions
|
||||||
|
Vector3 topEdge = position + Vector3.up * halfHeight;
|
||||||
|
Vector3 bottomEdge = position + Vector3.down * halfHeight;
|
||||||
|
Vector3 leftEdge = position + Vector3.left * halfWidth;
|
||||||
|
Vector3 rightEdge = position + Vector3.right * halfWidth;
|
||||||
|
|
||||||
|
// Draw screen edges with yellow color
|
||||||
|
Gizmos.color = screenEdgeColor;
|
||||||
|
|
||||||
|
// Draw full screen rectangle
|
||||||
|
Gizmos.DrawLine(leftEdge + Vector3.up * halfHeight, rightEdge + Vector3.up * halfHeight); // Top edge
|
||||||
|
Gizmos.DrawLine(leftEdge + Vector3.down * halfHeight, rightEdge + Vector3.down * halfHeight); // Bottom edge
|
||||||
|
Gizmos.DrawLine(leftEdge + Vector3.up * halfHeight, leftEdge + Vector3.down * halfHeight); // Left edge
|
||||||
|
Gizmos.DrawLine(rightEdge + Vector3.up * halfHeight, rightEdge + Vector3.down * halfHeight); // Right edge
|
||||||
|
|
||||||
|
// Draw margin references if enabled
|
||||||
|
Gizmos.color = gizmoColor;
|
||||||
|
|
||||||
|
if (showVerticalMargins)
|
||||||
|
{
|
||||||
|
// Top margin (distance from top edge)
|
||||||
|
Gizmos.DrawLine(
|
||||||
|
topEdge + Vector3.down * topMargin + Vector3.left * (targetWidth / 4f),
|
||||||
|
topEdge + Vector3.down * topMargin + Vector3.right * (targetWidth / 4f));
|
||||||
|
|
||||||
|
// Bottom margin (distance from bottom edge)
|
||||||
|
Gizmos.DrawLine(
|
||||||
|
bottomEdge + Vector3.up * bottomMargin + Vector3.left * (targetWidth / 4f),
|
||||||
|
bottomEdge + Vector3.up * bottomMargin + Vector3.right * (targetWidth / 4f));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (showHorizontalMargins)
|
||||||
|
{
|
||||||
|
// Left margin (distance from left edge)
|
||||||
|
Gizmos.DrawLine(
|
||||||
|
leftEdge + Vector3.right * leftMargin + Vector3.up * (halfHeight / 2f),
|
||||||
|
leftEdge + Vector3.right * leftMargin + Vector3.down * (halfHeight / 2f));
|
||||||
|
|
||||||
|
// Right margin (distance from right edge)
|
||||||
|
Gizmos.DrawLine(
|
||||||
|
rightEdge + Vector3.left * rightMargin + Vector3.up * (halfHeight / 2f),
|
||||||
|
rightEdge + Vector3.left * rightMargin + Vector3.down * (halfHeight / 2f));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Restore original color
|
||||||
|
Gizmos.color = originalColor;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 3058fe4801134fea916ad685f924668f
|
||||||
|
timeCreated: 1760359480
|
||||||
@@ -1,123 +1,128 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using AppleHills.Core.Settings;
|
||||||
|
using Core;
|
||||||
using Input;
|
using Input;
|
||||||
using Interactions;
|
using Interactions;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using AppleHills.Core.Settings;
|
|
||||||
using Core; // Added for IInteractionSettings
|
|
||||||
|
|
||||||
/// <summary>
|
// Added for IInteractionSettings
|
||||||
/// Handles level switching when interacted with. Applies switch data and triggers scene transitions.
|
|
||||||
/// </summary>
|
namespace LevelS
|
||||||
public class LevelSwitch : MonoBehaviour
|
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Data for this level switch (target scene, icon, etc).
|
/// Handles level switching when interacted with. Applies switch data and triggers scene transitions.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public LevelSwitchData switchData;
|
public class LevelSwitch : MonoBehaviour
|
||||||
private SpriteRenderer _iconRenderer;
|
{
|
||||||
private Interactable _interactable;
|
/// <summary>
|
||||||
|
/// Data for this level switch (target scene, icon, etc).
|
||||||
|
/// </summary>
|
||||||
|
public LevelSwitchData switchData;
|
||||||
|
private SpriteRenderer _iconRenderer;
|
||||||
|
private Interactable _interactable;
|
||||||
|
|
||||||
// Settings reference
|
// Settings reference
|
||||||
private IInteractionSettings _interactionSettings;
|
private IInteractionSettings _interactionSettings;
|
||||||
|
|
||||||
private bool _isActive = true;
|
private bool _isActive = true;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Unity Awake callback. Sets up icon, interactable, and event handlers.
|
/// Unity Awake callback. Sets up icon, interactable, and event handlers.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void Awake()
|
void Awake()
|
||||||
{
|
|
||||||
_isActive = true;
|
|
||||||
if (_iconRenderer == null)
|
|
||||||
_iconRenderer = GetComponent<SpriteRenderer>();
|
|
||||||
_interactable = GetComponent<Interactable>();
|
|
||||||
if (_interactable != null)
|
|
||||||
{
|
{
|
||||||
_interactable.characterArrived.AddListener(OnCharacterArrived);
|
_isActive = true;
|
||||||
|
if (_iconRenderer == null)
|
||||||
|
_iconRenderer = GetComponent<SpriteRenderer>();
|
||||||
|
_interactable = GetComponent<Interactable>();
|
||||||
|
if (_interactable != null)
|
||||||
|
{
|
||||||
|
_interactable.characterArrived.AddListener(OnCharacterArrived);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize settings reference
|
||||||
|
_interactionSettings = GameManager.GetSettingsObject<IInteractionSettings>();
|
||||||
|
|
||||||
|
ApplySwitchData();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize settings reference
|
|
||||||
_interactionSettings = GameManager.GetSettingsObject<IInteractionSettings>();
|
|
||||||
|
|
||||||
ApplySwitchData();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Unity OnDestroy callback. Cleans up event handlers.
|
/// Unity OnDestroy callback. Cleans up event handlers.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void OnDestroy()
|
void OnDestroy()
|
||||||
{
|
|
||||||
if (_interactable != null)
|
|
||||||
{
|
{
|
||||||
_interactable.characterArrived.RemoveListener(OnCharacterArrived);
|
if (_interactable != null)
|
||||||
|
{
|
||||||
|
_interactable.characterArrived.RemoveListener(OnCharacterArrived);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#if UNITY_EDITOR
|
#if UNITY_EDITOR
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Unity OnValidate callback. Ensures icon and data are up to date in editor.
|
/// Unity OnValidate callback. Ensures icon and data are up to date in editor.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void OnValidate()
|
void OnValidate()
|
||||||
{
|
{
|
||||||
if (_iconRenderer == null)
|
if (_iconRenderer == null)
|
||||||
_iconRenderer = GetComponent<SpriteRenderer>();
|
_iconRenderer = GetComponent<SpriteRenderer>();
|
||||||
ApplySwitchData();
|
ApplySwitchData();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Applies the switch data to the level switch (icon, name, etc).
|
/// Applies the switch data to the level switch (icon, name, etc).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void ApplySwitchData()
|
public void ApplySwitchData()
|
||||||
{
|
|
||||||
if (switchData != null)
|
|
||||||
{
|
{
|
||||||
if (_iconRenderer != null)
|
if (switchData != null)
|
||||||
_iconRenderer.sprite = switchData.mapSprite;
|
{
|
||||||
gameObject.name = switchData.targetLevelSceneName;
|
if (_iconRenderer != null)
|
||||||
// Optionally update other fields, e.g. description
|
_iconRenderer.sprite = switchData.mapSprite;
|
||||||
|
gameObject.name = switchData.targetLevelSceneName;
|
||||||
|
// Optionally update other fields, e.g. description
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Handles the start of an interaction (shows confirmation menu and switches the level if confirmed).
|
/// Handles the start of an interaction (shows confirmation menu and switches the level if confirmed).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void OnCharacterArrived()
|
private void OnCharacterArrived()
|
||||||
{
|
{
|
||||||
if (switchData == null || string.IsNullOrEmpty(switchData.targetLevelSceneName) || !_isActive)
|
if (switchData == null || string.IsNullOrEmpty(switchData.targetLevelSceneName) || !_isActive)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var menuPrefab = _interactionSettings?.LevelSwitchMenuPrefab;
|
var menuPrefab = _interactionSettings?.LevelSwitchMenuPrefab;
|
||||||
if (menuPrefab == null)
|
if (menuPrefab == null)
|
||||||
{
|
{
|
||||||
Debug.LogError("LevelSwitchMenu prefab not assigned in InteractionSettings!");
|
Debug.LogError("LevelSwitchMenu prefab not assigned in InteractionSettings!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Spawn the menu overlay (assume Canvas parent is handled in prefab setup)
|
// Spawn the menu overlay (assume Canvas parent is handled in prefab setup)
|
||||||
var menuGo = Instantiate(menuPrefab);
|
var menuGo = Instantiate(menuPrefab);
|
||||||
var menu = menuGo.GetComponent<LevelSwitchMenu>();
|
var menu = menuGo.GetComponent<LevelSwitchMenu>();
|
||||||
if (menu == null)
|
if (menu == null)
|
||||||
{
|
{
|
||||||
Debug.LogError("LevelSwitchMenu component missing on prefab!");
|
Debug.LogError("LevelSwitchMenu component missing on prefab!");
|
||||||
Destroy(menuGo);
|
Destroy(menuGo);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Setup menu with data and callbacks
|
// Setup menu with data and callbacks
|
||||||
menu.Setup(switchData, OnMenuConfirm, OnMenuCancel);
|
menu.Setup(switchData, OnMenuConfirm, OnMenuCancel);
|
||||||
_isActive = false; // Prevent re-triggering until menu is closed
|
_isActive = false; // Prevent re-triggering until menu is closed
|
||||||
|
|
||||||
// Switch input mode to UI only
|
// Switch input mode to UI only
|
||||||
InputManager.Instance.SetInputMode(InputMode.UI);
|
InputManager.Instance.SetInputMode(InputMode.UI);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void OnMenuConfirm()
|
private async void OnMenuConfirm()
|
||||||
{
|
{
|
||||||
var progress = new Progress<float>(p => Debug.Log($"Loading progress: {p * 100:F0}%"));
|
var progress = new Progress<float>(p => Debug.Log($"Loading progress: {p * 100:F0}%"));
|
||||||
await SceneManagerService.Instance.SwitchSceneAsync(switchData.targetLevelSceneName, progress);
|
await SceneManagerService.Instance.SwitchSceneAsync(switchData.targetLevelSceneName, progress);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnMenuCancel()
|
private void OnMenuCancel()
|
||||||
{
|
{
|
||||||
_isActive = true; // Allow interaction again if cancelled
|
_isActive = true; // Allow interaction again if cancelled
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
78
docs/camera_adaptation_readme.md
Normal file
78
docs/camera_adaptation_readme.md
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
# Camera Screen Adaptation System
|
||||||
|
|
||||||
|
This system helps adapt your 2D game's orthographic camera to different screen sizes, ensuring content is displayed consistently across various devices. It also provides tools for anchoring game objects to screen edges.
|
||||||
|
|
||||||
|
## Components
|
||||||
|
|
||||||
|
### 1. ScreenReferenceMarker
|
||||||
|
|
||||||
|
This component defines the target width and edge margins for your level content.
|
||||||
|
|
||||||
|
- **Target Width**: The desired width to be displayed on screen
|
||||||
|
- **Edge Margins**: Distances from screen edges for anchoring objects
|
||||||
|
- **Visualization**: Editor-only visualization of the reference sizes
|
||||||
|
|
||||||
|
### 2. CameraScreenAdapter
|
||||||
|
|
||||||
|
Automatically adjusts the camera's orthographic size to ensure the target width (defined by the ScreenReferenceMarker) matches the screen width.
|
||||||
|
|
||||||
|
- **Reference Marker**: Link to your ScreenReferenceMarker
|
||||||
|
- **Adapt on Resolution Change**: Automatically update when screen resolution changes
|
||||||
|
|
||||||
|
### 3. EdgeAnchor
|
||||||
|
|
||||||
|
Anchors game objects to screen edges, maintaining consistent distance when the camera's orthographic size changes.
|
||||||
|
|
||||||
|
- **Anchor Edge**: Which edge to anchor to (Top, Bottom, Left, Right)
|
||||||
|
- **Reference Marker**: Uses the same marker as the CameraScreenAdapter
|
||||||
|
- **Additional Offset**: Extra distance from the edge margin
|
||||||
|
- **Continuous Update**: Whether to update position every frame
|
||||||
|
|
||||||
|
### 4. CameraScreenVisualizer
|
||||||
|
|
||||||
|
Helper component for visualizing camera boundaries in the editor.
|
||||||
|
|
||||||
|
## Setup Instructions
|
||||||
|
|
||||||
|
### Basic Setup
|
||||||
|
|
||||||
|
1. **Create the Reference Marker:**
|
||||||
|
- Add a new empty GameObject to your scene
|
||||||
|
- Add the `ScreenReferenceMarker` component to it
|
||||||
|
- Position it at the center of your target view
|
||||||
|
- Set the `targetWidth` to match your level's ideal width
|
||||||
|
- Adjust margin values as needed
|
||||||
|
|
||||||
|
2. **Configure the Camera:**
|
||||||
|
- Add the `CameraScreenAdapter` component to your main camera
|
||||||
|
- Reference the ScreenReferenceMarker you created
|
||||||
|
- Optionally, add `CameraScreenVisualizer` for better editor visualization
|
||||||
|
|
||||||
|
3. **Anchor Game Objects:**
|
||||||
|
- For any objects that should maintain position relative to screen edges:
|
||||||
|
- Add the `EdgeAnchor` component
|
||||||
|
- Set the desired anchor edge (e.g., Top)
|
||||||
|
- Reference the same ScreenReferenceMarker
|
||||||
|
- Adjust additional offset if needed
|
||||||
|
|
||||||
|
### Example: Top-Edge Anchoring
|
||||||
|
|
||||||
|
For objects that need to stay a fixed distance from the top of the screen:
|
||||||
|
|
||||||
|
1. Set up your ScreenReferenceMarker with an appropriate topMargin value
|
||||||
|
2. Add EdgeAnchor to the object you want to anchor
|
||||||
|
3. Set AnchorEdge to Top
|
||||||
|
4. Adjust additionalOffset for fine-tuning
|
||||||
|
|
||||||
|
## Tips for Level Design
|
||||||
|
|
||||||
|
- Place the ScreenReferenceMarker at the center of your scene's critical content
|
||||||
|
- Use the visual gizmos to see how your reference width relates to camera boundaries
|
||||||
|
- Test your scene in different aspect ratios to ensure proper adaptation
|
||||||
|
- For complex levels, you might want multiple reference markers for different sections
|
||||||
|
|
||||||
|
## Runtime Considerations
|
||||||
|
|
||||||
|
- The system automatically adapts when the screen size changes
|
||||||
|
- The CameraScreenAdapter can be disabled if you need to temporarily override the automatic sizing
|
||||||
|
- EdgeAnchor components can be disabled when their objects don't need to maintain edge alignment
|
||||||
Reference in New Issue
Block a user