Add subtitle UI for voice playback

This commit is contained in:
2026-05-16 21:33:00 +01:00
parent 58050abded
commit 3174079e37
81 changed files with 8657 additions and 1231 deletions

View File

@@ -26,6 +26,12 @@ MonoBehaviour:
m_ReadOnly: 0 m_ReadOnly: 0
m_SerializedLabels: [] m_SerializedLabels: []
FlaggedDuringContentUpdateRestriction: 0 FlaggedDuringContentUpdateRestriction: 0
- m_GUID: 7874cf8dee22745db87b13634078aca7
m_Address: Assets/Data/Prefabs/Levels/Chapter One/Ashwick Hallow/C1 - Ashwick
Hallow - Outskirts.prefab
m_ReadOnly: 0
m_SerializedLabels: []
FlaggedDuringContentUpdateRestriction: 0
m_ReadOnly: 0 m_ReadOnly: 0
m_Settings: {fileID: 11400000, guid: b88fd73a09926470bad6fbcc5e204467, type: 2} m_Settings: {fileID: 11400000, guid: b88fd73a09926470bad6fbcc5e204467, type: 2}
m_SchemaSet: m_SchemaSet:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 380c2aff115e546c09cc151912880356
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 145fc1ecfff0443e8b1184fdc87c10fe
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: 584849d627012449fac35dbd2981ff99 guid: 151d27a90fc8a4728946e567567abd59
TextureImporter: TextureImporter:
internalIDToNameTable: [] internalIDToNameTable: []
externalObjects: {} externalObjects: {}

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: 800f7614145444ed4b622c80a6316d58 guid: def8f241f45d747adb3d96fc65f45261
TextureImporter: TextureImporter:
internalIDToNameTable: [] internalIDToNameTable: []
externalObjects: {} externalObjects: {}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

View File

@@ -0,0 +1,143 @@
fileFormatVersion: 2
guid: d87498f61738f44ffa14b93a6e9a68cb
TextureImporter:
internalIDToNameTable: []
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: 0
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
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: 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: 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: 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
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
customData:
physicsShape: []
bones: []
spriteID: 5e97eb03825dee720800000000000000
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spriteCustomMetadata:
entries: []
nameFileIdTable: {}
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

View File

@@ -0,0 +1,143 @@
fileFormatVersion: 2
guid: e44f37b5d832540acb0463159539a8f7
TextureImporter:
internalIDToNameTable: []
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: 0
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
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: 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: 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: 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
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
customData:
physicsShape: []
bones: []
spriteID: 5e97eb03825dee720800000000000000
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spriteCustomMetadata:
entries: []
nameFileIdTable: {}
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 119 KiB

After

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 MiB

After

Width:  |  Height:  |  Size: 524 KiB

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 95e75c6d21d9c4fb293517dfb967adf2
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because one or more lines are too long

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: 292366c0388bc477a9ff71168b304591 guid: 7099fc26212a447cc96d56d867feecaf
NativeFormatImporter: NativeFormatImporter:
externalObjects: {} externalObjects: {}
mainObjectFileID: 11400000 mainObjectFileID: 11400000

View File

@@ -0,0 +1,21 @@
fileFormatVersion: 2
guid: 8356f1b3f837945cfa8994a1ce4af566
TrueTypeFontImporter:
externalObjects: {}
serializedVersion: 4
fontSize: 16
forceTextureCase: -2
characterSpacing: 0
characterPadding: 1
includeFontData: 1
fontNames:
- Oxanium
fallbackFontReferences: []
customCharacters:
fontRenderingMode: 0
ascentCalculationMode: 1
useLegacyBoundsCalculation: 0
shouldRoundAdvanceValue: 1
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -10,7 +10,7 @@ MonoBehaviour:
m_Enabled: 1 m_Enabled: 1
m_EditorHideFlags: 0 m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: b492dfc759934d71b4f9cc4f8b41a155, type: 3} m_Script: {fileID: 11500000, guid: b492dfc759934d71b4f9cc4f8b41a155, type: 3}
m_Name: Ashwick Ridgeway m_Name: Ashwick Outskirts
m_EditorClassIdentifier: BriarQueen.Data::BriarQueen.Data.Assets.AssetEntry m_EditorClassIdentifier: BriarQueen.Data::BriarQueen.Data.Assets.AssetEntry
_entryType: 3 _entryType: 3
_uiKey: 0 _uiKey: 0
@@ -18,7 +18,7 @@ MonoBehaviour:
_levelKey: 2 _levelKey: 2
_itemKey: 0 _itemKey: 0
_asset: _asset:
m_AssetGUID: 9ad5adbf83cf74c26873156b9a975cb4 m_AssetGUID: 7874cf8dee22745db87b13634078aca7
m_SubObjectName: m_SubObjectName:
m_SubObjectType: m_SubObjectType:
m_SubObjectGUID: m_SubObjectGUID:

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: c914b10163a2c48e9a930c62a8395f3e guid: 8e302473b3bb241c88c7a9315ecc3d33
NativeFormatImporter: NativeFormatImporter:
externalObjects: {} externalObjects: {}
mainObjectFileID: 11400000 mainObjectFileID: 11400000

View File

@@ -1,25 +0,0 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: b492dfc759934d71b4f9cc4f8b41a155, type: 3}
m_Name: Harrow & Vale
m_EditorClassIdentifier: BriarQueen.Data::BriarQueen.Data.Assets.AssetEntry
_entryType: 3
_uiKey: 0
_sceneKey: 0
_levelKey: 5
_itemKey: 0
_asset:
m_AssetGUID:
m_SubObjectName:
m_SubObjectType:
m_SubObjectGUID:
m_EditorAssetChanged: 0

View File

@@ -16,13 +16,10 @@ MonoBehaviour:
_documentEntryID: 0 _documentEntryID: 0
_clueEntryID: 1 _clueEntryID: 1
_photoEntryID: 0 _photoEntryID: 0
_title: Strange Note _title: Jason's Note
_displayImage: {fileID: 0} _displayImage: {fileID: 0}
_bodyText: 'I managed to figure it out, it''s the lights. Use them. _bodyText: 'The keypad takes a three digit code and I finally figured it out. After
all this time, the answer was staring me right in the face. '
R = B,
L = ?'
_photoDescription: _photoDescription:
_polaroidWriting: _polaroidWriting:
_startsUnlocked: 0 _startsUnlocked: 0

View File

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

View File

@@ -17,12 +17,15 @@ MonoBehaviour:
- {fileID: 11400000, guid: c4a069c3f029048148fd0a09f7ccca19, type: 2} - {fileID: 11400000, guid: c4a069c3f029048148fd0a09f7ccca19, type: 2}
- {fileID: 11400000, guid: 0168c632b4acb41ed96b9679f773d696, type: 2} - {fileID: 11400000, guid: 0168c632b4acb41ed96b9679f773d696, type: 2}
- {fileID: 11400000, guid: 0c49d2ce5ec814acc9d6e5ef22163627, type: 2} - {fileID: 11400000, guid: 0c49d2ce5ec814acc9d6e5ef22163627, type: 2}
- {fileID: 11400000, guid: 32174971701734acb8b5753d1e0b33f6, type: 2}
- {fileID: 11400000, guid: 320922d3f881e4b7a9e46a652ba4691d, type: 2}
- {fileID: 11400000, guid: d1554ac927ae44f439f3445a69621a0c, type: 2}
- {fileID: 11400000, guid: c93f1507c5bfd47a488d8c538ee1cc31, type: 2}
_levelReferences: _levelReferences:
- {fileID: 11400000, guid: 8ba70613c7d254514a3a28f8974d699c, type: 2} - {fileID: 11400000, guid: 8ba70613c7d254514a3a28f8974d699c, type: 2}
- {fileID: 11400000, guid: bb46fdb752afa42d7a3cbccae913cf5c, type: 2} - {fileID: 11400000, guid: bb46fdb752afa42d7a3cbccae913cf5c, type: 2}
- {fileID: 11400000, guid: 292366c0388bc477a9ff71168b304591, type: 2} - {fileID: 11400000, guid: 8e302473b3bb241c88c7a9315ecc3d33, type: 2}
- {fileID: 11400000, guid: 338b59093323344b6b7245dca00bee01, type: 2} - {fileID: 11400000, guid: 338b59093323344b6b7245dca00bee01, type: 2}
- {fileID: 11400000, guid: c914b10163a2c48e9a930c62a8395f3e, type: 2}
_itemReferences: [] _itemReferences: []
_uiReferences: _uiReferences:
- {fileID: 11400000, guid: 5255435463c134748a561baf3243243a, type: 2} - {fileID: 11400000, guid: 5255435463c134748a561baf3243243a, type: 2}

View File

@@ -0,0 +1,153 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!21 &2100000
Material:
serializedVersion: 8
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: Keypad Light
m_Shader: {fileID: 4800000, guid: 37ffbc5d812345a3b233ed6d6929fbf5, type: 3}
m_Parent: {fileID: 0}
m_ModifiedSerializedProperties: 0
m_ValidKeywords:
- UNITY_UI_ALPHACLIP
m_InvalidKeywords: []
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses:
- MOTIONVECTORS
m_LockedProperties:
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _BaseMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _BumpMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailAlbedoMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailMask:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailNormalMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _EmissionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MetallicGlossMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _OcclusionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _ParallaxMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SpecGlossMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- unity_Lightmaps:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- unity_LightmapsInd:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- unity_ShadowMasks:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Ints: []
m_Floats:
- _AddPrecomputedVelocity: 0
- _AlphaClip: 0
- _AlphaToMask: 0
- _Blend: 0
- _BlendModePreserveSpecular: 1
- _BumpScale: 1
- _ClearCoatMask: 0
- _ClearCoatSmoothness: 0
- _ColorMask: 15
- _Cull: 2
- _Cutoff: 0.5
- _DetailAlbedoMapScale: 1
- _DetailNormalMapScale: 1
- _DstBlend: 0
- _DstBlendAlpha: 0
- _EnvironmentReflections: 1
- _Falloff: 0.242
- _FlickerOffset: 0
- _FlickerSpeed: 1.7
- _FlickerStrength: 0
- _GlossMapScale: 0
- _Glossiness: 0
- _GlossyReflections: 0
- _Intensity: 0.54
- _Metallic: 0
- _OcclusionStrength: 1
- _Parallax: 0.005
- _QueueOffset: 0
- _Radius: 0.186
- _ReceiveShadows: 1
- _Smoothness: 0.5
- _SmoothnessTextureChannel: 0
- _Softness: 2.78
- _SpecularHighlights: 1
- _SrcBlend: 1
- _SrcBlendAlpha: 1
- _Stencil: 0
- _StencilComp: 8
- _StencilOp: 0
- _StencilReadMask: 255
- _StencilWriteMask: 255
- _Surface: 0
- _UseUIAlphaClip: 1
- _WorkflowMode: 1
- _XRMotionVectorsPass: 1
- _ZWrite: 1
m_Colors:
- _BaseColor: {r: 1, g: 1, b: 1, a: 1}
- _Center: {r: 0.5, g: 0.5, b: 0, a: 0}
- _Color: {r: 1, g: 1, b: 1, a: 1}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _LightColor: {r: 0.8509804, g: 0.2, b: 0.2, a: 1}
- _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1}
m_BuildTextureStacks: []
m_AllowLocking: 1
--- !u!114 &1465423238885033028
MonoBehaviour:
m_ObjectHideFlags: 11
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
m_Name:
m_EditorClassIdentifier: Unity.RenderPipelines.Universal.Editor::UnityEditor.Rendering.Universal.AssetVersion
version: 10

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: b94c721b9ea2d4e069d663ef82170df9
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 2100000
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -101,12 +101,12 @@ Material:
- _EnvironmentReflections: 1 - _EnvironmentReflections: 1
- _Falloff: 0.242 - _Falloff: 0.242
- _FlickerOffset: 0 - _FlickerOffset: 0
- _FlickerSpeed: 1.7 - _FlickerSpeed: 0
- _FlickerStrength: 0.247 - _FlickerStrength: 1
- _GlossMapScale: 0 - _GlossMapScale: 0
- _Glossiness: 0 - _Glossiness: 0
- _GlossyReflections: 0 - _GlossyReflections: 0
- _Intensity: 1 - _Intensity: 0
- _Metallic: 0 - _Metallic: 0
- _OcclusionStrength: 1 - _OcclusionStrength: 1
- _Parallax: 0.005 - _Parallax: 0.005
@@ -134,7 +134,7 @@ Material:
- _Center: {r: 0.5, g: 0.5, b: 0, a: 0} - _Center: {r: 0.5, g: 0.5, b: 0, a: 0}
- _Color: {r: 1, g: 1, b: 1, a: 1} - _Color: {r: 1, g: 1, b: 1, a: 1}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1} - _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _LightColor: {r: 0.1490196, g: 0.6001954, b: 1, a: 1} - _LightColor: {r: 0.8509804, g: 0.2, b: 0.2, a: 1}
- _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1} - _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1}
m_BuildTextureStacks: [] m_BuildTextureStacks: []
m_AllowLocking: 1 m_AllowLocking: 1

View File

