Compare commits

..

2 Commits

Author SHA1 Message Date
3174079e37 Add subtitle UI for voice playback 2026-05-16 21:33:00 +01:00
58050abded Refine UI stack and add Ashwick keypad puzzle 2026-05-15 13:02:12 +01:00
121 changed files with 25095 additions and 2951 deletions

Submodule .claude/worktrees/heuristic-wright-1487d8 added at c203f836b1

View File

@@ -26,8 +26,9 @@ MonoBehaviour:
m_ReadOnly: 0
m_SerializedLabels: []
FlaggedDuringContentUpdateRestriction: 0
- m_GUID: 9ad5adbf83cf74c26873156b9a975cb4
m_Address: Assets/Data/Prefabs/Levels/Chapter One/Ashwick Hallow/C1_RAshwick_Ridgeway.prefab
- 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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 MiB

After

Width:  |  Height:  |  Size: 3.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 125 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 937 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 MiB

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 104572cca65364c53be1097bb5c3dbd4
guid: b575910de5ea144bfb271fa080e99df7
TextureImporter:
internalIDToNameTable: []
externalObjects: {}

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
guid: 66b1cc83801c94a85b950fb768f1a159
guid: 151d27a90fc8a4728946e567567abd59
TextureImporter:
internalIDToNameTable: []
externalObjects: {}

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

View File

@@ -0,0 +1,143 @@
fileFormatVersion: 2
guid: def8f241f45d747adb3d96fc65f45261
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: 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: 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

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
guid: 292366c0388bc477a9ff71168b304591
guid: 7099fc26212a447cc96d56d867feecaf
NativeFormatImporter:
externalObjects: {}
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_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: b492dfc759934d71b4f9cc4f8b41a155, type: 3}
m_Name: Ashwick Ridgeway
m_Name: Ashwick Outskirts
m_EditorClassIdentifier: BriarQueen.Data::BriarQueen.Data.Assets.AssetEntry
_entryType: 3
_uiKey: 0
@@ -18,7 +18,7 @@ MonoBehaviour:
_levelKey: 2
_itemKey: 0
_asset:
m_AssetGUID: 9ad5adbf83cf74c26873156b9a975cb4
m_AssetGUID: 7874cf8dee22745db87b13634078aca7
m_SubObjectName:
m_SubObjectType:
m_SubObjectGUID:

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: c914b10163a2c48e9a930c62a8395f3e
guid: 8e302473b3bb241c88c7a9315ecc3d33
NativeFormatImporter:
externalObjects: {}
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
_clueEntryID: 1
_photoEntryID: 0
_title: Strange Note
_title: Jason's Note
_displayImage: {fileID: 0}
_bodyText: 'I managed to figure it out, it''s the lights. Use them.
R = B,
L = ?'
_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. '
_photoDescription:
_polaroidWriting:
_startsUnlocked: 0

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 9ad5adbf83cf74c26873156b9a975cb4
guid: 7874cf8dee22745db87b13634078aca7
PrefabImporter:
externalObjects: {}
userData:

View File

