Merge branch 'main' into DamianBranch

This commit is contained in:
2025-10-13 10:17:54 +00:00
24 changed files with 4634 additions and 2074 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

@@ -0,0 +1,195 @@
fileFormatVersion: 2
guid: bcd3fab43168dbd43a286294c6cc7838
TextureImporter:
internalIDToNameTable:
- first:
213: 2758595457390328306
second: progress_circle_0
externalObjects: {}
serializedVersion: 13
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 1
wrapV: 1
wrapW: 1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 2
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 4
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: iOS
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: Android
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: WebGL
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: WindowsStoreApps
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites:
- serializedVersion: 2
name: progress_circle_0
rect:
serializedVersion: 2
x: 0
y: 1
width: 250
height: 247
alignment: 0
pivot: {x: 0, y: 0}
border: {x: 0, y: 0, z: 0, w: 0}
customData:
outline: []
physicsShape: []
tessellationDetail: -1
bones: []
spriteID: 2f9b1cce3ff784620800000000000000
internalID: 2758595457390328306
vertices: []
indices:
edges: []
weights: []
outline: []
customData:
physicsShape: []
bones: []
spriteID:
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spriteCustomMetadata:
entries: []
nameFileIdTable:
progress_circle_0: 2758595457390328306
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -60,7 +60,7 @@ Canvas:
m_AdditionalShaderChannelsFlag: 0 m_AdditionalShaderChannelsFlag: 0
m_UpdateRectTransformForStandalone: 0 m_UpdateRectTransformForStandalone: 0
m_SortingLayerID: 0 m_SortingLayerID: 0
m_SortingOrder: 0 m_SortingOrder: 10
m_TargetDisplay: 0 m_TargetDisplay: 0
--- !u!114 &3022940599780685530 --- !u!114 &3022940599780685530
MonoBehaviour: MonoBehaviour:
@@ -173,6 +173,81 @@ PlayableDirector:
value: {fileID: 0} value: {fileID: 0}
m_ExposedReferences: m_ExposedReferences:
m_References: [] m_References: []
--- !u!1 &3669323127008070100
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 538506048417711235}
- component: {fileID: 1082932495279705792}
- component: {fileID: 2786577800096043956}
m_Layer: 5
m_Name: SkipProgress
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &538506048417711235
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3669323127008070100}
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: 5494371867874695937}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 1, y: 0}
m_AnchorMax: {x: 1, y: 0}
m_AnchoredPosition: {x: -100, y: 100}
m_SizeDelta: {x: 100, y: 100}
m_Pivot: {x: 1, y: 0}
--- !u!222 &1082932495279705792
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3669323127008070100}
m_CullTransparentMesh: 1
--- !u!114 &2786577800096043956
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3669323127008070100}
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: 2758595457390328306, guid: bcd3fab43168dbd43a286294c6cc7838, type: 3}
m_Type: 3
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 0
m_FillClockwise: 1
m_FillOrigin: 0
m_UseSpriteMesh: 0
m_PixelsPerUnitMultiplier: 1
--- !u!1 &9166576207668444836 --- !u!1 &9166576207668444836
GameObject: GameObject:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
@@ -185,6 +260,7 @@ GameObject:
- component: {fileID: 3902696341833554714} - component: {fileID: 3902696341833554714}
- component: {fileID: 8235080513953117507} - component: {fileID: 8235080513953117507}
- component: {fileID: 2900690403017929526} - component: {fileID: 2900690403017929526}
- component: {fileID: 3357796695825044110}
m_Layer: 5 m_Layer: 5
m_Name: CinematicSprites m_Name: CinematicSprites
m_TagString: Untagged m_TagString: Untagged
@@ -203,7 +279,8 @@ RectTransform:
m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1} m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0 m_ConstrainProportionsScale: 0
m_Children: [] m_Children:
- {fileID: 538506048417711235}
m_Father: {fileID: 592992386388815559} m_Father: {fileID: 592992386388815559}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0} m_AnchorMin: {x: 0, y: 0}
@@ -271,3 +348,17 @@ Animator:
m_AllowConstantClipSamplingOptimization: 1 m_AllowConstantClipSamplingOptimization: 1
m_KeepAnimatorStateOnDisable: 0 m_KeepAnimatorStateOnDisable: 0
m_WriteDefaultValuesOnDisable: 0 m_WriteDefaultValuesOnDisable: 0
--- !u!114 &3357796695825044110
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 9166576207668444836}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 5526348c1593f9b43987b0edcaccdd24, type: 3}
m_Name:
m_EditorClassIdentifier: '::'
holdDuration: 1
radialProgressBar: {fileID: 2786577800096043956}