@@ -686,7 +686,7 @@ RectTransform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5}
m_AnchoredPosition: {x: -653, y: 37} m_AnchoredPosition: {x: -597, y: 51}
m_SizeDelta: {x: 900, y: 700} m_SizeDelta: {x: 900, y: 700}
m_Pivot: {x: 0.5, y: 0.5} m_Pivot: {x: 0.5, y: 0.5}
--- !u!1 &90101084 --- !u!1 &90101084
@@ -925,7 +925,7 @@ RectTransform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 1} m_AnchorMin: {x: 0.5, y: 1}
m_AnchorMax: {x: 0.5, y: 1} m_AnchorMax: {x: 0.5, y: 1}
m_AnchoredPosition: {x: 0, y: -85} m_AnchoredPosition: {x: 0, y: -112}
m_SizeDelta: {x: 900, y: 100} m_SizeDelta: {x: 900, y: 100}
m_Pivot: {x: 0.5, y: 1} m_Pivot: {x: 0.5, y: 1}
--- !u!114 &145691706 --- !u!114 &145691706
@@ -2533,17 +2533,17 @@ RectTransform:
m_PrefabInstance: {fileID: 0} m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0} m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 332249783} m_GameObject: {fileID: 332249783}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 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: []
m_Father: {fileID: 561703827} m_Father: {fileID: 551626280}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0.5, y: 0.5} m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: 0} m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 200, y: 50} m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0.5, y: 0.5} m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &332249785 --- !u!114 &332249785
MonoBehaviour: MonoBehaviour:
@@ -2575,8 +2575,8 @@ MonoBehaviour:
m_fontMaterials: [] m_fontMaterials: []
m_fontColor32: m_fontColor32:
serializedVersion: 2 serializedVersion: 2
rgba: 4279638559 rgba: 4292601329
m_fontColor: {r: 0.12156863, g: 0.101960786, b: 0.08627451, a: 1} m_fontColor: {r: 0.9433962, g: 0.8964242, b: 0.85884655, a: 1}
m_enableVertexGradient: 0 m_enableVertexGradient: 0
m_colorMode: 3 m_colorMode: 3
m_fontColorGradient: m_fontColorGradient:
@@ -2632,7 +2632,7 @@ MonoBehaviour:
m_VertexBufferAutoSizeReduction: 0 m_VertexBufferAutoSizeReduction: 0
m_useMaxVisibleDescender: 1 m_useMaxVisibleDescender: 1
m_pageToDisplay: 1 m_pageToDisplay: 1
m_margin: {x: -189.80365, y: -52.45459, z: -185.21564, w: -57.493774} m_margin: {x: 19.810547, y: 16.697144, z: 18.029297, w: 19.223694}
m_isUsingLegacyAnimationComponent: 0 m_isUsingLegacyAnimationComponent: 0
m_isVolumetricText: 0 m_isVolumetricText: 0
m_hasFontAssetChanged: 0 m_hasFontAssetChanged: 0
@@ -4267,7 +4267,7 @@ RectTransform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 1} m_AnchorMin: {x: 0, y: 1}
m_AnchorMax: {x: 0, y: 1} m_AnchorMax: {x: 0, y: 1}
m_AnchoredPosition: {x: 91, y: -51} m_AnchoredPosition: {x: 97.599976, y: -72.599976}
m_SizeDelta: {x: 400, y: 50} m_SizeDelta: {x: 400, y: 50}
m_Pivot: {x: 0, y: 1} m_Pivot: {x: 0, y: 1}
--- !u!114 &527861874 --- !u!114 &527861874
@@ -4324,8 +4324,8 @@ MonoBehaviour:
m_fontSizeMin: 18 m_fontSizeMin: 18
m_fontSizeMax: 72 m_fontSizeMax: 72
m_fontStyle: 32 m_fontStyle: 32
m_HorizontalAlignment: 1 m_HorizontalAlignment: 2
m_VerticalAlignment: 256 m_VerticalAlignment: 512
m_textAlignment: 65535 m_textAlignment: 65535
m_characterSpacing: 7 m_characterSpacing: 7
m_characterHorizontalScale: 1 m_characterHorizontalScale: 1
@@ -4686,6 +4686,82 @@ MonoBehaviour:
m_ChildScaleWidth: 0 m_ChildScaleWidth: 0
m_ChildScaleHeight: 0 m_ChildScaleHeight: 0
m_ReverseArrangement: 0 m_ReverseArrangement: 0
--- !u!1 &551626279
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 551626280}
- component: {fileID: 551626282}
- component: {fileID: 551626281}
m_Layer: 5
m_Name: Border
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &551626280
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 551626279}
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: 332249784}
m_Father: {fileID: 561703827}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &551626281
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 551626279}
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: 21300000, guid: 7e5a7da16cffd4355ad3b74dcaf8e4a8, 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!222 &551626282
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 551626279}
m_CullTransparentMesh: 1
--- !u!1 &561703826 --- !u!1 &561703826
GameObject: GameObject:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
@@ -4719,7 +4795,7 @@ RectTransform:
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: 332249784} - {fileID: 551626280}
m_Father: {fileID: 1455566988} m_Father: {fileID: 1455566988}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 1} m_AnchorMin: {x: 0, y: 1}
@@ -4752,15 +4828,15 @@ MonoBehaviour:
m_Name: m_Name:
m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.Image m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.Image
m_Material: {fileID: 0} m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1} m_Color: {r: 0.23584908, g: 0.21471167, b: 0.21471167, a: 0.65882355}
m_RaycastTarget: 1 m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1 m_Maskable: 1
m_OnCullStateChanged: m_OnCullStateChanged:
m_PersistentCalls: m_PersistentCalls:
m_Calls: [] m_Calls: []
m_Sprite: {fileID: 21300000, guid: 7e5a7da16cffd4355ad3b74dcaf8e4a8, type: 3} m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0}
m_Type: 0 m_Type: 1
m_PreserveAspect: 0 m_PreserveAspect: 0
m_FillCenter: 1 m_FillCenter: 1
m_FillMethod: 4 m_FillMethod: 4
@@ -8133,7 +8209,7 @@ RectTransform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 1, y: 1} m_AnchorMin: {x: 1, y: 1}
m_AnchorMax: {x: 1, y: 1} m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 217, y: -51} m_AnchoredPosition: {x: -48, y: -86}
m_SizeDelta: {x: 900, y: 50} m_SizeDelta: {x: 900, y: 50}
m_Pivot: {x: 1, y: 1} m_Pivot: {x: 1, y: 1}
--- !u!114 &1157564251 --- !u!114 &1157564251
@@ -8156,7 +8232,7 @@ MonoBehaviour:
m_OnCullStateChanged: m_OnCullStateChanged:
m_PersistentCalls: m_PersistentCalls:
m_Calls: [] m_Calls: []
m_text: Old Ridge Road m_text: At the Car
m_isRightToLeft: 0 m_isRightToLeft: 0
m_fontAsset: {fileID: 11400000, guid: 97bb3839c413f42c5932360cf6b0a3fc, type: 2} m_fontAsset: {fileID: 11400000, guid: 97bb3839c413f42c5932360cf6b0a3fc, type: 2}
m_sharedMaterial: {fileID: -2223467014058564004, guid: 97bb3839c413f42c5932360cf6b0a3fc, type: 2} m_sharedMaterial: {fileID: -2223467014058564004, guid: 97bb3839c413f42c5932360cf6b0a3fc, type: 2}
@@ -8183,15 +8259,15 @@ MonoBehaviour:
m_faceColor: m_faceColor:
serializedVersion: 2 serializedVersion: 2
rgba: 4294967295 rgba: 4294967295
m_fontSize: 64 m_fontSize: 42
m_fontSizeBase: 64 m_fontSizeBase: 42
m_fontWeight: 400 m_fontWeight: 400
m_enableAutoSizing: 0 m_enableAutoSizing: 0
m_fontSizeMin: 18 m_fontSizeMin: 18
m_fontSizeMax: 72 m_fontSizeMax: 72
m_fontStyle: 32 m_fontStyle: 32
m_HorizontalAlignment: 1 m_HorizontalAlignment: 4
m_VerticalAlignment: 256 m_VerticalAlignment: 1024
m_textAlignment: 65535 m_textAlignment: 65535
m_characterSpacing: 7 m_characterSpacing: 7
m_characterHorizontalScale: 1 m_characterHorizontalScale: 1
@@ -11383,7 +11459,7 @@ RectTransform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 1} m_AnchorMin: {x: 0.5, y: 1}
m_AnchorMax: {x: 0.5, y: 1} m_AnchorMax: {x: 0.5, y: 1}
m_AnchoredPosition: {x: 0, y: -170} m_AnchoredPosition: {x: 0, y: -224}
m_SizeDelta: {x: 900, y: 100} m_SizeDelta: {x: 900, y: 100}
m_Pivot: {x: 0.5, y: 1} m_Pivot: {x: 0.5, y: 1}
--- !u!114 &1488106359 --- !u!114 &1488106359
@@ -14644,7 +14720,7 @@ RectTransform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 1} m_AnchorMin: {x: 0.5, y: 1}
m_AnchorMax: {x: 0.5, y: 1} m_AnchorMax: {x: 0.5, y: 1}
m_AnchoredPosition: {x: 0, y: -340} m_AnchoredPosition: {x: 0, y: -448}
m_SizeDelta: {x: 900, y: 100} m_SizeDelta: {x: 900, y: 100}
m_Pivot: {x: 0.5, y: 1} m_Pivot: {x: 0.5, y: 1}
--- !u!114 &1816432720 --- !u!114 &1816432720
@@ -15188,7 +15264,7 @@ RectTransform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 1} m_AnchorMin: {x: 0.5, y: 1}
m_AnchorMax: {x: 0.5, y: 1} m_AnchorMax: {x: 0.5, y: 1}
m_AnchoredPosition: {x: 222, y: -255} m_AnchoredPosition: {x: 222, y: -336}
m_SizeDelta: {x: 900, y: 100} m_SizeDelta: {x: 900, y: 100}
m_Pivot: {x: 0.5, y: 1} m_Pivot: {x: 0.5, y: 1}
--- !u!114 &1861235553 --- !u!114 &1861235553

View File

