diff --git a/Assets/Art/Sprites/UI/progress_circle.png b/Assets/Art/Sprites/UI/progress_circle.png new file mode 100644 index 00000000..b74eed15 Binary files /dev/null and b/Assets/Art/Sprites/UI/progress_circle.png differ diff --git a/Assets/Art/Sprites/UI/progress_circle.png.meta b/Assets/Art/Sprites/UI/progress_circle.png.meta new file mode 100644 index 00000000..d1430383 --- /dev/null +++ b/Assets/Art/Sprites/UI/progress_circle.png.meta @@ -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: diff --git a/Assets/Prefabs/Managers/CinematicsManager.prefab b/Assets/Prefabs/Managers/CinematicsManager.prefab index 1f2294ef..6537d075 100644 --- a/Assets/Prefabs/Managers/CinematicsManager.prefab +++ b/Assets/Prefabs/Managers/CinematicsManager.prefab @@ -60,7 +60,7 @@ Canvas: m_AdditionalShaderChannelsFlag: 0 m_UpdateRectTransformForStandalone: 0 m_SortingLayerID: 0 - m_SortingOrder: 0 + m_SortingOrder: 10 m_TargetDisplay: 0 --- !u!114 &3022940599780685530 MonoBehaviour: @@ -173,6 +173,81 @@ PlayableDirector: value: {fileID: 0} m_ExposedReferences: 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 GameObject: m_ObjectHideFlags: 0 @@ -185,6 +260,7 @@ GameObject: - component: {fileID: 3902696341833554714} - component: {fileID: 8235080513953117507} - component: {fileID: 2900690403017929526} + - component: {fileID: 3357796695825044110} m_Layer: 5 m_Name: CinematicSprites m_TagString: Untagged @@ -203,7 +279,8 @@ RectTransform: m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} m_ConstrainProportionsScale: 0 - m_Children: [] + m_Children: + - {fileID: 538506048417711235} m_Father: {fileID: 592992386388815559} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} @@ -271,3 +348,17 @@ Animator: m_AllowConstantClipSamplingOptimization: 1 m_KeepAnimatorStateOnDisable: 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} diff --git a/Assets/Prefabs/UI/LoadingScreen.prefab b/Assets/Prefabs/UI/LoadingScreen.prefab new file mode 100644 index 00000000..ec83272c --- /dev/null +++ b/Assets/Prefabs/UI/LoadingScreen.prefab @@ -0,0 +1,225 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &6227327056795603591 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + 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 + m_Name: Background + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1060159907441385154 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8774492328535489678} + 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 &8332608793126180474 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8774492328535489678} + m_CullTransparentMesh: 1 +--- !u!114 &2562764243080155070 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8774492328535489678} + 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 diff --git a/Assets/Prefabs/UI/LoadingScreen.prefab.meta b/Assets/Prefabs/UI/LoadingScreen.prefab.meta new file mode 100644 index 00000000..f7098a9d --- /dev/null +++ b/Assets/Prefabs/UI/LoadingScreen.prefab.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 0e04621f47997754192ca4c53ed8c118 +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scenes/MainMenu.unity b/Assets/Scenes/MainMenu.unity index 206d5726..d83bbb6b 100644 --- a/Assets/Scenes/MainMenu.unity +++ b/Assets/Scenes/MainMenu.unity @@ -714,7 +714,6 @@ MonoBehaviour: m_ScreenCoordScaleBias: {x: 0, y: 0, z: 0, w: 0} m_RequiresDepthTexture: 0 m_RequiresColorTexture: 0 - m_Version: 2 m_TaaSettings: m_Quality: 3 m_FrameInfluence: 0.1 @@ -722,6 +721,7 @@ MonoBehaviour: m_MipBias: 0 m_VarianceClampScale: 0.9 m_ContrastAdaptiveSharpening: 0 + m_Version: 2 --- !u!1 &1285439200 GameObject: m_ObjectHideFlags: 0 diff --git a/Assets/Scripts/Cinematics/CinematicsManager.cs b/Assets/Scripts/Cinematics/CinematicsManager.cs index ed8583a1..a9725780 100644 --- a/Assets/Scripts/Cinematics/CinematicsManager.cs +++ b/Assets/Scripts/Cinematics/CinematicsManager.cs @@ -1,14 +1,12 @@ -using Bootstrap; -using System; -using UnityEditor; +using System.Collections.Generic; using UnityEngine; using UnityEngine.AddressableAssets; -using UnityEngine.InputSystem; +using UnityEngine.ResourceManagement.AsyncOperations; using UnityEngine.Playables; using UnityEngine.SceneManagement; using UnityEngine.UI; -namespace CinematicsM +namespace Cinematics { /// /// Handles loading, playing and unloading cinematics @@ -20,6 +18,10 @@ namespace CinematicsM private Image cinematicSprites; public PlayableAsset cinematicToPlay; + // Dictionary to track addressable handles by PlayableDirector + private Dictionary> _addressableHandles + = new Dictionary>(); + public static CinematicsManager Instance { get @@ -41,8 +43,24 @@ namespace CinematicsM 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(); + } + /// /// Plays a cinematic from an object reference and returns the PlayableDirector playing the timeline /// @@ -59,6 +77,9 @@ namespace CinematicsM { cinematicSprites.enabled = false; Debug.Log("Cinematic stopped!"); + + // Release the addressable handle associated with this director + ReleaseAddressableHandle(director); } /// @@ -66,18 +87,73 @@ namespace CinematicsM /// public PlayableDirector LoadAndPlayCinematic(string key) { + // Load the asset via addressables var handle = Addressables.LoadAssetAsync(key); var result = handle.WaitForCompletion(); + + // Store the handle for later release + _addressableHandles[playableDirector] = handle; + + Debug.Log($"[CinematicsManager] Loaded addressable cinematic: {key}"); + return PlayCinematic(result); } - // Update is called once per frame - void Update() - { - - } - private void Awake() + /// + /// Skips the currently playing cinematic if one is active + /// + public void SkipCurrentCinematic() { + if (playableDirector != null && playableDirector.state == PlayState.Playing) + { + Debug.Log("Skipping current cinematic"); + playableDirector.Stop(); + } + } + + /// + /// Checks if a cinematic is currently playing + /// + public bool IsCinematicPlaying() + { + return playableDirector != null && playableDirector.state == PlayState.Playing; + } + + /// + /// Releases the addressable handle associated with a specific PlayableDirector + /// + 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); + } + } + + /// + /// Releases all active addressable handles + /// + 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; playableDirector = GetComponent(); cinematicSprites = GetComponentInChildren(true); diff --git a/Assets/Scripts/Cinematics/SkipCinematic.cs b/Assets/Scripts/Cinematics/SkipCinematic.cs new file mode 100644 index 00000000..d058cb3d --- /dev/null +++ b/Assets/Scripts/Cinematics/SkipCinematic.cs @@ -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 + } +} diff --git a/Assets/Scripts/Cinematics/SkipCinematic.cs.meta b/Assets/Scripts/Cinematics/SkipCinematic.cs.meta new file mode 100644 index 00000000..f5235e06 --- /dev/null +++ b/Assets/Scripts/Cinematics/SkipCinematic.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 5526348c1593f9b43987b0edcaccdd24 \ No newline at end of file diff --git a/Assets/Scripts/Core/QuickAccess.cs b/Assets/Scripts/Core/QuickAccess.cs index 17d43235..17fd16f1 100644 --- a/Assets/Scripts/Core/QuickAccess.cs +++ b/Assets/Scripts/Core/QuickAccess.cs @@ -1,12 +1,8 @@ using UnityEngine; -using Interactions; -using System.Collections.Generic; -using AppleHills.Core.Settings; using AppleHills.Data.CardSystem; -using CinematicsM; +using Cinematics; using Core; using Input; -using Minigames.DivingForPictures; using PuzzleS; namespace AppleHills.Core diff --git a/Assets/Scripts/Input/InputManager.cs b/Assets/Scripts/Input/InputManager.cs index bb8929ad..dbbd3c71 100644 --- a/Assets/Scripts/Input/InputManager.cs +++ b/Assets/Scripts/Input/InputManager.cs @@ -31,6 +31,9 @@ namespace Input // Override consumer stack - using a list to support multiple overrides that can be removed in LIFO order private readonly List _overrideConsumers = new List(); + // Track which consumer is handling the current hold operation + private ITouchInputConsumer _activeHoldConsumer; + public static InputManager Instance { get @@ -193,6 +196,18 @@ namespace Input Vector3 worldPos = Camera.main.ScreenToWorldPoint(screenPos); Vector2 worldPos2D = new Vector2(worldPos.x, worldPos.y); 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); } @@ -207,7 +222,10 @@ namespace Input Vector3 worldPos = Camera.main.ScreenToWorldPoint(screenPos); Vector2 worldPos2D = new Vector2(worldPos.x, worldPos.y); 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; } /// @@ -221,7 +239,9 @@ namespace Input Vector3 worldPos = Camera.main.ScreenToWorldPoint(screenPos); Vector2 worldPos2D = new Vector2(worldPos.x, worldPos.y); // 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)) return; + // If this is the active hold consumer, reset it + if (_activeHoldConsumer == consumer) + { + _activeHoldConsumer = null; + } + _overrideConsumers.Remove(consumer); Debug.Log($"[InputManager] Override consumer unregistered: {consumer}"); } @@ -351,6 +377,7 @@ namespace Input /// public void ClearOverrideConsumers() { + _activeHoldConsumer = null; _overrideConsumers.Clear(); Debug.Log("[InputManager] All override consumers cleared."); }