View File

@@ -29,7 +29,8 @@ Transform:
m_LocalPosition: {x: -3.4031, y: -1.84829, z: 0} m_LocalPosition: {x: -3.4031, y: -1.84829, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1} m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0 m_ConstrainProportionsScale: 0
m_Children: [] m_Children:
- {fileID: 7090108953567368886}
m_Father: {fileID: 0} m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &5327225408302228741 --- !u!114 &5327225408302228741
@@ -44,3 +45,125 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 360f320f4d7a48e38f5fd7cdfa28144a, type: 3} m_Script: {fileID: 11500000, guid: 360f320f4d7a48e38f5fd7cdfa28144a, type: 3}
m_Name: m_Name:
m_EditorClassIdentifier: 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}

View File

@@ -437,7 +437,7 @@ MonoBehaviour:
m_FallbackScreenDPI: 96 m_FallbackScreenDPI: 96
m_DefaultSpriteDPI: 96 m_DefaultSpriteDPI: 96
m_DynamicPixelsPerUnit: 1 m_DynamicPixelsPerUnit: 1
m_PresetInfoIsWorld: 1 m_PresetInfoIsWorld: 0
--- !u!114 &9137259633125916521 --- !u!114 &9137259633125916521
MonoBehaviour: MonoBehaviour:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0

View File

@@ -0,0 +1,422 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &1125713904569917005
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- 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 &1829050514129388015
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
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: 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 &6196942992508754867
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 6888795583318782279}
m_CullTransparentMesh: 1
--- !u!114 &417829661404037751
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 6888795583318782279}
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.13207549, g: 0.13207549, b: 0.13207549, 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: 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 &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

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 19fad826fce26d34ba304620216a7f47
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@@ -456006,6 +456006,10 @@ PrefabInstance:
propertyPath: m_Name propertyPath: m_Name
value: DialogueCanvas value: DialogueCanvas
objectReference: {fileID: 0} objectReference: {fileID: 0}
- target: {fileID: 6771925387362164676, guid: a8b0a1c6cf21352439dc24d3b03182db, type: 3}
propertyPath: m_PresetInfoIsWorld
value: 1
objectReference: {fileID: 0}
- target: {fileID: 7704981663008171144, guid: a8b0a1c6cf21352439dc24d3b03182db, type: 3} - target: {fileID: 7704981663008171144, guid: a8b0a1c6cf21352439dc24d3b03182db, type: 3}
propertyPath: m_AnchorMax.y propertyPath: m_AnchorMax.y
value: 0 value: 0
@@ -456065,7 +456069,7 @@ MonoBehaviour:
m_Name: m_Name:
m_EditorClassIdentifier: AppleHillsScripts::Dialogue.SpeechBubble m_EditorClassIdentifier: AppleHillsScripts::Dialogue.SpeechBubble
textDisplay: {fileID: 1200370542} textDisplay: {fileID: 1200370542}
imageDisplay: {fileID: 0} imageDisplay: {fileID: 2114652570}
displayMode: 1 displayMode: 1
typewriterSpeed: 0.05 typewriterSpeed: 0.05
typingSoundSource: {fileID: 0} typingSoundSource: {fileID: 0}
@@ -463232,6 +463236,17 @@ Transform:
m_CorrespondingSourceObject: {fileID: 5145306031820616614, guid: fbbe1f4baf226904b96f839fe0c00181, type: 3} m_CorrespondingSourceObject: {fileID: 5145306031820616614, guid: fbbe1f4baf226904b96f839fe0c00181, type: 3}
m_PrefabInstance: {fileID: 2109163090} m_PrefabInstance: {fileID: 2109163090}
m_PrefabAsset: {fileID: 0} m_PrefabAsset: {fileID: 0}
--- !u!114 &2114652570 stripped
MonoBehaviour:
m_CorrespondingSourceObject: {fileID: 60731842453945467, guid: a8b0a1c6cf21352439dc24d3b03182db, type: 3}
m_PrefabInstance: {fileID: 1687785381}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
m_Name:
m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.Image
--- !u!1001 &2117822310 --- !u!1001 &2117822310
PrefabInstance: PrefabInstance:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0