@@ -174,7 +174,7 @@ Light:
m_PrefabAsset: {fileID: 0} m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 203844586} m_GameObject: {fileID: 203844586}
m_Enabled: 1 m_Enabled: 1
serializedVersion: 13 serializedVersion: 12
m_Type: 1 m_Type: 1
m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1} m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1}
m_Intensity: 1 m_Intensity: 1
@@ -226,7 +226,7 @@ Light:
m_UseBoundingSphereOverride: 0 m_UseBoundingSphereOverride: 0
m_UseViewFrustumForShadowCasterCull: 1 m_UseViewFrustumForShadowCasterCull: 1
m_ForceVisible: 0 m_ForceVisible: 0
m_ShapeRadius: 0 m_ShadowRadius: 0
m_ShadowAngle: 0 m_ShadowAngle: 0
m_LightUnit: 1 m_LightUnit: 1
m_LuxAtDistance: 1 m_LuxAtDistance: 1
@@ -246,44 +246,6 @@ Transform:
m_Children: [] m_Children: []
m_Father: {fileID: 0} m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0} m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0}
--- !u!1 &285394230
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 285394231}
m_Layer: 5
m_Name: Gate
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &285394231
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 285394230}
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: 1155499929}
- {fileID: 1565395032}
- {fileID: 652020456}
m_Father: {fileID: 1253864016}
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: 100, y: 100}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!1 &290940345 --- !u!1 &290940345
GameObject: GameObject:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
@@ -421,412 +383,6 @@ Transform:
m_Children: [] m_Children: []
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!1 &652020455
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 652020456}
- component: {fileID: 652020460}
- component: {fileID: 652020459}
- component: {fileID: 652020457}
- component: {fileID: 652020461}
m_Layer: 5
m_Name: Keypad Zone
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &652020456
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 652020455}
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: 285394231}
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: -6.3408, y: -135.728}
m_SizeDelta: {x: 135.7673, y: 196.0822}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!225 &652020457
CanvasGroup:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 652020455}
m_Enabled: 1
m_Alpha: 1
m_Interactable: 1
m_BlocksRaycasts: 1
m_IgnoreParentGroups: 0
--- !u!114 &652020459
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 652020455}
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: 0}
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!222 &652020460
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 652020455}
m_CullTransparentMesh: 1
--- !u!114 &652020461
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 652020455}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 9528c00201e44fc2baf036655881cf0d, type: 3}
m_Name:
m_EditorClassIdentifier: BriarQueen.Game::BriarQueen.Game.Items.HoverZones.TransitionZone
_levelToLoad: 4
_levelName:
_lockedTooltipText:
_lockedInteractText:
_locked: 0
_cursorStyle: 6
_soundEffectOnClick: 0
CanvasGroup: {fileID: 0}
--- !u!1 &778009335
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 778009340}
- component: {fileID: 778009339}
- component: {fileID: 778009338}
- component: {fileID: 778009337}
- component: {fileID: 778009336}
m_Layer: 5
m_Name: C1 - Ashwick Hallow - Outskirts
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &778009336
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 778009335}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: b17e98637f5042b4b70962875c373f5f, type: 3}
m_Name:
m_EditorClassIdentifier: BriarQueen.Game::BriarQueen.Game.Levels.ChapterOne.Ashwick.AshwickOutskirts
_levelKey: 0
_levelName:
Pickups: []
CodexTriggers: []
Puzzles: []
_raycaster: {fileID: 778009337}
_background: {fileID: 0}
_backgroundOpenSprite: {fileID: 0}
--- !u!114 &778009337
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 778009335}
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 &778009338
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 778009335}
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: 1
m_ReferencePixelsPerUnit: 100
m_ScaleFactor: 1
m_ReferenceResolution: {x: 1920, y: 1200}
m_ScreenMatchMode: 0
m_MatchWidthOrHeight: 0.5
m_PhysicalUnit: 3
m_FallbackScreenDPI: 96
m_DefaultSpriteDPI: 96
m_DynamicPixelsPerUnit: 1
m_PresetInfoIsWorld: 0
--- !u!223 &778009339
Canvas:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 778009335}
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_UseReflectionProbes: 0
m_AdditionalShaderChannelsFlag: 0
m_UpdateRectTransformForStandalone: 0
m_SortingLayerID: 0
m_SortingOrder: 0
m_TargetDisplay: 0
--- !u!224 &778009340
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 778009335}
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: 1253864016}
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!1 &1155499928
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1155499929}
- component: {fileID: 1155499932}
- component: {fileID: 1155499931}
- component: {fileID: 1155499930}
m_Layer: 5
m_Name: Next Level Zone
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &1155499929
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1155499928}
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: 285394231}
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.7054, y: -128.2476}
m_SizeDelta: {x: 1033.4109, y: 522.4951}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &1155499930
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1155499928}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 9528c00201e44fc2baf036655881cf0d, type: 3}
m_Name:
m_EditorClassIdentifier: BriarQueen.Game::BriarQueen.Game.Items.HoverZones.TransitionZone
_levelToLoad: 0
_levelName:
_lockedTooltipText:
_lockedInteractText:
_locked: 0
_cursorStyle: 6
_soundEffectOnClick: 0
CanvasGroup: {fileID: 0}
--- !u!114 &1155499931
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1155499928}
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: 0}
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!222 &1155499932
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1155499928}
m_CullTransparentMesh: 1
--- !u!1 &1253864015
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1253864016}
- component: {fileID: 1253864018}
- component: {fileID: 1253864017}
m_Layer: 5
m_Name: Background
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &1253864016
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1253864015}
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: 1927796941}
- {fileID: 285394231}
m_Father: {fileID: 778009340}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &1253864017
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1253864015}
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: 21300000, guid: d9a30acbf766745e48561f564db262ee, 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!222 &1253864018
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1253864015}
m_CullTransparentMesh: 1
--- !u!1 &1399123064 --- !u!1 &1399123064
GameObject: GameObject:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
@@ -906,216 +462,6 @@ Transform:
m_Children: [] m_Children: []
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!1 &1565395031
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1565395032}
- component: {fileID: 1565395036}
- component: {fileID: 1565395035}
- component: {fileID: 1565395034}
- component: {fileID: 1565395033}
m_Layer: 5
m_Name: Ashwick Gate
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &1565395032
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1565395031}
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: 285394231}
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.7054, y: -128.2476}
m_SizeDelta: {x: 1033.4109, y: 522.4951}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!225 &1565395033
CanvasGroup:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1565395031}
m_Enabled: 1
m_Alpha: 1
m_Interactable: 1
m_BlocksRaycasts: 1
m_IgnoreParentGroups: 0
--- !u!114 &1565395034
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1565395031}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 1bc3c6697e5b4c029e807116f930e9a3, type: 3}
m_Name:
m_EditorClassIdentifier: BriarQueen.Game::BriarQueen.Game.Puzzles.ChapterOne.AshwickHallow.GatePuzzle.AshwickGate
_itemData: {fileID: 0}
_interactableTooltip:
_pickupText:
_canvasGroup: {fileID: 1565395033}
--- !u!114 &1565395035
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1565395031}
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: 0}
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!222 &1565395036
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1565395031}
m_CullTransparentMesh: 1
--- !u!1 &1598455747
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1598455748}
- component: {fileID: 1598455752}
- component: {fileID: 1598455751}
- component: {fileID: 1598455750}
- component: {fileID: 1598455749}
m_Layer: 5
m_Name: Teddy Bear
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &1598455748
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1598455747}
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: 1927796941}
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: 582, y: -395}
m_SizeDelta: {x: 117, y: 130}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!225 &1598455749
CanvasGroup:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1598455747}
m_Enabled: 1
m_Alpha: 1
m_Interactable: 1
m_BlocksRaycasts: 1
m_IgnoreParentGroups: 0
--- !u!114 &1598455750
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1598455747}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 529a2a922f6f48a982159e2dbc41c542, type: 3}
m_Name:
m_EditorClassIdentifier: BriarQueen.Framework::BriarQueen.Framework.Managers.Levels.Data.BaseItem
_itemData: {fileID: 11400000, guid: a39f2408f72ff4d01a10e37e76dcd84b, type: 2}
_interactableTooltip:
_pickupText: Dirty Teddy Bear
_canvasGroup: {fileID: 1598455749}
--- !u!114 &1598455751
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1598455747}
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: 21300000, guid: 357e8b2f7ab3044ba8098c50e16a169b, 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!222 &1598455752
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1598455747}
m_CullTransparentMesh: 1
--- !u!1 &1684932629 --- !u!1 &1684932629
GameObject: GameObject:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
@@ -1160,42 +506,6 @@ Transform:
m_Children: [] m_Children: []
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!1 &1927796940
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1927796941}
m_Layer: 5
m_Name: Items
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &1927796941
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1927796940}
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: 1598455748}
m_Father: {fileID: 1253864016}
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: 100, y: 100}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!1660057539 &9223372036854775807 --- !u!1660057539 &9223372036854775807
SceneRoots: SceneRoots:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
@@ -1204,4 +514,3 @@ SceneRoots:
- {fileID: 1684932631} - {fileID: 1684932631}
- {fileID: 290940349} - {fileID: 290940349}
- {fileID: 1399123067} - {fileID: 1399123067}
- {fileID: 778009340}

View File

@@ -25,7 +25,7 @@ mainly on vines and thorns.
9. **Tokens** - Cancellation Tokens should be re-used where possible. 9. **Tokens** - Cancellation Tokens should be re-used where possible.
10. **Versions** - We're using C# 9 with Unity 6.3 10. **Versions** - We're using C# 9 with Unity 6.3
11. **Workflow** - You're not to make any code changes until you've shown me the proposed changes, I'll then either approve, deny, or modify them before you make the change. 11. **Workflow** - You're not to make any code changes until you've shown me the proposed changes, I'll then either approve, deny, or modify them before you make the change.
12. **Events** - We use C# events, actions, and delegates rather than UnityEvents, except when dealing with raw/stock ui components.
## Documentation ## Documentation

View File

@@ -27,7 +27,6 @@ namespace BriarQueen.Data.Identifiers
ChapterOneArrivalRoad, ChapterOneArrivalRoad,
ChapterOneAshwickOutskirts, ChapterOneAshwickOutskirts,
ChapterOneInsideBrokenDownCar, ChapterOneInsideBrokenDownCar,
ChapterOneAshwickOutskirtsKeypad,
} }
public enum AssetItemKey public enum AssetItemKey

View File

@@ -13,6 +13,7 @@ namespace BriarQueen.Data.Identifiers
None = 0, None = 0,
CarDoorOpening, CarDoorOpening,
ItemPickup, ItemPickup,
AshwickGateOpening
} }
public enum UIFXKey public enum UIFXKey
@@ -30,6 +31,22 @@ namespace BriarQueen.Data.Identifiers
public enum VoiceKey public enum VoiceKey
{ {
None = 0, None = 0,
EmptyHands,
CantUseItem,
SomethingMissing,
CarefulInteract,
LooksImportant,
WrongTool,
CodexLocked,
Locked,
CantGoThere,
DoesntBelong,
FireHot,
AshwickHallowSign,
FirstSkeleton,
ClockTower,
} }
public static class AudioNameIdentifiers public static class AudioNameIdentifiers
@@ -46,16 +63,17 @@ namespace BriarQueen.Data.Identifiers
new ReadOnlyDictionary<SFXKey, string>( new ReadOnlyDictionary<SFXKey, string>(
new Dictionary<SFXKey, string> new Dictionary<SFXKey, string>
{ {
{ SFXKey.CarDoorOpening, "SFX:CarDoorOpening" }, { SFXKey.CarDoorOpening, "SFX:General:CarDoorOpening" },
{ SFXKey.ItemPickup, "SFX:ItemPickup" }, { SFXKey.ItemPickup, "SFX:General:ItemPickup" },
{ SFXKey.AshwickGateOpening, "SFX:Level:AshwickOutskirts:GateOpening" },
}); });
public static readonly IReadOnlyDictionary<UIFXKey, string> UIFX = public static readonly IReadOnlyDictionary<UIFXKey, string> UIFX =
new ReadOnlyDictionary<UIFXKey, string>( new ReadOnlyDictionary<UIFXKey, string>(
new Dictionary<UIFXKey, string> new Dictionary<UIFXKey, string>
{ {
{ UIFXKey.AchievementUnlocked, "UIFX:AchievementUnlocked" }, { UIFXKey.AchievementUnlocked, "UIFX:General:AchievementUnlocked" },
{ UIFXKey.CodexEntryUnlocked, "UIFX:CodexEntryUnlocked" }, { UIFXKey.CodexEntryUnlocked, "UIFX:General:CodexEntryUnlocked" },
}); });
public static readonly IReadOnlyDictionary<AmbienceKey, string> Ambience = public static readonly IReadOnlyDictionary<AmbienceKey, string> Ambience =
@@ -69,7 +87,21 @@ namespace BriarQueen.Data.Identifiers
new ReadOnlyDictionary<VoiceKey, string>( new ReadOnlyDictionary<VoiceKey, string>(
new Dictionary<VoiceKey, string> new Dictionary<VoiceKey, string>
{ {
// Add voice mappings here { VoiceKey.EmptyHands, "Voice:Item:EmptyHands" },
{ VoiceKey.CantUseItem, "Voice:Item:CantUseItem" },
{ VoiceKey.SomethingMissing, "Voice:Item:SomethingMissing" },
{ VoiceKey.CarefulInteract, "Voice:Item:CarefulInteract" },
{ VoiceKey.LooksImportant, "Voice:Item:LooksImportant" },
{ VoiceKey.WrongTool, "Voice:Item:WrongTool" },
{ VoiceKey.CodexLocked, "Voice:Item:CodexLocked" },
{ VoiceKey.Locked, "Voice:Environment:Locked" },
{ VoiceKey.CantGoThere, "Voice:Environment:CantGoThere" },
{ VoiceKey.DoesntBelong, "Voice:Environment:DoesntBelong" },
{ VoiceKey.FireHot, "Voice:Environment:FireHot" },
{ VoiceKey.AshwickHallowSign, "Voice:Environment:AshwickHallowSign" },
{ VoiceKey.FirstSkeleton, "Voice:Environment:FirstSkeleton" },
{ VoiceKey.ClockTower, "Voice:Environment:ClockTower" },
}); });
public static string Get(MusicKey key) public static string Get(MusicKey key)

View File

@@ -12,7 +12,7 @@ namespace BriarQueen.Data.Identifiers
public enum ClueEntryID public enum ClueEntryID
{ {
None = 0, None = 0,
AshwickMarketGate, JasonsNote,
} }
public enum PhotoEntryID public enum PhotoEntryID
@@ -37,7 +37,7 @@ namespace BriarQueen.Data.Identifiers
new ReadOnlyDictionary<ClueEntryID, string>( new ReadOnlyDictionary<ClueEntryID, string>(
new Dictionary<ClueEntryID, string> new Dictionary<ClueEntryID, string>
{ {
{ ClueEntryID.AshwickMarketGate, $"{PHOTO_PREFIX}:AshwickMarketGate" }, { ClueEntryID.JasonsNote, $"{PHOTO_PREFIX}:AshwickMarketGate" },
}); });
public static readonly IReadOnlyDictionary<PhotoEntryID, string> Photos = public static readonly IReadOnlyDictionary<PhotoEntryID, string> Photos =

View File

@@ -18,7 +18,6 @@ namespace BriarQueen.Data.Identifiers
public enum LevelInteractKey public enum LevelInteractKey
{ {
None = 0, None = 0,
MarketplaceFirstEntry
} }
public enum EnvironmentInteractKey public enum EnvironmentInteractKey
@@ -29,11 +28,8 @@ namespace BriarQueen.Data.Identifiers
DoesntBelong = 3, DoesntBelong = 3,
FireHot = 4, FireHot = 4,
AshwickHallowSign = 5, AshwickHallowSign = 5,
AshwickRidgewayStatue = 6,
AshwickBlockedRidgwayRoad = 7,
AshwickRidgewaySkeleton = 8,
AskwickMarketplaceSign = 9,
FirstSkeleton = 10, FirstSkeleton = 10,
ClockTower = 11,
} }
public enum UIInteractKey public enum UIInteractKey
@@ -62,7 +58,6 @@ namespace BriarQueen.Data.Identifiers
new ReadOnlyDictionary<LevelInteractKey, string>( new ReadOnlyDictionary<LevelInteractKey, string>(
new Dictionary<LevelInteractKey, string> new Dictionary<LevelInteractKey, string>
{ {
{ LevelInteractKey.MarketplaceFirstEntry, "I wonder if any of these are unlocked."}
}); });
public static readonly IReadOnlyDictionary<EnvironmentInteractKey, string> EnvironmentInteractions = public static readonly IReadOnlyDictionary<EnvironmentInteractKey, string> EnvironmentInteractions =
@@ -74,9 +69,8 @@ namespace BriarQueen.Data.Identifiers
{ EnvironmentInteractKey.DoesntBelong, "This feels out of place." }, { EnvironmentInteractKey.DoesntBelong, "This feels out of place." },
{ EnvironmentInteractKey.FireHot, "Too hot to get close." }, { EnvironmentInteractKey.FireHot, "Too hot to get close." },
{ EnvironmentInteractKey.AshwickHallowSign, "Ashwick Hallow… Even the name feels like a warning."}, { EnvironmentInteractKey.AshwickHallowSign, "Ashwick Hallow… Even the name feels like a warning."},
{ EnvironmentInteractKey.AshwickRidgewayStatue, "Lovely sculpture. Mildly terrifying, but lovely."}, { EnvironmentInteractKey.FirstSkeleton, "What the hell happened here?"},
{ EnvironmentInteractKey.AshwickBlockedRidgwayRoad, "Right. Closed road. Of course it is."}, { EnvironmentInteractKey.ClockTower, "Even from here, something about that clock tower feels wrong."}
{ EnvironmentInteractKey.FirstSkeleton, "What the hell happened here?"}
}); });
public static readonly IReadOnlyDictionary<UIInteractKey, string> UIInteractions = public static readonly IReadOnlyDictionary<UIInteractKey, string> UIInteractions =

