diff --git a/Assets/Prefabs/Managers/SceneManager.prefab b/Assets/Prefabs/Managers/SceneManager.prefab
index ea036003..d28c028c 100644
--- a/Assets/Prefabs/Managers/SceneManager.prefab
+++ b/Assets/Prefabs/Managers/SceneManager.prefab
@@ -29,7 +29,8 @@ Transform:
m_LocalPosition: {x: -3.4031, y: -1.84829, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
- m_Children: []
+ m_Children:
+ - {fileID: 7090108953567368886}
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &5327225408302228741
@@ -44,3 +45,125 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 360f320f4d7a48e38f5fd7cdfa28144a, type: 3}
m_Name:
m_EditorClassIdentifier:
+ loadingScreen: {fileID: 3391437592962192360}
+--- !u!1001 &6967569849783118800
+PrefabInstance:
+ m_ObjectHideFlags: 0
+ serializedVersion: 2
+ m_Modification:
+ serializedVersion: 3
+ m_TransformParent: {fileID: 3506046067200272545}
+ m_Modifications:
+ - target: {fileID: 204042265062571366, guid: 19fad826fce26d34ba304620216a7f47, type: 3}
+ propertyPath: m_Pivot.x
+ value: 0
+ objectReference: {fileID: 0}
+ - target: {fileID: 204042265062571366, guid: 19fad826fce26d34ba304620216a7f47, type: 3}
+ propertyPath: m_Pivot.y
+ value: 0
+ objectReference: {fileID: 0}
+ - target: {fileID: 204042265062571366, guid: 19fad826fce26d34ba304620216a7f47, type: 3}
+ propertyPath: m_AnchorMax.x
+ value: 0
+ objectReference: {fileID: 0}
+ - target: {fileID: 204042265062571366, guid: 19fad826fce26d34ba304620216a7f47, type: 3}
+ propertyPath: m_AnchorMax.y
+ value: 0
+ objectReference: {fileID: 0}
+ - target: {fileID: 204042265062571366, guid: 19fad826fce26d34ba304620216a7f47, type: 3}
+ propertyPath: m_AnchorMin.x
+ value: 0
+ objectReference: {fileID: 0}
+ - target: {fileID: 204042265062571366, guid: 19fad826fce26d34ba304620216a7f47, type: 3}
+ propertyPath: m_AnchorMin.y
+ value: 0
+ objectReference: {fileID: 0}
+ - target: {fileID: 204042265062571366, guid: 19fad826fce26d34ba304620216a7f47, type: 3}
+ propertyPath: m_SizeDelta.x
+ value: 0
+ objectReference: {fileID: 0}
+ - target: {fileID: 204042265062571366, guid: 19fad826fce26d34ba304620216a7f47, type: 3}
+ propertyPath: m_SizeDelta.y
+ value: 0
+ objectReference: {fileID: 0}
+ - target: {fileID: 204042265062571366, guid: 19fad826fce26d34ba304620216a7f47, type: 3}
+ propertyPath: m_LocalPosition.x
+ value: 0
+ objectReference: {fileID: 0}
+ - target: {fileID: 204042265062571366, guid: 19fad826fce26d34ba304620216a7f47, type: 3}
+ propertyPath: m_LocalPosition.y
+ value: 0
+ objectReference: {fileID: 0}
+ - target: {fileID: 204042265062571366, guid: 19fad826fce26d34ba304620216a7f47, type: 3}
+ propertyPath: m_LocalPosition.z
+ value: 0
+ objectReference: {fileID: 0}
+ - target: {fileID: 204042265062571366, guid: 19fad826fce26d34ba304620216a7f47, type: 3}
+ propertyPath: m_LocalRotation.w
+ value: 1
+ objectReference: {fileID: 0}
+ - target: {fileID: 204042265062571366, guid: 19fad826fce26d34ba304620216a7f47, type: 3}
+ propertyPath: m_LocalRotation.x
+ value: 0
+ objectReference: {fileID: 0}
+ - target: {fileID: 204042265062571366, guid: 19fad826fce26d34ba304620216a7f47, type: 3}
+ propertyPath: m_LocalRotation.y
+ value: 0
+ objectReference: {fileID: 0}
+ - target: {fileID: 204042265062571366, guid: 19fad826fce26d34ba304620216a7f47, type: 3}
+ propertyPath: m_LocalRotation.z
+ value: 0
+ objectReference: {fileID: 0}
+ - target: {fileID: 204042265062571366, guid: 19fad826fce26d34ba304620216a7f47, type: 3}
+ propertyPath: m_AnchoredPosition.x
+ value: 0
+ objectReference: {fileID: 0}
+ - target: {fileID: 204042265062571366, guid: 19fad826fce26d34ba304620216a7f47, type: 3}
+ propertyPath: m_AnchoredPosition.y
+ value: 0
+ objectReference: {fileID: 0}
+ - target: {fileID: 204042265062571366, guid: 19fad826fce26d34ba304620216a7f47, type: 3}
+ propertyPath: m_LocalEulerAnglesHint.x
+ value: 0
+ objectReference: {fileID: 0}
+ - target: {fileID: 204042265062571366, guid: 19fad826fce26d34ba304620216a7f47, type: 3}
+ propertyPath: m_LocalEulerAnglesHint.y
+ value: 0
+ objectReference: {fileID: 0}
+ - target: {fileID: 204042265062571366, guid: 19fad826fce26d34ba304620216a7f47, type: 3}
+ propertyPath: m_LocalEulerAnglesHint.z
+ value: 0
+ objectReference: {fileID: 0}
+ - target: {fileID: 4869161796575291839, guid: 19fad826fce26d34ba304620216a7f47, type: 3}
+ propertyPath: m_Name
+ value: LoadingScreen
+ objectReference: {fileID: 0}
+ - target: {fileID: 4869161796575291839, guid: 19fad826fce26d34ba304620216a7f47, type: 3}
+ propertyPath: m_IsActive
+ value: 1
+ objectReference: {fileID: 0}
+ - target: {fileID: 5737877680156686392, guid: 19fad826fce26d34ba304620216a7f47, type: 3}
+ propertyPath: minimumDisplayTime
+ value: 1
+ objectReference: {fileID: 0}
+ m_RemovedComponents: []
+ m_RemovedGameObjects: []
+ m_AddedGameObjects: []
+ m_AddedComponents: []
+ m_SourcePrefab: {fileID: 100100000, guid: 19fad826fce26d34ba304620216a7f47, type: 3}
+--- !u!114 &3391437592962192360 stripped
+MonoBehaviour:
+ m_CorrespondingSourceObject: {fileID: 5737877680156686392, guid: 19fad826fce26d34ba304620216a7f47, type: 3}
+ m_PrefabInstance: {fileID: 6967569849783118800}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 0}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: 1494b10574e74acd880f9101b4248239, type: 3}
+ m_Name:
+ m_EditorClassIdentifier: AppleHillsScripts::UI.LoadingScreenController
+--- !u!224 &7090108953567368886 stripped
+RectTransform:
+ m_CorrespondingSourceObject: {fileID: 204042265062571366, guid: 19fad826fce26d34ba304620216a7f47, type: 3}
+ m_PrefabInstance: {fileID: 6967569849783118800}
+ m_PrefabAsset: {fileID: 0}
diff --git a/Assets/Prefabs/UI/LoadingScreen.prefab b/Assets/Prefabs/UI/LoadingScreen.prefab
index ec83272c..ddbfae6f 100644
--- a/Assets/Prefabs/UI/LoadingScreen.prefab
+++ b/Assets/Prefabs/UI/LoadingScreen.prefab
@@ -1,6 +1,6 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
---- !u!1 &6227327056795603591
+--- !u!1 &1125713904569917005
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
@@ -8,198 +8,283 @@ GameObject:
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- - component: {fileID: 5037978548184922544}
- - component: {fileID: 2250902395970853255}
- - component: {fileID: 3558142398769816589}
- m_Layer: 5
- m_Name: LoadElement
- m_TagString: Untagged
- m_Icon: {fileID: 0}
- m_NavMeshLayer: 0
- m_StaticEditorFlags: 0
- m_IsActive: 1
---- !u!224 &5037978548184922544
-RectTransform:
- m_ObjectHideFlags: 0
- m_CorrespondingSourceObject: {fileID: 0}
- m_PrefabInstance: {fileID: 0}
- m_PrefabAsset: {fileID: 0}
- m_GameObject: {fileID: 6227327056795603591}
- 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: 3551826825771426741}
- 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!222 &2250902395970853255
-CanvasRenderer:
- m_ObjectHideFlags: 0
- m_CorrespondingSourceObject: {fileID: 0}
- m_PrefabInstance: {fileID: 0}
- m_PrefabAsset: {fileID: 0}
- m_GameObject: {fileID: 6227327056795603591}
- m_CullTransparentMesh: 1
---- !u!114 &3558142398769816589
-MonoBehaviour:
- m_ObjectHideFlags: 0
- m_CorrespondingSourceObject: {fileID: 0}
- m_PrefabInstance: {fileID: 0}
- m_PrefabAsset: {fileID: 0}
- m_GameObject: {fileID: 6227327056795603591}
- m_Enabled: 1
- m_EditorHideFlags: 0
- m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
- m_Name:
- m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.Image
- m_Material: {fileID: 0}
- m_Color: {r: 1, g: 1, b: 1, a: 1}
- m_RaycastTarget: 1
- m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
- m_Maskable: 1
- m_OnCullStateChanged:
- m_PersistentCalls:
- m_Calls: []
- m_Sprite: {fileID: -1067459232888207889, guid: 6767e1e5c0a16f14e926a72a81bf95cb, type: 3}
- m_Type: 3
- m_PreserveAspect: 0
- m_FillCenter: 1
- m_FillMethod: 1
- m_FillAmount: 0
- m_FillClockwise: 1
- m_FillOrigin: 0
- m_UseSpriteMesh: 0
- m_PixelsPerUnitMultiplier: 1
---- !u!1 &7358822077113160787
-GameObject:
- m_ObjectHideFlags: 0
- m_CorrespondingSourceObject: {fileID: 0}
- m_PrefabInstance: {fileID: 0}
- m_PrefabAsset: {fileID: 0}
- serializedVersion: 6
- m_Component:
- - component: {fileID: 3551826825771426741}
- - component: {fileID: 7315297104366629978}
- - component: {fileID: 3595348625820180868}
- m_Layer: 5
- m_Name: LoadingScreen
- m_TagString: Untagged
- m_Icon: {fileID: 0}
- m_NavMeshLayer: 0
- m_StaticEditorFlags: 0
- m_IsActive: 1
---- !u!224 &3551826825771426741
-RectTransform:
- m_ObjectHideFlags: 0
- m_CorrespondingSourceObject: {fileID: 0}
- m_PrefabInstance: {fileID: 0}
- m_PrefabAsset: {fileID: 0}
- m_GameObject: {fileID: 7358822077113160787}
- m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
- m_LocalPosition: {x: 0, y: 0, z: 0}
- m_LocalScale: {x: 1, y: 1, z: 1}
- m_ConstrainProportionsScale: 0
- m_Children:
- - {fileID: 1060159907441385154}
- - {fileID: 5037978548184922544}
- m_Father: {fileID: 0}
- m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
- m_AnchorMin: {x: 0.5, y: 0.5}
- m_AnchorMax: {x: 0.5, y: 0.5}
- m_AnchoredPosition: {x: 0, y: 0}
- m_SizeDelta: {x: 0, y: 0}
- m_Pivot: {x: 0.5, y: 0.5}
---- !u!114 &7315297104366629978
-MonoBehaviour:
- m_ObjectHideFlags: 0
- m_CorrespondingSourceObject: {fileID: 0}
- m_PrefabInstance: {fileID: 0}
- m_PrefabAsset: {fileID: 0}
- m_GameObject: {fileID: 7358822077113160787}
- m_Enabled: 1
- m_EditorHideFlags: 0
- m_Script: {fileID: 11500000, guid: 306cc8c2b49d7114eaa3623786fc2126, type: 3}
- m_Name:
- m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.LayoutElement
- m_IgnoreLayout: 0
- m_MinWidth: -1
- m_MinHeight: -1
- m_PreferredWidth: 400
- m_PreferredHeight: 400
- m_FlexibleWidth: -1
- m_FlexibleHeight: -1
- m_LayoutPriority: 1
---- !u!114 &3595348625820180868
-MonoBehaviour:
- m_ObjectHideFlags: 0
- m_CorrespondingSourceObject: {fileID: 0}
- m_PrefabInstance: {fileID: 0}
- m_PrefabAsset: {fileID: 0}
- m_GameObject: {fileID: 7358822077113160787}
- m_Enabled: 1
- m_EditorHideFlags: 0
- m_Script: {fileID: 11500000, guid: 3245ec927659c4140ac4f8d17403cc18, type: 3}
- m_Name:
- m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.ContentSizeFitter
- m_HorizontalFit: 2
- m_VerticalFit: 2
---- !u!1 &8774492328535489678
-GameObject:
- m_ObjectHideFlags: 0
- m_CorrespondingSourceObject: {fileID: 0}
- m_PrefabInstance: {fileID: 0}
- m_PrefabAsset: {fileID: 0}
- serializedVersion: 6
- m_Component:
- - component: {fileID: 1060159907441385154}
- - component: {fileID: 8332608793126180474}
- - component: {fileID: 2562764243080155070}
- m_Layer: 5
+ - component: {fileID: 1829050514129388015}
+ - component: {fileID: 6854969622723068570}
+ - component: {fileID: 2721768192801054246}
+ m_Layer: 0
m_Name: Background
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
---- !u!224 &1060159907441385154
+--- !u!224 &1829050514129388015
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
- m_GameObject: {fileID: 8774492328535489678}
+ m_GameObject: {fileID: 1125713904569917005}
+ 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: 2752257465779931077}
+ 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: 2240, y: 980}
+ m_Pivot: {x: 0.5, y: 0.5}
+--- !u!222 &6854969622723068570
+CanvasRenderer:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1125713904569917005}
+ m_CullTransparentMesh: 1
+--- !u!114 &2721768192801054246
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1125713904569917005}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
+ m_Name:
+ m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.Image
+ m_Material: {fileID: 0}
+ m_Color: {r: 0.4641509, g: 0.4641509, b: 0.4641509, a: 1}
+ m_RaycastTarget: 1
+ m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
+ m_Maskable: 1
+ m_OnCullStateChanged:
+ m_PersistentCalls:
+ m_Calls: []
+ m_Sprite: {fileID: 0}
+ m_Type: 0
+ m_PreserveAspect: 0
+ m_FillCenter: 1
+ m_FillMethod: 4
+ m_FillAmount: 1
+ m_FillClockwise: 1
+ m_FillOrigin: 0
+ m_UseSpriteMesh: 0
+ m_PixelsPerUnitMultiplier: 1
+--- !u!1 &4630651415052704154
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 1663577520044158588}
+ m_Layer: 5
+ m_Name: LoadingScreenElements
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!224 &1663577520044158588
+RectTransform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 4630651415052704154}
+ m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
+ m_LocalPosition: {x: 0, y: 0, z: 0}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_ConstrainProportionsScale: 0
+ m_Children:
+ - {fileID: 2948407004548698891}
+ - {fileID: 7185167273988469881}
+ m_Father: {fileID: 2752257465779931077}
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+ m_AnchorMin: {x: 0.5, y: 0.5}
+ m_AnchorMax: {x: 0.5, y: 0.5}
+ m_AnchoredPosition: {x: 0, y: 0}
+ m_SizeDelta: {x: 400, y: 400}
+ m_Pivot: {x: 0.5, y: 0.5}
+--- !u!1 &4869161796575291839
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 204042265062571366}
+ - component: {fileID: 7965354554598863860}
+ - component: {fileID: 1530258026314376533}
+ - component: {fileID: 6014203435857962984}
+ - component: {fileID: 5737877680156686392}
+ m_Layer: 0
+ m_Name: LoadingScreen
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!224 &204042265062571366
+RectTransform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 4869161796575291839}
+ 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: 2752257465779931077}
+ 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!223 &7965354554598863860
+Canvas:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 4869161796575291839}
+ m_Enabled: 1
+ serializedVersion: 3
+ m_RenderMode: 0
+ m_Camera: {fileID: 0}
+ m_PlaneDistance: 100
+ m_PixelPerfect: 0
+ m_ReceivesEvents: 1
+ m_OverrideSorting: 0
+ m_OverridePixelPerfect: 0
+ m_SortingBucketNormalizedSize: 0
+ m_VertexColorAlwaysGammaSpace: 0
+ m_AdditionalShaderChannelsFlag: 0
+ m_UpdateRectTransformForStandalone: 0
+ m_SortingLayerID: 0
+ m_SortingOrder: 10
+ m_TargetDisplay: 0
+--- !u!114 &1530258026314376533
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 4869161796575291839}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: 0cd44c1031e13a943bb63640046fad76, type: 3}
+ m_Name:
+ m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.CanvasScaler
+ 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!114 &6014203435857962984
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 4869161796575291839}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: dc42784cf147c0c48a680349fa168899, type: 3}
+ m_Name:
+ m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.GraphicRaycaster
+ m_IgnoreReversedGraphics: 1
+ m_BlockingObjects: 0
+ m_BlockingMask:
+ serializedVersion: 2
+ m_Bits: 4294967295
+--- !u!114 &5737877680156686392
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 4869161796575291839}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: 1494b10574e74acd880f9101b4248239, type: 3}
+ m_Name:
+ m_EditorClassIdentifier: AppleHillsScripts::UI.LoadingScreenController
+ loadingScreenContainer: {fileID: 7270617579256400696}
+ progressBarImage: {fileID: 1674678211233966532}
+ minimumDisplayTime: 2
+ animateProgressBar: 1
+ progressBarSmoothTime: 0.1
+ progressUpdateInterval: 0.1
+--- !u!1 &6888795583318782279
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 2948407004548698891}
+ - component: {fileID: 6196942992508754867}
+ - component: {fileID: 417829661404037751}
+ m_Layer: 5
+ m_Name: LoadBackground
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!224 &2948407004548698891
+RectTransform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 6888795583318782279}
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: 3551826825771426741}
+ m_Father: {fileID: 1663577520044158588}
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!222 &8332608793126180474
+--- !u!222 &6196942992508754867
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
- m_GameObject: {fileID: 8774492328535489678}
+ m_GameObject: {fileID: 6888795583318782279}
m_CullTransparentMesh: 1
---- !u!114 &2562764243080155070
+--- !u!114 &417829661404037751
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
- m_GameObject: {fileID: 8774492328535489678}
+ m_GameObject: {fileID: 6888795583318782279}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
@@ -223,3 +308,115 @@ MonoBehaviour:
m_FillOrigin: 0
m_UseSpriteMesh: 0
m_PixelsPerUnitMultiplier: 1
+--- !u!1 &7270617579256400696
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 2752257465779931077}
+ m_Layer: 0
+ m_Name: Container
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!224 &2752257465779931077
+RectTransform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 7270617579256400696}
+ m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_LocalPosition: {x: 0, y: 0, z: 0}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_ConstrainProportionsScale: 0
+ m_Children:
+ - {fileID: 1829050514129388015}
+ - {fileID: 1663577520044158588}
+ m_Father: {fileID: 204042265062571366}
+ 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: -2240, y: -980}
+ m_Pivot: {x: 0.5, y: 0.5}
+--- !u!1 &8086003862407389006
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 7185167273988469881}
+ - component: {fileID: 4134417229148755022}
+ - component: {fileID: 1674678211233966532}
+ m_Layer: 5
+ m_Name: LoadElement
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!224 &7185167273988469881
+RectTransform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 8086003862407389006}
+ 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: 1663577520044158588}
+ 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!222 &4134417229148755022
+CanvasRenderer:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 8086003862407389006}
+ m_CullTransparentMesh: 1
+--- !u!114 &1674678211233966532
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 8086003862407389006}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
+ m_Name:
+ m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.Image
+ m_Material: {fileID: 0}
+ m_Color: {r: 1, g: 1, b: 1, a: 1}
+ m_RaycastTarget: 1
+ m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
+ m_Maskable: 1
+ m_OnCullStateChanged:
+ m_PersistentCalls:
+ m_Calls: []
+ m_Sprite: {fileID: -1067459232888207889, guid: 6767e1e5c0a16f14e926a72a81bf95cb, type: 3}
+ m_Type: 3
+ m_PreserveAspect: 0
+ m_FillCenter: 1
+ m_FillMethod: 1
+ m_FillAmount: 0
+ m_FillClockwise: 1
+ m_FillOrigin: 0
+ m_UseSpriteMesh: 0
+ m_PixelsPerUnitMultiplier: 1
diff --git a/Assets/Prefabs/UI/LoadingScreen.prefab.meta b/Assets/Prefabs/UI/LoadingScreen.prefab.meta
index f7098a9d..0f9825e0 100644
--- a/Assets/Prefabs/UI/LoadingScreen.prefab.meta
+++ b/Assets/Prefabs/UI/LoadingScreen.prefab.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: 0e04621f47997754192ca4c53ed8c118
+guid: 19fad826fce26d34ba304620216a7f47
PrefabImporter:
externalObjects: {}
userData:
diff --git a/Assets/Scripts/Core/SceneManagerService.cs b/Assets/Scripts/Core/SceneManagerService.cs
index db3af600..0693f1ee 100644
--- a/Assets/Scripts/Core/SceneManagerService.cs
+++ b/Assets/Scripts/Core/SceneManagerService.cs
@@ -1,255 +1,299 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
+using UI;
using UnityEngine;
using UnityEngine.SceneManagement;
-///
-/// Singleton service for loading and unloading Unity scenes asynchronously, with events for progress and completion.
-///
-public class SceneManagerService : MonoBehaviour
+namespace Core
{
- private static SceneManagerService _instance;
- private static bool _isQuitting = false;
///
- /// Singleton instance of the SceneManagerService.
+ /// Singleton service for loading and unloading Unity scenes asynchronously, with events for progress and completion.
///
- public static SceneManagerService Instance
+ public class SceneManagerService : MonoBehaviour
{
- get
+ [SerializeField] private LoadingScreenController loadingScreen;
+
+ private static SceneManagerService _instance;
+ private static bool _isQuitting = false;
+ ///
+ /// Singleton instance of the SceneManagerService.
+ ///
+ public static SceneManagerService Instance
{
- if (_instance == null && Application.isPlaying && !_isQuitting)
+ get
{
- _instance = FindAnyObjectByType();
- if (_instance == null)
+ if (_instance == null && Application.isPlaying && !_isQuitting)
{
- var go = new GameObject("SceneManagerService");
- _instance = go.AddComponent();
- // DontDestroyOnLoad(go);
+ _instance = FindAnyObjectByType();
+ if (_instance == null)
+ {
+ var go = new GameObject("SceneManagerService");
+ _instance = go.AddComponent();
+ // DontDestroyOnLoad(go);
+ }
+ }
+ return _instance;
+ }
+ }
+
+ // Events for scene lifecycle
+ public event Action SceneLoadStarted;
+ public event Action SceneLoadProgress;
+ public event Action SceneLoadCompleted;
+ public event Action SceneUnloadStarted;
+ public event Action SceneUnloadProgress;
+ public event Action SceneUnloadCompleted;
+
+ private readonly Dictionary _activeLoads = new();
+ private readonly Dictionary _activeUnloads = new();
+ private const string BootstrapSceneName = "BootstrapScene";
+
+ void Awake()
+ {
+ _instance = this;
+ // DontDestroyOnLoad(gameObject);
+#if UNITY_EDITOR
+ // In Editor, set CurrentGameplayScene to the currently open scene at play start
+ if (Application.isPlaying)
+ {
+ var activeScene = SceneManager.GetActiveScene();
+ if (activeScene.IsValid())
+ {
+ CurrentGameplayScene = activeScene.name;
}
}
- return _instance;
- }
- }
-
- // Events for scene lifecycle
- public event Action SceneLoadStarted;
- public event Action SceneLoadProgress;
- public event Action SceneLoadCompleted;
- public event Action SceneUnloadStarted;
- public event Action SceneUnloadProgress;
- public event Action SceneUnloadCompleted;
-
- private readonly Dictionary _activeLoads = new();
- private readonly Dictionary _activeUnloads = new();
- private const string BootstrapSceneName = "BootstrapScene";
-
- void Awake()
- {
- _instance = this;
- // DontDestroyOnLoad(gameObject);
-#if UNITY_EDITOR
- // In Editor, set CurrentGameplayScene to the currently open scene at play start
- if (Application.isPlaying)
- {
- var activeScene = SceneManager.GetActiveScene();
- if (activeScene.IsValid())
- {
- CurrentGameplayScene = activeScene.name;
- }
- }
#endif
- // Ensure BootstrapScene is loaded at startup
- var bootstrap = SceneManager.GetSceneByName(BootstrapSceneName);
- if (!bootstrap.isLoaded)
- {
- SceneManager.LoadScene(BootstrapSceneName, LoadSceneMode.Additive);
- }
- }
-
- void OnApplicationQuit()
- {
- _isQuitting = true;
- }
-
- ///
- /// Load a single scene asynchronously (additive).
- ///
- /// Name of the scene to load.
- /// Optional progress reporter.
- public async Task LoadSceneAsync(string sceneName, IProgress progress = null)
- {
- SceneLoadStarted?.Invoke(sceneName);
- var op = SceneManager.LoadSceneAsync(sceneName, LoadSceneMode.Additive);
- _activeLoads[sceneName] = op;
- while (!op.isDone)
- {
- progress?.Report(op.progress);
- SceneLoadProgress?.Invoke(sceneName, op.progress);
- await Task.Yield();
- }
- _activeLoads.Remove(sceneName);
- SceneLoadCompleted?.Invoke(sceneName);
- }
-
- ///
- /// Unload a single scene asynchronously.
- ///
- /// Name of the scene to unload.
- /// Optional progress reporter.
- public async Task UnloadSceneAsync(string sceneName, IProgress progress = null)
- {
- var scene = SceneManager.GetSceneByName(sceneName);
- if (!scene.isLoaded)
- {
- Debug.LogWarning($"SceneManagerService: Attempted to unload scene '{sceneName}', but it is not loaded.");
- return;
- }
- SceneUnloadStarted?.Invoke(sceneName);
- var op = SceneManager.UnloadSceneAsync(sceneName);
- _activeUnloads[sceneName] = op;
- while (!op.isDone)
- {
- progress?.Report(op.progress);
- SceneUnloadProgress?.Invoke(sceneName, op.progress);
- await Task.Yield();
- }
- _activeUnloads.Remove(sceneName);
- SceneUnloadCompleted?.Invoke(sceneName);
- }
-
- ///
- /// Load multiple scenes asynchronously.
- ///
- /// Enumerable of scene names to load.
- /// Optional progress reporter.
- public async Task LoadScenesAsync(IEnumerable sceneNames, IProgress progress = null)
- {
- int total = 0;
- int done = 0;
- var ops = new List();
- foreach (var name in sceneNames)
- {
- total++;
- var op = SceneManager.LoadSceneAsync(name, LoadSceneMode.Additive);
- _activeLoads[name] = op;
- ops.Add(op);
- SceneLoadStarted?.Invoke(name);
- }
- while (done < total)
- {
- done = 0;
- float aggregate = 0f;
- foreach (var op in ops)
+ // Set up loading screen event handlers
+ SetupLoadingScreenEvents();
+
+ // Ensure BootstrapScene is loaded at startup
+ var bootstrap = SceneManager.GetSceneByName(BootstrapSceneName);
+ if (!bootstrap.isLoaded)
{
- if (op.isDone) done++;
- aggregate += op.progress;
+ SceneManager.LoadScene(BootstrapSceneName, LoadSceneMode.Additive);
}
- float avgProgress = aggregate / total;
- progress?.Report(avgProgress);
- // Optionally, could invoke SceneLoadProgress for each scene
- await Task.Yield();
}
- foreach (var name in sceneNames)
+
+ private void SetupLoadingScreenEvents()
{
- _activeLoads.Remove(name);
- SceneLoadCompleted?.Invoke(name);
+ if (loadingScreen == null) return;
+
+ SceneLoadStarted += _ => loadingScreen.ShowLoadingScreen();
+ SceneLoadCompleted += _ => loadingScreen.HideLoadingScreen();
}
- }
- ///
- /// Unload multiple scenes asynchronously.
- ///
- /// Enumerable of scene names to unload.
- /// Optional progress reporter.
- public async Task UnloadScenesAsync(IEnumerable sceneNames, IProgress progress = null)
- {
- int total = 0;
- int done = 0;
- var ops = new List();
- foreach (var name in sceneNames)
+ void OnApplicationQuit()
{
- total++;
- var op = SceneManager.UnloadSceneAsync(name);
- _activeUnloads[name] = op;
- ops.Add(op);
- SceneUnloadStarted?.Invoke(name);
+ _isQuitting = true;
}
- while (done < total)
+
+ ///
+ /// Load a single scene asynchronously (additive).
+ ///
+ /// Name of the scene to load.
+ /// Optional progress reporter.
+ public async Task LoadSceneAsync(string sceneName, IProgress progress = null)
{
- done = 0;
- float aggregate = 0f;
- foreach (var op in ops)
+ SceneLoadStarted?.Invoke(sceneName);
+ var op = SceneManager.LoadSceneAsync(sceneName, LoadSceneMode.Additive);
+ _activeLoads[sceneName] = op;
+ while (!op.isDone)
{
- aggregate += op.progress;
- if (op.isDone) done++;
+ progress?.Report(op.progress);
+ SceneLoadProgress?.Invoke(sceneName, op.progress);
+ await Task.Yield();
}
- float avg = aggregate / total;
- progress?.Report(avg);
+ _activeLoads.Remove(sceneName);
+ SceneLoadCompleted?.Invoke(sceneName);
+ }
+
+ ///
+ /// Unload a single scene asynchronously.
+ ///
+ /// Name of the scene to unload.
+ /// Optional progress reporter.
+ public async Task UnloadSceneAsync(string sceneName, IProgress progress = null)
+ {
+ var scene = SceneManager.GetSceneByName(sceneName);
+ if (!scene.isLoaded)
+ {
+ Debug.LogWarning($"SceneManagerService: Attempted to unload scene '{sceneName}', but it is not loaded.");
+ return;
+ }
+ SceneUnloadStarted?.Invoke(sceneName);
+ var op = SceneManager.UnloadSceneAsync(sceneName);
+ _activeUnloads[sceneName] = op;
+ while (!op.isDone)
+ {
+ progress?.Report(op.progress);
+ SceneUnloadProgress?.Invoke(sceneName, op.progress);
+ await Task.Yield();
+ }
+ _activeUnloads.Remove(sceneName);
+ SceneUnloadCompleted?.Invoke(sceneName);
+ }
+
+ ///
+ /// Load multiple scenes asynchronously.
+ ///
+ /// Enumerable of scene names to load.
+ /// Optional progress reporter.
+ public async Task LoadScenesAsync(IEnumerable sceneNames, IProgress progress = null)
+ {
+ // Show loading screen at the start of multiple scene loading
+ if (loadingScreen != null)
+ {
+ loadingScreen.ShowLoadingScreen();
+ }
+
+ int total = 0;
+ int done = 0;
+ var ops = new List();
foreach (var name in sceneNames)
- SceneUnloadProgress?.Invoke(name, avg);
- await Task.Yield();
- }
- foreach (var name in sceneNames)
- {
- _activeUnloads.Remove(name);
- SceneUnloadCompleted?.Invoke(name);
- }
- }
-
- // Optionally: expose current progress for all active operations
- public float GetAggregateLoadProgress()
- {
- if (_activeLoads.Count == 0) return 1f;
- float sum = 0f;
- foreach (var op in _activeLoads.Values) sum += op.progress;
- return sum / _activeLoads.Count;
- }
- public float GetAggregateUnloadProgress()
- {
- if (_activeUnloads.Count == 0) return 1f;
- float sum = 0f;
- foreach (var op in _activeUnloads.Values) sum += op.progress;
- return sum / _activeUnloads.Count;
- }
-
- // Tracks the currently loaded gameplay scene (not persistent/bootstrapper)
- public string CurrentGameplayScene { get; private set; } = "MainMenu";
-
- // Switches from current gameplay scene to a new one
- public async Task SwitchSceneAsync(string newSceneName, IProgress progress = null)
- {
- // Remove all AstarPath (A* Pathfinder) singletons before loading the new scene
- var astarPaths = FindObjectsByType(FindObjectsSortMode.None);
- foreach (var astar in astarPaths)
- {
- if (Application.isPlaying)
- Destroy(astar.gameObject);
- else
- DestroyImmediate(astar.gameObject);
- }
- // Unload previous gameplay scene (if not BootstrapScene and not same as new)
- if (!string.IsNullOrEmpty(CurrentGameplayScene) && CurrentGameplayScene != newSceneName && CurrentGameplayScene != BootstrapSceneName)
- {
- var prevScene = SceneManager.GetSceneByName(CurrentGameplayScene);
- if (prevScene.isLoaded)
{
- await UnloadSceneAsync(CurrentGameplayScene);
+ total++;
+ var op = SceneManager.LoadSceneAsync(name, LoadSceneMode.Additive);
+ _activeLoads[name] = op;
+ ops.Add(op);
+ SceneLoadStarted?.Invoke(name);
}
- else
+
+ while (done < total)
{
- Debug.LogWarning($"SceneManagerService: Previous scene '{CurrentGameplayScene}' is not loaded, skipping unload.");
+ done = 0;
+ float aggregate = 0f;
+ foreach (var op in ops)
+ {
+ if (op.isDone) done++;
+ aggregate += op.progress;
+ }
+ float avgProgress = aggregate / total;
+ progress?.Report(avgProgress);
+
+ await Task.Yield();
+ }
+
+ foreach (var name in sceneNames)
+ {
+ _activeLoads.Remove(name);
+ SceneLoadCompleted?.Invoke(name);
+ }
+
+ // Hide loading screen after all scenes are loaded
+ if (loadingScreen != null)
+ {
+ loadingScreen.HideLoadingScreen();
}
}
- // Ensure BootstrapScene is loaded before loading new scene
- var bootstrap = SceneManager.GetSceneByName(BootstrapSceneName);
- if (!bootstrap.isLoaded)
+
+ ///
+ /// Unload multiple scenes asynchronously.
+ ///
+ /// Enumerable of scene names to unload.
+ /// Optional progress reporter.
+ public async Task UnloadScenesAsync(IEnumerable sceneNames, IProgress progress = null)
{
- SceneManager.LoadScene(BootstrapSceneName, LoadSceneMode.Additive);
+ // Show loading screen at the start of multiple scene unloading
+ if (loadingScreen != null)
+ {
+ loadingScreen.ShowLoadingScreen();
+ }
+
+ int total = 0;
+ int done = 0;
+ var ops = new List();
+ foreach (var name in sceneNames)
+ {
+ total++;
+ var op = SceneManager.UnloadSceneAsync(name);
+ _activeUnloads[name] = op;
+ ops.Add(op);
+ SceneUnloadStarted?.Invoke(name);
+ }
+
+ while (done < total)
+ {
+ done = 0;
+ float aggregate = 0f;
+ foreach (var op in ops)
+ {
+ aggregate += op.progress;
+ if (op.isDone) done++;
+ }
+ float avg = aggregate / total;
+ progress?.Report(avg);
+
+ await Task.Yield();
+ }
+
+ foreach (var name in sceneNames)
+ {
+ _activeUnloads.Remove(name);
+ SceneUnloadCompleted?.Invoke(name);
+ }
+
+ // Hide loading screen after all scenes are unloaded
+ if (loadingScreen != null)
+ {
+ loadingScreen.HideLoadingScreen();
+ }
+ }
+
+ // Optionally: expose current progress for all active operations
+ public float GetAggregateLoadProgress()
+ {
+ if (_activeLoads.Count == 0) return 1f;
+ float sum = 0f;
+ foreach (var op in _activeLoads.Values) sum += op.progress;
+ return sum / _activeLoads.Count;
+ }
+ public float GetAggregateUnloadProgress()
+ {
+ if (_activeUnloads.Count == 0) return 1f;
+ float sum = 0f;
+ foreach (var op in _activeUnloads.Values) sum += op.progress;
+ return sum / _activeUnloads.Count;
+ }
+
+ // Tracks the currently loaded gameplay scene (not persistent/bootstrapper)
+ public string CurrentGameplayScene { get; private set; } = "MainMenu";
+
+ // Switches from current gameplay scene to a new one
+ public async Task SwitchSceneAsync(string newSceneName, IProgress progress = null)
+ {
+ // Remove all AstarPath (A* Pathfinder) singletons before loading the new scene
+ var astarPaths = FindObjectsByType(FindObjectsSortMode.None);
+ foreach (var astar in astarPaths)
+ {
+ if (Application.isPlaying)
+ Destroy(astar.gameObject);
+ else
+ DestroyImmediate(astar.gameObject);
+ }
+ // Unload previous gameplay scene (if not BootstrapScene and not same as new)
+ if (!string.IsNullOrEmpty(CurrentGameplayScene) && CurrentGameplayScene != newSceneName && CurrentGameplayScene != BootstrapSceneName)
+ {
+ var prevScene = SceneManager.GetSceneByName(CurrentGameplayScene);
+ if (prevScene.isLoaded)
+ {
+ await UnloadSceneAsync(CurrentGameplayScene);
+ }
+ else
+ {
+ Debug.LogWarning($"SceneManagerService: Previous scene '{CurrentGameplayScene}' is not loaded, skipping unload.");
+ }
+ }
+ // Ensure BootstrapScene is loaded before loading new scene
+ var bootstrap = SceneManager.GetSceneByName(BootstrapSceneName);
+ if (!bootstrap.isLoaded)
+ {
+ SceneManager.LoadScene(BootstrapSceneName, LoadSceneMode.Additive);
+ }
+ // Load new gameplay scene
+ await LoadSceneAsync(newSceneName, progress);
+ // Update tracker
+ CurrentGameplayScene = newSceneName;
}
- // Load new gameplay scene
- await LoadSceneAsync(newSceneName, progress);
- // Update tracker
- CurrentGameplayScene = newSceneName;
}
}
diff --git a/Assets/Scripts/LevelS/LevelSwitch.cs b/Assets/Scripts/LevelS/LevelSwitch.cs
index b37f9725..e94edf50 100644
--- a/Assets/Scripts/LevelS/LevelSwitch.cs
+++ b/Assets/Scripts/LevelS/LevelSwitch.cs
@@ -2,7 +2,8 @@
using Input;
using Interactions;
using UnityEngine;
-using AppleHills.Core.Settings; // Added for IInteractionSettings
+using AppleHills.Core.Settings;
+using Core; // Added for IInteractionSettings
///
/// Handles level switching when interacted with. Applies switch data and triggers scene transitions.
diff --git a/Assets/Scripts/UI/LoadingScreenController.cs b/Assets/Scripts/UI/LoadingScreenController.cs
new file mode 100644
index 00000000..9a629f7c
--- /dev/null
+++ b/Assets/Scripts/UI/LoadingScreenController.cs
@@ -0,0 +1,168 @@
+using System.Collections;
+using UnityEngine;
+using UnityEngine.UI;
+using Core;
+
+namespace UI
+{
+ ///
+ /// Controls the loading screen UI display, progress updates, and timing
+ ///
+ public class LoadingScreenController : MonoBehaviour
+ {
+ [Header("UI References")]
+ [SerializeField] private GameObject loadingScreenContainer;
+ [SerializeField] private Image progressBarImage;
+
+ [Header("Settings")]
+ [SerializeField] private float minimumDisplayTime = 1.0f;
+ [SerializeField] private float progressUpdateInterval = 0.1f;
+
+ private float _displayStartTime;
+ private Coroutine _progressCoroutine;
+ private bool _loadingComplete = false;
+ private bool _animationComplete = false;
+
+ private void Awake()
+ {
+ if (loadingScreenContainer == null)
+ loadingScreenContainer = gameObject;
+
+ // Ensure the loading screen is initially hidden
+ if (loadingScreenContainer != null)
+ {
+ loadingScreenContainer.SetActive(false);
+ }
+ }
+
+ ///
+ /// Shows the loading screen and resets the progress bar to zero
+ ///
+ public void ShowLoadingScreen()
+ {
+ // Stop any existing progress coroutine
+ if (_progressCoroutine != null)
+ {
+ StopCoroutine(_progressCoroutine);
+ _progressCoroutine = null;
+ }
+
+ _displayStartTime = Time.time;
+ _loadingComplete = false;
+ _animationComplete = false;
+
+ if (progressBarImage != null)
+ {
+ progressBarImage.fillAmount = 0f;
+ }
+
+ if (loadingScreenContainer != null)
+ {
+ loadingScreenContainer.SetActive(true);
+ }
+
+ // Start the progress filling coroutine
+ _progressCoroutine = StartCoroutine(AnimateProgressBar());
+ }
+
+ ///
+ /// Animates the progress bar at a steady pace over the minimum display time,
+ /// while also checking actual loading progress from SceneManagerService
+ ///
+ private IEnumerator AnimateProgressBar()
+ {
+ float startTime = Time.time;
+
+ // Continue until both animation and loading are complete
+ while (!_animationComplete)
+ {
+ // Calculate the steady progress based on elapsed time
+ float elapsedTime = Time.time - startTime;
+ float steadyProgress = Mathf.Clamp01(elapsedTime / minimumDisplayTime);
+
+ // Get the actual loading progress from SceneManagerService
+ float actualProgress = 0f;
+ if (SceneManagerService.Instance != null)
+ {
+ actualProgress = SceneManagerService.Instance.GetAggregateLoadProgress();
+ }
+
+ // If loading is complete, actualProgress should be 1.0
+ if (_loadingComplete)
+ {
+ actualProgress = 1.0f;
+ }
+
+ // Use the minimum of steady progress and actual progress
+ // This ensures we don't show more progress than actual loading
+ float displayProgress = Mathf.Min(steadyProgress, actualProgress);
+
+ // Log the progress values for debugging
+ Debug.Log($"[LoadingScreen] Progress - Default: {steadyProgress:F2}, Actual: {actualProgress:F2}, Display: {displayProgress:F2}");
+
+ // Directly set the progress bar fill amount without smoothing
+ if (progressBarImage != null)
+ {
+ progressBarImage.fillAmount = displayProgress;
+ }
+
+ // Check if the animation has completed
+ // Animation is complete when we've reached the minimum display time AND we're at 100% progress
+ if (steadyProgress >= 1.0f && displayProgress >= 1.0f)
+ {
+ _animationComplete = true;
+ Debug.Log("[LoadingScreen] Animation complete");
+ break;
+ }
+
+ // Wait for the configured interval before updating again
+ yield return new WaitForSeconds(progressUpdateInterval);
+ }
+
+ // Ensure we end at 100% progress
+ if (progressBarImage != null)
+ {
+ progressBarImage.fillAmount = 1.0f;
+ Debug.Log("[LoadingScreen] Final progress set to 1.0");
+ }
+
+ // Hide the screen if loading is also complete
+ if (_loadingComplete)
+ {
+ if (loadingScreenContainer != null)
+ {
+ loadingScreenContainer.SetActive(false);
+ Debug.Log("[LoadingScreen] Animation AND loading complete, hiding screen");
+ }
+ }
+
+ _progressCoroutine = null;
+ }
+
+ ///
+ /// Called when the actual loading process is complete
+ ///
+ public void HideLoadingScreen()
+ {
+ Debug.Log("[LoadingScreen] Loading complete, marking loading as finished");
+
+ // Mark that loading is complete
+ _loadingComplete = true;
+
+ // If animation is already complete, we can hide the screen now
+ if (_animationComplete)
+ {
+ if (loadingScreenContainer != null)
+ {
+ loadingScreenContainer.SetActive(false);
+ Debug.Log("[LoadingScreen] Animation already complete, hiding screen immediately");
+ }
+ }
+ else
+ {
+ Debug.Log("[LoadingScreen] Animation still in progress, waiting for it to complete");
+ // The coroutine will handle hiding when animation completes
+ }
+ }
+ }
+}
diff --git a/Assets/Scripts/UI/LoadingScreenController.cs.meta b/Assets/Scripts/UI/LoadingScreenController.cs.meta
new file mode 100644
index 00000000..403584a1
--- /dev/null
+++ b/Assets/Scripts/UI/LoadingScreenController.cs.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 1494b10574e74acd880f9101b4248239
+timeCreated: 1760341032
\ No newline at end of file
diff --git a/Assets/Scripts/UI/MainMenu.cs b/Assets/Scripts/UI/MainMenu.cs
index 59dc1e02..6aca0c16 100644
--- a/Assets/Scripts/UI/MainMenu.cs
+++ b/Assets/Scripts/UI/MainMenu.cs
@@ -1,4 +1,5 @@
using System;
+using Core;
using UnityEngine;
using UnityEngine.SceneManagement;
diff --git a/Assets/Scripts/UI/PauseMenu.cs b/Assets/Scripts/UI/PauseMenu.cs
index ed500867..a94f6b7f 100644
--- a/Assets/Scripts/UI/PauseMenu.cs
+++ b/Assets/Scripts/UI/PauseMenu.cs
@@ -1,4 +1,5 @@
using System;
+using Core;
using UnityEngine;
using UnityEngine.SceneManagement;
using Input;