View File

@@ -714,7 +714,6 @@ MonoBehaviour:
m_ScreenCoordScaleBias: {x: 0, y: 0, z: 0, w: 0} m_ScreenCoordScaleBias: {x: 0, y: 0, z: 0, w: 0}
m_RequiresDepthTexture: 0 m_RequiresDepthTexture: 0
m_RequiresColorTexture: 0 m_RequiresColorTexture: 0
m_Version: 2
m_TaaSettings: m_TaaSettings:
m_Quality: 3 m_Quality: 3
m_FrameInfluence: 0.1 m_FrameInfluence: 0.1
@@ -722,6 +721,7 @@ MonoBehaviour:
m_MipBias: 0 m_MipBias: 0
m_VarianceClampScale: 0.9 m_VarianceClampScale: 0.9
m_ContrastAdaptiveSharpening: 0 m_ContrastAdaptiveSharpening: 0
m_Version: 2
--- !u!1 &1285439200 --- !u!1 &1285439200
GameObject: GameObject:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 9999e33608d12e04a87dd0edf7b7866f
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,14 +1,12 @@
using Bootstrap; using System.Collections.Generic;
using System;
using UnityEditor;
using UnityEngine; using UnityEngine;
using UnityEngine.AddressableAssets; using UnityEngine.AddressableAssets;
using UnityEngine.InputSystem; using UnityEngine.ResourceManagement.AsyncOperations;
using UnityEngine.Playables; using UnityEngine.Playables;
using UnityEngine.SceneManagement; using UnityEngine.SceneManagement;
using UnityEngine.UI; using UnityEngine.UI;
namespace CinematicsM namespace Cinematics
{ {
/// <summary> /// <summary>
/// Handles loading, playing and unloading cinematics /// Handles loading, playing and unloading cinematics
@@ -20,6 +18,10 @@ namespace CinematicsM
private Image cinematicSprites; private Image cinematicSprites;
public PlayableAsset cinematicToPlay; public PlayableAsset cinematicToPlay;
// Dictionary to track addressable handles by PlayableDirector
private Dictionary<PlayableDirector, AsyncOperationHandle<PlayableAsset>> _addressableHandles
= new Dictionary<PlayableDirector, AsyncOperationHandle<PlayableAsset>>();
public static CinematicsManager Instance public static CinematicsManager Instance
{ {
get get
@@ -41,8 +43,24 @@ namespace CinematicsM
private void OnEnable() private void OnEnable()
{ {
// Subscribe to application quit event to ensure cleanup
Application.quitting += OnApplicationQuit;
} }
private void OnDisable()
{
// Unsubscribe from application quit event
Application.quitting -= OnApplicationQuit;
// Clean up any remaining addressable handles when disabled
ReleaseAllHandles();
}
private void OnApplicationQuit()
{
ReleaseAllHandles();
}
/// <summary> /// <summary>
/// Plays a cinematic from an object reference and returns the PlayableDirector playing the timeline /// Plays a cinematic from an object reference and returns the PlayableDirector playing the timeline
/// </summary> /// </summary>
@@ -59,6 +77,9 @@ namespace CinematicsM
{ {
cinematicSprites.enabled = false; cinematicSprites.enabled = false;
Debug.Log("Cinematic stopped!"); Debug.Log("Cinematic stopped!");
// Release the addressable handle associated with this director
ReleaseAddressableHandle(director);
} }
/// <summary> /// <summary>
@@ -66,18 +87,73 @@ namespace CinematicsM
/// </summary> /// </summary>
public PlayableDirector LoadAndPlayCinematic(string key) public PlayableDirector LoadAndPlayCinematic(string key)
{ {
// Load the asset via addressables
var handle = Addressables.LoadAssetAsync<PlayableAsset>(key); var handle = Addressables.LoadAssetAsync<PlayableAsset>(key);
var result = handle.WaitForCompletion(); var result = handle.WaitForCompletion();
// Store the handle for later release
_addressableHandles[playableDirector] = handle;
Debug.Log($"[CinematicsManager] Loaded addressable cinematic: {key}");
return PlayCinematic(result); return PlayCinematic(result);
} }
// Update is called once per frame /// <summary>
void Update() /// Skips the currently playing cinematic if one is active
{ /// </summary>
public void SkipCurrentCinematic()
}
private void Awake()
{ {
if (playableDirector != null && playableDirector.state == PlayState.Playing)
{
Debug.Log("Skipping current cinematic");
playableDirector.Stop();
}
}
/// <summary>
/// Checks if a cinematic is currently playing
/// </summary>
public bool IsCinematicPlaying()
{
return playableDirector != null && playableDirector.state == PlayState.Playing;
}
/// <summary>
/// Releases the addressable handle associated with a specific PlayableDirector
/// </summary>
private void ReleaseAddressableHandle(PlayableDirector director)
{
if (_addressableHandles.TryGetValue(director, out var handle))
{
Debug.Log($"[CinematicsManager] Releasing addressable handle for cinematic");
Addressables.Release(handle);
_addressableHandles.Remove(director);
}
}
/// <summary>
/// Releases all active addressable handles
/// </summary>
private void ReleaseAllHandles()
{
foreach (var handle in _addressableHandles.Values)
{
if (handle.IsValid())
{
Addressables.Release(handle);
}
}
_addressableHandles.Clear();
}
private void Start()
{
if (!SceneManager.GetActiveScene().name.ToLower().Contains("mainmenu"))
{
return;
}
_instance = this; _instance = this;
if (!SceneManager.GetActiveScene().name.ToLower().Contains("mainmenu")) if (!SceneManager.GetActiveScene().name.ToLower().Contains("mainmenu"))

View File

@@ -0,0 +1,112 @@
using Input;
using UnityEngine;
using UnityEngine.UI;
namespace Cinematics
{
public class SkipCinematic : MonoBehaviour, ITouchInputConsumer
{
[Header("Configuration")]
[SerializeField] private float holdDuration = 2.0f;
[SerializeField] private Image radialProgressBar;
private float _holdStartTime;
private bool _isHolding;
private bool _skipPerformed;
void Start()
{
// Reset the progress bar
if (radialProgressBar != null)
{
radialProgressBar.fillAmount = 0f;
}
}
void OnEnable()
{
// Register as override consumer when enabled
InputManager.Instance.RegisterOverrideConsumer(this);
}
void OnDisable()
{
// Unregister when disabled
InputManager.Instance.UnregisterOverrideConsumer(this);
}
void Update()
{
// Only process while cinematic is playing and we're holding
if (_isHolding && CinematicsManager.Instance.IsCinematicPlaying())
{
float holdTime = Time.time - _holdStartTime;
float progress = Mathf.Clamp01(holdTime / holdDuration);
// Update progress bar
if (radialProgressBar != null)
{
radialProgressBar.fillAmount = progress;
}
// Check if we've held long enough to skip
if (progress >= 1.0f && !_skipPerformed)
{
_skipPerformed = true;
DoSkipCinematic();
}
}
}
private void DoSkipCinematic()
{
CinematicsManager.Instance.SkipCurrentCinematic();
Debug.Log("Cinematic skipped via touch hold");
// Reset UI
if (radialProgressBar != null)
{
radialProgressBar.fillAmount = 0f;
}
// Remember to clear up input override
InputManager.Instance.UnregisterOverrideConsumer(this);
}
#region ITouchInputConsumer Implementation
public void OnTap(Vector2 position)
{
// Not using tap for skipping
}
public void OnHoldStart(Vector2 position)
{
// Start tracking hold time
_isHolding = true;
_skipPerformed = false;
_holdStartTime = Time.time;
Debug.Log("Starting cinematic skip gesture");
}
public void OnHoldMove(Vector2 position)
{
// Hold movement is tracked in Update method
}
public void OnHoldEnd(Vector2 position)
{
// Reset state when hold ends
_isHolding = false;
// Reset UI
if (radialProgressBar != null)
{
radialProgressBar.fillAmount = 0f;
}
Debug.Log("Cinematic skip gesture canceled");
}
#endregion
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 5526348c1593f9b43987b0edcaccdd24

View File

@@ -1,12 +1,8 @@
using UnityEngine; using UnityEngine;
using Interactions;
using System.Collections.Generic;
using AppleHills.Core.Settings;
using AppleHills.Data.CardSystem; using AppleHills.Data.CardSystem;
using CinematicsM; using Cinematics;
using Core; using Core;
using Input; using Input;
using Minigames.DivingForPictures;
using PuzzleS; using PuzzleS;
namespace AppleHills.Core namespace AppleHills.Core

View File

@@ -1,255 +1,299 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using UI;
using UnityEngine; using UnityEngine;
using UnityEngine.SceneManagement; using UnityEngine.SceneManagement;
/// <summary> namespace Core
/// Singleton service for loading and unloading Unity scenes asynchronously, with events for progress and completion.
/// </summary>
public class SceneManagerService : MonoBehaviour
{ {
private static SceneManagerService _instance;
private static bool _isQuitting = false;
/// <summary> /// <summary>
/// Singleton instance of the SceneManagerService. /// Singleton service for loading and unloading Unity scenes asynchronously, with events for progress and completion.
/// </summary> /// </summary>
public static SceneManagerService Instance public class SceneManagerService : MonoBehaviour
{ {
get [SerializeField] private LoadingScreenController loadingScreen;
private static SceneManagerService _instance;
private static bool _isQuitting = false;
/// <summary>
/// Singleton instance of the SceneManagerService.
/// </summary>
public static SceneManagerService Instance
{ {
if (_instance == null && Application.isPlaying && !_isQuitting) get
{ {
_instance = FindAnyObjectByType<SceneManagerService>(); if (_instance == null && Application.isPlaying && !_isQuitting)
if (_instance == null)
{ {
var go = new GameObject("SceneManagerService"); _instance = FindAnyObjectByType<SceneManagerService>();
_instance = go.AddComponent<SceneManagerService>(); if (_instance == null)
// DontDestroyOnLoad(go); {
var go = new GameObject("SceneManagerService");
_instance = go.AddComponent<SceneManagerService>();
// DontDestroyOnLoad(go);
}
}
return _instance;
}
}
// Events for scene lifecycle
public event Action<string> SceneLoadStarted;
public event Action<string, float> SceneLoadProgress;
public event Action<string> SceneLoadCompleted;
public event Action<string> SceneUnloadStarted;
public event Action<string, float> SceneUnloadProgress;
public event Action<string> SceneUnloadCompleted;
private readonly Dictionary<string, AsyncOperation> _activeLoads = new();
private readonly Dictionary<string, AsyncOperation> _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<string> SceneLoadStarted;
public event Action<string, float> SceneLoadProgress;
public event Action<string> SceneLoadCompleted;
public event Action<string> SceneUnloadStarted;
public event Action<string, float> SceneUnloadProgress;
public event Action<string> SceneUnloadCompleted;
private readonly Dictionary<string, AsyncOperation> _activeLoads = new();
private readonly Dictionary<string, AsyncOperation> _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 #endif
// Ensure BootstrapScene is loaded at startup // Set up loading screen event handlers
var bootstrap = SceneManager.GetSceneByName(BootstrapSceneName); SetupLoadingScreenEvents();
if (!bootstrap.isLoaded)
{ // Ensure BootstrapScene is loaded at startup
SceneManager.LoadScene(BootstrapSceneName, LoadSceneMode.Additive); var bootstrap = SceneManager.GetSceneByName(BootstrapSceneName);
} if (!bootstrap.isLoaded)
}
void OnApplicationQuit()
{
_isQuitting = true;
}
/// <summary>
/// Load a single scene asynchronously (additive).
/// </summary>
/// <param name="sceneName">Name of the scene to load.</param>
/// <param name="progress">Optional progress reporter.</param>
public async Task LoadSceneAsync(string sceneName, IProgress<float> 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);
}
/// <summary>
/// Unload a single scene asynchronously.
/// </summary>
/// <param name="sceneName">Name of the scene to unload.</param>
/// <param name="progress">Optional progress reporter.</param>
public async Task UnloadSceneAsync(string sceneName, IProgress<float> 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);
}
/// <summary>
/// Load multiple scenes asynchronously.
/// </summary>
/// <param name="sceneNames">Enumerable of scene names to load.</param>
/// <param name="progress">Optional progress reporter.</param>
public async Task LoadScenesAsync(IEnumerable<string> sceneNames, IProgress<float> progress = null)
{
int total = 0;
int done = 0;
var ops = new List<AsyncOperation>();
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)
{ {
if (op.isDone) done++; SceneManager.LoadScene(BootstrapSceneName, LoadSceneMode.Additive);
aggregate += op.progress;
} }
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); if (loadingScreen == null) return;
SceneLoadCompleted?.Invoke(name);
SceneLoadStarted += _ => loadingScreen.ShowLoadingScreen();
SceneLoadCompleted += _ => loadingScreen.HideLoadingScreen();
} }
}
/// <summary> void OnApplicationQuit()
/// Unload multiple scenes asynchronously.
/// </summary>
/// <param name="sceneNames">Enumerable of scene names to unload.</param>
/// <param name="progress">Optional progress reporter.</param>
public async Task UnloadScenesAsync(IEnumerable<string> sceneNames, IProgress<float> progress = null)
{
int total = 0;
int done = 0;
var ops = new List<AsyncOperation>();
foreach (var name in sceneNames)
{ {
total++; _isQuitting = true;
var op = SceneManager.UnloadSceneAsync(name);
_activeUnloads[name] = op;
ops.Add(op);
SceneUnloadStarted?.Invoke(name);
} }
while (done < total)
/// <summary>
/// Load a single scene asynchronously (additive).
/// </summary>
/// <param name="sceneName">Name of the scene to load.</param>
/// <param name="progress">Optional progress reporter.</param>
public async Task LoadSceneAsync(string sceneName, IProgress<float> progress = null)
{ {
done = 0; SceneLoadStarted?.Invoke(sceneName);
float aggregate = 0f; var op = SceneManager.LoadSceneAsync(sceneName, LoadSceneMode.Additive);
foreach (var op in ops) _activeLoads[sceneName] = op;
while (!op.isDone)
{ {
aggregate += op.progress; progress?.Report(op.progress);
if (op.isDone) done++; SceneLoadProgress?.Invoke(sceneName, op.progress);
await Task.Yield();
} }
float avg = aggregate / total; _activeLoads.Remove(sceneName);
progress?.Report(avg); SceneLoadCompleted?.Invoke(sceneName);
}
/// <summary>
/// Unload a single scene asynchronously.
/// </summary>
/// <param name="sceneName">Name of the scene to unload.</param>
/// <param name="progress">Optional progress reporter.</param>
public async Task UnloadSceneAsync(string sceneName, IProgress<float> 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);
}
/// <summary>
/// Load multiple scenes asynchronously.
/// </summary>
/// <param name="sceneNames">Enumerable of scene names to load.</param>
/// <param name="progress">Optional progress reporter.</param>
public async Task LoadScenesAsync(IEnumerable<string> sceneNames, IProgress<float> 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<AsyncOperation>();
foreach (var name in sceneNames) 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<float> progress = null)
{
// Remove all AstarPath (A* Pathfinder) singletons before loading the new scene
var astarPaths = FindObjectsByType<AstarPath>(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); /// <summary>
if (!bootstrap.isLoaded) /// Unload multiple scenes asynchronously.
/// </summary>
/// <param name="sceneNames">Enumerable of scene names to unload.</param>
/// <param name="progress">Optional progress reporter.</param>
public async Task UnloadScenesAsync(IEnumerable<string> sceneNames, IProgress<float> 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<AsyncOperation>();
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<float> progress = null)
{
// Remove all AstarPath (A* Pathfinder) singletons before loading the new scene
var astarPaths = FindObjectsByType<AstarPath>(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;
} }
} }

View File

@@ -31,6 +31,9 @@ namespace Input
// Override consumer stack - using a list to support multiple overrides that can be removed in LIFO order // Override consumer stack - using a list to support multiple overrides that can be removed in LIFO order
private readonly List<ITouchInputConsumer> _overrideConsumers = new List<ITouchInputConsumer>(); private readonly List<ITouchInputConsumer> _overrideConsumers = new List<ITouchInputConsumer>();
// Track which consumer is handling the current hold operation
private ITouchInputConsumer _activeHoldConsumer;
public static InputManager Instance public static InputManager Instance
{ {
get get
@@ -193,6 +196,18 @@ namespace Input
Vector3 worldPos = Camera.main.ScreenToWorldPoint(screenPos); Vector3 worldPos = Camera.main.ScreenToWorldPoint(screenPos);
Vector2 worldPos2D = new Vector2(worldPos.x, worldPos.y); Vector2 worldPos2D = new Vector2(worldPos.x, worldPos.y);
Debug.Log($"[InputManager] HoldMove started at {worldPos2D}"); Debug.Log($"[InputManager] HoldMove started at {worldPos2D}");
// First check for override consumers
if (_overrideConsumers.Count > 0)
{
_activeHoldConsumer = _overrideConsumers[_overrideConsumers.Count - 1];
Debug.Log($"[InputManager] Hold delegated to override consumer: {_activeHoldConsumer}");
_activeHoldConsumer.OnHoldStart(worldPos2D);
return;
}
// If no override consumers, use default consumer
_activeHoldConsumer = defaultConsumer;
defaultConsumer?.OnHoldStart(worldPos2D); defaultConsumer?.OnHoldStart(worldPos2D);
} }
@@ -207,7 +222,10 @@ namespace Input
Vector3 worldPos = Camera.main.ScreenToWorldPoint(screenPos); Vector3 worldPos = Camera.main.ScreenToWorldPoint(screenPos);
Vector2 worldPos2D = new Vector2(worldPos.x, worldPos.y); Vector2 worldPos2D = new Vector2(worldPos.x, worldPos.y);
Debug.Log($"[InputManager] HoldMove canceled at {worldPos2D}"); Debug.Log($"[InputManager] HoldMove canceled at {worldPos2D}");
defaultConsumer?.OnHoldEnd(worldPos2D);
// Notify the active hold consumer that the hold has ended
_activeHoldConsumer?.OnHoldEnd(worldPos2D);
_activeHoldConsumer = null;
} }
/// <summary> /// <summary>
@@ -221,7 +239,9 @@ namespace Input
Vector3 worldPos = Camera.main.ScreenToWorldPoint(screenPos); Vector3 worldPos = Camera.main.ScreenToWorldPoint(screenPos);
Vector2 worldPos2D = new Vector2(worldPos.x, worldPos.y); Vector2 worldPos2D = new Vector2(worldPos.x, worldPos.y);
// Debug.Log($"[InputManager] HoldMove update at {worldPos2D}"); // Debug.Log($"[InputManager] HoldMove update at {worldPos2D}");
defaultConsumer?.OnHoldMove(worldPos2D);
// Send hold move updates to the active hold consumer
_activeHoldConsumer?.OnHoldMove(worldPos2D);
} }
} }
@@ -342,6 +362,12 @@ namespace Input
if (consumer == null || !_overrideConsumers.Contains(consumer)) if (consumer == null || !_overrideConsumers.Contains(consumer))
return; return;
// If this is the active hold consumer, reset it
if (_activeHoldConsumer == consumer)
{
_activeHoldConsumer = null;
}
_overrideConsumers.Remove(consumer); _overrideConsumers.Remove(consumer);
Debug.Log($"[InputManager] Override consumer unregistered: {consumer}"); Debug.Log($"[InputManager] Override consumer unregistered: {consumer}");
} }
@@ -351,6 +377,7 @@ namespace Input
/// </summary> /// </summary>
public void ClearOverrideConsumers() public void ClearOverrideConsumers()
{ {
_activeHoldConsumer = null;
_overrideConsumers.Clear(); _overrideConsumers.Clear();
Debug.Log("[InputManager] All override consumers cleared."); Debug.Log("[InputManager] All override consumers cleared.");
} }