View File

@@ -11,24 +11,45 @@ namespace BriarQueen.Data.Identifiers
// TutorialTip = 2 // TutorialTip = 2
} }
public readonly struct SubtitleEntry
{
public SubtitleEntry(string text, float preferredDurationSeconds = 0f)
{
Text = text;
PreferredDurationSeconds = preferredDurationSeconds;
}
public string Text { get; }
public float PreferredDurationSeconds { get; }
}
public static class SubtitleIdentifiers public static class SubtitleIdentifiers
{ {
public static readonly IReadOnlyDictionary<SubtitleKey, string> Subtitles = public static readonly IReadOnlyDictionary<SubtitleKey, SubtitleEntry> Subtitles =
new ReadOnlyDictionary<SubtitleKey, string>( new ReadOnlyDictionary<SubtitleKey, SubtitleEntry>(
new Dictionary<SubtitleKey, string> new Dictionary<SubtitleKey, SubtitleEntry>
{ {
// { SubtitleKey.IntroLine, "Subtitle:IntroLine" }, // { SubtitleKey.IntroLine, new SubtitleEntry("Example subtitle.", 2.5f) },
// { SubtitleKey.TutorialTip, "Subtitle:TutorialTip" }
}); });
public static string Get(SubtitleKey key) public static bool TryGet(SubtitleKey key, out SubtitleEntry entry)
{ {
return Subtitles.TryGetValue(key, out var value) ? value : string.Empty; return Subtitles.TryGetValue(key, out entry);
} }
public static IEnumerable<string> GetAll() public static string GetText(SubtitleKey key)
{ {
return Subtitles.Values; return Subtitles.TryGetValue(key, out var entry) ? entry.Text : string.Empty;
}
public static float GetPreferredDuration(SubtitleKey key)
{
return Subtitles.TryGetValue(key, out var entry) ? entry.PreferredDurationSeconds : 0f;
}
public static IEnumerable<SubtitleKey> GetAllKeys()
{
return Subtitles.Keys;
} }
} }
} }

View File

@@ -7,12 +7,12 @@ namespace BriarQueen.Data.Identifiers
ReturnToPreviousLevel, ReturnToPreviousLevel,
UsingItemsTogether, UsingItemsTogether,
HideHUD, HideHUD,
ExitItems,
MultipleUseItems, MultipleUseItems,
DarkRooms, DarkRooms,
Codex, Codex,
HiddenItems, HiddenItems,
ResetPuzzles, ResetPuzzles,
LeavingPuzzles,
Tools, Tools,
ItemsAway, ItemsAway,
ItemCycling, ItemCycling,
@@ -25,7 +25,7 @@ namespace BriarQueen.Data.Identifiers
{ {
{ {
TutorialPopupID.ReturnToPreviousLevel, TutorialPopupID.ReturnToPreviousLevel,
"Click the bottom corners to return to the previous area." "Click the lower corners to return to the previous area."
}, },
{ {
TutorialPopupID.UsingItemsTogether, TutorialPopupID.UsingItemsTogether,
@@ -35,13 +35,9 @@ namespace BriarQueen.Data.Identifiers
TutorialPopupID.HideHUD, TutorialPopupID.HideHUD,
"Press '{Hide_HUD}' to hide the HUD." "Press '{Hide_HUD}' to hide the HUD."
}, },
{
TutorialPopupID.ExitItems,
"Press '{Right_Click}' to exit the current interaction."
},
{ {
TutorialPopupID.MultipleUseItems, TutorialPopupID.MultipleUseItems,
"Some items can be used multiple times, but they may wear out." "Some items can be used more than once, but they may wear out."
}, },
{ {
TutorialPopupID.DarkRooms, TutorialPopupID.DarkRooms,
@@ -49,7 +45,7 @@ namespace BriarQueen.Data.Identifiers
}, },
{ {
TutorialPopupID.Codex, TutorialPopupID.Codex,
"The Codex is used to collect any documents you encounter. Press '{Codex}' to open it." "Documents you find are stored in the Codex. Press '{Codex}' to open it."
}, },
{ {
TutorialPopupID.HiddenItems, TutorialPopupID.HiddenItems,
@@ -57,24 +53,29 @@ namespace BriarQueen.Data.Identifiers
}, },
{ {
TutorialPopupID.ResetPuzzles, TutorialPopupID.ResetPuzzles,
"Some puzzles can be reset." "Some puzzles can be reset if you get stuck."
}, },
{
TutorialPopupID.LeavingPuzzles,
"When you leave a puzzle, your progress is saved."
},
{ {
TutorialPopupID.Tools, TutorialPopupID.Tools,
"You'll find tools as you explore. Try them on different objects. Press '{Show_Tools}' to view your tools." "You'll find tools as you explore. Try them on different objects. Press '{Show_Tools}' to open your tools."
}, },
{ {
TutorialPopupID.ItemsAway, TutorialPopupID.ItemsAway,
"Press '{Right_Click}' to put away the current item." "Press '{Right_Click}' to put away the selected item."
}, },
{ {
TutorialPopupID.ItemCycling, TutorialPopupID.ItemCycling,
"Press '{Previous_Item}' or '{Next_Item}' to cycle through your backpack." "Press '{Previous_Item}' or '{Next_Item}' to cycle through the items in your backpack."
}, },
{ {
TutorialPopupID.ToolCycling, TutorialPopupID.ToolCycling,
"Press '{Previous_Tool}' or '{Next_Tool}' to cycle through your tools." "Press '{Previous_Tool}' or '{Next_Tool}' to cycle through your tools."
} },
}; };
public static IEnumerable<string> GetAllTexts() => AllPopups.Values; public static IEnumerable<string> GetAllTexts() => AllPopups.Values;

View File

@@ -32,6 +32,9 @@ namespace BriarQueen.Framework.Effects
[SerializeField] [SerializeField]
private bool _randomizeFlickerOffset = true; private bool _randomizeFlickerOffset = true;
[SerializeField]
private bool _useStartingValues;
[Header("Tween")] [Header("Tween")]
[SerializeField] [SerializeField]
@@ -81,8 +84,12 @@ namespace BriarQueen.Framework.Effects
} }
CreateRuntimeMaterial(); CreateRuntimeMaterial();
if(_useStartingValues)
{
SetLightColor(_startingColor); SetLightColor(_startingColor);
SetIntensity(_startingIntensity); SetIntensity(_startingIntensity);
}
if (_randomizeFlickerOffset && _runtimeMaterial != null) if (_randomizeFlickerOffset && _runtimeMaterial != null)
{ {

View File

@@ -0,0 +1,9 @@
using BriarQueen.Data.Identifiers;
using BriarQueen.Framework.Events.System;
namespace BriarQueen.Framework.Events.Audio
{
public record VoicePlaybackFinishedEvent(
VoiceKey VoiceKey,
SubtitleKey SubtitleKey) : IEvent;
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: a5c701b2f1b56482cb423352feaecd6b

View File

@@ -0,0 +1,10 @@
using BriarQueen.Data.Identifiers;
using BriarQueen.Framework.Events.System;
namespace BriarQueen.Framework.Events.Audio
{
public record VoicePlaybackStartedEvent(
VoiceKey VoiceKey,
SubtitleKey SubtitleKey,
float ClipLengthSeconds) : IEvent;
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 7b2afa1c54b63413293f433a9490a998

View File

@@ -0,0 +1,6 @@
using BriarQueen.Framework.Events.System;
namespace BriarQueen.Framework.Events.UI
{
public record SubtitleDisplayChangedEvent(string Text, bool Visible) : IEvent;
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: d606965a42b7a4bc29e67528e42120e2

View File

@@ -45,7 +45,8 @@ namespace BriarQueen.Framework.Managers.Audio
private AudioSource _musicSourceB; private AudioSource _musicSourceB;
private AudioSource _voiceSource; private AudioSource _voiceSource;
private string _activeVoiceSubtitleId; private VoiceKey _activeVoiceKey = VoiceKey.None;
private SubtitleKey _activeSubtitleKey = SubtitleKey.None;
private AudioFileSo _currentMusicTrack; private AudioFileSo _currentMusicTrack;
private CancellationTokenSource _musicDuckCts; private CancellationTokenSource _musicDuckCts;
@@ -140,7 +141,8 @@ namespace BriarQueen.Framework.Managers.Audio
_musicSourceB = null; _musicSourceB = null;
_voiceSource = null; _voiceSource = null;
_currentMusicTrack = null; _currentMusicTrack = null;
_activeVoiceSubtitleId = null; _activeVoiceKey = VoiceKey.None;
_activeSubtitleKey = SubtitleKey.None;
_voiceFinishedPublished = false; _voiceFinishedPublished = false;
Initialized = false; Initialized = false;
} }
@@ -205,8 +207,7 @@ namespace BriarQueen.Framework.Managers.Audio
if (_audioMixer == null || string.IsNullOrWhiteSpace(parameter)) if (_audioMixer == null || string.IsNullOrWhiteSpace(parameter))
return; return;
if (!_baseDb.TryGetValue(parameter, out var baseDb)) var baseDb = _baseDb.GetValueOrDefault(parameter, 0f);
baseDb = 0f;
var effective = baseDb; var effective = baseDb;
@@ -340,10 +341,14 @@ namespace BriarQueen.Framework.Managers.Audio
_voiceCts = new CancellationTokenSource(); _voiceCts = new CancellationTokenSource();
var token = _voiceCts.Token; var token = _voiceCts.Token;
_activeVoiceSubtitleId = SubtitleIdentifiers.Get(audioData.MatchingSubtitleID); _activeVoiceKey = audioData.VoiceKey;
_activeSubtitleKey = audioData.MatchingSubtitleID;
_voiceFinishedPublished = false; _voiceFinishedPublished = false;
_eventCoordinator.Publish(new VoiceLineStartedEvent(_activeVoiceSubtitleId)); _eventCoordinator.Publish(new VoicePlaybackStartedEvent(
_activeVoiceKey,
_activeSubtitleKey,
audioData.Clip.length));
_voiceSource.clip = audioData.Clip; _voiceSource.clip = audioData.Clip;
_voiceSource.pitch = audioData.Pitch; _voiceSource.pitch = audioData.Pitch;
@@ -369,11 +374,16 @@ namespace BriarQueen.Framework.Managers.Audio
{ {
if (_voiceFinishedPublished) return; if (_voiceFinishedPublished) return;
if (!string.IsNullOrEmpty(_activeVoiceSubtitleId)) if (_activeVoiceKey != VoiceKey.None || _activeSubtitleKey != SubtitleKey.None)
_eventCoordinator.Publish(new VoiceLineFinishedEvent(_activeVoiceSubtitleId)); {
_eventCoordinator.Publish(new VoicePlaybackFinishedEvent(
_activeVoiceKey,
_activeSubtitleKey));
}
_voiceFinishedPublished = true; _voiceFinishedPublished = true;
_activeVoiceSubtitleId = null; _activeVoiceKey = VoiceKey.None;
_activeSubtitleKey = SubtitleKey.None;
} }
public void StopVoice() public void StopVoice()

View File

@@ -449,13 +449,12 @@ namespace BriarQueen.Framework.Managers.Input
private void OnPause(InputAction.CallbackContext ctx) private void OnPause(InputAction.CallbackContext ctx)
{ {
var isMainMenu = _gameService != null && _gameService.IsMainMenuSceneLoaded; var isMainMenu = _gameService != null && _gameService.IsMainMenuSceneLoaded;
if (isMainMenu || _isAnyUIOpen) if (isMainMenu)
{ {
_eventCoordinator?.PublishImmediate(new UIBackRequestedEvent()); _eventCoordinator?.PublishImmediate(new UIBackRequestedEvent());
return; return;
} }
_isPaused = true;
_eventCoordinator?.Publish(new PauseButtonClickedEvent()); _eventCoordinator?.Publish(new PauseButtonClickedEvent());
} }

View File

@@ -163,6 +163,22 @@ namespace BriarQueen.Framework.Managers.Interaction
Debug.Log($"[InteractManager] SetExclusiveRaycaster set to {raycaster.gameObject.name}."); Debug.Log($"[InteractManager] SetExclusiveRaycaster set to {raycaster.gameObject.name}.");
} }
public void ReleaseExclusiveRaycaster(GraphicRaycaster raycaster)
{
if (raycaster == null)
return;
if (_exclusiveRaycaster != raycaster)
return;
_exclusiveRaycaster = null;
if (_currentHovered != null)
ClearHover().Forget();
Debug.Log($"[InteractManager] Released exclusive raycaster {raycaster.gameObject.name}.");
}
/// <summary> /// <summary>
/// Clear exclusive mode and return to using all registered raycasters. /// Clear exclusive mode and return to using all registered raycasters.
/// </summary> /// </summary>

View File

@@ -15,10 +15,15 @@ namespace BriarQueen.Framework.Managers.Player.Data.Codex
[Header("Codex")] [Header("Codex")]
[SerializeField] [SerializeField]
private CodexEntrySo _codexEntry; private CodexEntrySo _codexEntry;
[SerializeField] [SerializeField]
private bool _removeTrigger; private bool _removeTrigger;
[Header("Events")]
[SerializeField]
private SFXKey _soundEffect;
[SerializeField]
private VoiceKey _voiceLine;
public override UICursorService.CursorStyle ApplicableCursorStyle => UICursorService.CursorStyle.Inspect; public override UICursorService.CursorStyle ApplicableCursorStyle => UICursorService.CursorStyle.Inspect;
public override string InteractableName => public override string InteractableName =>
@@ -40,12 +45,23 @@ namespace BriarQueen.Framework.Managers.Player.Data.Codex
return; return;
} }
PlayerManager.UnlockCodexEntry(_codexEntry); PlayerManager.UnlockCodexEntry(_codexEntry);
if (_removeTrigger) if (_removeTrigger)
{ {
await Remove(); await Remove();
} }
if (_soundEffect != SFXKey.None)
{
AudioManager.Play(AudioNameIdentifiers.Get(_soundEffect));
}
if (_voiceLine != VoiceKey.None)
{
AudioManager.Play(AudioNameIdentifiers.Get(_voiceLine));
}
} }
protected override void UpdateSaveGameOnRemoval() protected override void UpdateSaveGameOnRemoval()