@@ -17,12 +17,15 @@ MonoBehaviour:
- {fileID: 11400000, guid: c4a069c3f029048148fd0a09f7ccca19, type: 2}
- {fileID: 11400000, guid: 0168c632b4acb41ed96b9679f773d696, 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:
- {fileID: 11400000, guid: 8ba70613c7d254514a3a28f8974d699c, 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: c914b10163a2c48e9a930c62a8395f3e, type: 2}
_itemReferences: []
_uiReferences:
- {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,17 +101,17 @@ Material:
- _EnvironmentReflections: 1
- _Falloff: 0.242
- _FlickerOffset: 0
- _FlickerSpeed: 1.7
- _FlickerStrength: 0.247
- _FlickerSpeed: 0
- _FlickerStrength: 1
- _GlossMapScale: 0
- _Glossiness: 0
- _GlossyReflections: 0
- _Intensity: 1
- _Intensity: 0
- _Metallic: 0
- _OcclusionStrength: 1
- _Parallax: 0.005
- _QueueOffset: 0
- _Radius: 0
- _Radius: 0.144
- _ReceiveShadows: 1
- _Smoothness: 0.5
- _SmoothnessTextureChannel: 0
@@ -134,7 +134,7 @@ Material:
- _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.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}
m_BuildTextureStacks: []
m_AllowLocking: 1

View File

@@ -686,7 +686,7 @@ RectTransform:
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: -653, y: 37}
m_AnchoredPosition: {x: -597, y: 51}
m_SizeDelta: {x: 900, y: 700}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!1 &90101084
@@ -925,7 +925,7 @@ RectTransform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {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_Pivot: {x: 0.5, y: 1}
--- !u!114 &145691706
@@ -2533,17 +2533,17 @@ RectTransform:
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
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_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 561703827}
m_Father: {fileID: 551626280}
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_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
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}
--- !u!114 &332249785
MonoBehaviour:
@@ -2575,8 +2575,8 @@ MonoBehaviour:
m_fontMaterials: []
m_fontColor32:
serializedVersion: 2
rgba: 4279638559
m_fontColor: {r: 0.12156863, g: 0.101960786, b: 0.08627451, a: 1}
rgba: 4292601329
m_fontColor: {r: 0.9433962, g: 0.8964242, b: 0.85884655, a: 1}
m_enableVertexGradient: 0
m_colorMode: 3
m_fontColorGradient:
@@ -2632,7 +2632,7 @@ MonoBehaviour:
m_VertexBufferAutoSizeReduction: 0
m_useMaxVisibleDescender: 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_isVolumetricText: 0
m_hasFontAssetChanged: 0
@@ -4267,7 +4267,7 @@ RectTransform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {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_Pivot: {x: 0, y: 1}
--- !u!114 &527861874
@@ -4324,8 +4324,8 @@ MonoBehaviour:
m_fontSizeMin: 18
m_fontSizeMax: 72
m_fontStyle: 32
m_HorizontalAlignment: 1
m_VerticalAlignment: 256
m_HorizontalAlignment: 2
m_VerticalAlignment: 512
m_textAlignment: 65535
m_characterSpacing: 7
m_characterHorizontalScale: 1
@@ -4686,6 +4686,82 @@ MonoBehaviour:
m_ChildScaleWidth: 0
m_ChildScaleHeight: 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
GameObject:
m_ObjectHideFlags: 0
@@ -4719,7 +4795,7 @@ RectTransform:
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 332249784}
- {fileID: 551626280}
m_Father: {fileID: 1455566988}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 1}
@@ -4752,15 +4828,15 @@ MonoBehaviour:
m_Name:
m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.Image
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_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_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0}
m_Type: 1
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
@@ -8133,7 +8209,7 @@ RectTransform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {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_Pivot: {x: 1, y: 1}
--- !u!114 &1157564251
@@ -8156,7 +8232,7 @@ MonoBehaviour:
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_text: Old Ridge Road
m_text: At the Car
m_isRightToLeft: 0
m_fontAsset: {fileID: 11400000, guid: 97bb3839c413f42c5932360cf6b0a3fc, type: 2}
m_sharedMaterial: {fileID: -2223467014058564004, guid: 97bb3839c413f42c5932360cf6b0a3fc, type: 2}
@@ -8183,15 +8259,15 @@ MonoBehaviour:
m_faceColor:
serializedVersion: 2
rgba: 4294967295
m_fontSize: 64
m_fontSizeBase: 64
m_fontSize: 42
m_fontSizeBase: 42
m_fontWeight: 400
m_enableAutoSizing: 0
m_fontSizeMin: 18
m_fontSizeMax: 72
m_fontStyle: 32
m_HorizontalAlignment: 1
m_VerticalAlignment: 256
m_HorizontalAlignment: 4
m_VerticalAlignment: 1024
m_textAlignment: 65535
m_characterSpacing: 7
m_characterHorizontalScale: 1
@@ -11383,7 +11459,7 @@ RectTransform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {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_Pivot: {x: 0.5, y: 1}
--- !u!114 &1488106359
@@ -14644,7 +14720,7 @@ RectTransform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {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_Pivot: {x: 0.5, y: 1}
--- !u!114 &1816432720
@@ -15188,7 +15264,7 @@ RectTransform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {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_Pivot: {x: 0.5, y: 1}
--- !u!114 &1861235553

View File

@@ -816,7 +816,6 @@ RectTransform:
m_Children:
- {fileID: 416449373}
- {fileID: 1425763776}
- {fileID: 1518385058}
m_Father: {fileID: 1216136270}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
@@ -1187,20 +1186,20 @@ RectTransform:
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 534739474}
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_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 1292853201}
- {fileID: 1677150152}
m_Father: {fileID: 1425763776}
m_Father: {fileID: 1287558152}
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: 100, y: 100}
m_Pivot: {x: 0.5, y: 0.5}
m_Pivot: {x: 0, y: 0.5}
--- !u!114 &534739476
MonoBehaviour:
m_ObjectHideFlags: 0
@@ -2698,7 +2697,7 @@ MonoBehaviour:
_pressStartText: {fileID: 676780942}
_introGroupDissolveGroup: {fileID: 1251031440}
_mainMenuGroup: {fileID: 365451919}
_buttonsGroup: {fileID: 1425763779}
_displayGroup: {fileID: 1425763779}
_mainMenuSelectionGroup: {fileID: 1425763778}
_startGameSelectionButton: {fileID: 2092529973}
_settingsSelectionButton: {fileID: 534739476}
@@ -2742,6 +2741,22 @@ MonoBehaviour:
useUnscaledTime: 1
_useFixedUpdate: 0
_updateType: 0
_settingsOverlayTweenSettings:
duration: 0.25
ease: 6
customEase:
serializedVersion: 2
m_Curve: []
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
cycles: 0
cycleMode: 0
startDelay: 0
endDelay: 0
useUnscaledTime: 1
_useFixedUpdate: 0
_updateType: 0
_pressStartPulseTweenSettings:
duration: 0.85
ease: 4
@@ -2986,6 +3001,71 @@ CanvasRenderer:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1275027011}
m_CullTransparentMesh: 1
--- !u!1 &1287558151
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1287558152}
- component: {fileID: 1287558153}
m_Layer: 5
m_Name: Buttons
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &1287558152
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1287558151}
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: 2092529972}
- {fileID: 534739475}
- {fileID: 1477093090}
m_Father: {fileID: 1425763776}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 112, y: 335}
m_SizeDelta: {x: 100, y: 100}
m_Pivot: {x: 0, y: 0}
--- !u!114 &1287558153
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1287558151}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 59f8146938fff824cb5fd77236b75775, type: 3}
m_Name:
m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.VerticalLayoutGroup
m_Padding:
m_Left: 0
m_Right: 0
m_Top: 0
m_Bottom: 0
m_ChildAlignment: 0
m_Spacing: 100
m_ChildForceExpandWidth: 1
m_ChildForceExpandHeight: 1
m_ChildControlWidth: 0
m_ChildControlHeight: 0
m_ChildScaleWidth: 0
m_ChildScaleHeight: 0
m_ReverseArrangement: 0
--- !u!1 &1292853200
GameObject:
m_ObjectHideFlags: 0
@@ -3269,11 +3349,10 @@ GameObject:
serializedVersion: 6
m_Component:
- component: {fileID: 1425763776}
- component: {fileID: 1425763777}
- component: {fileID: 1425763778}
- component: {fileID: 1425763779}
m_Layer: 5
m_Name: Buttons
m_Name: Display
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
@@ -3291,42 +3370,15 @@ RectTransform:
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 2092529972}
- {fileID: 534739475}
- {fileID: 1477093090}
- {fileID: 1518385058}
- {fileID: 1287558152}
m_Father: {fileID: 365451918}
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: -711, y: -246}
m_SizeDelta: {x: 100, y: 100}
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 &1425763777
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1425763775}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 59f8146938fff824cb5fd77236b75775, type: 3}
m_Name:
m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.VerticalLayoutGroup
m_Padding:
m_Left: 0
m_Right: 0
m_Top: 0
m_Bottom: 0
m_ChildAlignment: 0
m_Spacing: 100
m_ChildForceExpandWidth: 1
m_ChildForceExpandHeight: 1
m_ChildControlWidth: 0
m_ChildControlHeight: 0
m_ChildScaleWidth: 0
m_ChildScaleHeight: 0
m_ReverseArrangement: 0
--- !u!114 &1425763778
MonoBehaviour:
m_ObjectHideFlags: 0
@@ -3383,20 +3435,20 @@ RectTransform:
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1477093089}
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_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 1882478302}
- {fileID: 377952812}
m_Father: {fileID: 1425763776}
m_Father: {fileID: 1287558152}
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: 100, y: 100}
m_Pivot: {x: 0.5, y: 0.5}
m_Pivot: {x: 0, y: 0.5}
--- !u!114 &1477093091
MonoBehaviour:
m_ObjectHideFlags: 0
@@ -3620,11 +3672,11 @@ RectTransform:
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 1719828717}
m_Father: {fileID: 365451918}
m_Father: {fileID: 1425763776}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 1}
m_AnchorMax: {x: 0, y: 1}
m_AnchoredPosition: {x: 124, y: -68}
m_AnchoredPosition: {x: 64, y: -115}
m_SizeDelta: {x: 893.3687, y: 115.333496}
m_Pivot: {x: 0, y: 1}
--- !u!225 &1518385059
@@ -4804,20 +4856,20 @@ RectTransform:
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2092529971}
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_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 1275027012}
- {fileID: 317717159}
m_Father: {fileID: 1425763776}
m_Father: {fileID: 1287558152}
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: 100, y: 100}
m_Pivot: {x: 0.5, y: 0.5}
m_Pivot: {x: 0, y: 0.5}
--- !u!114 &2092529973
MonoBehaviour:
m_ObjectHideFlags: 0