View File

@@ -2,7 +2,8 @@
using Input; using Input;
using Interactions; using Interactions;
using UnityEngine; using UnityEngine;
using AppleHills.Core.Settings; // Added for IInteractionSettings using AppleHills.Core.Settings;
using Core; // Added for IInteractionSettings
/// <summary> /// <summary>
/// Handles level switching when interacted with. Applies switch data and triggers scene transitions. /// Handles level switching when interacted with. Applies switch data and triggers scene transitions.

View File

@@ -335,28 +335,19 @@ public class FollowerController: MonoBehaviour
} }
OnPickupArrived?.Invoke(); OnPickupArrived?.Invoke();
// Wait briefly, then return to player // Brief pause at the item before returning
yield return new WaitForSeconds(_interactionSettings.FollowerPickupDelay); yield return new WaitForSeconds(_interactionSettings.FollowerPickupDelay);
if (_aiPath != null && playerTransform != null)
{
_aiPath.maxSpeed = _followerMaxSpeed;
_aiPath.destination = playerTransform.position;
}
_isReturningToPlayer = true;
// Wait until follower returns to player (2D distance)
while (playerTransform != null && Vector2.Distance(new Vector2(transform.position.x, transform.position.y), new Vector2(playerTransform.position.x, playerTransform.position.y)) > _settings.StopThreshold)
{
yield return null;
}
_isReturningToPlayer = false;
OnPickupReturned?.Invoke();
// Reset follower speed to normal after pickup // Reset follower speed to normal after pickup
_followerMaxSpeed = _defaultFollowerMaxSpeed; _followerMaxSpeed = _defaultFollowerMaxSpeed;
if (_aiPath != null) if (_aiPath != null)
_aiPath.maxSpeed = _followerMaxSpeed; _aiPath.maxSpeed = _followerMaxSpeed;
// Immediately resume normal following behavior
_isManualFollowing = true; _isManualFollowing = true;
if (_aiPath != null) if (_aiPath != null)
_aiPath.enabled = false; _aiPath.enabled = false;
_pickupCoroutine = null; _pickupCoroutine = null;
} }
@@ -382,6 +373,16 @@ public class FollowerController: MonoBehaviour
// Signal arrival // Signal arrival
OnPickupArrived?.Invoke(); OnPickupArrived?.Invoke();
// Reset follower speed to normal after reaching the point
_followerMaxSpeed = _defaultFollowerMaxSpeed;
if (_aiPath != null)
_aiPath.maxSpeed = _followerMaxSpeed;
// Immediately resume normal following behavior
_isManualFollowing = true;
if (_aiPath != null)
_aiPath.enabled = false;
_pickupCoroutine = null; _pickupCoroutine = null;
} }