View File

@@ -4,6 +4,7 @@ namespace BriarQueen.Framework.Managers.UI.Base
{ {
public interface IUIOverlayHost public interface IUIOverlayHost
{ {
bool CanSuspendFor(WindowType incomingWindowType);
UniTask SuspendForOverlay(); UniTask SuspendForOverlay();
UniTask ResumeFromOverlay(); UniTask ResumeFromOverlay();
} }

View File

@@ -1,16 +1,19 @@
using System.Threading;
using Cysharp.Threading.Tasks; using Cysharp.Threading.Tasks;
using PrimeTween;
using UnityEngine;
namespace BriarQueen.Framework.Managers.UI.Base namespace BriarQueen.Framework.Managers.UI.Base
{ {
public enum UIPauseBehavior
{
TreatAsBackRequest,
OpenPauseOverlay
}
public interface IUIWindow public interface IUIWindow
{ {
UniTask Show(); UniTask Show();
UniTask Hide(); UniTask Hide();
WindowType WindowType { get; } WindowType WindowType { get; }
UIPauseBehavior PauseBehavior { get; }
} }
} }

View File

@@ -4,6 +4,7 @@ namespace BriarQueen.Framework.Managers.UI.Base
{ {
PauseMenuWindow, PauseMenuWindow,
SettingsWindow, SettingsWindow,
CodexWindow CodexWindow,
AshwickGateKeypadWindow
} }
} }

View File

@@ -41,12 +41,14 @@ namespace BriarQueen.Framework.Managers.UI
public bool Initialized { get; private set; } public bool Initialized { get; private set; }
private sealed record OverlayResumeContext(WindowType OverlayWindowType, IUIOverlayHost Host);
private IHud _hudContainer; private IHud _hudContainer;
private IPopup _infoPopup; private IPopup _infoPopup;
private IPopup _tutorialPopup; private IPopup _tutorialPopup;
private IScreenFader _screenFader; private IScreenFader _screenFader;
private IUIOverlayHost _mainMenuOverlayHost; private IUIOverlayHost _mainMenuOverlayHost;
private IUIOverlayHost _activeSettingsOverlayHost; private readonly Stack<OverlayResumeContext> _overlayResumeStack = new();
[Inject] [Inject]
public UIManager( public UIManager(
@@ -127,6 +129,18 @@ namespace BriarQueen.Framework.Managers.UI
window.Hide().Forget(); window.Hide().Forget();
} }
public void UnregisterWindow(IUIWindow window)
{
if (window == null)
return;
if (_windows.TryGetValue(window.WindowType, out var registered) && ReferenceEquals(registered, window))
_windows.Remove(window.WindowType);
if (window is IUIOverlayHost overlayHost)
RemoveOverlayResumeContextsForHost(overlayHost);
}
public void RegisterHUD(IHud hudContainer) public void RegisterHUD(IHud hudContainer)
{ {
_hudContainer = hudContainer; _hudContainer = hudContainer;
@@ -169,9 +183,7 @@ namespace BriarQueen.Framework.Managers.UI
if (!ReferenceEquals(_mainMenuOverlayHost, host)) if (!ReferenceEquals(_mainMenuOverlayHost, host))
return; return;
if (ReferenceEquals(_activeSettingsOverlayHost, host)) RemoveOverlayResumeContextsForHost(host);
_activeSettingsOverlayHost = null;
_mainMenuOverlayHost = null; _mainMenuOverlayHost = null;
} }
@@ -186,6 +198,51 @@ namespace BriarQueen.Framework.Managers.UI
return target != null && _windowStack.Contains(target); return target != null && _windowStack.Contains(target);
} }
private void RemoveOverlayResumeContextsForHost(IUIOverlayHost host)
{
if (host == null || _overlayResumeStack.Count == 0)
return;
var contextsToKeep = new List<OverlayResumeContext>();
foreach (var context in _overlayResumeStack)
{
if (!ReferenceEquals(context.Host, host))
contextsToKeep.Add(context);
}
_overlayResumeStack.Clear();
for (var i = contextsToKeep.Count - 1; i >= 0; i--)
_overlayResumeStack.Push(contextsToKeep[i]);
}
private async UniTask<bool> TrySuspendActiveWindowFor(WindowType incomingWindowType)
{
if (ActiveWindow is IUIOverlayHost overlayHost &&
overlayHost.CanSuspendFor(incomingWindowType))
{
await overlayHost.SuspendForOverlay();
_overlayResumeStack.Push(new OverlayResumeContext(incomingWindowType, overlayHost));
return true;
}
return false;
}
private async UniTask RestoreUnderlyingUi(WindowType closedWindowType)
{
if (_overlayResumeStack.Count > 0 &&
_overlayResumeStack.Peek().OverlayWindowType == closedWindowType)
{
var resumeContext = _overlayResumeStack.Pop();
await resumeContext.Host.ResumeFromOverlay();
return;
}
if (ActiveWindow != null)
await ActiveWindow.Show();
}
private async UniTask ApplyHudVisibility(bool visible) private async UniTask ApplyHudVisibility(bool visible)
{ {
if (_disposed || _hudContainer == null) if (_disposed || _hudContainer == null)
@@ -206,13 +263,25 @@ namespace BriarQueen.Framework.Managers.UI
private void OnPauseClickReceived(PauseButtonClickedEvent _) private void OnPauseClickReceived(PauseButtonClickedEvent _)
{ {
if (_windowStack.Count > 0) if (ActiveWindow == null)
{
OpenWindow(WindowType.PauseMenuWindow);
return;
}
if (ActiveWindow.WindowType == WindowType.PauseMenuWindow)
{ {
TryHandleBackRequest(); TryHandleBackRequest();
return; return;
} }
if (ActiveWindow.PauseBehavior == UIPauseBehavior.OpenPauseOverlay)
{
OpenWindow(WindowType.PauseMenuWindow); OpenWindow(WindowType.PauseMenuWindow);
return;
}
TryHandleBackRequest();
} }
private void OnBackRequested(UIBackRequestedEvent _) private void OnBackRequested(UIBackRequestedEvent _)
@@ -350,28 +419,22 @@ namespace BriarQueen.Framework.Managers.UI
if (_windowStack.Contains(window)) if (_windowStack.Contains(window))
return; return;
_activeSettingsOverlayHost = null; var suspended = false;
var openingSettingsOverPause = if (source == SettingsOpenSource.MainMenu &&
source == SettingsOpenSource.PauseMenu && _mainMenuOverlayHost != null &&
ActiveWindow?.WindowType == WindowType.PauseMenuWindow && _mainMenuOverlayHost.CanSuspendFor(WindowType.SettingsWindow))
ActiveWindow is IUIOverlayHost;
var openingSettingsOverMainMenu =
source == SettingsOpenSource.MainMenu &&
_mainMenuOverlayHost != null;
if (openingSettingsOverPause)
{ {
_activeSettingsOverlayHost = (IUIOverlayHost)ActiveWindow; await _mainMenuOverlayHost.SuspendForOverlay();
await _activeSettingsOverlayHost.SuspendForOverlay(); _overlayResumeStack.Push(new OverlayResumeContext(WindowType.SettingsWindow, _mainMenuOverlayHost));
suspended = true;
} }
else if (openingSettingsOverMainMenu) else
{ {
_activeSettingsOverlayHost = _mainMenuOverlayHost; suspended = await TrySuspendActiveWindowFor(WindowType.SettingsWindow);
await _activeSettingsOverlayHost.SuspendForOverlay();
} }
else if (ActiveWindow != null)
if (!suspended && ActiveWindow != null)
{ {
await ActiveWindow.Hide(); await ActiveWindow.Hide();
} }
@@ -407,7 +470,9 @@ namespace BriarQueen.Framework.Managers.UI
if (_windowStack.Contains(window)) if (_windowStack.Contains(window))
return; return;
if (ActiveWindow != null) var suspended = await TrySuspendActiveWindowFor(windowType);
if (!suspended && ActiveWindow != null)
await ActiveWindow.Hide(); await ActiveWindow.Hide();
_windowStack.Push(window); _windowStack.Push(window);
@@ -452,15 +517,7 @@ namespace BriarQueen.Framework.Managers.UI
break; break;
} }
if (target.WindowType == WindowType.SettingsWindow && _activeSettingsOverlayHost != null) await RestoreUnderlyingUi(target.WindowType);
{
await _activeSettingsOverlayHost.ResumeFromOverlay();
_activeSettingsOverlayHost = null;
}
else if (ActiveWindow != null)
{
await ActiveWindow.Show();
}
NotifyUIStackChanged(); NotifyUIStackChanged();
} }
@@ -506,17 +563,8 @@ namespace BriarQueen.Framework.Managers.UI
NotifyWindowStateChanged(top.WindowType, false); NotifyWindowStateChanged(top.WindowType, false);
} }
if (top != null && if (top != null)
top.WindowType == WindowType.SettingsWindow && await RestoreUnderlyingUi(top.WindowType);
_activeSettingsOverlayHost != null)
{
await _activeSettingsOverlayHost.ResumeFromOverlay();
_activeSettingsOverlayHost = null;
}
else if (ActiveWindow != null)
{
await ActiveWindow.Show();
}
NotifyUIStackChanged(); NotifyUIStackChanged();
} }
@@ -536,17 +584,12 @@ namespace BriarQueen.Framework.Managers.UI
await _windowTransitionGate.WaitAsync(); await _windowTransitionGate.WaitAsync();
try try
{ {
var shouldResumeSettingsHost = false;
while (_windowStack.Count > 0) while (_windowStack.Count > 0)
{ {
var window = _windowStack.Pop(); var window = _windowStack.Pop();
if (window == null) if (window == null)
continue; continue;
if (window.WindowType == WindowType.SettingsWindow && _activeSettingsOverlayHost != null)
shouldResumeSettingsHost = true;
try try
{ {
await window.Hide(); await window.Hide();
@@ -557,18 +600,7 @@ namespace BriarQueen.Framework.Managers.UI
} }
} }
if (shouldResumeSettingsHost) _overlayResumeStack.Clear();
{
try
{
await _activeSettingsOverlayHost.ResumeFromOverlay();
}
catch
{
}
}
_activeSettingsOverlayHost = null;
if (_tutorialPopup != null) if (_tutorialPopup != null)
{ {
@@ -621,7 +653,7 @@ namespace BriarQueen.Framework.Managers.UI
faderComponent.gameObject.SetActive(false); faderComponent.gameObject.SetActive(false);
_windowStack.Clear(); _windowStack.Clear();
_activeSettingsOverlayHost = null; _overlayResumeStack.Clear();
_mainMenuOverlayHost = null; _mainMenuOverlayHost = null;
} }

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 1973a703eae6841b6b53b6f33b951713
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,148 @@
using System;
using System.Threading;
using BriarQueen.Data.Identifiers;
using BriarQueen.Framework.Coordinators.Events;
using BriarQueen.Framework.Events.Audio;
using BriarQueen.Framework.Events.UI;
using Cysharp.Threading.Tasks;
using VContainer;
namespace BriarQueen.Framework.Services.Subtitles
{
public class SubtitleService : IDisposable
{
private readonly EventCoordinator _eventCoordinator;
private CancellationTokenSource _subtitleCts;
private SubtitleKey _activeSubtitleKey = SubtitleKey.None;
private string _currentText = string.Empty;
public bool IsVisible => _activeSubtitleKey != SubtitleKey.None && !string.IsNullOrWhiteSpace(_currentText);
public string CurrentText => _currentText;
[Inject]
public SubtitleService(EventCoordinator eventCoordinator)
{
_eventCoordinator = eventCoordinator;
}
public void Initialize()
{
_eventCoordinator.Subscribe<VoicePlaybackStartedEvent>(OnVoicePlaybackStarted);
_eventCoordinator.Subscribe<VoicePlaybackFinishedEvent>(OnVoicePlaybackFinished);
}
public void Dispose()
{
_eventCoordinator.Unsubscribe<VoicePlaybackStartedEvent>(OnVoicePlaybackStarted);
_eventCoordinator.Unsubscribe<VoicePlaybackFinishedEvent>(OnVoicePlaybackFinished);
CancelCurrentSubtitle();
ClearSubtitle();
}
public void PlayScriptedSubtitle(SubtitleKey subtitleKey, float durationOverrideSeconds = 0f)
{
if (subtitleKey == SubtitleKey.None)
{
ClearScriptedSubtitle();
return;
}
if (!SubtitleIdentifiers.TryGet(subtitleKey, out var entry) || string.IsNullOrWhiteSpace(entry.Text))
return;
var duration = durationOverrideSeconds > 0f
? durationOverrideSeconds
: entry.PreferredDurationSeconds;
ShowSubtitle(subtitleKey, entry.Text, duration).Forget();
}
public void ClearScriptedSubtitle()
{
CancelCurrentSubtitle();
ClearSubtitle();
}
private void OnVoicePlaybackStarted(VoicePlaybackStartedEvent evt)
{
if (evt.SubtitleKey == SubtitleKey.None)
return;
if (!SubtitleIdentifiers.TryGet(evt.SubtitleKey, out var entry) || string.IsNullOrWhiteSpace(entry.Text))
return;
var duration = entry.PreferredDurationSeconds > 0f
? entry.PreferredDurationSeconds
: evt.ClipLengthSeconds;
ShowSubtitle(evt.SubtitleKey, entry.Text, duration).Forget();
}
private void OnVoicePlaybackFinished(VoicePlaybackFinishedEvent evt)
{
if (evt.SubtitleKey == SubtitleKey.None)
return;
if (_activeSubtitleKey != evt.SubtitleKey)
return;
CancelCurrentSubtitle();
ClearSubtitle();
}
private async UniTaskVoid ShowSubtitle(SubtitleKey subtitleKey, string text, float durationSeconds)
{
CancelCurrentSubtitle();
_activeSubtitleKey = subtitleKey;
_currentText = text;
_subtitleCts = new CancellationTokenSource();
_eventCoordinator.PublishImmediate(new SubtitleDisplayChangedEvent(text, true));
var safeDuration = Math.Max(0f, durationSeconds);
if (safeDuration <= 0f)
return;
try
{
await UniTask.Delay(
TimeSpan.FromSeconds(safeDuration),
DelayType.UnscaledDeltaTime,
cancellationToken: _subtitleCts.Token);
}
catch (OperationCanceledException)
{
return;
}
if (_activeSubtitleKey == subtitleKey)
ClearSubtitle();
}
private void CancelCurrentSubtitle()
{
if (_subtitleCts == null)
return;
try
{
_subtitleCts.Cancel();
}
catch
{
}
_subtitleCts.Dispose();
_subtitleCts = null;
}
private void ClearSubtitle()
{
_activeSubtitleKey = SubtitleKey.None;
_currentText = string.Empty;
_eventCoordinator.PublishImmediate(new SubtitleDisplayChangedEvent(string.Empty, false));
}
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 61b6e034a002e4319a76ebe6bd90f50f

View File

@@ -92,15 +92,9 @@ namespace BriarQueen.Game.Items.Environment.General.Book
_bookInterface.CanvasGroup.blocksRaycasts = true; _bookInterface.CanvasGroup.blocksRaycasts = true;
_bookInterface.CanvasGroup.interactable = true; _bookInterface.CanvasGroup.interactable = true;
ShowTutorialIfNeeded();
UnlockCodexEntry(); UnlockCodexEntry();
} }
private void ShowTutorialIfNeeded()
{
TutorialService.DisplayTutorial(TutorialPopupID.ExitItems);
}
private void UnlockCodexEntry() private void UnlockCodexEntry()
{ {
PlayerManager.UnlockCodexEntry(CodexEntryIDs.Get(_documentEntryID)); PlayerManager.UnlockCodexEntry(CodexEntryIDs.Get(_documentEntryID));

View File

@@ -17,6 +17,13 @@ namespace BriarQueen.Game.Items.Environment.General
[SerializeField] [SerializeField]
private bool _removeTrigger; private bool _removeTrigger;
[Header("Events")]
[SerializeField]
private SFXKey _soundEffect;
[SerializeField]
private VoiceKey _voiceLine;
public override UICursorService.CursorStyle ApplicableCursorStyle => UICursorService.CursorStyle.Inspect; public override UICursorService.CursorStyle ApplicableCursorStyle => UICursorService.CursorStyle.Inspect;
public override string InteractableName => InteractableTooltip; public override string InteractableName => InteractableTooltip;
@@ -29,6 +36,16 @@ namespace BriarQueen.Game.Items.Environment.General
if (_removeTrigger) if (_removeTrigger)
await Remove(); await Remove();
if (_soundEffect != SFXKey.None)
{
AudioManager.Play(AudioNameIdentifiers.Get(_soundEffect));
}
if (_voiceLine != VoiceKey.None)
{
AudioManager.Play(AudioNameIdentifiers.Get(_voiceLine));
}
} }
} }
} }