View File

@@ -506,107 +506,6 @@ Transform:
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1001 &484196172824267200
PrefabInstance:
m_ObjectHideFlags: 0
serializedVersion: 2
m_Modification:
serializedVersion: 3
m_TransformParent: {fileID: 0}
m_Modifications:
- target: {fileID: 3834506191261054081, guid: 22000bda479564d5b95d3cdc42a29f33, type: 3}
propertyPath: m_Name
value: C1 - Ashwick Hallow - Marketplace
objectReference: {fileID: 0}
- target: {fileID: 3834506191261054081, guid: 22000bda479564d5b95d3cdc42a29f33, type: 3}
propertyPath: m_IsActive
value: 1
objectReference: {fileID: 0}
- target: {fileID: 6698916268511761357, guid: 22000bda479564d5b95d3cdc42a29f33, type: 3}
propertyPath: m_Pivot.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 6698916268511761357, guid: 22000bda479564d5b95d3cdc42a29f33, type: 3}
propertyPath: m_Pivot.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 6698916268511761357, guid: 22000bda479564d5b95d3cdc42a29f33, type: 3}
propertyPath: m_AnchorMax.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 6698916268511761357, guid: 22000bda479564d5b95d3cdc42a29f33, type: 3}
propertyPath: m_AnchorMax.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 6698916268511761357, guid: 22000bda479564d5b95d3cdc42a29f33, type: 3}
propertyPath: m_AnchorMin.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 6698916268511761357, guid: 22000bda479564d5b95d3cdc42a29f33, type: 3}
propertyPath: m_AnchorMin.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 6698916268511761357, guid: 22000bda479564d5b95d3cdc42a29f33, type: 3}
propertyPath: m_SizeDelta.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 6698916268511761357, guid: 22000bda479564d5b95d3cdc42a29f33, type: 3}
propertyPath: m_SizeDelta.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 6698916268511761357, guid: 22000bda479564d5b95d3cdc42a29f33, type: 3}
propertyPath: m_LocalPosition.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 6698916268511761357, guid: 22000bda479564d5b95d3cdc42a29f33, type: 3}
propertyPath: m_LocalPosition.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 6698916268511761357, guid: 22000bda479564d5b95d3cdc42a29f33, type: 3}
propertyPath: m_LocalPosition.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: 6698916268511761357, guid: 22000bda479564d5b95d3cdc42a29f33, type: 3}
propertyPath: m_LocalRotation.w
value: 1
objectReference: {fileID: 0}
- target: {fileID: 6698916268511761357, guid: 22000bda479564d5b95d3cdc42a29f33, type: 3}
propertyPath: m_LocalRotation.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 6698916268511761357, guid: 22000bda479564d5b95d3cdc42a29f33, type: 3}
propertyPath: m_LocalRotation.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 6698916268511761357, guid: 22000bda479564d5b95d3cdc42a29f33, type: 3}
propertyPath: m_LocalRotation.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: 6698916268511761357, guid: 22000bda479564d5b95d3cdc42a29f33, type: 3}
propertyPath: m_AnchoredPosition.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 6698916268511761357, guid: 22000bda479564d5b95d3cdc42a29f33, type: 3}
propertyPath: m_AnchoredPosition.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 6698916268511761357, guid: 22000bda479564d5b95d3cdc42a29f33, type: 3}
propertyPath: m_LocalEulerAnglesHint.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 6698916268511761357, guid: 22000bda479564d5b95d3cdc42a29f33, type: 3}
propertyPath: m_LocalEulerAnglesHint.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 6698916268511761357, guid: 22000bda479564d5b95d3cdc42a29f33, type: 3}
propertyPath: m_LocalEulerAnglesHint.z
value: 0
objectReference: {fileID: 0}
m_RemovedComponents: []
m_RemovedGameObjects: []
m_AddedGameObjects: []
m_AddedComponents: []
m_SourcePrefab: {fileID: 100100000, guid: 22000bda479564d5b95d3cdc42a29f33, type: 3}
--- !u!1660057539 &9223372036854775807
SceneRoots:
m_ObjectHideFlags: 0
@@ -614,5 +513,4 @@ SceneRoots:
- {fileID: 203844589}
- {fileID: 1684932631}
- {fileID: 290940349}
- {fileID: 484196172824267200}
- {fileID: 1399123067}