View File

@@ -0,0 +1,168 @@
using System.Collections;
using UnityEngine;
using UnityEngine.UI;
using Core;
namespace UI
{
/// <summary>
/// Controls the loading screen UI display, progress updates, and timing
/// </summary>
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);
}
}
/// <summary>
/// Shows the loading screen and resets the progress bar to zero
/// </summary>
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());
}
/// <summary>
/// Animates the progress bar at a steady pace over the minimum display time,
/// while also checking actual loading progress from SceneManagerService
/// </summary>
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;
}
/// <summary>
/// Called when the actual loading process is complete
/// </summary>
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
}
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 1494b10574e74acd880f9101b4248239
timeCreated: 1760341032

View File

@@ -1,4 +1,5 @@
using System; using System;
using Core;
using UnityEngine; using UnityEngine;
using UnityEngine.SceneManagement; using UnityEngine.SceneManagement;

View File

@@ -1,4 +1,5 @@
using System; using System;
using Core;
using UnityEngine; using UnityEngine;
using UnityEngine.SceneManagement; using UnityEngine.SceneManagement;
using Input; using Input;
@@ -47,11 +48,13 @@ namespace UI
// Subscribe to scene loaded events // Subscribe to scene loaded events
SceneManagerService.Instance.SceneLoadCompleted += SetPauseMenuByLevel; SceneManagerService.Instance.SceneLoadCompleted += SetPauseMenuByLevel;
#if UNITY_EDITOR
// Set initial state based on current scene // Set initial state based on current scene
SetPauseMenuByLevel(SceneManager.GetActiveScene().name); SetPauseMenuByLevel(SceneManager.GetActiveScene().name);
// Initialize pause menu state // Initialize pause menu state
HidePauseMenu(false); HidePauseMenu(false);
#endif
} }
private void OnDestroy() private void OnDestroy()