View File

@@ -21,9 +21,6 @@ namespace BriarQueen.Game.Levels.ChapterOne.Ashwick
[SerializeField] [SerializeField]
private AshwickGate _ashwickGate; private AshwickGate _ashwickGate;
[SerializeField]
private TransitionZone _keypadZone;
[SerializeField] [SerializeField]
private TransitionZone _nextLevelZone; private TransitionZone _nextLevelZone;
@@ -36,22 +33,17 @@ namespace BriarQueen.Game.Levels.ChapterOne.Ashwick
_background.sprite = _backgroundOpenSprite; _background.sprite = _backgroundOpenSprite;
_nextLevelZone.Unlock(); _nextLevelZone.Unlock();
await DestructionService.Destroy(_ashwickGate.gameObject); await DestructionService.Destroy(_ashwickGate.gameObject);
await DestructionService.Destroy(_keypadZone.gameObject);
} }
} }
public async UniTask OpenGate() public async UniTask OpenGate()
{ {
EventCoordinator.PublishImmediate(new FadeEvent(false));
_background.sprite = _backgroundOpenSprite; _background.sprite = _backgroundOpenSprite;
_nextLevelZone.Unlock(); _nextLevelZone.Unlock();
await DestructionService.Destroy(_ashwickGate.gameObject); await DestructionService.Destroy(_ashwickGate.gameObject);
await DestructionService.Destroy(_keypadZone.gameObject);
SaveManager.SetLevelFlag(LevelFlag.AshwickGateOpen, true); SaveManager.SetLevelFlag(LevelFlag.AshwickGateOpen, true);
EventCoordinator.PublishImmediate(new FadeEvent(true));
} }
} }
} }

View File

@@ -1,24 +0,0 @@
using BriarQueen.Data.Identifiers;
using BriarQueen.Data.IO.Saves;
using BriarQueen.Framework.Events.Save;
using BriarQueen.Framework.Events.UI;
using BriarQueen.Framework.Managers.Levels.Data;
using Cysharp.Threading.Tasks;
namespace BriarQueen.Game.Levels.ChapterOne.Ashwick
{
public class Marketplace : BaseLevel
{
protected override UniTask PostActivateInternal()
{
if (SaveManager.GetLevelFlag(LevelFlag.MarketplaceFirstEntry))
return UniTask.CompletedTask;
EventCoordinator.Publish(new DisplayInteractEvent(InteractEventIDs.Get(LevelInteractKey.MarketplaceFirstEntry)));
SaveManager.SetLevelFlag(LevelFlag.MarketplaceFirstEntry, true);
return UniTask.CompletedTask;
}
}
}

View File

@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 2d9beb847a184e2e897942fff18a396e
timeCreated: 1778696777

View File

@@ -10,6 +10,7 @@ using BriarQueen.Framework.Managers.Levels;
using BriarQueen.Framework.Managers.Player; using BriarQueen.Framework.Managers.Player;
using BriarQueen.Framework.Managers.UI; using BriarQueen.Framework.Managers.UI;
using BriarQueen.Framework.Services.Settings; using BriarQueen.Framework.Services.Settings;
using BriarQueen.Framework.Services.Subtitles;
using BriarQueen.Framework.Services.Tutorials; using BriarQueen.Framework.Services.Tutorials;
using BriarQueen.Game.Cinematics; using BriarQueen.Game.Cinematics;
using Cysharp.Threading.Tasks; using Cysharp.Threading.Tasks;
@@ -30,6 +31,7 @@ namespace BriarQueen.Game.Misc
private readonly SettingsService _settingsService; private readonly SettingsService _settingsService;
private readonly SplashScreens _splashScreens; private readonly SplashScreens _splashScreens;
private readonly SteamManager _steamManager; private readonly SteamManager _steamManager;
private readonly SubtitleService _subtitleService;
private readonly TutorialService _tutorialService; private readonly TutorialService _tutorialService;
private readonly UIManager _uiManager; private readonly UIManager _uiManager;
@@ -45,6 +47,7 @@ namespace BriarQueen.Game.Misc
SettingsService settingsService, SettingsService settingsService,
SteamManager steamManager, SteamManager steamManager,
SplashScreens splashScreens, SplashScreens splashScreens,
SubtitleService subtitleService,
TutorialService tutorialService) TutorialService tutorialService)
{ {
_audioManager = audioManager; _audioManager = audioManager;
@@ -58,6 +61,8 @@ namespace BriarQueen.Game.Misc
_settingsService = settingsService; _settingsService = settingsService;
_steamManager = steamManager; _steamManager = steamManager;
_splashScreens = splashScreens; _splashScreens = splashScreens;
_subtitleService = subtitleService;
_tutorialService = tutorialService;
} }
public async UniTask StartAsync(CancellationToken cancellationToken) public async UniTask StartAsync(CancellationToken cancellationToken)
@@ -67,6 +72,9 @@ namespace BriarQueen.Game.Misc
Debug.Log("[Bootstrap] Audio..."); Debug.Log("[Bootstrap] Audio...");
_audioManager.Initialize(); _audioManager.Initialize();
Debug.Log("[Bootstrap] Subtitles...");
_subtitleService.Initialize();
Debug.Log("[Bootstrap] Settings..."); Debug.Log("[Bootstrap] Settings...");
await _settingsService.InitializeAsync(); await _settingsService.InitializeAsync();

View File