View File

@@ -25,7 +25,7 @@ mainly on vines and thorns.
9. **Tokens** - Cancellation Tokens should be re-used where possible.
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.
12. **Events** - We use C# events, actions, and delegates rather than UnityEvents, except when dealing with raw/stock ui components.
## Documentation

View File

@@ -98,7 +98,7 @@ namespace BriarQueen.Data.IO.Saves
public enum LevelFlag
{
None = 0,
MarketGateOpen,
AshwickGateOpen,
MarketplaceFirstEntry,
}

View File

@@ -25,13 +25,8 @@ namespace BriarQueen.Data.Identifiers
{
None = 0,
ChapterOneArrivalRoad,
ChapterOneAshwickRidgeway,
ChapterOneAshwickOutskirts,
ChapterOneInsideBrokenDownCar,
ChapterOneAshwickMarketplace,
ChapterOneAshwickMournfall,
ChapterOneAshwickRavensQuill,
ChapterOneGloomedVeil,
ChapterOneAshwickWaxworks
}
public enum AssetItemKey

View File

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

View File

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

View File

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

View File

@@ -11,24 +11,45 @@ namespace BriarQueen.Data.Identifiers
// 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 readonly IReadOnlyDictionary<SubtitleKey, string> Subtitles =
new ReadOnlyDictionary<SubtitleKey, string>(
new Dictionary<SubtitleKey, string>
public static readonly IReadOnlyDictionary<SubtitleKey, SubtitleEntry> Subtitles =
new ReadOnlyDictionary<SubtitleKey, SubtitleEntry>(
new Dictionary<SubtitleKey, SubtitleEntry>
{
// { SubtitleKey.IntroLine, "Subtitle:IntroLine" },
// { SubtitleKey.TutorialTip, "Subtitle:TutorialTip" }
// { SubtitleKey.IntroLine, new SubtitleEntry("Example subtitle.", 2.5f) },
});
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,
UsingItemsTogether,
HideHUD,
ExitItems,
MultipleUseItems,
DarkRooms,
Codex,
HiddenItems,
ResetPuzzles,
LeavingPuzzles,
Tools,
ItemsAway,
ItemCycling,
@@ -25,7 +25,7 @@ namespace BriarQueen.Data.Identifiers
{
{
TutorialPopupID.ReturnToPreviousLevel,
"Click the bottom corners to return to the previous area."
"Click the lower corners to return to the previous area."
},
{
TutorialPopupID.UsingItemsTogether,
@@ -35,13 +35,9 @@ namespace BriarQueen.Data.Identifiers
TutorialPopupID.HideHUD,
"Press '{Hide_HUD}' to hide the HUD."
},
{
TutorialPopupID.ExitItems,
"Press '{Right_Click}' to exit the current interaction."
},
{
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,
@@ -49,7 +45,7 @@ namespace BriarQueen.Data.Identifiers
},
{
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,
@@ -57,24 +53,29 @@ namespace BriarQueen.Data.Identifiers
},
{
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,
"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,
"Press '{Right_Click}' to put away the current item."
"Press '{Right_Click}' to put away the selected item."
},
{
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,
"Press '{Previous_Tool}' or '{Next_Tool}' to cycle through your tools."
}
},
};
public static IEnumerable<string> GetAllTexts() => AllPopups.Values;

View File

@@ -32,6 +32,9 @@ namespace BriarQueen.Framework.Effects
[SerializeField]
private bool _randomizeFlickerOffset = true;
[SerializeField]
private bool _useStartingValues;
[Header("Tween")]
[SerializeField]
@@ -81,8 +84,12 @@ namespace BriarQueen.Framework.Effects
}
CreateRuntimeMaterial();
if(_useStartingValues)
{
SetLightColor(_startingColor);
SetIntensity(_startingIntensity);
}
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

@@ -0,0 +1,7 @@
using BriarQueen.Framework.Events.System;
using BriarQueen.Framework.Managers.UI.Base;
namespace BriarQueen.Framework.Events.UI
{
public record UIWindowStateChangedEvent(WindowType WindowType, bool IsOpen) : IEvent;
}

View File

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

View File

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

View File