@@ -1,5 +1,6 @@
using BriarQueen.Framework.Managers.Levels.Data; using BriarQueen.Framework.Managers.Levels.Data;
using BriarQueen.Framework.Managers.Player.Data; using BriarQueen.Framework.Managers.Player.Data;
using BriarQueen.Framework.Managers.UI;
using Cysharp.Threading.Tasks; using Cysharp.Threading.Tasks;
using UnityEngine; using UnityEngine;
@@ -7,10 +8,13 @@ namespace BriarQueen.Game.Puzzles.ChapterOne.AshwickHallow
{ {
public class AshwickGate : BaseItem public class AshwickGate : BaseItem
{ {
[Header("Keypad")]
[SerializeField] private AshwickGateKeypadPuzzle _keypadPuzzle; [SerializeField] private AshwickGateKeypadPuzzle _keypadPuzzle;
public override string InteractableName => "Iron Gate"; public override string InteractableName => "Iron Gate";
public override UICursorService.CursorStyle ApplicableCursorStyle => UICursorService.CursorStyle.Interact;
public override UniTask OnInteract(ItemDataSo item = null) public override UniTask OnInteract(ItemDataSo item = null)
{ {
if (!CheckEmptyHands()) if (!CheckEmptyHands())

View File

@@ -5,7 +5,10 @@ using BriarQueen.Data.IO.Saves;
using BriarQueen.Framework.Effects; using BriarQueen.Framework.Effects;
using BriarQueen.Framework.Events.Save; using BriarQueen.Framework.Events.Save;
using BriarQueen.Framework.Managers.Interaction; using BriarQueen.Framework.Managers.Interaction;
using BriarQueen.Framework.Managers.UI;
using BriarQueen.Framework.Managers.UI.Base;
using BriarQueen.Framework.Services.Puzzles.Base; using BriarQueen.Framework.Services.Puzzles.Base;
using BriarQueen.Framework.Services.Tutorials;
using BriarQueen.Game.Levels.ChapterOne.Ashwick; using BriarQueen.Game.Levels.ChapterOne.Ashwick;
using Cysharp.Threading.Tasks; using Cysharp.Threading.Tasks;
using MemoryPack; using MemoryPack;
@@ -24,7 +27,7 @@ namespace BriarQueen.Game.Puzzles.ChapterOne.AshwickHallow
public string Digits; public string Digits;
} }
public class AshwickGateKeypadPuzzle : BasePuzzle, IPuzzleStateful public class AshwickGateKeypadPuzzle : BasePuzzle, IPuzzleStateful, IUIWindow, IUIBackHandler, IUIOverlayHost
{ {
private const string CorrectCode = "312"; private const string CorrectCode = "312";
private const int RequiredDigits = 3; private const int RequiredDigits = 3;
@@ -63,14 +66,25 @@ namespace BriarQueen.Game.Puzzles.ChapterOne.AshwickHallow
private bool _isEvaluating; private bool _isEvaluating;
private bool _isOpen; private bool _isOpen;
private bool _raycasterRegistered; private bool _raycasterRegistered;
private bool _skipSaveOnHide;
private TutorialService _tutorialService;
private UIManager _uiManager;
public override string PuzzleID => PuzzleIdentifiers.AllPuzzles[PuzzleKey.AshwickMarketGate]; public override string PuzzleID => PuzzleIdentifiers.AllPuzzles[PuzzleKey.AshwickMarketGate];
public bool IsCompleted => _isCompleted || SaveManager.GetLevelFlag(LevelFlag.AshwickGateOpen); public bool IsCompleted => _isCompleted || SaveManager.GetLevelFlag(LevelFlag.AshwickGateOpen);
public WindowType WindowType => WindowType.AshwickGateKeypadWindow;
public UIPauseBehavior PauseBehavior => UIPauseBehavior.OpenPauseOverlay;
[Inject] [Inject]
public void ConstructKeypad(InteractManager interactManager) public void ConstructKeypad(
InteractManager interactManager,
UIManager uiManager,
TutorialService tutorialService)
{ {
_interactManager = interactManager; _interactManager = interactManager;
_uiManager = uiManager;
_tutorialService = tutorialService;
} }
private void Awake() private void Awake()
@@ -86,8 +100,14 @@ namespace BriarQueen.Game.Puzzles.ChapterOne.AshwickHallow
SyncDisplay(); SyncDisplay();
} }
private void Start()
{
_uiManager?.RegisterWindow(this);
}
private void OnDestroy() private void OnDestroy()
{ {
_uiManager?.UnregisterWindow(this);
UnbindButtons(); UnbindButtons();
TryUnregisterRaycaster(); TryUnregisterRaycaster();
CancelPanelTween(); CancelPanelTween();
@@ -98,10 +118,7 @@ namespace BriarQueen.Game.Puzzles.ChapterOne.AshwickHallow
_isCompleted = SaveManager.GetLevelFlag(LevelFlag.AshwickGateOpen); _isCompleted = SaveManager.GetLevelFlag(LevelFlag.AshwickGateOpen);
_isOpen = false; _isOpen = false;
_isEvaluating = false; _isEvaluating = false;
_skipSaveOnHide = false;
SetPanelState(0f, false, false);
SyncDisplay();
_statusGlow?.TurnOff().Forget();
return UniTask.CompletedTask; return UniTask.CompletedTask;
} }
@@ -113,12 +130,15 @@ namespace BriarQueen.Game.Puzzles.ChapterOne.AshwickHallow
public void Open() public void Open()
{ {
OpenInternal().Forget(); if (IsCompleted || _uiManager == null)
return;
_uiManager.OpenWindow(WindowType);
} }
public void Close() public void Close()
{ {
CloseInternal(requestSave: true).Forget(); _uiManager?.CloseWindow(WindowType);
} }
public UniTask<byte[]> CaptureState() public UniTask<byte[]> CaptureState()
@@ -159,12 +179,13 @@ namespace BriarQueen.Game.Puzzles.ChapterOne.AshwickHallow
SyncDisplay(); SyncDisplay();
SaveManager.SetPuzzleCompleted(PuzzleKey.AshwickMarketGate, true, requestSave: false); SaveManager.SetPuzzleCompleted(PuzzleKey.AshwickMarketGate, true, requestSave: false);
_skipSaveOnHide = true;
await CloseInternal(requestSave: false); _uiManager?.CloseWindow(WindowType);
AudioManager.Play(AudioNameIdentifiers.Get(SFXKey.AshwickGateOpening));
await _outskirts.OpenGate(); await _outskirts.OpenGate();
} }
private async UniTaskVoid OpenInternal() public async UniTask Show()
{ {
if (IsCompleted || _isEvaluating || _isOpen) if (IsCompleted || _isEvaluating || _isOpen)
return; return;
@@ -174,8 +195,7 @@ namespace BriarQueen.Game.Puzzles.ChapterOne.AshwickHallow
SetPanelState(0f, false, true); SetPanelState(0f, false, true);
SyncDisplay(); SyncDisplay();
TryRegisterRaycaster(); EnsureExclusiveRaycaster();
_statusGlow?.TurnOff().Forget();
try try
{ {
@@ -199,9 +219,10 @@ namespace BriarQueen.Game.Puzzles.ChapterOne.AshwickHallow
} }
SetPanelState(1f, true, true); SetPanelState(1f, true, true);
_tutorialService?.DisplayTutorial(TutorialPopupID.LeavingPuzzles);
} }
private async UniTask CloseInternal(bool requestSave) public async UniTask Hide()
{ {
if (!_isOpen) if (!_isOpen)
return; return;
@@ -239,8 +260,91 @@ namespace BriarQueen.Game.Puzzles.ChapterOne.AshwickHallow
SetPanelState(0f, false, false); SetPanelState(0f, false, false);
TryUnregisterRaycaster(); TryUnregisterRaycaster();
if (requestSave) if (!_skipSaveOnHide && !_isCompleted)
EventCoordinator.PublishImmediate(new RequestGameSaveEvent()); EventCoordinator.PublishImmediate(new RequestGameSaveEvent());
_skipSaveOnHide = false;
}
public bool HandleBackRequest()
{
Close();
return true;
}
public bool CanSuspendFor(WindowType incomingWindowType)
{
return incomingWindowType == WindowType.PauseMenuWindow;
}
public async UniTask SuspendForOverlay()
{
if (!_isOpen)
return;
ResetPanelTween();
if (_panelGroup != null)
{
_panelGroup.interactable = false;
_panelGroup.blocksRaycasts = false;
}
try
{
_panelSequence = Sequence.Create(useUnscaledTime: true)
.Group(Tween.Alpha(_panelGroup, new TweenSettings<float>
{
startValue = _panelGroup != null ? _panelGroup.alpha : 1f,
endValue = 0f,
settings = _panelFadeTweenSettings
}));
await _panelSequence.ToUniTask(cancellationToken: _panelCts.Token);
}
catch (OperationCanceledException)
{
return;
}
finally
{
_panelSequence = default;
}
SetPanelState(0f, false, false);
}
public async UniTask ResumeFromOverlay()
{
if (!_isOpen)
return;
ResetPanelTween();
EnsureExclusiveRaycaster();
SetPanelState(0f, false, true);
try
{
_panelSequence = Sequence.Create(useUnscaledTime: true)
.Group(Tween.Alpha(_panelGroup, new TweenSettings<float>
{
startValue = 0f,
endValue = 1f,
settings = _panelFadeTweenSettings
}));
await _panelSequence.ToUniTask(cancellationToken: _panelCts.Token);
}
catch (OperationCanceledException)
{
return;
}
finally
{
_panelSequence = default;
}
SetPanelState(1f, !_isEvaluating, true);
} }
private void OnDigitPressed(int digit) private void OnDigitPressed(int digit)
@@ -370,23 +474,27 @@ namespace BriarQueen.Game.Puzzles.ChapterOne.AshwickHallow
} }
} }
private void TryRegisterRaycaster() private void EnsureExclusiveRaycaster()
{ {
if (_raycasterRegistered || _interactManager == null || _graphicRaycaster == null) if (_interactManager == null || _graphicRaycaster == null)
return; return;
if (!_raycasterRegistered)
{
_interactManager.AddUIRaycaster(_graphicRaycaster); _interactManager.AddUIRaycaster(_graphicRaycaster);
_interactManager.SetExclusiveRaycaster(_graphicRaycaster);
_raycasterRegistered = true; _raycasterRegistered = true;
} }
_interactManager.SetExclusiveRaycaster(_graphicRaycaster);
}
private void TryUnregisterRaycaster() private void TryUnregisterRaycaster()
{ {
if (!_raycasterRegistered || _interactManager == null || _graphicRaycaster == null) if (!_raycasterRegistered || _interactManager == null || _graphicRaycaster == null)
return; return;
_interactManager.RemoveUIRaycaster(_graphicRaycaster); _interactManager.RemoveUIRaycaster(_graphicRaycaster);
_interactManager.ClearExclusiveRaycaster(); _interactManager.ReleaseExclusiveRaycaster(_graphicRaycaster);
_raycasterRegistered = false; _raycasterRegistered = false;
} }
} }

View File

@@ -15,6 +15,7 @@ using BriarQueen.Framework.Services.Destruction;
using BriarQueen.Framework.Services.Game; using BriarQueen.Framework.Services.Game;
using BriarQueen.Framework.Services.Puzzles; using BriarQueen.Framework.Services.Puzzles;
using BriarQueen.Framework.Services.Settings; using BriarQueen.Framework.Services.Settings;
using BriarQueen.Framework.Services.Subtitles;
using BriarQueen.Framework.Services.Tutorials; using BriarQueen.Framework.Services.Tutorials;
using BriarQueen.Game.Cinematics; using BriarQueen.Game.Cinematics;
using BriarQueen.Game.Misc; using BriarQueen.Game.Misc;
@@ -89,6 +90,7 @@ namespace BriarQueen.Game.Scopes
builder.Register<SaveManager>(Lifetime.Singleton); builder.Register<SaveManager>(Lifetime.Singleton);
builder.Register<SettingsService>(Lifetime.Singleton); builder.Register<SettingsService>(Lifetime.Singleton);
builder.Register<SteamManager>(Lifetime.Singleton); builder.Register<SteamManager>(Lifetime.Singleton);
builder.Register<SubtitleService>(Lifetime.Singleton);
builder.Register<TutorialService>(Lifetime.Singleton); builder.Register<TutorialService>(Lifetime.Singleton);
builder.Register<UIManager>(Lifetime.Singleton); builder.Register<UIManager>(Lifetime.Singleton);
} }

View File