@@ -5,6 +5,7 @@ using BriarQueen.Framework.Events.Gameplay;
using BriarQueen.Framework.Events.Input;
using BriarQueen.Framework.Events.UI;
using BriarQueen.Framework.Managers.UI;
using BriarQueen.Framework.Managers.UI.Base;
using BriarQueen.Framework.Services.Game;
using UnityEngine;
using UnityEngine.InputSystem;
@@ -109,7 +110,7 @@ namespace BriarQueen.Framework.Managers.Input
if (_eventCoordinator != null)
{
_eventCoordinator.Unsubscribe<UIToggleHudEvent>(OnHudStateChanged);
_eventCoordinator.Unsubscribe<ToggleCodexEvent>(OnCodexStateChanged);
_eventCoordinator.Unsubscribe<UIWindowStateChangedEvent>(OnWindowStateChanged);
_eventCoordinator.Unsubscribe<ToggleToolScreenEvent>(OnToolScreenStateChanged);
_eventCoordinator.Unsubscribe<UIStackChangedEvent>(OnUIStackChanged);
}
@@ -158,7 +159,7 @@ namespace BriarQueen.Framework.Managers.Input
ApplyCursorModeForCurrentScheme();
_eventCoordinator.Subscribe<UIToggleHudEvent>(OnHudStateChanged);
_eventCoordinator.Subscribe<ToggleCodexEvent>(OnCodexStateChanged);
_eventCoordinator.Subscribe<UIWindowStateChangedEvent>(OnWindowStateChanged);
_eventCoordinator.Subscribe<ToggleToolScreenEvent>(OnToolScreenStateChanged);
_eventCoordinator.Subscribe<UIStackChangedEvent>(OnUIStackChanged);
@@ -422,9 +423,10 @@ namespace BriarQueen.Framework.Managers.Input
_hudHidden = !evt.Show;
}
private void OnCodexStateChanged(ToggleCodexEvent evt)
private void OnWindowStateChanged(UIWindowStateChangedEvent evt)
{
_codexShown = evt.Shown;
if (evt.WindowType == WindowType.CodexWindow)
_codexShown = evt.IsOpen;
}
private void OnToolScreenStateChanged(ToggleToolScreenEvent evt)
@@ -447,13 +449,12 @@ namespace BriarQueen.Framework.Managers.Input
private void OnPause(InputAction.CallbackContext ctx)
{
var isMainMenu = _gameService != null && _gameService.IsMainMenuSceneLoaded;
if (isMainMenu || _isAnyUIOpen)
if (isMainMenu)
{
_eventCoordinator?.PublishImmediate(new UIBackRequestedEvent());
return;
}
_isPaused = true;
_eventCoordinator?.Publish(new PauseButtonClickedEvent());
}
@@ -461,8 +462,8 @@ namespace BriarQueen.Framework.Managers.Input
{
if(_gameService.IsMainMenuSceneLoaded)
return;
_codexShown = !_codexShown;
_eventCoordinator?.Publish(new ToggleCodexEvent(_codexShown));
_eventCoordinator?.Publish(new ToggleCodexEvent(!_codexShown));
}
private void OnClick(InputAction.CallbackContext ctx)

View File

@@ -163,6 +163,22 @@ namespace BriarQueen.Framework.Managers.Interaction
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>
/// Clear exclusive mode and return to using all registered raycasters.
/// </summary>

View File

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

View File