@@ -255,6 +255,7 @@ namespace BriarQueen.UI.Codex
} }
public WindowType WindowType => WindowType.CodexWindow; public WindowType WindowType => WindowType.CodexWindow;
public UIPauseBehavior PauseBehavior => UIPauseBehavior.TreatAsBackRequest;
// ── IUIWindow ───────────────────────────────────────────────── // ── IUIWindow ─────────────────────────────────────────────────
@@ -263,7 +264,7 @@ namespace BriarQueen.UI.Codex
ResetOperationCts(); ResetOperationCts();
gameObject.SetActive(true); gameObject.SetActive(true);
TryRegisterRaycaster(); EnsureExclusiveRaycaster();
if (_canvasGroup != null) if (_canvasGroup != null)
{ {
@@ -380,7 +381,7 @@ namespace BriarQueen.UI.Codex
// ── Raycaster ───────────────────────────────────────────────── // ── Raycaster ─────────────────────────────────────────────────
private void TryRegisterRaycaster() private void EnsureExclusiveRaycaster()
{ {
Debug.Log($"[CodexWindow] TryRegisterRaycaster " + Debug.Log($"[CodexWindow] TryRegisterRaycaster " +
@@ -392,10 +393,15 @@ namespace BriarQueen.UI.Codex
Debug.Log("[CodexWindow] Try register raycaster."); Debug.Log("[CodexWindow] Try register raycaster.");
if (_raycasterRegistered || _interactManager == null || _graphicRaycaster == null) return; if (_interactManager == null || _graphicRaycaster == null) return;
if (!_raycasterRegistered)
{
_interactManager.AddUIRaycaster(_graphicRaycaster); _interactManager.AddUIRaycaster(_graphicRaycaster);
_interactManager.SetExclusiveRaycaster(_graphicRaycaster);
_raycasterRegistered = true; _raycasterRegistered = true;
}
_interactManager.SetExclusiveRaycaster(_graphicRaycaster);
Debug.Log("[CodexWindow] Registered raycaster."); Debug.Log("[CodexWindow] Registered raycaster.");
} }
@@ -406,7 +412,7 @@ namespace BriarQueen.UI.Codex
if (!_raycasterRegistered || _interactManager == null || _graphicRaycaster == null) return; if (!_raycasterRegistered || _interactManager == null || _graphicRaycaster == null) return;
_interactManager.RemoveUIRaycaster(_graphicRaycaster); _interactManager.RemoveUIRaycaster(_graphicRaycaster);
_interactManager.ClearExclusiveRaycaster(); _interactManager.ReleaseExclusiveRaycaster(_graphicRaycaster);
_raycasterRegistered = false; _raycasterRegistered = false;
Debug.Log("[CodexWindow] Raycaster unregistered."); Debug.Log("[CodexWindow] Raycaster unregistered.");

View File

@@ -0,0 +1,212 @@
using System;
using System.Threading;
using BriarQueen.Framework.Coordinators.Events;
using BriarQueen.Framework.Events.UI;
using BriarQueen.Framework.Services.Subtitles;
using Cysharp.Threading.Tasks;
using PrimeTween;
using UnityEngine;
using VContainer;
namespace BriarQueen.UI.HUD
{
public class SubtitleUI : MonoBehaviour
{
[Header("UI")]
[SerializeField]
private InteractTextUI _interactTextUI;
[SerializeField]
private CanvasGroup _canvasGroup;
[Header("Tweens")]
[SerializeField]
private TweenSettings _tweenSettings = new()
{
duration = 0.2f,
ease = Ease.InOutSine,
useUnscaledTime = true
};
private EventCoordinator _eventCoordinator;
private SubtitleService _subtitleService;
private CancellationTokenSource _cancellationTokenSource;
private Sequence _sequence;
[Inject]
public void Construct(EventCoordinator eventCoordinator, SubtitleService subtitleService)
{
_eventCoordinator = eventCoordinator;
_subtitleService = subtitleService;
}
private void Awake()
{
ApplyImmediate(string.Empty, false);
}
private void OnEnable()
{
_eventCoordinator?.Subscribe<SubtitleDisplayChangedEvent>(OnSubtitleDisplayChanged);
SyncFromService();
}
private void OnDisable()
{
_eventCoordinator?.Unsubscribe<SubtitleDisplayChangedEvent>(OnSubtitleDisplayChanged);
StopTween();
}
private void OnDestroy()
{
StopTween();
}
private void SyncFromService()
{
if (_subtitleService != null && _subtitleService.IsVisible)
{
ApplyImmediate(_subtitleService.CurrentText, true);
return;
}
ApplyImmediate(string.Empty, false);
}
private void OnSubtitleDisplayChanged(SubtitleDisplayChangedEvent eventData)
{
if (!eventData.Visible || string.IsNullOrWhiteSpace(eventData.Text))
{
HideSubtitle().Forget();
return;
}
ShowSubtitle(eventData.Text).Forget();
}
private async UniTaskVoid ShowSubtitle(string text)
{
if (_canvasGroup == null || _interactTextUI == null)
return;
StopTween();
_interactTextUI.SetText(text);
_canvasGroup.blocksRaycasts = false;
_canvasGroup.interactable = false;
_cancellationTokenSource = new CancellationTokenSource();
var tween = new TweenSettings<float>
{
startValue = _canvasGroup.alpha,
endValue = 1f,
settings = _tweenSettings
};
_sequence = Sequence.Create(useUnscaledTime: true)
.Group(Tween.Alpha(_canvasGroup, tween));
try
{
await _sequence.ToUniTask(cancellationToken: _cancellationTokenSource.Token);
}
catch (OperationCanceledException)
{
return;
}
finally
{
DisposeTweenState();
}
_canvasGroup.alpha = 1f;
}
private async UniTaskVoid HideSubtitle()
{
if (_canvasGroup == null || _interactTextUI == null)
return;
StopTween();
_cancellationTokenSource = new CancellationTokenSource();
var tween = new TweenSettings<float>
{
startValue = _canvasGroup.alpha,
endValue = 0f,
settings = _tweenSettings
};
_sequence = Sequence.Create(useUnscaledTime: true)
.Group(Tween.Alpha(_canvasGroup, tween));
try
{
await _sequence.ToUniTask(cancellationToken: _cancellationTokenSource.Token);
}
catch (OperationCanceledException)
{
return;
}
finally
{
DisposeTweenState();
}
ApplyImmediate(string.Empty, false);
}
private void ApplyImmediate(string text, bool visible)
{
if (_interactTextUI != null)
{
if (visible)
_interactTextUI.SetText(text);
else
_interactTextUI.ClearText();
}
if (_canvasGroup == null)
return;
_canvasGroup.alpha = visible ? 1f : 0f;
_canvasGroup.blocksRaycasts = false;
_canvasGroup.interactable = false;
}
private void StopTween()
{
if (_sequence.isAlive)
_sequence.Stop();
_sequence = default;
if (_cancellationTokenSource == null)
return;
try
{
_cancellationTokenSource.Cancel();
}
catch
{
}
_cancellationTokenSource.Dispose();
_cancellationTokenSource = null;
}
private void DisposeTweenState()
{
_sequence = default;
if (_cancellationTokenSource == null)
return;
_cancellationTokenSource.Dispose();
_cancellationTokenSource = null;
}
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: a7225bc6a3f524fb8b820162cd937c1e

View File

@@ -635,6 +635,11 @@ namespace BriarQueen.UI.Menus
group.blocksRaycasts = inputEnabled; group.blocksRaycasts = inputEnabled;
} }
public bool CanSuspendFor(WindowType incomingWindowType)
{
return incomingWindowType == WindowType.SettingsWindow;
}
public async UniTask SuspendForOverlay() public async UniTask SuspendForOverlay()
{ {
if (_mainMenuGroup == null) if (_mainMenuGroup == null)

View File

@@ -79,20 +79,27 @@ namespace BriarQueen.UI.Menus
public bool IsModal => true; public bool IsModal => true;
public WindowType WindowType => WindowType.PauseMenuWindow; public WindowType WindowType => WindowType.PauseMenuWindow;
public UIPauseBehavior PauseBehavior => UIPauseBehavior.TreatAsBackRequest;
private void TryRegisterRaycaster() public bool CanSuspendFor(WindowType incomingWindowType)
{ {
if (_raycasterRegistered) return incomingWindowType == WindowType.SettingsWindow;
return; }
private void EnsureExclusiveRaycaster()
{
if (_interactManager == null || _graphicRaycaster == null) if (_interactManager == null || _graphicRaycaster == null)
return; return;
if (!_raycasterRegistered)
{
_interactManager.AddUIRaycaster(_graphicRaycaster); _interactManager.AddUIRaycaster(_graphicRaycaster);
_interactManager.SetExclusiveRaycaster(_graphicRaycaster);
_raycasterRegistered = true; _raycasterRegistered = true;
} }
_interactManager.SetExclusiveRaycaster(_graphicRaycaster);
}
private void TryUnregisterRaycaster() private void TryUnregisterRaycaster()
{ {
if (!_raycasterRegistered) if (!_raycasterRegistered)
@@ -102,7 +109,7 @@ namespace BriarQueen.UI.Menus
return; return;
_interactManager.RemoveUIRaycaster(_graphicRaycaster); _interactManager.RemoveUIRaycaster(_graphicRaycaster);
_interactManager.ClearExclusiveRaycaster(); _interactManager.ReleaseExclusiveRaycaster(_graphicRaycaster);
_raycasterRegistered = false; _raycasterRegistered = false;
} }
@@ -149,7 +156,7 @@ namespace BriarQueen.UI.Menus
SetLevelName(); SetLevelName();
gameObject.SetActive(true); gameObject.SetActive(true);
TryRegisterRaycaster(); EnsureExclusiveRaycaster();
_canvasGroup.blocksRaycasts = false; _canvasGroup.blocksRaycasts = false;
_canvasGroup.interactable = false; _canvasGroup.interactable = false;
@@ -233,6 +240,7 @@ namespace BriarQueen.UI.Menus
public async UniTask ResumeFromOverlay() public async UniTask ResumeFromOverlay()
{ {
StopAndResetCancellation(); StopAndResetCancellation();
EnsureExclusiveRaycaster();
_buttonsGroup.blocksRaycasts = true; _buttonsGroup.blocksRaycasts = true;
_buttonsGroup.interactable = true; _buttonsGroup.interactable = true;

View File

@@ -147,6 +147,7 @@ namespace BriarQueen.UI.Menus
// ── IUIWindow ───────────────────────────────────────────────── // ── IUIWindow ─────────────────────────────────────────────────
public bool IsModal => true; public bool IsModal => true;
public WindowType WindowType => WindowType.SettingsWindow; public WindowType WindowType => WindowType.SettingsWindow;
public UIPauseBehavior PauseBehavior => UIPauseBehavior.TreatAsBackRequest;
// ── Unity lifecycle ─────────────────────────────────────────── // ── Unity lifecycle ───────────────────────────────────────────
private void Awake() private void Awake()
@@ -155,9 +156,9 @@ namespace BriarQueen.UI.Menus
if (_backButton != null) _backButton.onClick.AddListener(OnBackClicked); if (_backButton != null) _backButton.onClick.AddListener(OnBackClicked);
// Individual buttons drive panel switching via SelectionRequested // Individual buttons drive panel switching via SelectionRequested
if (_gameCategoryButton != null) _gameCategoryButton.SelectionRequested += _ => SwitchCategory(Category.Game); if (_gameCategoryButton != null) _gameCategoryButton.SelectionRequested += OnGameCategorySelected;
if (_visualCategoryButton != null) _visualCategoryButton.SelectionRequested += _ => SwitchCategory(Category.Visual); if (_visualCategoryButton != null) _visualCategoryButton.SelectionRequested += OnVisualCategorySelected;
if (_audioCategoryButton != null) _audioCategoryButton.SelectionRequested += _ => SwitchCategory(Category.Audio); if (_audioCategoryButton != null) _audioCategoryButton.SelectionRequested += OnAudioCategorySelected;
HookSlider(_masterVolumeSlider, _masterVolumeText, v => _draftAudio.MasterVolume = v); HookSlider(_masterVolumeSlider, _masterVolumeText, v => _draftAudio.MasterVolume = v);
HookSlider(_musicVolumeSlider, _musicVolumeText, v => _draftAudio.MusicVolume = v); HookSlider(_musicVolumeSlider, _musicVolumeText, v => _draftAudio.MusicVolume = v);
@@ -210,9 +211,9 @@ namespace BriarQueen.UI.Menus
if (_applyButton != null) _applyButton.onClick.RemoveListener(OnApplyClicked); if (_applyButton != null) _applyButton.onClick.RemoveListener(OnApplyClicked);
if (_backButton != null) _backButton.onClick.RemoveListener(OnBackClicked); if (_backButton != null) _backButton.onClick.RemoveListener(OnBackClicked);
if (_gameCategoryButton != null) _gameCategoryButton.SelectionRequested -= _ => SwitchCategory(Category.Game); if (_gameCategoryButton != null) _gameCategoryButton.SelectionRequested -= OnGameCategorySelected;
if (_visualCategoryButton != null) _visualCategoryButton.SelectionRequested -= _ => SwitchCategory(Category.Visual); if (_visualCategoryButton != null) _visualCategoryButton.SelectionRequested -= OnVisualCategorySelected;
if (_audioCategoryButton != null) _audioCategoryButton.SelectionRequested -= _ => SwitchCategory(Category.Audio); if (_audioCategoryButton != null) _audioCategoryButton.SelectionRequested -= OnAudioCategorySelected;
if (_popupDisplayDurationSlider != null) if (_popupDisplayDurationSlider != null)
_popupDisplayDurationSlider.onValueChanged.RemoveListener(OnPopupDisplayDurationChanged); _popupDisplayDurationSlider.onValueChanged.RemoveListener(OnPopupDisplayDurationChanged);
@@ -246,7 +247,7 @@ namespace BriarQueen.UI.Menus
StopAndResetCancellation(); StopAndResetCancellation();
gameObject.SetActive(true); gameObject.SetActive(true);
TryRegisterRaycaster(); EnsureExclusiveRaycaster();
_canvasGroup.alpha = 1f; _canvasGroup.alpha = 1f;
_canvasGroup.blocksRaycasts = false; _canvasGroup.blocksRaycasts = false;
@@ -368,6 +369,21 @@ namespace BriarQueen.UI.Menus
return true; return true;
} }
private void OnGameCategorySelected(AnimatedSelectionButton _)
{
SwitchCategory(Category.Game);
}
private void OnVisualCategorySelected(AnimatedSelectionButton _)
{
SwitchCategory(Category.Visual);
}
private void OnAudioCategorySelected(AnimatedSelectionButton _)
{
SwitchCategory(Category.Audio);
}
// ── Category switching ──────────────────────────────────────── // ── Category switching ────────────────────────────────────────
private void SwitchCategory(Category category) private void SwitchCategory(Category category)
@@ -909,19 +925,20 @@ namespace BriarQueen.UI.Menus
}; };
} }
private void TryRegisterRaycaster() private void EnsureExclusiveRaycaster()
{ {
if (_raycasterRegistered)
return;
if (_interactManager == null || _graphicRaycaster == null) if (_interactManager == null || _graphicRaycaster == null)
return; return;
if (!_raycasterRegistered)
{
_interactManager.AddUIRaycaster(_graphicRaycaster); _interactManager.AddUIRaycaster(_graphicRaycaster);
_interactManager.SetExclusiveRaycaster(_graphicRaycaster);
_raycasterRegistered = true; _raycasterRegistered = true;
} }
_interactManager.SetExclusiveRaycaster(_graphicRaycaster);
}
private void TryUnregisterRaycaster() private void TryUnregisterRaycaster()
{ {
if (!_raycasterRegistered) if (!_raycasterRegistered)
@@ -931,7 +948,7 @@ namespace BriarQueen.UI.Menus
return; return;
_interactManager.RemoveUIRaycaster(_graphicRaycaster); _interactManager.RemoveUIRaycaster(_graphicRaycaster);
_interactManager.ClearExclusiveRaycaster(); _interactManager.ReleaseExclusiveRaycaster(_graphicRaycaster);
_raycasterRegistered = false; _raycasterRegistered = false;
} }
} }

View File

@@ -41,6 +41,9 @@ namespace BriarQueen.UI.Scopes
[SerializeField] [SerializeField]
private InventoryBar _inventoryBar; private InventoryBar _inventoryBar;
[SerializeField]
private SubtitleUI _subtitleUI;
protected override void Configure(IContainerBuilder builder) protected override void Configure(IContainerBuilder builder)
{ {
@@ -71,6 +74,9 @@ namespace BriarQueen.UI.Scopes
if (_inventoryBar != null) if (_inventoryBar != null)
builder.RegisterComponent(_inventoryBar); builder.RegisterComponent(_inventoryBar);
if (_subtitleUI != null)
builder.RegisterComponent(_subtitleUI);
builder.RegisterBuildCallback(container => builder.RegisterBuildCallback(container =>
{ {