@@ -0,0 +1,11 @@
using Cysharp.Threading.Tasks;
namespace BriarQueen.Framework.Managers.UI.Base
{
public interface IUIOverlayHost
{
bool CanSuspendFor(WindowType incomingWindowType);
UniTask SuspendForOverlay();
UniTask ResumeFromOverlay();
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 4424bf26f2b764c1ca63bc73d75470d6

View File

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

View File

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

View File

@@ -0,0 +1,9 @@
namespace BriarQueen.Framework.Managers.UI.Events
{
public enum SettingsOpenSource
{
Unknown,
PauseMenu,
MainMenu
}
}

View File

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

View File

@@ -2,5 +2,5 @@ using BriarQueen.Framework.Events.System;
namespace BriarQueen.Framework.Managers.UI.Events
{
public record UIToggleSettingsWindow(bool Show) : IEvent;
public record UIToggleSettingsWindow(bool Show, SettingsOpenSource Source = SettingsOpenSource.Unknown) : IEvent;
}

View File

@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Threading;
using BriarQueen.Data.Identifiers;
using BriarQueen.Framework.Coordinators.Events;
using BriarQueen.Framework.Events.UI;
@@ -34,15 +35,20 @@ namespace BriarQueen.Framework.Managers.UI
private readonly Dictionary<WindowType, IUIWindow> _windows = new();
private readonly Stack<IUIWindow> _windowStack = new();
private readonly SemaphoreSlim _windowTransitionGate = new(1, 1);
private bool _disposed;
public bool Initialized { get; private set; }
private sealed record OverlayResumeContext(WindowType OverlayWindowType, IUIOverlayHost Host);
private IHud _hudContainer;
private IPopup _infoPopup;
private IPopup _tutorialPopup;
private IScreenFader _screenFader;
private IUIOverlayHost _mainMenuOverlayHost;
private readonly Stack<OverlayResumeContext> _overlayResumeStack = new();
[Inject]
public UIManager(
@@ -123,6 +129,18 @@ namespace BriarQueen.Framework.Managers.UI
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)
{
_hudContainer = hudContainer;
@@ -155,11 +173,76 @@ namespace BriarQueen.Framework.Managers.UI
_screenFader = screenFader;
}
public void RegisterMainMenuOverlayHost(IUIOverlayHost host)
{
_mainMenuOverlayHost = host;
}
public void UnregisterMainMenuOverlayHost(IUIOverlayHost host)
{
if (!ReferenceEquals(_mainMenuOverlayHost, host))
return;
RemoveOverlayResumeContextsForHost(host);
_mainMenuOverlayHost = null;
}
private IUIWindow GetWindow(WindowType windowType)
{
return _windows.TryGetValue(windowType, out var window) ? window : null;
}
public bool IsWindowOpen(WindowType windowType)
{
var target = GetWindow(windowType);
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)
{
if (_disposed || _hudContainer == null)
@@ -180,13 +263,25 @@ namespace BriarQueen.Framework.Managers.UI
private void OnPauseClickReceived(PauseButtonClickedEvent _)
{
if (_windowStack.Count > 0)
if (ActiveWindow == null)
{
OpenWindow(WindowType.PauseMenuWindow);
return;
}
if (ActiveWindow.WindowType == WindowType.PauseMenuWindow)
{
TryHandleBackRequest();
return;
}
if (ActiveWindow.PauseBehavior == UIPauseBehavior.OpenPauseOverlay)
{
OpenWindow(WindowType.PauseMenuWindow);
return;
}
TryHandleBackRequest();
}
private void OnBackRequested(UIBackRequestedEvent _)
@@ -197,7 +292,7 @@ namespace BriarQueen.Framework.Managers.UI
private void ToggleSettingsWindow(UIToggleSettingsWindow eventData)
{
if (eventData.Show)
OpenWindow(WindowType.SettingsWindow);
OpenSettingsWindow(eventData.Source).Forget();
else
CloseWindow(WindowType.SettingsWindow);
}
@@ -208,10 +303,16 @@ namespace BriarQueen.Framework.Managers.UI
return;
if (eventData.Shown)
{
if (!IsWindowOpen(WindowType.CodexWindow))
OpenWindow(WindowType.CodexWindow);
}
else
{
if (IsWindowOpen(WindowType.CodexWindow))
CloseWindow(WindowType.CodexWindow);
}
}
private void OnCodexChangedEvent(CodexChangedEvent eventData)
{
@@ -300,7 +401,60 @@ namespace BriarQueen.Framework.Managers.UI
OpenWindowInternal(windowType).Forget();
}
private async UniTask OpenSettingsWindow(SettingsOpenSource source)
{
await _windowTransitionGate.WaitAsync();
try
{
if (_disposed)
return;
var window = GetWindow(WindowType.SettingsWindow);
if (window == null)
{
Debug.LogError("[UIManager] Window of type SettingsWindow not registered.");
return;
}
if (_windowStack.Contains(window))
return;
var suspended = false;
if (source == SettingsOpenSource.MainMenu &&
_mainMenuOverlayHost != null &&
_mainMenuOverlayHost.CanSuspendFor(WindowType.SettingsWindow))
{
await _mainMenuOverlayHost.SuspendForOverlay();
_overlayResumeStack.Push(new OverlayResumeContext(WindowType.SettingsWindow, _mainMenuOverlayHost));
suspended = true;
}
else
{
suspended = await TrySuspendActiveWindowFor(WindowType.SettingsWindow);
}
if (!suspended && ActiveWindow != null)
{
await ActiveWindow.Hide();
}
_windowStack.Push(window);
await window.Show();
NotifyWindowStateChanged(window.WindowType, true);
NotifyUIStackChanged();
}
finally
{
_windowTransitionGate.Release();
}
}
private async UniTask OpenWindowInternal(WindowType windowType)
{
await _windowTransitionGate.WaitAsync();
try
{
if (_disposed)
return;
@@ -313,20 +467,25 @@ namespace BriarQueen.Framework.Managers.UI
return;
}
if (ActiveWindow == window)
if (_windowStack.Contains(window))
return;
if (ActiveWindow != null)
{
var suspended = await TrySuspendActiveWindowFor(windowType);
if (!suspended && ActiveWindow != null)
await ActiveWindow.Hide();
}
_windowStack.Push(window);
await window.Show();
NotifyWindowStateChanged(window.WindowType, true);
NotifyUIStackChanged();
}
finally
{
_windowTransitionGate.Release();
}
}
public void CloseWindow(WindowType windowType)
{
@@ -334,29 +493,39 @@ namespace BriarQueen.Framework.Managers.UI
}
private async UniTask CloseWindowInternal(WindowType windowType)
{
await _windowTransitionGate.WaitAsync();
try
{
if (_disposed || _windowStack.Count == 0)
return;
var target = GetWindow(windowType);
if (target == null)
if (target == null || !_windowStack.Contains(target))
return;
while (_windowStack.Count > 0)
{
var current = _windowStack.Pop();
if (current != null)
{
await current.Hide();
NotifyWindowStateChanged(current.WindowType, false);
}
if (current == target)
break;
}
if (ActiveWindow != null)
await ActiveWindow.Show();
await RestoreUnderlyingUi(target.WindowType);
NotifyUIStackChanged();
}
finally
{
_windowTransitionGate.Release();
}
}
public void CloseTopWindow()
{
@@ -379,6 +548,9 @@ namespace BriarQueen.Framework.Managers.UI
}
private async UniTask CloseTopWindowInternal()
{
await _windowTransitionGate.WaitAsync();
try
{
if (_disposed || _windowStack.Count == 0)
return;
@@ -386,13 +558,21 @@ namespace BriarQueen.Framework.Managers.UI
var top = _windowStack.Pop();
if (top != null)
{
await top.Hide();
NotifyWindowStateChanged(top.WindowType, false);
}
if (ActiveWindow != null)
await ActiveWindow.Show();
if (top != null)
await RestoreUnderlyingUi(top.WindowType);
NotifyUIStackChanged();
}
finally
{
_windowTransitionGate.Release();
}
}
public void ResetUIState()
{
@@ -400,21 +580,27 @@ namespace BriarQueen.Framework.Managers.UI
}
public async UniTask ResetUIStateAsync()
{
await _windowTransitionGate.WaitAsync();
try
{
while (_windowStack.Count > 0)
{
var window = _windowStack.Pop();
if (window != null)
{
if (window == null)
continue;
try
{
await window.Hide();
NotifyWindowStateChanged(window.WindowType, false);
}
catch
{
}
}
}
_overlayResumeStack.Clear();
if (_tutorialPopup != null)
{
@@ -440,6 +626,11 @@ namespace BriarQueen.Framework.Managers.UI
NotifyUIStackChanged();
}
finally
{
_windowTransitionGate.Release();
}
}
private void ResetUIStateHard()
{
@@ -462,11 +653,18 @@ namespace BriarQueen.Framework.Managers.UI
faderComponent.gameObject.SetActive(false);
_windowStack.Clear();
_overlayResumeStack.Clear();
_mainMenuOverlayHost = null;
}
private void NotifyUIStackChanged()
{
_eventCoordinator.Publish(new UIStackChangedEvent(_windowStack.Count > 0));
}
private void NotifyWindowStateChanged(WindowType windowType, bool isOpen)
{
_eventCoordinator.Publish(new UIWindowStateChangedEvent(windowType, isOpen));
}
}
}

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.interactable = true;
ShowTutorialIfNeeded();
UnlockCodexEntry();
}
private void ShowTutorialIfNeeded()
{
TutorialService.DisplayTutorial(TutorialPopupID.ExitItems);
}
private void UnlockCodexEntry()
{
PlayerManager.UnlockCodexEntry(CodexEntryIDs.Get(_documentEntryID));

View File

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

View File

@@ -14,7 +14,7 @@ using VContainer;
namespace BriarQueen.Game.Items.HoverZones
{
public class InteractZone : MonoBehaviour, IInteractable
public class TransitionZone : MonoBehaviour, IInteractable
{
[Header("Level Setup")]
[SerializeField]

View File

@@ -0,0 +1,49 @@
using BriarQueen.Data.IO.Saves;
using BriarQueen.Framework.Events.UI;
using BriarQueen.Framework.Managers.Levels.Data;
using BriarQueen.Game.Items.HoverZones;
using BriarQueen.Game.Puzzles.ChapterOne.AshwickHallow;
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.UI;
namespace BriarQueen.Game.Levels.ChapterOne.Ashwick
{
public class AshwickOutskirts : BaseLevel
{
[Header("Background")]
[SerializeField]
private Image _background;
[SerializeField]
private Sprite _backgroundOpenSprite;
[Header("Keypad Puzzle")]
[SerializeField]
private AshwickGate _ashwickGate;
[SerializeField]
private TransitionZone _nextLevelZone;
private Sprite _defaultSprite;
protected async override UniTask PostLoadInternal()
{
if (SaveManager.GetLevelFlag(LevelFlag.AshwickGateOpen))
{
_background.sprite = _backgroundOpenSprite;
_nextLevelZone.Unlock();
await DestructionService.Destroy(_ashwickGate.gameObject);
}
}
public async UniTask OpenGate()
{
_background.sprite = _backgroundOpenSprite;
_nextLevelZone.Unlock();
await DestructionService.Destroy(_ashwickGate.gameObject);
SaveManager.SetLevelFlag(LevelFlag.AshwickGateOpen, true);
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: b17e98637f5042b4b70962875c373f5f
timeCreated: 1778704389

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

View File

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

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: b7b31f5b3d0844359def22f68ccea856
timeCreated: 1778781649

View File

@@ -0,0 +1,501 @@
using System;
using System.Threading;
using BriarQueen.Data.Identifiers;
using BriarQueen.Data.IO.Saves;
using BriarQueen.Framework.Effects;
using BriarQueen.Framework.Events.Save;
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.Tutorials;
using BriarQueen.Game.Levels.ChapterOne.Ashwick;
using Cysharp.Threading.Tasks;
using MemoryPack;
using PrimeTween;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
using VContainer;
namespace BriarQueen.Game.Puzzles.ChapterOne.AshwickHallow
{
[MemoryPackable]
public partial class AshwickGateKeypadPuzzleState
{
public string Digits;
}
public class AshwickGateKeypadPuzzle : BasePuzzle, IPuzzleStateful, IUIWindow, IUIBackHandler, IUIOverlayHost
{
private const string CorrectCode = "312";
private const int RequiredDigits = 3;
[Header("Scene References")]
[SerializeField] private AshwickOutskirts _outskirts;
[SerializeField] private CanvasGroup _panelGroup;
[SerializeField] private TMP_InputField _displayField;
[SerializeField] private UILightGlow _statusGlow;
[SerializeField] private GraphicRaycaster _graphicRaycaster;
[SerializeField] private Button _closeButton;
[SerializeField] private Button[] _digitButtons = new Button[9];
[Header("Light Colors")]
[SerializeField] private Color _incorrectGlowColor = new(0.85f, 0.2f, 0.2f, 1f);
[SerializeField] private Color _correctGlowColor = new(0.2f, 0.85f, 0.35f, 1f);
[Header("Timing")]
[SerializeField] private float _feedbackDuration = 0.35f;
[SerializeField] private TweenSettings _panelFadeTweenSettings = new()
{
duration = 1.5f,
ease = Ease.OutQuad,
useUnscaledTime = true
};
private readonly UnityAction[] _digitCallbacks = new UnityAction[9];
private InteractManager _interactManager;
private CancellationTokenSource _panelCts;
private Sequence _panelSequence;
private string _currentDigits = string.Empty;
private bool _isCompleted;
private bool _isEvaluating;
private bool _isOpen;
private bool _raycasterRegistered;
private bool _skipSaveOnHide;
private TutorialService _tutorialService;
private UIManager _uiManager;
public override string PuzzleID => PuzzleIdentifiers.AllPuzzles[PuzzleKey.AshwickMarketGate];
public bool IsCompleted => _isCompleted || SaveManager.GetLevelFlag(LevelFlag.AshwickGateOpen);
public WindowType WindowType => WindowType.AshwickGateKeypadWindow;
public UIPauseBehavior PauseBehavior => UIPauseBehavior.OpenPauseOverlay;
[Inject]
public void ConstructKeypad(
InteractManager interactManager,
UIManager uiManager,
TutorialService tutorialService)
{
_interactManager = interactManager;
_uiManager = uiManager;
_tutorialService = tutorialService;
}
private void Awake()
{
if (_displayField != null)
{
_displayField.readOnly = true;
_displayField.text = string.Empty;
}
BindButtons();
SetPanelState(0f, false, false);
SyncDisplay();
}
private void Start()
{
_uiManager?.RegisterWindow(this);
}
private void OnDestroy()
{
_uiManager?.UnregisterWindow(this);
UnbindButtons();
TryUnregisterRaycaster();
CancelPanelTween();
}
public override UniTask PostLoad()
{
_isCompleted = SaveManager.GetLevelFlag(LevelFlag.AshwickGateOpen);
_isOpen = false;
_isEvaluating = false;
_skipSaveOnHide = false;
return UniTask.CompletedTask;
}
public override UniTask CompletePuzzle()
{
return CompletePuzzleInternal();
}
public void Open()
{
if (IsCompleted || _uiManager == null)
return;
_uiManager.OpenWindow(WindowType);
}
public void Close()
{
_uiManager?.CloseWindow(WindowType);
}
public UniTask<byte[]> CaptureState()
{
var state = new AshwickGateKeypadPuzzleState
{
Digits = IsCompleted ? string.Empty : _currentDigits
};
return UniTask.FromResult(MemoryPackSerializer.Serialize(state));
}
public UniTask RestoreState(byte[] state)
{
_isCompleted = SaveManager.GetLevelFlag(LevelFlag.AshwickGateOpen);
_currentDigits = string.Empty;
if (!_isCompleted && state is { Length: > 0 })
{
var restored = MemoryPackSerializer.Deserialize<AshwickGateKeypadPuzzleState>(state);
_currentDigits = restored?.Digits ?? string.Empty;
if (_currentDigits.Length > RequiredDigits)
_currentDigits = _currentDigits[..RequiredDigits];
}
SyncDisplay();
return UniTask.CompletedTask;
}
private async UniTask CompletePuzzleInternal()
{
if (IsCompleted || _outskirts == null)
return;
_isCompleted = true;
_currentDigits = string.Empty;
SyncDisplay();
SaveManager.SetPuzzleCompleted(PuzzleKey.AshwickMarketGate, true, requestSave: false);
_skipSaveOnHide = true;
_uiManager?.CloseWindow(WindowType);
AudioManager.Play(AudioNameIdentifiers.Get(SFXKey.AshwickGateOpening));
await _outskirts.OpenGate();
}
public async UniTask Show()
{
if (IsCompleted || _isEvaluating || _isOpen)
return;
_isOpen = true;
ResetPanelTween();
SetPanelState(0f, false, true);
SyncDisplay();
EnsureExclusiveRaycaster();
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, true, true);
_tutorialService?.DisplayTutorial(TutorialPopupID.LeavingPuzzles);
}
public async UniTask Hide()
{
if (!_isOpen)
return;
_isOpen = false;
ResetPanelTween();
if (_panelGroup != null)
{
_panelGroup.interactable = false;
_panelGroup.blocksRaycasts = true;
}
try
{
_panelSequence = Sequence.Create(useUnscaledTime: true)
.Group(Tween.Alpha(_panelGroup, new TweenSettings<float>
{
startValue = _panelGroup != null ? _panelGroup.alpha : 0f,
endValue = 0f,
settings = _panelFadeTweenSettings
}));
await _panelSequence.ToUniTask(cancellationToken: _panelCts.Token);
}
catch (OperationCanceledException)
{
return;
}
finally
{
_panelSequence = default;
}
SetPanelState(0f, false, false);
TryUnregisterRaycaster();
if (!_skipSaveOnHide && !_isCompleted)
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)
{
if (_isEvaluating || IsCompleted || !_isOpen || _currentDigits.Length >= RequiredDigits)
return;
_currentDigits += digit.ToString();
SyncDisplay();
if (_currentDigits.Length == RequiredDigits)
EvaluateCode().Forget();
}
private async UniTaskVoid EvaluateCode()
{
_isEvaluating = true;
if (_panelGroup != null)
_panelGroup.interactable = false;
if (_currentDigits == CorrectCode)
{
if (_statusGlow != null)
{
_statusGlow.SetLightColor(_correctGlowColor);
await _statusGlow.TurnOn();
}
await CompletePuzzleInternal();
}
else
{
if (_statusGlow != null)
{
_statusGlow.SetLightColor(_incorrectGlowColor);
await _statusGlow.TurnOn();
}
_currentDigits = string.Empty;
SyncDisplay();
if (_statusGlow != null)
await _statusGlow.TurnOff();
if (_isOpen && _panelGroup != null)
_panelGroup.interactable = true;
}
_isEvaluating = false;
}
private void BindButtons()
{
for (var i = 0; i < _digitButtons.Length; i++)
{
var button = _digitButtons[i];
if (button == null)
continue;
var digit = i + 1;
_digitCallbacks[i] = () => OnDigitPressed(digit);
button.onClick.AddListener(_digitCallbacks[i]);
}
if (_closeButton != null)
_closeButton.onClick.AddListener(Close);
}
private void UnbindButtons()
{
for (var i = 0; i < _digitButtons.Length; i++)
{
var button = _digitButtons[i];
if (button == null || _digitCallbacks[i] == null)
continue;
button.onClick.RemoveListener(_digitCallbacks[i]);
_digitCallbacks[i] = null;
}
if (_closeButton != null)
_closeButton.onClick.RemoveListener(Close);
}
private void SyncDisplay()
{
if (_displayField == null)
return;
_displayField.text = _currentDigits;
}
private void SetPanelState(float alpha, bool interactable, bool blocksRaycasts)
{
if (_panelGroup == null)
return;
_panelGroup.alpha = alpha;
_panelGroup.interactable = interactable;
_panelGroup.blocksRaycasts = blocksRaycasts;
}
private void ResetPanelTween()
{
CancelPanelTween();
_panelCts = new CancellationTokenSource();
}
private void CancelPanelTween()
{
if (_panelSequence.isAlive)
_panelSequence.Stop();
if (_panelCts != null)
{
try
{
_panelCts.Cancel();
}
catch
{
}
_panelCts.Dispose();
_panelCts = null;
}
}
private void EnsureExclusiveRaycaster()
{
if (_interactManager == null || _graphicRaycaster == null)
return;
if (!_raycasterRegistered)
{
_interactManager.AddUIRaycaster(_graphicRaycaster);
_raycasterRegistered = true;
}
_interactManager.SetExclusiveRaycaster(_graphicRaycaster);
}
private void TryUnregisterRaycaster()
{
if (!_raycasterRegistered || _interactManager == null || _graphicRaycaster == null)
return;
_interactManager.RemoveUIRaycaster(_graphicRaycaster);
_interactManager.ReleaseExclusiveRaycaster(_graphicRaycaster);
_raycasterRegistered = false;
}
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 229b8c87b487340b8b0a02349675f70c

View File

@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 9afe762158da4f8c8bb8a1bcb98d62b1
timeCreated: 1778242706

Some files were not shown because too many files have changed in this diff Show More