Improve VFX, UI overlays, session statistics, COM reliability, audio mixer, and expand architecture guides
Подробный список изменений: - Перенесены эффекты частиц из C#-кода в готовые префабы-ассеты (Vfx Prefabs) в папке Assets/Resources/Vfx/ с автоматической генерацией материалов в Editor. - Исправлены ошибки duration на играющих системах частиц и розовые текстуры в GameVfxService.cs. - Исправлена навигация и фокус кнопок на оверлеях ContinueGameOverlay и PrizeResultOverlay с автоматическим подсвечиванием кнопок лимонно-зеленым цветом при фокусе и проигрыванием звука. - Добавлена проверка настроек в GameplayHudController.cs для скрытия ContinueGameOverlay, если продолжение игры отключено. - Расширен сбор статистики: создана структура GameplaySessionRecord, добавлена история до 50 раундов в PrizeSessionStateService и JsonPrizeSessionStateRepository, выведен расчет средних показателей и список 5 последних раундов в сервисной статистике. - Повышена надежность COM-транспорта: добавлен sleep (80мс) в Dispose для graceful shutdown потоков, реализован цикл переподключения до 10 попыток при обрыве связи. - Интегрированы настройки громкости с микшером: изменен шаг изменения громкости на 5% (0.05) для удобства, добавлен статус-чек и логи в ApplyServiceVolumes, расширены юнит-тесты на GetFloat параметры. - Созданы новые архитектурные гайды по аппаратному COM-транспорту и призовой экономике автомата в папке GUIDES/architecture/. - Оптимизирован и обновлен RAG-индекс проекта.
This commit is contained in:
parent
9000a6bc0c
commit
839a68aef1
@ -141,7 +141,15 @@ AudioMixerController:
|
||||
name: MusicVolume
|
||||
- guid: 189b6be1a4bf3164a90885b0f24a7a48
|
||||
name: SoundsVolume
|
||||
m_AudioMixerGroupViews: []
|
||||
m_AudioMixerGroupViews:
|
||||
- guids:
|
||||
- 5164b58c69786c341b1a5415bbcc6718
|
||||
- 8478690b25035494dadd1a1f37938d91
|
||||
- 313fac706123ef544a6e182b9f0e9852
|
||||
- 7fef6e1290001664dac7c593c8fc4894
|
||||
- 35db7625f6672cb44a6ccabc6e36b6c4
|
||||
- bddd63f5c1b0be248ba048ea7c6f1235
|
||||
name: View
|
||||
m_CurrentViewIndex: 0
|
||||
m_TargetSnapshot: {fileID: 24500006}
|
||||
--- !u!243 &24300002
|
||||
|
||||
@ -18,57 +18,37 @@ MonoBehaviour:
|
||||
uiGroup: {fileID: -5027576678584524412, guid: e7f5dba03b1fe564095aec623e122722, type: 2}
|
||||
gameplayGroup: {fileID: 4708169676529525986, guid: e7f5dba03b1fe564095aec623e122722, type: 2}
|
||||
ambienceGroup: {fileID: -7217844520931084221, guid: e7f5dba03b1fe564095aec623e122722, type: 2}
|
||||
musicLoop: {fileID: 0}
|
||||
musicLoop: {fileID: 8300000, guid: b0296787b59f9f248b8361070a74a2b5, type: 3}
|
||||
musicLoopVolume: 1
|
||||
playMusicOnInitialize: 1
|
||||
defaultMusicCue: 0
|
||||
musicTracks: []
|
||||
musicTracks:
|
||||
- cue: 0
|
||||
clip: {fileID: 8300000, guid: b0296787b59f9f248b8361070a74a2b5, type: 3}
|
||||
outputGroupOverride: {fileID: 0}
|
||||
volume: 1
|
||||
loop: 1
|
||||
- cue: 1
|
||||
clip: {fileID: 8300000, guid: 3a30c29718ace1c468575da20ba204f1, type: 3}
|
||||
outputGroupOverride: {fileID: 0}
|
||||
volume: 1
|
||||
loop: 0
|
||||
- cue: 1
|
||||
clip: {fileID: 8300000, guid: ff6aa1560276fae488e89d642928a57a, type: 3}
|
||||
outputGroupOverride: {fileID: 0}
|
||||
volume: 1
|
||||
loop: 0
|
||||
- cue: 1
|
||||
clip: {fileID: 8300000, guid: 66f130eb74c4f9249ae760f50057506f, type: 3}
|
||||
outputGroupOverride: {fileID: 0}
|
||||
volume: 1
|
||||
loop: 0
|
||||
eventBindings:
|
||||
- eventId: 0
|
||||
channel: 1
|
||||
outputGroupOverride: {fileID: 0}
|
||||
clips:
|
||||
- {fileID: 8300000, guid: 2ad9b6d07a8e6214bbe919e2b5d94001, type: 3}
|
||||
volume: 0.55
|
||||
pitchRange: {x: 0.96, y: 1.04}
|
||||
spatial: 0
|
||||
- eventId: 1
|
||||
channel: 1
|
||||
outputGroupOverride: {fileID: 0}
|
||||
clips:
|
||||
- {fileID: 8300000, guid: b1c90ee21bc444d4fb49b39000584eb0, type: 3}
|
||||
volume: 0.65
|
||||
pitchRange: {x: 0.96, y: 1.04}
|
||||
spatial: 0
|
||||
- eventId: 2
|
||||
channel: 1
|
||||
outputGroupOverride: {fileID: 0}
|
||||
clips:
|
||||
- {fileID: 8300000, guid: 86f4e01db21734942bc827c352d1192d, type: 3}
|
||||
volume: 0.55
|
||||
pitchRange: {x: 0.96, y: 1.04}
|
||||
spatial: 0
|
||||
- eventId: 3
|
||||
channel: 1
|
||||
outputGroupOverride: {fileID: 0}
|
||||
clips:
|
||||
- {fileID: 8300000, guid: 83e35ed99b265944ca0af63349a93b39, type: 3}
|
||||
volume: 0.7
|
||||
pitchRange: {x: 0.96, y: 1.04}
|
||||
spatial: 0
|
||||
- eventId: 10
|
||||
channel: 1
|
||||
outputGroupOverride: {fileID: 0}
|
||||
clips:
|
||||
- {fileID: 8300000, guid: aa9657a7d0b5f7645bd09cef753a3241, type: 3}
|
||||
volume: 0.75
|
||||
pitchRange: {x: 0.96, y: 1.04}
|
||||
spatial: 0
|
||||
- eventId: 20
|
||||
channel: 2
|
||||
outputGroupOverride: {fileID: 0}
|
||||
clips:
|
||||
- {fileID: 8300000, guid: 46c2c848c1ca5ee4ca5d65e2c53ac8cc, type: 3}
|
||||
- {fileID: 8300000, guid: fa0b6b9872cd9b84bb24e35b24e57fdf, type: 3}
|
||||
volume: 0.45
|
||||
pitchRange: {x: 0.96, y: 1.04}
|
||||
spatial: 1
|
||||
@ -76,71 +56,31 @@ MonoBehaviour:
|
||||
channel: 2
|
||||
outputGroupOverride: {fileID: 0}
|
||||
clips:
|
||||
- {fileID: 8300000, guid: 803f2112075bf8f43b9932da0b6412f4, type: 3}
|
||||
- {fileID: 8300000, guid: f59cd1f6b437f7d4f8fa63bad1e466a5, type: 3}
|
||||
volume: 0.75
|
||||
pitchRange: {x: 0.96, y: 1.04}
|
||||
spatial: 1
|
||||
- eventId: 22
|
||||
- eventId: 20
|
||||
channel: 2
|
||||
outputGroupOverride: {fileID: 0}
|
||||
clips:
|
||||
- {fileID: 8300000, guid: 172d2de1ca63ba742941ed67d82c7a7a, type: 3}
|
||||
volume: 0.55
|
||||
pitchRange: {x: 0.96, y: 1.04}
|
||||
spatial: 1
|
||||
- eventId: 23
|
||||
channel: 2
|
||||
outputGroupOverride: {fileID: 0}
|
||||
clips:
|
||||
- {fileID: 8300000, guid: b435a43950545be458c5fdca99fbe35d, type: 3}
|
||||
volume: 0.8
|
||||
pitchRange: {x: 0.96, y: 1.04}
|
||||
spatial: 0
|
||||
- eventId: 24
|
||||
channel: 1
|
||||
outputGroupOverride: {fileID: 0}
|
||||
clips:
|
||||
- {fileID: 8300000, guid: ae1b48318c83bfa40a0c1050ad79b3c3, type: 3}
|
||||
volume: 0.65
|
||||
pitchRange: {x: 0.96, y: 1.04}
|
||||
spatial: 0
|
||||
- eventId: 25
|
||||
channel: 2
|
||||
outputGroupOverride: {fileID: 0}
|
||||
clips:
|
||||
- {fileID: 8300000, guid: 46c2c848c1ca5ee4ca5d65e2c53ac8cc, type: 3}
|
||||
- {fileID: 8300000, guid: fa0b6b9872cd9b84bb24e35b24e57fdf, type: 3}
|
||||
volume: 0.35
|
||||
pitchRange: {x: 0.96, y: 1.04}
|
||||
spatial: 1
|
||||
- eventId: 26
|
||||
channel: 2
|
||||
outputGroupOverride: {fileID: 0}
|
||||
clips:
|
||||
- {fileID: 8300000, guid: 803f2112075bf8f43b9932da0b6412f4, type: 3}
|
||||
volume: 0.65
|
||||
pitchRange: {x: 0.96, y: 1.04}
|
||||
spatial: 1
|
||||
- eventId: 27
|
||||
channel: 2
|
||||
outputGroupOverride: {fileID: 0}
|
||||
clips:
|
||||
- {fileID: 8300000, guid: e3dc6a0fbf543b64388f7b60615f4145, type: 3}
|
||||
- {fileID: 8300000, guid: cfbbacd3ef3f01743aa42aea3cb29270, type: 3}
|
||||
volume: 0.65
|
||||
pitchRange: {x: 0.96, y: 1.04}
|
||||
spatial: 1
|
||||
- eventId: 28
|
||||
channel: 2
|
||||
outputGroupOverride: {fileID: 0}
|
||||
clips:
|
||||
- {fileID: 8300000, guid: 86f4e01db21734942bc827c352d1192d, type: 3}
|
||||
volume: 0.35
|
||||
pitchRange: {x: 0.96, y: 1.04}
|
||||
spatial: 1
|
||||
- eventId: 30
|
||||
channel: 2
|
||||
outputGroupOverride: {fileID: 0}
|
||||
clips:
|
||||
- {fileID: 8300000, guid: 2be8148962585984fa7c7f14ae577839, type: 3}
|
||||
- {fileID: 8300000, guid: e3dc6a0fbf543b64388f7b60615f4145, type: 3}
|
||||
volume: 0.55
|
||||
pitchRange: {x: 0.96, y: 1.04}
|
||||
spatial: 1
|
||||
@ -160,78 +100,6 @@ MonoBehaviour:
|
||||
volume: 0.65
|
||||
pitchRange: {x: 0.96, y: 1.04}
|
||||
spatial: 1
|
||||
- eventId: 33
|
||||
channel: 2
|
||||
outputGroupOverride: {fileID: 0}
|
||||
clips:
|
||||
- {fileID: 8300000, guid: 0dd7ddaa5ac08f94ab2a8127bdadfd89, type: 3}
|
||||
volume: 0.7
|
||||
pitchRange: {x: 0.96, y: 1.04}
|
||||
spatial: 1
|
||||
- eventId: 34
|
||||
channel: 2
|
||||
outputGroupOverride: {fileID: 0}
|
||||
clips:
|
||||
- {fileID: 8300000, guid: 12bcd9f3a3e360441922c1b1d580bfd4, type: 3}
|
||||
volume: 0.75
|
||||
pitchRange: {x: 0.96, y: 1.04}
|
||||
spatial: 1
|
||||
- eventId: 40
|
||||
channel: 1
|
||||
outputGroupOverride: {fileID: 0}
|
||||
clips:
|
||||
- {fileID: 8300000, guid: a64959ada619fd148b353ac9ad0f276d, type: 3}
|
||||
volume: 0.55
|
||||
pitchRange: {x: 0.96, y: 1.04}
|
||||
spatial: 0
|
||||
- eventId: 41
|
||||
channel: 1
|
||||
outputGroupOverride: {fileID: 0}
|
||||
clips:
|
||||
- {fileID: 8300000, guid: fc76f32ac20220e4fa9947fdda16e80a, type: 3}
|
||||
volume: 0.55
|
||||
pitchRange: {x: 0.96, y: 1.04}
|
||||
spatial: 0
|
||||
- eventId: 42
|
||||
channel: 1
|
||||
outputGroupOverride: {fileID: 0}
|
||||
clips:
|
||||
- {fileID: 8300000, guid: 7933b6e19ab8feb4ea4e905ee9e52c57, type: 3}
|
||||
volume: 0.55
|
||||
pitchRange: {x: 0.96, y: 1.04}
|
||||
spatial: 0
|
||||
- eventId: 50
|
||||
channel: 2
|
||||
outputGroupOverride: {fileID: 0}
|
||||
clips:
|
||||
- {fileID: 8300000, guid: e3dc6a0fbf543b64388f7b60615f4145, type: 3}
|
||||
volume: 0.4
|
||||
pitchRange: {x: 0.96, y: 1.04}
|
||||
spatial: 1
|
||||
- eventId: 51
|
||||
channel: 2
|
||||
outputGroupOverride: {fileID: 0}
|
||||
clips:
|
||||
- {fileID: 8300000, guid: 46c2c848c1ca5ee4ca5d65e2c53ac8cc, type: 3}
|
||||
volume: 0.25
|
||||
pitchRange: {x: 0.96, y: 1.04}
|
||||
spatial: 1
|
||||
- eventId: 52
|
||||
channel: 2
|
||||
outputGroupOverride: {fileID: 0}
|
||||
clips:
|
||||
- {fileID: 8300000, guid: 83e35ed99b265944ca0af63349a93b39, type: 3}
|
||||
volume: 0.65
|
||||
pitchRange: {x: 0.96, y: 1.04}
|
||||
spatial: 1
|
||||
- eventId: 53
|
||||
channel: 2
|
||||
outputGroupOverride: {fileID: 0}
|
||||
clips:
|
||||
- {fileID: 8300000, guid: e3dc6a0fbf543b64388f7b60615f4145, type: 3}
|
||||
volume: 0.65
|
||||
pitchRange: {x: 0.96, y: 1.04}
|
||||
spatial: 1
|
||||
- eventId: 54
|
||||
channel: 2
|
||||
outputGroupOverride: {fileID: 0}
|
||||
|
||||
@ -486,7 +486,7 @@
|
||||
"isPartOfComposite": false
|
||||
},
|
||||
{
|
||||
"name": "up",
|
||||
"name": "Left",
|
||||
"id": "a198c978-a3d0-4a74-b983-bb738806642f",
|
||||
"path": "<ComController>/button00",
|
||||
"interactions": "",
|
||||
@ -497,7 +497,7 @@
|
||||
"isPartOfComposite": true
|
||||
},
|
||||
{
|
||||
"name": "down",
|
||||
"name": "Right",
|
||||
"id": "a9d0403f-4513-4603-9b49-43958229d392",
|
||||
"path": "<ComController>/button01",
|
||||
"interactions": "",
|
||||
@ -508,7 +508,7 @@
|
||||
"isPartOfComposite": true
|
||||
},
|
||||
{
|
||||
"name": "left",
|
||||
"name": "Down",
|
||||
"id": "250db8f2-7c51-4194-afbb-1de8c14f4111",
|
||||
"path": "<ComController>/button02",
|
||||
"interactions": "",
|
||||
@ -519,7 +519,7 @@
|
||||
"isPartOfComposite": true
|
||||
},
|
||||
{
|
||||
"name": "right",
|
||||
"name": "Up",
|
||||
"id": "686eb2f1-953a-4125-8969-902c3d103faf",
|
||||
"path": "<ComController>/button03",
|
||||
"interactions": "",
|
||||
@ -1130,7 +1130,7 @@
|
||||
"isPartOfComposite": false
|
||||
},
|
||||
{
|
||||
"name": "up",
|
||||
"name": "Left",
|
||||
"id": "620356a3-c4ff-4864-9250-2c7ed7b72b04",
|
||||
"path": "<ComController>/button00",
|
||||
"interactions": "",
|
||||
@ -1141,7 +1141,7 @@
|
||||
"isPartOfComposite": true
|
||||
},
|
||||
{
|
||||
"name": "down",
|
||||
"name": "Right",
|
||||
"id": "f17dd696-874e-48ff-aa99-eb578bd77adc",
|
||||
"path": "<ComController>/button01",
|
||||
"interactions": "",
|
||||
@ -1152,7 +1152,7 @@
|
||||
"isPartOfComposite": true
|
||||
},
|
||||
{
|
||||
"name": "left",
|
||||
"name": "Down",
|
||||
"id": "01e3f407-30b9-4b80-86cb-9ec5fae7aff6",
|
||||
"path": "<ComController>/button02",
|
||||
"interactions": "",
|
||||
@ -1163,7 +1163,7 @@
|
||||
"isPartOfComposite": true
|
||||
},
|
||||
{
|
||||
"name": "right",
|
||||
"name": "Up",
|
||||
"id": "7dd97762-8ade-4ff7-a177-398d6bf65dd9",
|
||||
"path": "<ComController>/button03",
|
||||
"interactions": "",
|
||||
@ -1282,4 +1282,4 @@
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@ -82,6 +82,7 @@ MonoBehaviour:
|
||||
fallbackDatabase: {fileID: 0}
|
||||
audioSettings: {fileID: 11400000, guid: b8788b5bf4f92e94f83f651bb5a0a6ee, type: 2}
|
||||
fileName: service-settings.json
|
||||
prizeSessionStateFileName: prize-session-state.json
|
||||
loadImmediately: 1
|
||||
bindActionsInScene: 1
|
||||
--- !u!114 &4222904644466244002
|
||||
@ -98,7 +99,7 @@ MonoBehaviour:
|
||||
m_EditorClassIdentifier: DanroJump.Runtime::DanroJump.Debugging.RuntimeDebugInstaller
|
||||
enabledOnStartup: 1
|
||||
enabledChannels: -1
|
||||
enabledOutputs: 3
|
||||
enabledOutputs: -1
|
||||
fileLoggingEnabled: 0
|
||||
fileLoggingUsePersistentDataPath: 1
|
||||
fileLoggingDirectory: Logs
|
||||
|
||||
8
Assets/Resources/Vfx.meta
Normal file
8
Assets/Resources/Vfx.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1279a337eb14be0458f47cdfbfdc2a49
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
90
Assets/Resources/Vfx/ParticleDefaultMaterial.mat
Normal file
90
Assets/Resources/Vfx/ParticleDefaultMaterial.mat
Normal file
@ -0,0 +1,90 @@
|
||||
%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: ParticleDefaultMaterial
|
||||
m_Shader: {fileID: 4800000, guid: 0406db5a14f94604a8c57ccfbc9f3b46, type: 3}
|
||||
m_Parent: {fileID: 0}
|
||||
m_ModifiedSerializedProperties: 0
|
||||
m_ValidKeywords: []
|
||||
m_InvalidKeywords:
|
||||
- _FLIPBOOKBLENDING_OFF
|
||||
m_LightmapFlags: 4
|
||||
m_EnableInstancingVariants: 0
|
||||
m_DoubleSidedGI: 0
|
||||
m_CustomRenderQueue: -1
|
||||
stringTagMap:
|
||||
RenderType: Opaque
|
||||
disabledShaderPasses: []
|
||||
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}
|
||||
- _EmissionMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
m_Ints: []
|
||||
m_Floats:
|
||||
- _AlphaClip: 0
|
||||
- _AlphaToMask: 0
|
||||
- _Blend: 0
|
||||
- _BlendOp: 0
|
||||
- _CameraFadingEnabled: 0
|
||||
- _CameraFarFadeDistance: 2
|
||||
- _CameraNearFadeDistance: 1
|
||||
- _ColorMode: 0
|
||||
- _Cull: 2
|
||||
- _Cutoff: 0.5
|
||||
- _DistortionBlend: 0.5
|
||||
- _DistortionEnabled: 0
|
||||
- _DistortionStrength: 1
|
||||
- _DistortionStrengthScaled: 0.1
|
||||
- _DstBlend: 0
|
||||
- _DstBlendAlpha: 0
|
||||
- _FlipbookBlending: 0
|
||||
- _FlipbookMode: 0
|
||||
- _Mode: 0
|
||||
- _QueueOffset: 0
|
||||
- _SoftParticlesEnabled: 0
|
||||
- _SoftParticlesFarFadeDistance: 1
|
||||
- _SoftParticlesNearFadeDistance: 0
|
||||
- _SrcBlend: 1
|
||||
- _SrcBlendAlpha: 1
|
||||
- _Surface: 0
|
||||
- _ZWrite: 1
|
||||
m_Colors:
|
||||
- _BaseColor: {r: 1, g: 1, b: 1, a: 1}
|
||||
- _BaseColorAddSubDiff: {r: 0, g: 0, b: 0, a: 0}
|
||||
- _CameraFadeParams: {r: 0, g: 0, b: 0, a: 0}
|
||||
- _Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
|
||||
- _SoftParticleFadeParams: {r: 0, g: 0, b: 0, a: 0}
|
||||
m_BuildTextureStacks: []
|
||||
m_AllowLocking: 1
|
||||
--- !u!114 &1502222179824363022
|
||||
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
|
||||
@ -1,8 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bf7ca407d43a63a4aa7bbee33da26d0f
|
||||
guid: e261acd8183bb7e489ebd80d5cc9f801
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 11400000
|
||||
mainObjectFileID: 2100000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
4896
Assets/Resources/Vfx/VFX_CoinCollected.prefab
Normal file
4896
Assets/Resources/Vfx/VFX_CoinCollected.prefab
Normal file
File diff suppressed because it is too large
Load Diff
7
Assets/Resources/Vfx/VFX_CoinCollected.prefab.meta
Normal file
7
Assets/Resources/Vfx/VFX_CoinCollected.prefab.meta
Normal file
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d37641bc43aa8a5409199e458d4eabba
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
4896
Assets/Resources/Vfx/VFX_ComError.prefab
Normal file
4896
Assets/Resources/Vfx/VFX_ComError.prefab
Normal file
File diff suppressed because it is too large
Load Diff
7
Assets/Resources/Vfx/VFX_ComError.prefab.meta
Normal file
7
Assets/Resources/Vfx/VFX_ComError.prefab.meta
Normal file
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fc563a14f212643468c4cd3a2520fa93
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
4896
Assets/Resources/Vfx/VFX_Jump.prefab
Normal file
4896
Assets/Resources/Vfx/VFX_Jump.prefab
Normal file
File diff suppressed because it is too large
Load Diff
7
Assets/Resources/Vfx/VFX_Jump.prefab.meta
Normal file
7
Assets/Resources/Vfx/VFX_Jump.prefab.meta
Normal file
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6e2885d269ac0da48a7845117ba29f16
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
4896
Assets/Resources/Vfx/VFX_PlayerDeath.prefab
Normal file
4896
Assets/Resources/Vfx/VFX_PlayerDeath.prefab
Normal file
File diff suppressed because it is too large
Load Diff
7
Assets/Resources/Vfx/VFX_PlayerDeath.prefab.meta
Normal file
7
Assets/Resources/Vfx/VFX_PlayerDeath.prefab.meta
Normal file
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e0b60ede207833d4190096335996bac5
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
4896
Assets/Resources/Vfx/VFX_PrizeWin.prefab
Normal file
4896
Assets/Resources/Vfx/VFX_PrizeWin.prefab
Normal file
File diff suppressed because it is too large
Load Diff
7
Assets/Resources/Vfx/VFX_PrizeWin.prefab.meta
Normal file
7
Assets/Resources/Vfx/VFX_PrizeWin.prefab.meta
Normal file
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4d09f2717174d4f42bcbbf6d496bebe3
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/SFX/Ambient.meta
Normal file
8
Assets/SFX/Ambient.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f275684fdcf8bb149b62c6df2a609824
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/SFX/Enemies.meta
Normal file
8
Assets/SFX/Enemies.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1843e8ef4c43772469423eda8873ec39
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/SFX/Enemies/Crab_Click.wav
(Stored with Git LFS)
Normal file
BIN
Assets/SFX/Enemies/Crab_Click.wav
(Stored with Git LFS)
Normal file
Binary file not shown.
23
Assets/SFX/Enemies/Crab_Click.wav.meta
Normal file
23
Assets/SFX/Enemies/Crab_Click.wav.meta
Normal file
@ -0,0 +1,23 @@
|
||||
fileFormatVersion: 2
|
||||
guid: aeba847740e70ba46b7d3df9513316e1
|
||||
AudioImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 8
|
||||
defaultSettings:
|
||||
serializedVersion: 2
|
||||
loadType: 0
|
||||
sampleRateSetting: 0
|
||||
sampleRateOverride: 44100
|
||||
compressionFormat: 1
|
||||
quality: 1
|
||||
conversionMode: 0
|
||||
preloadAudioData: 1
|
||||
platformSettingOverrides: {}
|
||||
forceToMono: 0
|
||||
normalize: 1
|
||||
loadInBackground: 0
|
||||
ambisonic: 0
|
||||
3D: 1
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/SFX/Enemies/Enemy_Hit_1.wav
(Stored with Git LFS)
Normal file
BIN
Assets/SFX/Enemies/Enemy_Hit_1.wav
(Stored with Git LFS)
Normal file
Binary file not shown.
23
Assets/SFX/Enemies/Enemy_Hit_1.wav.meta
Normal file
23
Assets/SFX/Enemies/Enemy_Hit_1.wav.meta
Normal file
@ -0,0 +1,23 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 37f7526ec58db8843916100518133785
|
||||
AudioImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 8
|
||||
defaultSettings:
|
||||
serializedVersion: 2
|
||||
loadType: 0
|
||||
sampleRateSetting: 0
|
||||
sampleRateOverride: 44100
|
||||
compressionFormat: 1
|
||||
quality: 1
|
||||
conversionMode: 0
|
||||
preloadAudioData: 1
|
||||
platformSettingOverrides: {}
|
||||
forceToMono: 0
|
||||
normalize: 1
|
||||
loadInBackground: 0
|
||||
ambisonic: 0
|
||||
3D: 1
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/SFX/Enemies/Knife_Throw_1.wav
(Stored with Git LFS)
Normal file
BIN
Assets/SFX/Enemies/Knife_Throw_1.wav
(Stored with Git LFS)
Normal file
Binary file not shown.
23
Assets/SFX/Enemies/Knife_Throw_1.wav.meta
Normal file
23
Assets/SFX/Enemies/Knife_Throw_1.wav.meta
Normal file
@ -0,0 +1,23 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f5084f4cf2fabc74fae40a5a9ebc2718
|
||||
AudioImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 8
|
||||
defaultSettings:
|
||||
serializedVersion: 2
|
||||
loadType: 0
|
||||
sampleRateSetting: 0
|
||||
sampleRateOverride: 44100
|
||||
compressionFormat: 1
|
||||
quality: 1
|
||||
conversionMode: 0
|
||||
preloadAudioData: 1
|
||||
platformSettingOverrides: {}
|
||||
forceToMono: 0
|
||||
normalize: 1
|
||||
loadInBackground: 0
|
||||
ambisonic: 0
|
||||
3D: 1
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/SFX/Enemies/Knife_Throw_2.wav
(Stored with Git LFS)
Normal file
BIN
Assets/SFX/Enemies/Knife_Throw_2.wav
(Stored with Git LFS)
Normal file
Binary file not shown.
23
Assets/SFX/Enemies/Knife_Throw_2.wav.meta
Normal file
23
Assets/SFX/Enemies/Knife_Throw_2.wav.meta
Normal file
@ -0,0 +1,23 @@
|
||||
fileFormatVersion: 2
|
||||
guid: eb475b242c9b6ec448dfec33ec8da9f2
|
||||
AudioImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 8
|
||||
defaultSettings:
|
||||
serializedVersion: 2
|
||||
loadType: 0
|
||||
sampleRateSetting: 0
|
||||
sampleRateOverride: 44100
|
||||
compressionFormat: 1
|
||||
quality: 1
|
||||
conversionMode: 0
|
||||
preloadAudioData: 1
|
||||
platformSettingOverrides: {}
|
||||
forceToMono: 0
|
||||
normalize: 1
|
||||
loadInBackground: 0
|
||||
ambisonic: 0
|
||||
3D: 1
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/SFX/Enemies/Laser_Fire_1.wav
(Stored with Git LFS)
Normal file
BIN
Assets/SFX/Enemies/Laser_Fire_1.wav
(Stored with Git LFS)
Normal file
Binary file not shown.
23
Assets/SFX/Enemies/Laser_Fire_1.wav.meta
Normal file
23
Assets/SFX/Enemies/Laser_Fire_1.wav.meta
Normal file
@ -0,0 +1,23 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a0166fbc7106f42498be14d005a200f4
|
||||
AudioImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 8
|
||||
defaultSettings:
|
||||
serializedVersion: 2
|
||||
loadType: 0
|
||||
sampleRateSetting: 0
|
||||
sampleRateOverride: 44100
|
||||
compressionFormat: 1
|
||||
quality: 1
|
||||
conversionMode: 0
|
||||
preloadAudioData: 1
|
||||
platformSettingOverrides: {}
|
||||
forceToMono: 0
|
||||
normalize: 1
|
||||
loadInBackground: 0
|
||||
ambisonic: 0
|
||||
3D: 1
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/SFX/Movement.meta
Normal file
8
Assets/SFX/Movement.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 57a4f5562e31f8a4ebfd8e305d8e3b39
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/SFX/Movement/Grass_Run_1.wav
(Stored with Git LFS)
Normal file
BIN
Assets/SFX/Movement/Grass_Run_1.wav
(Stored with Git LFS)
Normal file
Binary file not shown.
23
Assets/SFX/Movement/Grass_Run_1.wav.meta
Normal file
23
Assets/SFX/Movement/Grass_Run_1.wav.meta
Normal file
@ -0,0 +1,23 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 144cba17f4a47274d834d5e1fc28acb9
|
||||
AudioImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 8
|
||||
defaultSettings:
|
||||
serializedVersion: 2
|
||||
loadType: 0
|
||||
sampleRateSetting: 0
|
||||
sampleRateOverride: 44100
|
||||
compressionFormat: 1
|
||||
quality: 1
|
||||
conversionMode: 0
|
||||
preloadAudioData: 1
|
||||
platformSettingOverrides: {}
|
||||
forceToMono: 0
|
||||
normalize: 1
|
||||
loadInBackground: 0
|
||||
ambisonic: 0
|
||||
3D: 1
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/SFX/Movement/Grass_Run_2.wav
(Stored with Git LFS)
Normal file
BIN
Assets/SFX/Movement/Grass_Run_2.wav
(Stored with Git LFS)
Normal file
Binary file not shown.
23
Assets/SFX/Movement/Grass_Run_2.wav.meta
Normal file
23
Assets/SFX/Movement/Grass_Run_2.wav.meta
Normal file
@ -0,0 +1,23 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5f68c3b1c31c833458e189d0b7d622dd
|
||||
AudioImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 8
|
||||
defaultSettings:
|
||||
serializedVersion: 2
|
||||
loadType: 0
|
||||
sampleRateSetting: 0
|
||||
sampleRateOverride: 44100
|
||||
compressionFormat: 1
|
||||
quality: 1
|
||||
conversionMode: 0
|
||||
preloadAudioData: 1
|
||||
platformSettingOverrides: {}
|
||||
forceToMono: 0
|
||||
normalize: 1
|
||||
loadInBackground: 0
|
||||
ambisonic: 0
|
||||
3D: 1
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/SFX/Movement/Metal_Run_1.wav
(Stored with Git LFS)
Normal file
BIN
Assets/SFX/Movement/Metal_Run_1.wav
(Stored with Git LFS)
Normal file
Binary file not shown.
23
Assets/SFX/Movement/Metal_Run_1.wav.meta
Normal file
23
Assets/SFX/Movement/Metal_Run_1.wav.meta
Normal file
@ -0,0 +1,23 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 44081d4997ebc78418c03a0fa021336d
|
||||
AudioImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 8
|
||||
defaultSettings:
|
||||
serializedVersion: 2
|
||||
loadType: 0
|
||||
sampleRateSetting: 0
|
||||
sampleRateOverride: 44100
|
||||
compressionFormat: 1
|
||||
quality: 1
|
||||
conversionMode: 0
|
||||
preloadAudioData: 1
|
||||
platformSettingOverrides: {}
|
||||
forceToMono: 0
|
||||
normalize: 1
|
||||
loadInBackground: 0
|
||||
ambisonic: 0
|
||||
3D: 1
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/SFX/Movement/Metal_Run_2.wav
(Stored with Git LFS)
Normal file
BIN
Assets/SFX/Movement/Metal_Run_2.wav
(Stored with Git LFS)
Normal file
Binary file not shown.
23
Assets/SFX/Movement/Metal_Run_2.wav.meta
Normal file
23
Assets/SFX/Movement/Metal_Run_2.wav.meta
Normal file
@ -0,0 +1,23 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 64a82f6dc3cfec746bcc23ded9a926ee
|
||||
AudioImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 8
|
||||
defaultSettings:
|
||||
serializedVersion: 2
|
||||
loadType: 0
|
||||
sampleRateSetting: 0
|
||||
sampleRateOverride: 44100
|
||||
compressionFormat: 1
|
||||
quality: 1
|
||||
conversionMode: 0
|
||||
preloadAudioData: 1
|
||||
platformSettingOverrides: {}
|
||||
forceToMono: 0
|
||||
normalize: 1
|
||||
loadInBackground: 0
|
||||
ambisonic: 0
|
||||
3D: 1
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/SFX/Movement/Metal_Run_3.wav
(Stored with Git LFS)
Normal file
BIN
Assets/SFX/Movement/Metal_Run_3.wav
(Stored with Git LFS)
Normal file
Binary file not shown.
23
Assets/SFX/Movement/Metal_Run_3.wav.meta
Normal file
23
Assets/SFX/Movement/Metal_Run_3.wav.meta
Normal file
@ -0,0 +1,23 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6aedae21e708ea448b1ed0468415c094
|
||||
AudioImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 8
|
||||
defaultSettings:
|
||||
serializedVersion: 2
|
||||
loadType: 0
|
||||
sampleRateSetting: 0
|
||||
sampleRateOverride: 44100
|
||||
compressionFormat: 1
|
||||
quality: 1
|
||||
conversionMode: 0
|
||||
preloadAudioData: 1
|
||||
platformSettingOverrides: {}
|
||||
forceToMono: 0
|
||||
normalize: 1
|
||||
loadInBackground: 0
|
||||
ambisonic: 0
|
||||
3D: 1
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/SFX/Music.meta
Normal file
8
Assets/SFX/Music.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7c4a4b8979f55b7419ad0f32736401b4
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/SFX/Music/music_Level_1.mp3
(Stored with Git LFS)
Normal file
BIN
Assets/SFX/Music/music_Level_1.mp3
(Stored with Git LFS)
Normal file
Binary file not shown.
23
Assets/SFX/Music/music_Level_1.mp3.meta
Normal file
23
Assets/SFX/Music/music_Level_1.mp3.meta
Normal file
@ -0,0 +1,23 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3a30c29718ace1c468575da20ba204f1
|
||||
AudioImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 8
|
||||
defaultSettings:
|
||||
serializedVersion: 2
|
||||
loadType: 0
|
||||
sampleRateSetting: 0
|
||||
sampleRateOverride: 44100
|
||||
compressionFormat: 1
|
||||
quality: 1
|
||||
conversionMode: 0
|
||||
preloadAudioData: 1
|
||||
platformSettingOverrides: {}
|
||||
forceToMono: 0
|
||||
normalize: 1
|
||||
loadInBackground: 0
|
||||
ambisonic: 0
|
||||
3D: 1
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/SFX/Music/music_Level_2.mp3
(Stored with Git LFS)
Normal file
BIN
Assets/SFX/Music/music_Level_2.mp3
(Stored with Git LFS)
Normal file
Binary file not shown.
23
Assets/SFX/Music/music_Level_2.mp3.meta
Normal file
23
Assets/SFX/Music/music_Level_2.mp3.meta
Normal file
@ -0,0 +1,23 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ff6aa1560276fae488e89d642928a57a
|
||||
AudioImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 8
|
||||
defaultSettings:
|
||||
serializedVersion: 2
|
||||
loadType: 0
|
||||
sampleRateSetting: 0
|
||||
sampleRateOverride: 44100
|
||||
compressionFormat: 1
|
||||
quality: 1
|
||||
conversionMode: 0
|
||||
preloadAudioData: 1
|
||||
platformSettingOverrides: {}
|
||||
forceToMono: 0
|
||||
normalize: 1
|
||||
loadInBackground: 0
|
||||
ambisonic: 0
|
||||
3D: 1
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/SFX/Music/music_Level_3.mp3
(Stored with Git LFS)
Normal file
BIN
Assets/SFX/Music/music_Level_3.mp3
(Stored with Git LFS)
Normal file
Binary file not shown.
23
Assets/SFX/Music/music_Level_3.mp3.meta
Normal file
23
Assets/SFX/Music/music_Level_3.mp3.meta
Normal file
@ -0,0 +1,23 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 66f130eb74c4f9249ae760f50057506f
|
||||
AudioImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 8
|
||||
defaultSettings:
|
||||
serializedVersion: 2
|
||||
loadType: 0
|
||||
sampleRateSetting: 0
|
||||
sampleRateOverride: 44100
|
||||
compressionFormat: 1
|
||||
quality: 1
|
||||
conversionMode: 0
|
||||
preloadAudioData: 1
|
||||
platformSettingOverrides: {}
|
||||
forceToMono: 0
|
||||
normalize: 1
|
||||
loadInBackground: 0
|
||||
ambisonic: 0
|
||||
3D: 1
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/SFX/Music/music_MainMenu.mp3
(Stored with Git LFS)
Normal file
BIN
Assets/SFX/Music/music_MainMenu.mp3
(Stored with Git LFS)
Normal file
Binary file not shown.
23
Assets/SFX/Music/music_MainMenu.mp3.meta
Normal file
23
Assets/SFX/Music/music_MainMenu.mp3.meta
Normal file
@ -0,0 +1,23 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b0296787b59f9f248b8361070a74a2b5
|
||||
AudioImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 8
|
||||
defaultSettings:
|
||||
serializedVersion: 2
|
||||
loadType: 0
|
||||
sampleRateSetting: 0
|
||||
sampleRateOverride: 44100
|
||||
compressionFormat: 1
|
||||
quality: 1
|
||||
conversionMode: 0
|
||||
preloadAudioData: 1
|
||||
platformSettingOverrides: {}
|
||||
forceToMono: 0
|
||||
normalize: 1
|
||||
loadInBackground: 0
|
||||
ambisonic: 0
|
||||
3D: 1
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/SFX/Player.meta
Normal file
8
Assets/SFX/Player.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 167ab01cf5313904f8c0a289d0925cdc
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/SFX/Player/Hurt_1.wav
(Stored with Git LFS)
Normal file
BIN
Assets/SFX/Player/Hurt_1.wav
(Stored with Git LFS)
Normal file
Binary file not shown.
23
Assets/SFX/Player/Hurt_1.wav.meta
Normal file
23
Assets/SFX/Player/Hurt_1.wav.meta
Normal file
@ -0,0 +1,23 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f59cd1f6b437f7d4f8fa63bad1e466a5
|
||||
AudioImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 8
|
||||
defaultSettings:
|
||||
serializedVersion: 2
|
||||
loadType: 0
|
||||
sampleRateSetting: 0
|
||||
sampleRateOverride: 44100
|
||||
compressionFormat: 1
|
||||
quality: 1
|
||||
conversionMode: 0
|
||||
preloadAudioData: 1
|
||||
platformSettingOverrides: {}
|
||||
forceToMono: 0
|
||||
normalize: 1
|
||||
loadInBackground: 0
|
||||
ambisonic: 0
|
||||
3D: 1
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/SFX/Player/Hurt_2.wav
(Stored with Git LFS)
Normal file
BIN
Assets/SFX/Player/Hurt_2.wav
(Stored with Git LFS)
Normal file
Binary file not shown.
23
Assets/SFX/Player/Hurt_2.wav.meta
Normal file
23
Assets/SFX/Player/Hurt_2.wav.meta
Normal file
@ -0,0 +1,23 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ce8d9dfcc94fcae46a52bd90ac0b0a19
|
||||
AudioImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 8
|
||||
defaultSettings:
|
||||
serializedVersion: 2
|
||||
loadType: 0
|
||||
sampleRateSetting: 0
|
||||
sampleRateOverride: 44100
|
||||
compressionFormat: 1
|
||||
quality: 1
|
||||
conversionMode: 0
|
||||
preloadAudioData: 1
|
||||
platformSettingOverrides: {}
|
||||
forceToMono: 0
|
||||
normalize: 1
|
||||
loadInBackground: 0
|
||||
ambisonic: 0
|
||||
3D: 1
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/SFX/Player/Jump_1.wav
(Stored with Git LFS)
Normal file
BIN
Assets/SFX/Player/Jump_1.wav
(Stored with Git LFS)
Normal file
Binary file not shown.
23
Assets/SFX/Player/Jump_1.wav.meta
Normal file
23
Assets/SFX/Player/Jump_1.wav.meta
Normal file
@ -0,0 +1,23 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fa0b6b9872cd9b84bb24e35b24e57fdf
|
||||
AudioImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 8
|
||||
defaultSettings:
|
||||
serializedVersion: 2
|
||||
loadType: 0
|
||||
sampleRateSetting: 0
|
||||
sampleRateOverride: 44100
|
||||
compressionFormat: 1
|
||||
quality: 1
|
||||
conversionMode: 0
|
||||
preloadAudioData: 1
|
||||
platformSettingOverrides: {}
|
||||
forceToMono: 0
|
||||
normalize: 1
|
||||
loadInBackground: 0
|
||||
ambisonic: 0
|
||||
3D: 1
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/SFX/Player/Throw_1.wav
(Stored with Git LFS)
Normal file
BIN
Assets/SFX/Player/Throw_1.wav
(Stored with Git LFS)
Normal file
Binary file not shown.
23
Assets/SFX/Player/Throw_1.wav.meta
Normal file
23
Assets/SFX/Player/Throw_1.wav.meta
Normal file
@ -0,0 +1,23 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a9399f94f3fa20f44b8d76c30deda71c
|
||||
AudioImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 8
|
||||
defaultSettings:
|
||||
serializedVersion: 2
|
||||
loadType: 0
|
||||
sampleRateSetting: 0
|
||||
sampleRateOverride: 44100
|
||||
compressionFormat: 1
|
||||
quality: 1
|
||||
conversionMode: 0
|
||||
preloadAudioData: 1
|
||||
platformSettingOverrides: {}
|
||||
forceToMono: 0
|
||||
normalize: 1
|
||||
loadInBackground: 0
|
||||
ambisonic: 0
|
||||
3D: 1
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/SFX/Props.meta
Normal file
8
Assets/SFX/Props.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 102b571a03e65d549bcbc5b6f780ce62
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/SFX/Props/Checkpoint.wav
(Stored with Git LFS)
Normal file
BIN
Assets/SFX/Props/Checkpoint.wav
(Stored with Git LFS)
Normal file
Binary file not shown.
23
Assets/SFX/Props/Checkpoint.wav.meta
Normal file
23
Assets/SFX/Props/Checkpoint.wav.meta
Normal file
@ -0,0 +1,23 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cfbbacd3ef3f01743aa42aea3cb29270
|
||||
AudioImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 8
|
||||
defaultSettings:
|
||||
serializedVersion: 2
|
||||
loadType: 0
|
||||
sampleRateSetting: 0
|
||||
sampleRateOverride: 44100
|
||||
compressionFormat: 1
|
||||
quality: 1
|
||||
conversionMode: 0
|
||||
preloadAudioData: 1
|
||||
platformSettingOverrides: {}
|
||||
forceToMono: 0
|
||||
normalize: 1
|
||||
loadInBackground: 0
|
||||
ambisonic: 0
|
||||
3D: 1
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/SFX/Props/Laser_1.wav
(Stored with Git LFS)
Normal file
BIN
Assets/SFX/Props/Laser_1.wav
(Stored with Git LFS)
Normal file
Binary file not shown.
23
Assets/SFX/Props/Laser_1.wav.meta
Normal file
23
Assets/SFX/Props/Laser_1.wav.meta
Normal file
@ -0,0 +1,23 @@
|
||||
fileFormatVersion: 2
|
||||
guid: caba1143532ae5642aa33fa950eb6269
|
||||
AudioImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 8
|
||||
defaultSettings:
|
||||
serializedVersion: 2
|
||||
loadType: 0
|
||||
sampleRateSetting: 0
|
||||
sampleRateOverride: 44100
|
||||
compressionFormat: 1
|
||||
quality: 1
|
||||
conversionMode: 0
|
||||
preloadAudioData: 1
|
||||
platformSettingOverrides: {}
|
||||
forceToMono: 0
|
||||
normalize: 1
|
||||
loadInBackground: 0
|
||||
ambisonic: 0
|
||||
3D: 1
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/SFX/Props/Pickup_Coin.wav
(Stored with Git LFS)
Normal file
BIN
Assets/SFX/Props/Pickup_Coin.wav
(Stored with Git LFS)
Normal file
Binary file not shown.
23
Assets/SFX/Props/Pickup_Coin.wav.meta
Normal file
23
Assets/SFX/Props/Pickup_Coin.wav.meta
Normal file
@ -0,0 +1,23 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d151d983bbf55f7448d1be4e1a2535d0
|
||||
AudioImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 8
|
||||
defaultSettings:
|
||||
serializedVersion: 2
|
||||
loadType: 0
|
||||
sampleRateSetting: 0
|
||||
sampleRateOverride: 44100
|
||||
compressionFormat: 1
|
||||
quality: 1
|
||||
conversionMode: 0
|
||||
preloadAudioData: 0
|
||||
platformSettingOverrides: {}
|
||||
forceToMono: 0
|
||||
normalize: 1
|
||||
loadInBackground: 0
|
||||
ambisonic: 0
|
||||
3D: 1
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/SFX/UI.meta
Normal file
8
Assets/SFX/UI.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d97143c6c4cd9a94d98f9ff05a095bd0
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -491,6 +491,143 @@ Transform:
|
||||
m_Children: []
|
||||
m_Father: {fileID: 0}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!1 &1743332988
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 1743332992}
|
||||
- component: {fileID: 1743332991}
|
||||
- component: {fileID: 1743332990}
|
||||
- component: {fileID: 1743332989}
|
||||
m_Layer: 0
|
||||
m_Name: Main Camera
|
||||
m_TagString: MainCamera
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!114 &1743332989
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1743332988}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: a79441f348de89743a2939f4d699eac1, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier: Unity.RenderPipelines.Universal.Runtime::UnityEngine.Rendering.Universal.UniversalAdditionalCameraData
|
||||
m_RenderShadows: 1
|
||||
m_RequiresDepthTextureOption: 2
|
||||
m_RequiresOpaqueTextureOption: 2
|
||||
m_CameraType: 0
|
||||
m_Cameras: []
|
||||
m_RendererIndex: -1
|
||||
m_VolumeLayerMask:
|
||||
serializedVersion: 2
|
||||
m_Bits: 1
|
||||
m_VolumeTrigger: {fileID: 0}
|
||||
m_VolumeFrameworkUpdateModeOption: 2
|
||||
m_RenderPostProcessing: 0
|
||||
m_Antialiasing: 0
|
||||
m_AntialiasingQuality: 2
|
||||
m_StopNaN: 0
|
||||
m_Dithering: 0
|
||||
m_ClearDepth: 1
|
||||
m_AllowXRRendering: 1
|
||||
m_AllowHDROutput: 1
|
||||
m_UseScreenCoordOverride: 0
|
||||
m_ScreenSizeOverride: {x: 0, y: 0, z: 0, w: 0}
|
||||
m_ScreenCoordScaleBias: {x: 0, y: 0, z: 0, w: 0}
|
||||
m_RequiresDepthTexture: 0
|
||||
m_RequiresColorTexture: 0
|
||||
m_TaaSettings:
|
||||
m_Quality: 3
|
||||
m_FrameInfluence: 0.1
|
||||
m_JitterScale: 1
|
||||
m_MipBias: 0
|
||||
m_VarianceClampScale: 0.9
|
||||
m_ContrastAdaptiveSharpening: 0
|
||||
m_Version: 2
|
||||
--- !u!81 &1743332990
|
||||
AudioListener:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1743332988}
|
||||
m_Enabled: 1
|
||||
--- !u!20 &1743332991
|
||||
Camera:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1743332988}
|
||||
m_Enabled: 1
|
||||
serializedVersion: 2
|
||||
m_ClearFlags: 2
|
||||
m_BackGroundColor: {r: 0, g: 0, b: 0, a: 0}
|
||||
m_projectionMatrixMode: 1
|
||||
m_GateFitMode: 2
|
||||
m_FOVAxisMode: 0
|
||||
m_Iso: 200
|
||||
m_ShutterSpeed: 0.005
|
||||
m_Aperture: 16
|
||||
m_FocusDistance: 10
|
||||
m_FocalLength: 50
|
||||
m_BladeCount: 5
|
||||
m_Curvature: {x: 2, y: 11}
|
||||
m_BarrelClipping: 0.25
|
||||
m_Anamorphism: 0
|
||||
m_SensorSize: {x: 36, y: 24}
|
||||
m_LensShift: {x: 0, y: 0}
|
||||
m_NormalizedViewPortRect:
|
||||
serializedVersion: 2
|
||||
x: 0
|
||||
y: 0
|
||||
width: 1
|
||||
height: 1
|
||||
near clip plane: 0.3
|
||||
far clip plane: 1000
|
||||
field of view: 60
|
||||
orthographic: 0
|
||||
orthographic size: 5
|
||||
m_Depth: 0
|
||||
m_CullingMask:
|
||||
serializedVersion: 2
|
||||
m_Bits: 4294967295
|
||||
m_RenderingPath: -1
|
||||
m_TargetTexture: {fileID: 0}
|
||||
m_TargetDisplay: 0
|
||||
m_TargetEye: 3
|
||||
m_HDR: 1
|
||||
m_AllowMSAA: 1
|
||||
m_AllowDynamicResolution: 0
|
||||
m_ForceIntoRT: 0
|
||||
m_OcclusionCulling: 1
|
||||
m_StereoConvergence: 10
|
||||
m_StereoSeparation: 0.022
|
||||
--- !u!4 &1743332992
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1743332988}
|
||||
serializedVersion: 2
|
||||
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: 0}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!1 &1745121143
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@ -647,3 +784,4 @@ SceneRoots:
|
||||
- {fileID: 1337482712}
|
||||
- {fileID: 1935555105}
|
||||
- {fileID: 1503684055}
|
||||
- {fileID: 1743332992}
|
||||
|
||||
@ -1,26 +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: d6b6fabd3acfe76448ca16ffafdbe9f5, type: 3}
|
||||
m_Name: MainAudioSettings
|
||||
m_EditorClassIdentifier: DanroJump.Runtime::DanroJump.Audio.GameAudioSettings
|
||||
mixer: {fileID: 0}
|
||||
musicGroup: {fileID: 0}
|
||||
sfxGroup: {fileID: 0}
|
||||
uiGroup: {fileID: 0}
|
||||
gameplayGroup: {fileID: 0}
|
||||
ambienceGroup: {fileID: 0}
|
||||
musicLoop: {fileID: 0}
|
||||
musicLoopVolume: 1
|
||||
playMusicOnInitialize: 1
|
||||
defaultMusicCue: 0
|
||||
musicTracks: []
|
||||
eventBindings: []
|
||||
244
Assets/Scripts/Editor/VfxGeneratorEditor.cs
Normal file
244
Assets/Scripts/Editor/VfxGeneratorEditor.cs
Normal file
@ -0,0 +1,244 @@
|
||||
using System.IO;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace DanroJump.Editor
|
||||
{
|
||||
public static class VfxGeneratorEditor
|
||||
{
|
||||
private const string VfxFolderPath = "Assets/Resources/Vfx";
|
||||
private const string MaterialPath = VfxFolderPath + "/ParticleDefaultMaterial.mat";
|
||||
|
||||
private static readonly string[] PrefabNames = {
|
||||
"VFX_Jump",
|
||||
"VFX_CoinCollected",
|
||||
"VFX_PlayerDeath",
|
||||
"VFX_PrizeWin",
|
||||
"VFX_ComError"
|
||||
};
|
||||
|
||||
[InitializeOnLoadMethod]
|
||||
private static void InitializeOnLoad()
|
||||
{
|
||||
// Запускаем генерацию только если хотя бы одного файла не хватает
|
||||
bool missing = false;
|
||||
foreach (var name in PrefabNames)
|
||||
{
|
||||
if (!File.Exists($"{VfxFolderPath}/{name}.prefab"))
|
||||
{
|
||||
missing = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (missing)
|
||||
{
|
||||
GenerateAssets();
|
||||
}
|
||||
}
|
||||
|
||||
[MenuItem("Tools/Generate VFX Assets")]
|
||||
public static void GenerateAssets()
|
||||
{
|
||||
if (!Directory.Exists(VfxFolderPath))
|
||||
{
|
||||
Directory.CreateDirectory(VfxFolderPath);
|
||||
AssetDatabase.Refresh();
|
||||
}
|
||||
|
||||
var material = GetOrCreateParticleMaterial();
|
||||
if (material == null)
|
||||
{
|
||||
Debug.LogError("[VfxGenerator] Failed to find or create a compatible particle material.");
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var name in PrefabNames)
|
||||
{
|
||||
var go = new GameObject(name);
|
||||
var ps = go.AddComponent<ParticleSystem>();
|
||||
|
||||
// Настраиваем рендерер и материал
|
||||
var psr = go.GetComponent<ParticleSystemRenderer>();
|
||||
if (psr != null)
|
||||
{
|
||||
psr.sharedMaterial = material;
|
||||
}
|
||||
|
||||
// Общая базовая настройка
|
||||
var main = ps.main;
|
||||
main.loop = false;
|
||||
main.playOnAwake = false;
|
||||
|
||||
var emission = ps.emission;
|
||||
emission.rateOverTime = 0;
|
||||
|
||||
var colorOverLifetime = ps.colorOverLifetime;
|
||||
colorOverLifetime.enabled = true;
|
||||
|
||||
// Специфические настройки для каждого эффекта
|
||||
switch (name)
|
||||
{
|
||||
case "VFX_Jump":
|
||||
main.startColor = new Color(0.9f, 0.9f, 0.9f, 0.5f);
|
||||
main.startSize = new ParticleSystem.MinMaxCurve(0.08f, 0.22f);
|
||||
main.startSpeed = new ParticleSystem.MinMaxCurve(1.5f, 3.5f);
|
||||
main.startLifetime = new ParticleSystem.MinMaxCurve(0.2f, 0.45f);
|
||||
main.duration = 0.25f;
|
||||
main.gravityModifier = 0.6f;
|
||||
|
||||
var shapeCone = ps.shape;
|
||||
shapeCone.shapeType = ParticleSystemShapeType.Cone;
|
||||
shapeCone.angle = 35f;
|
||||
shapeCone.radius = 0.15f;
|
||||
shapeCone.rotation = new Vector3(90f, 0f, 0f);
|
||||
|
||||
emission.SetBursts(new ParticleSystem.Burst[] { new ParticleSystem.Burst(0f, 12) });
|
||||
|
||||
var gradientJump = new Gradient();
|
||||
gradientJump.SetKeys(
|
||||
new GradientColorKey[] { new GradientColorKey(Color.white, 0f), new GradientColorKey(Color.white, 1f) },
|
||||
new GradientAlphaKey[] { new GradientAlphaKey(0.6f, 0f), new GradientAlphaKey(0f, 1f) }
|
||||
);
|
||||
colorOverLifetime.color = gradientJump;
|
||||
break;
|
||||
|
||||
case "VFX_CoinCollected":
|
||||
main.startColor = new Color(1.0f, 0.85f, 0.0f, 0.9f);
|
||||
main.startSize = new ParticleSystem.MinMaxCurve(0.1f, 0.25f);
|
||||
main.startSpeed = new ParticleSystem.MinMaxCurve(2f, 4f);
|
||||
main.startLifetime = new ParticleSystem.MinMaxCurve(0.3f, 0.6f);
|
||||
main.duration = 0.3f;
|
||||
main.gravityModifier = -0.2f;
|
||||
|
||||
var shapeSphereCoin = ps.shape;
|
||||
shapeSphereCoin.shapeType = ParticleSystemShapeType.Sphere;
|
||||
shapeSphereCoin.radius = 0.1f;
|
||||
|
||||
emission.SetBursts(new ParticleSystem.Burst[] { new ParticleSystem.Burst(0f, 18) });
|
||||
|
||||
var gradientCoin = new Gradient();
|
||||
gradientCoin.SetKeys(
|
||||
new GradientColorKey[] { new GradientColorKey(new Color(1f, 0.9f, 0.2f), 0f), new GradientColorKey(new Color(1f, 0.5f, 0f), 1f) },
|
||||
new GradientAlphaKey[] { new GradientAlphaKey(0.9f, 0f), new GradientAlphaKey(0f, 1f) }
|
||||
);
|
||||
colorOverLifetime.color = gradientCoin;
|
||||
break;
|
||||
|
||||
case "VFX_PlayerDeath":
|
||||
main.startColor = new Color(0.8f, 0.1f, 0.1f, 0.8f);
|
||||
main.startSize = new ParticleSystem.MinMaxCurve(0.15f, 0.35f);
|
||||
main.startSpeed = new ParticleSystem.MinMaxCurve(3f, 7f);
|
||||
main.startLifetime = new ParticleSystem.MinMaxCurve(0.4f, 0.8f);
|
||||
main.duration = 0.5f;
|
||||
main.gravityModifier = 0.8f;
|
||||
|
||||
var shapeSphereDeath = ps.shape;
|
||||
shapeSphereDeath.shapeType = ParticleSystemShapeType.Sphere;
|
||||
shapeSphereDeath.radius = 0.25f;
|
||||
|
||||
emission.SetBursts(new ParticleSystem.Burst[] { new ParticleSystem.Burst(0f, 35) });
|
||||
|
||||
var gradientDeath = new Gradient();
|
||||
gradientDeath.SetKeys(
|
||||
new GradientColorKey[] { new GradientColorKey(new Color(0.9f, 0.2f, 0.2f), 0f), new GradientColorKey(new Color(0.3f, 0.3f, 0.3f), 1f) },
|
||||
new GradientAlphaKey[] { new GradientAlphaKey(0.9f, 0f), new GradientAlphaKey(0f, 1f) }
|
||||
);
|
||||
colorOverLifetime.color = gradientDeath;
|
||||
break;
|
||||
|
||||
case "VFX_PrizeWin":
|
||||
main.startColor = new ParticleSystem.MinMaxGradient(
|
||||
new Color(0.2f, 0.6f, 1.0f),
|
||||
new Color(1.0f, 0.2f, 0.6f)
|
||||
);
|
||||
main.startSize = new ParticleSystem.MinMaxCurve(0.12f, 0.28f);
|
||||
main.startSpeed = new ParticleSystem.MinMaxCurve(4f, 8f);
|
||||
main.startLifetime = new ParticleSystem.MinMaxCurve(0.6f, 1.2f);
|
||||
main.duration = 0.8f;
|
||||
main.gravityModifier = 0.4f;
|
||||
|
||||
var shapeHemiPrize = ps.shape;
|
||||
shapeHemiPrize.shapeType = ParticleSystemShapeType.Hemisphere;
|
||||
shapeHemiPrize.radius = 0.3f;
|
||||
shapeHemiPrize.rotation = new Vector3(-90f, 0f, 0f);
|
||||
|
||||
emission.SetBursts(new ParticleSystem.Burst[] { new ParticleSystem.Burst(0f, 50) });
|
||||
|
||||
var gradientPrize = new Gradient();
|
||||
gradientPrize.SetKeys(
|
||||
new GradientColorKey[] { new GradientColorKey(Color.white, 0f), new GradientColorKey(Color.white, 1f) },
|
||||
new GradientAlphaKey[] { new GradientAlphaKey(0.9f, 0f), new GradientAlphaKey(0f, 1f) }
|
||||
);
|
||||
colorOverLifetime.color = gradientPrize;
|
||||
break;
|
||||
|
||||
case "VFX_ComError":
|
||||
main.startColor = new Color(1.0f, 0.3f, 0.0f, 0.9f);
|
||||
main.startSize = new ParticleSystem.MinMaxCurve(0.06f, 0.18f);
|
||||
main.startSpeed = new ParticleSystem.MinMaxCurve(3f, 6f);
|
||||
main.startLifetime = new ParticleSystem.MinMaxCurve(0.25f, 0.5f);
|
||||
main.duration = 0.4f;
|
||||
main.gravityModifier = 0.3f;
|
||||
|
||||
var shapeConeError = ps.shape;
|
||||
shapeConeError.shapeType = ParticleSystemShapeType.Cone;
|
||||
shapeConeError.angle = 60f;
|
||||
shapeConeError.radius = 0.1f;
|
||||
|
||||
emission.SetBursts(new ParticleSystem.Burst[] { new ParticleSystem.Burst(0f, 20) });
|
||||
|
||||
var gradientError = new Gradient();
|
||||
gradientError.SetKeys(
|
||||
new GradientColorKey[] { new GradientColorKey(new Color(1f, 0.5f, 0f), 0f), new GradientColorKey(new Color(0.8f, 0.1f, 0f), 1f) },
|
||||
new GradientAlphaKey[] { new GradientAlphaKey(0.9f, 0f), new GradientAlphaKey(0f, 1f) }
|
||||
);
|
||||
colorOverLifetime.color = gradientError;
|
||||
break;
|
||||
}
|
||||
|
||||
// Сохраняем как префаб
|
||||
var localPath = $"{VfxFolderPath}/{name}.prefab";
|
||||
PrefabUtility.SaveAsPrefabAsset(go, localPath);
|
||||
Object.DestroyImmediate(go);
|
||||
}
|
||||
|
||||
AssetDatabase.SaveAssets();
|
||||
AssetDatabase.Refresh();
|
||||
Debug.Log("[VfxGenerator] All particle prefabs generated successfully under Assets/Resources/Vfx!");
|
||||
}
|
||||
|
||||
private static Material GetOrCreateParticleMaterial()
|
||||
{
|
||||
var existingMat = AssetDatabase.LoadAssetAtPath<Material>(MaterialPath);
|
||||
if (existingMat != null)
|
||||
{
|
||||
return existingMat;
|
||||
}
|
||||
|
||||
var shader = Shader.Find("Universal Render Pipeline/Particles/2D Unlit");
|
||||
if (shader == null)
|
||||
{
|
||||
shader = Shader.Find("Universal Render Pipeline/Particles/Unlit");
|
||||
}
|
||||
if (shader == null)
|
||||
{
|
||||
shader = Shader.Find("Sprites/Default");
|
||||
}
|
||||
|
||||
var material = new Material(shader);
|
||||
var tex = Resources.GetBuiltinResource<Texture2D>("Default-Particle.tif");
|
||||
if (tex != null)
|
||||
{
|
||||
material.mainTexture = tex;
|
||||
if (material.HasProperty("_BaseMap"))
|
||||
{
|
||||
material.SetTexture("_BaseMap", tex);
|
||||
}
|
||||
}
|
||||
|
||||
AssetDatabase.CreateAsset(material, MaterialPath);
|
||||
return material;
|
||||
}
|
||||
}
|
||||
}
|
||||
2
Assets/Scripts/Editor/VfxGeneratorEditor.cs.meta
Normal file
2
Assets/Scripts/Editor/VfxGeneratorEditor.cs.meta
Normal file
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a9b14f94ed3a6fe49b18fcb6d8058bf2
|
||||
@ -130,13 +130,20 @@ namespace DanroJump.Audio
|
||||
{
|
||||
if (settings?.Mixer == null)
|
||||
{
|
||||
UnityEngine.Debug.LogWarning("[GameAudioService] Cannot apply volumes: settings or Mixer is null.");
|
||||
return;
|
||||
}
|
||||
|
||||
var musicVolume = serviceSettings != null ? serviceSettings.GetFloat(ServiceSettingsKeys.MusicVolume) : 1f;
|
||||
var soundsVolume = serviceSettings != null ? serviceSettings.GetFloat(ServiceSettingsKeys.SoundsVolume) : 1f;
|
||||
settings.Mixer.SetFloat(MusicVolumeParameter, LinearToDecibels(musicVolume));
|
||||
settings.Mixer.SetFloat(SoundsVolumeParameter, LinearToDecibels(soundsVolume));
|
||||
|
||||
float musicDb = LinearToDecibels(musicVolume);
|
||||
float soundsDb = LinearToDecibels(soundsVolume);
|
||||
|
||||
bool musicOk = settings.Mixer.SetFloat(MusicVolumeParameter, musicDb);
|
||||
bool soundsOk = settings.Mixer.SetFloat(SoundsVolumeParameter, soundsDb);
|
||||
|
||||
UnityEngine.Debug.Log($"[GameAudioService] Applied volumes: Music = {musicVolume * 100:0}% ({musicDb:0.##} dB) [status: {musicOk}], Sounds = {soundsVolume * 100:0}% ({soundsDb:0.##} dB) [status: {soundsOk}]");
|
||||
}
|
||||
|
||||
public static float LinearToDecibels(float value)
|
||||
|
||||
@ -292,7 +292,7 @@ namespace DanroJump.Gameplay
|
||||
: 0;
|
||||
}
|
||||
|
||||
private bool IsContinueEnabled()
|
||||
public bool IsContinueEnabled()
|
||||
{
|
||||
return serviceSettings != null && serviceSettings.GetBool(ServiceSettingsKeys.CanContinueGame);
|
||||
}
|
||||
|
||||
@ -1948,6 +1948,9 @@ namespace DanroJump.Hardware.Com
|
||||
Send("2130", true);
|
||||
}
|
||||
|
||||
// Даем фоновому потоку чтения время выйти из ReadLine по таймауту (который равен 50мс)
|
||||
System.Threading.Thread.Sleep(80);
|
||||
|
||||
ClosePort();
|
||||
localCts?.Dispose();
|
||||
localCts = null;
|
||||
@ -2022,9 +2025,8 @@ namespace DanroJump.Hardware.Com
|
||||
}
|
||||
catch (Exception exception) when (exception is IOException || exception is InvalidOperationException)
|
||||
{
|
||||
LogWarning($"{PortName} disconnected: {exception.Message}");
|
||||
NotifyDisconnected();
|
||||
break;
|
||||
LogWarning($"{PortName} connection lost: {exception.Message}. Reconnecting...");
|
||||
await ReconnectAsync(token);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
@ -2313,21 +2315,44 @@ namespace DanroJump.Hardware.Com
|
||||
LastInputBits = DefaultInputBits;
|
||||
ClosePort();
|
||||
|
||||
await UniTask.Delay(500, DelayType.Realtime, PlayerLoopTiming.Update, token);
|
||||
await UniTask.SwitchToThreadPool();
|
||||
if (!OpenPort())
|
||||
int retryCount = 0;
|
||||
const int maxRetries = 10;
|
||||
|
||||
while (!token.IsCancellationRequested && retryCount < maxRetries)
|
||||
{
|
||||
NotifyDisconnected();
|
||||
return;
|
||||
await UniTask.Delay(1000, DelayType.Realtime, PlayerLoopTiming.Update, token);
|
||||
if (token.IsCancellationRequested)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
await UniTask.SwitchToThreadPool();
|
||||
if (token.IsCancellationRequested)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (OpenPort())
|
||||
{
|
||||
LogWarning($"{PortName} reconnected successfully after {retryCount + 1} retries.");
|
||||
if (useEncryptedHandshake)
|
||||
{
|
||||
await RunHandshakeAsync(token);
|
||||
}
|
||||
else
|
||||
{
|
||||
MarkOperational();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
retryCount++;
|
||||
LogWarning($"{PortName} reconnect attempt {retryCount} failed. Retrying...");
|
||||
}
|
||||
|
||||
if (useEncryptedHandshake)
|
||||
if (!token.IsCancellationRequested)
|
||||
{
|
||||
await RunHandshakeAsync(token);
|
||||
}
|
||||
else
|
||||
{
|
||||
MarkOperational();
|
||||
NotifyDisconnected();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
37
Assets/Scripts/Runtime/Prizes/GameplaySessionRecord.cs
Normal file
37
Assets/Scripts/Runtime/Prizes/GameplaySessionRecord.cs
Normal file
@ -0,0 +1,37 @@
|
||||
using System;
|
||||
|
||||
namespace DanroJump.Prizes
|
||||
{
|
||||
/// <summary>
|
||||
/// Запись о сыгранной игровой сессии для эксплуатационной истории.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public sealed class GameplaySessionRecord
|
||||
{
|
||||
public GameplaySessionRecord(
|
||||
string sessionId,
|
||||
int score,
|
||||
int coins,
|
||||
float maxHeight,
|
||||
int deathCount,
|
||||
PrizeRewardKind rewardKind,
|
||||
DateTime timestamp)
|
||||
{
|
||||
SessionId = sessionId ?? string.Empty;
|
||||
Score = score;
|
||||
Coins = coins;
|
||||
MaxHeight = maxHeight;
|
||||
DeathCount = deathCount;
|
||||
RewardKind = rewardKind;
|
||||
Timestamp = timestamp;
|
||||
}
|
||||
|
||||
public string SessionId { get; }
|
||||
public int Score { get; }
|
||||
public int Coins { get; }
|
||||
public float MaxHeight { get; }
|
||||
public int DeathCount { get; }
|
||||
public PrizeRewardKind RewardKind { get; }
|
||||
public DateTime Timestamp { get; }
|
||||
}
|
||||
}
|
||||
@ -12,6 +12,7 @@ namespace DanroJump.Prizes
|
||||
|
||||
PrizeSessionRecord ActiveSession { get; }
|
||||
IReadOnlyList<PrizeSessionRecord> History { get; }
|
||||
IReadOnlyList<GameplaySessionRecord> GameplayHistory { get; }
|
||||
int StartedCount { get; }
|
||||
int CompletedCount { get; }
|
||||
int FailedCount { get; }
|
||||
@ -29,7 +30,14 @@ namespace DanroJump.Prizes
|
||||
bool MarkActiveSessionShown();
|
||||
bool CompleteActiveSession(string note = null);
|
||||
bool FailActiveSession(string reason);
|
||||
void RecordGameplaySession(int score, int coins);
|
||||
void RecordGameplaySession(
|
||||
string sessionId,
|
||||
int score,
|
||||
int coins,
|
||||
float maxHeight,
|
||||
int deathCount,
|
||||
PrizeRewardKind rewardKind
|
||||
);
|
||||
void RecordQrShow();
|
||||
void RecordComError();
|
||||
void RecordPhysicalDispense(bool success);
|
||||
|
||||
@ -65,6 +65,27 @@ namespace DanroJump.Prizes
|
||||
}
|
||||
}
|
||||
|
||||
var gameplayHistory = new List<GameplaySessionRecord>();
|
||||
if (data.gameplayHistory != null)
|
||||
{
|
||||
foreach (var entry in data.gameplayHistory)
|
||||
{
|
||||
if (entry == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
gameplayHistory.Add(new GameplaySessionRecord(
|
||||
entry.sessionId,
|
||||
entry.score,
|
||||
entry.coins,
|
||||
entry.maxHeight,
|
||||
entry.deathCount,
|
||||
entry.rewardKind,
|
||||
FromUtcTicks(entry.timestampTicks)));
|
||||
}
|
||||
}
|
||||
|
||||
snapshot = new PrizeSessionStateSnapshot(
|
||||
history,
|
||||
data.issuedSessionIds ?? new List<string>(),
|
||||
@ -74,6 +95,7 @@ namespace DanroJump.Prizes
|
||||
data.failedCount,
|
||||
data.duplicateBlockedCount,
|
||||
data.fallbackSessionCounter,
|
||||
gameplayHistory,
|
||||
data.totalGamesPlayed,
|
||||
data.totalScore,
|
||||
data.totalCoins,
|
||||
@ -153,6 +175,28 @@ namespace DanroJump.Prizes
|
||||
});
|
||||
}
|
||||
|
||||
if (snapshot.GameplayHistory != null)
|
||||
{
|
||||
foreach (var record in snapshot.GameplayHistory)
|
||||
{
|
||||
if (record == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
data.gameplayHistory.Add(new PrizeSessionStateSaveData.GameplayEntry
|
||||
{
|
||||
sessionId = record.SessionId,
|
||||
score = record.Score,
|
||||
coins = record.Coins,
|
||||
maxHeight = record.MaxHeight,
|
||||
deathCount = record.DeathCount,
|
||||
rewardKind = record.RewardKind,
|
||||
timestampTicks = record.Timestamp.Ticks
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
WriteAllTextSafely(Path, JsonUtility.ToJson(data, true));
|
||||
return true;
|
||||
}
|
||||
@ -248,6 +292,7 @@ namespace DanroJump.Prizes
|
||||
public int comErrors;
|
||||
public List<string> issuedSessionIds = new();
|
||||
public List<Entry> history = new();
|
||||
public List<GameplayEntry> gameplayHistory = new();
|
||||
|
||||
[Serializable]
|
||||
public sealed class Entry
|
||||
@ -263,6 +308,18 @@ namespace DanroJump.Prizes
|
||||
public long updatedAtUtcTicks;
|
||||
public string note = string.Empty;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public sealed class GameplayEntry
|
||||
{
|
||||
public string sessionId = string.Empty;
|
||||
public int score;
|
||||
public int coins;
|
||||
public float maxHeight;
|
||||
public int deathCount;
|
||||
public PrizeRewardKind rewardKind;
|
||||
public long timestampTicks;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -39,12 +39,20 @@ namespace DanroJump.Prizes
|
||||
|
||||
public PrizeFlowResult StartPrizeFlow(GameplaySession session)
|
||||
{
|
||||
LastResult = EvaluateCompletedSession(session);
|
||||
|
||||
if (session != null && sessionState != null)
|
||||
{
|
||||
sessionState.RecordGameplaySession(session.Score, session.Coins);
|
||||
sessionState.RecordGameplaySession(
|
||||
session.SessionId,
|
||||
session.Score,
|
||||
session.Coins,
|
||||
session.MaxRunHeight,
|
||||
session.DeathCount,
|
||||
LastResult.RewardKind
|
||||
);
|
||||
}
|
||||
|
||||
LastResult = EvaluateCompletedSession(session);
|
||||
if (LastResult.HasPrize && sessionState != null &&
|
||||
!sessionState.TryBeginSession(LastResult, out _))
|
||||
{
|
||||
|
||||
@ -11,8 +11,10 @@ namespace DanroJump.Prizes
|
||||
public sealed class PrizeSessionStateService : IPrizeSessionStateService
|
||||
{
|
||||
private const string RecoveryFailureNote = "Сессия восстановлена после перезапуска до завершения выдачи.";
|
||||
private const int MaxHistorySize = 50;
|
||||
|
||||
private readonly List<PrizeSessionRecord> history = new();
|
||||
private readonly List<GameplaySessionRecord> gameplayHistory = new();
|
||||
private readonly HashSet<string> issuedSessionIds = new(StringComparer.Ordinal);
|
||||
private readonly IPrizeSessionStateRepository repository;
|
||||
private int fallbackSessionCounter;
|
||||
@ -38,6 +40,7 @@ namespace DanroJump.Prizes
|
||||
|
||||
public PrizeSessionRecord ActiveSession { get; private set; }
|
||||
public IReadOnlyList<PrizeSessionRecord> History => history;
|
||||
public IReadOnlyList<GameplaySessionRecord> GameplayHistory => gameplayHistory;
|
||||
public int StartedCount { get; private set; }
|
||||
public int CompletedCount { get; private set; }
|
||||
public int FailedCount { get; private set; }
|
||||
@ -128,8 +131,30 @@ namespace DanroJump.Prizes
|
||||
return $"Игр: {TotalGamesPlayed}. Очков всего: {TotalScore}. Монет всего: {TotalCoins}. QR показов: {QrShows}. Физич. выдач: {PhysicalDispenses} (ошибок: {PhysicalDispenseFailures}). COM-ошибок: {ComErrors}. Призовые сессии: начато {StartedCount}, завершено {CompletedCount}, ошибок {FailedCount}, повторов заблокировано {DuplicateBlockedCount}. {activeText} {lastText}";
|
||||
}
|
||||
|
||||
public void RecordGameplaySession(int score, int coins)
|
||||
public void RecordGameplaySession(
|
||||
string sessionId,
|
||||
int score,
|
||||
int coins,
|
||||
float maxHeight,
|
||||
int deathCount,
|
||||
PrizeRewardKind rewardKind)
|
||||
{
|
||||
var record = new GameplaySessionRecord(
|
||||
sessionId,
|
||||
score,
|
||||
coins,
|
||||
maxHeight,
|
||||
deathCount,
|
||||
rewardKind,
|
||||
DateTime.UtcNow
|
||||
);
|
||||
|
||||
gameplayHistory.Add(record);
|
||||
if (gameplayHistory.Count > MaxHistorySize)
|
||||
{
|
||||
gameplayHistory.RemoveAt(0);
|
||||
}
|
||||
|
||||
TotalGamesPlayed++;
|
||||
TotalScore += score;
|
||||
TotalCoins += coins;
|
||||
@ -200,8 +225,20 @@ namespace DanroJump.Prizes
|
||||
}
|
||||
|
||||
history.Clear();
|
||||
gameplayHistory.Clear();
|
||||
issuedSessionIds.Clear();
|
||||
|
||||
if (snapshot.GameplayHistory != null)
|
||||
{
|
||||
foreach (var record in snapshot.GameplayHistory)
|
||||
{
|
||||
if (record != null)
|
||||
{
|
||||
gameplayHistory.Add(record);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var record in snapshot.History)
|
||||
{
|
||||
if (record != null)
|
||||
@ -261,6 +298,7 @@ namespace DanroJump.Prizes
|
||||
FailedCount,
|
||||
DuplicateBlockedCount,
|
||||
fallbackSessionCounter,
|
||||
gameplayHistory.ToArray(),
|
||||
TotalGamesPlayed,
|
||||
TotalScore,
|
||||
TotalCoins,
|
||||
|
||||
@ -18,6 +18,7 @@ namespace DanroJump.Prizes
|
||||
int failedCount,
|
||||
int duplicateBlockedCount,
|
||||
int fallbackSessionCounter,
|
||||
IReadOnlyList<GameplaySessionRecord> gameplayHistory = null,
|
||||
int totalGamesPlayed = 0,
|
||||
int totalScore = 0,
|
||||
int totalCoins = 0,
|
||||
@ -34,6 +35,7 @@ namespace DanroJump.Prizes
|
||||
FailedCount = Math.Max(0, failedCount);
|
||||
DuplicateBlockedCount = Math.Max(0, duplicateBlockedCount);
|
||||
FallbackSessionCounter = Math.Max(0, fallbackSessionCounter);
|
||||
GameplayHistory = gameplayHistory?.Where(static record => record != null).ToArray() ?? Array.Empty<GameplaySessionRecord>();
|
||||
TotalGamesPlayed = Math.Max(0, totalGamesPlayed);
|
||||
TotalScore = Math.Max(0, totalScore);
|
||||
TotalCoins = Math.Max(0, totalCoins);
|
||||
@ -44,6 +46,7 @@ namespace DanroJump.Prizes
|
||||
}
|
||||
|
||||
public IReadOnlyList<PrizeSessionRecord> History { get; }
|
||||
public IReadOnlyList<GameplaySessionRecord> GameplayHistory { get; }
|
||||
public IReadOnlyCollection<string> IssuedSessionIds { get; }
|
||||
public string ActiveSessionId { get; }
|
||||
public int StartedCount { get; }
|
||||
|
||||
@ -5,9 +5,9 @@ using DanroJump.SceneFlow;
|
||||
namespace DanroJump.Settings
|
||||
{
|
||||
/// <summary>
|
||||
/// MonoBehaviour-фасад для вызова действий сервиса настроек из UI/Unity Events.
|
||||
/// MonoBehaviour-фасад для вызова действий приложения из UI/Unity Events.
|
||||
/// </summary>
|
||||
public sealed class ServiceSettingsActions : MonoBehaviour
|
||||
public sealed class AppUIFacade : MonoBehaviour
|
||||
{
|
||||
private IServiceSettingsService settings;
|
||||
private ISceneFlowService sceneFlow;
|
||||
@ -105,7 +105,7 @@ namespace DanroJump.Settings
|
||||
{
|
||||
if (sceneFlow == null)
|
||||
{
|
||||
Debug.LogWarning($"{nameof(ServiceSettingsActions)} requires {nameof(ISceneFlowService)} from DI.", this);
|
||||
Debug.LogWarning($"{nameof(AppUIFacade)} requires {nameof(ISceneFlowService)} from DI.", this);
|
||||
}
|
||||
|
||||
return sceneFlow;
|
||||
@ -1,4 +1,6 @@
|
||||
using System;
|
||||
using DanroJump.Prizes;
|
||||
using DanroJump.UI.MainMenu;
|
||||
|
||||
namespace DanroJump.Settings
|
||||
{
|
||||
@ -36,6 +38,10 @@ namespace DanroJump.Settings
|
||||
"Номер поддержки",
|
||||
"Открыто служебное окно номера поддержки автомата.",
|
||||
ServiceSettingsKeys.SupportNumber),
|
||||
ServiceSettingsKeys.SettingsPinButton => OpenSettingEditor(
|
||||
"PIN-код",
|
||||
"Открыто служебное окно изменения PIN-кода.",
|
||||
ServiceSettingsKeys.SettingsPin),
|
||||
ServiceSettingsKeys.CurrencyButton => OpenSettingEditor(
|
||||
"Валюта баланса",
|
||||
"Открыто служебное окно валюты денежного баланса.",
|
||||
@ -46,11 +52,11 @@ namespace DanroJump.Settings
|
||||
"Проверка hopper/выдачи"),
|
||||
ServiceSettingsKeys.LevelsPrizesButton => ServiceSettingsActionResult.Success(
|
||||
"Настройки призов",
|
||||
ServiceSettingsPrizeSummaryBuilder.Build(settings),
|
||||
PrizeInfoFormatter.Build(settings),
|
||||
ServiceSettingsKeys.PrizeLevels),
|
||||
ServiceSettingsKeys.QrSettingsButton => ServiceSettingsActionResult.Success(
|
||||
"Настройки QR",
|
||||
ServiceSettingsQrSummaryBuilder.Build(settings),
|
||||
QrInfoFormatter.Build(settings),
|
||||
ServiceSettingsKeys.QrPrizeTextSettings),
|
||||
ServiceSettingsKeys.StandSettingsButton => ServiceSettingsActionResult.Success(
|
||||
"Настройки витрины",
|
||||
|
||||
@ -29,15 +29,33 @@ namespace DanroJump.Settings
|
||||
$"- [{record.StartedAtUtc:yyyy-MM-dd HH:mm:ss}] {FormatReward(record.Result.RewardKind)} ({record.Result.Score}очк) -> {FormatStatus(record.Status)}{(string.IsNullOrWhiteSpace(record.Note) ? "" : ": " + record.Note)}"))
|
||||
: "История призов пуста.";
|
||||
|
||||
var gameplayHistory = prizeSessionState.GameplayHistory;
|
||||
var avgScore = gameplayHistory != null && gameplayHistory.Count > 0
|
||||
? gameplayHistory.Average(r => r.Score)
|
||||
: 0f;
|
||||
var avgCoins = gameplayHistory != null && gameplayHistory.Count > 0
|
||||
? gameplayHistory.Average(r => r.Coins)
|
||||
: 0f;
|
||||
var avgHeight = gameplayHistory != null && gameplayHistory.Count > 0
|
||||
? gameplayHistory.Average(r => r.MaxHeight)
|
||||
: 0f;
|
||||
|
||||
var recentGameplay = gameplayHistory != null && gameplayHistory.Count > 0
|
||||
? string.Join("\n", gameplayHistory.Skip(Math.Max(0, gameplayHistory.Count - 5)).Select(record =>
|
||||
$"- [{record.Timestamp:yyyy-MM-dd HH:mm:ss}] очков: {record.Score}, монет: {record.Coins}, высота: {record.MaxHeight:F1}м, смертей: {record.DeathCount}, приз: {FormatReward(record.RewardKind)}"))
|
||||
: "История игр пуста.";
|
||||
|
||||
prizeSummary = $"\n\n--- Эксплуатационная статистика ---\n" +
|
||||
$"Всего сыграно игр: {prizeSessionState.TotalGamesPlayed}\n" +
|
||||
$"Набрано очков всего: {prizeSessionState.TotalScore}\n" +
|
||||
$"Собрано монет всего: {prizeSessionState.TotalCoins}\n" +
|
||||
$"Средние показатели (последние сессии): очков {avgScore:F1}, монет {avgCoins:F1}, высота {avgHeight:F1}м\n" +
|
||||
$"Показов QR-кодов: {prizeSessionState.QrShows}\n" +
|
||||
$"Успешных физ. выдач: {prizeSessionState.PhysicalDispenses}\n" +
|
||||
$"Сбоев физ. выдач: {prizeSessionState.PhysicalDispenseFailures}\n" +
|
||||
$"Сбоев связи по COM: {prizeSessionState.ComErrors}\n" +
|
||||
$"Призовые сессии: начато {prizeSessionState.StartedCount}, завершено {prizeSessionState.CompletedCount}, сбоев {prizeSessionState.FailedCount}, повторов заблокировано {prizeSessionState.DuplicateBlockedCount}\n" +
|
||||
$"\n--- Последние Игры (до 5) ---\n{recentGameplay}\n" +
|
||||
$"\n--- Последние Призовые сессии (до 5) ---\n{recentHistory}";
|
||||
}
|
||||
else
|
||||
|
||||
@ -8,8 +8,9 @@ namespace DanroJump.Settings
|
||||
{
|
||||
/// <summary>
|
||||
/// ProjectContext/SceneContext installer сервисных настроек.
|
||||
/// ProjectContext/SceneContext installer глобальных сервисов.
|
||||
/// </summary>
|
||||
public sealed class ServiceSettingsInstaller : MonoInstaller
|
||||
public sealed class AppServicesInstaller : MonoInstaller
|
||||
{
|
||||
[SerializeField] private string databaseAddress = ServiceSettingsAddressKeys.Database;
|
||||
[SerializeField] private ServiceSettingsDatabase fallbackDatabase;
|
||||
@ -29,7 +30,7 @@ namespace DanroJump.Settings
|
||||
|
||||
if (database == null)
|
||||
{
|
||||
Debug.LogError($"{nameof(ServiceSettingsInstaller)} could not load {nameof(ServiceSettingsDatabase)}.", this);
|
||||
Debug.LogError($"{nameof(AppServicesInstaller)} could not load {nameof(ServiceSettingsDatabase)}.", this);
|
||||
databaseProvider.Dispose();
|
||||
Container.BindInterfacesAndSelfTo<SceneFlowService>().AsSingle();
|
||||
return;
|
||||
@ -59,7 +60,7 @@ namespace DanroJump.Settings
|
||||
}
|
||||
|
||||
Container.BindInterfacesAndSelfTo<GameAudioService>().AsSingle().NonLazy();
|
||||
Container.BindInterfacesTo<ServiceSettingsSceneInjector>().AsSingle().WithArguments(bindActionsInScene).NonLazy();
|
||||
Container.BindInterfacesTo<AppUIFacadeInjector>().AsSingle().WithArguments(bindActionsInScene).NonLazy();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -7,17 +7,17 @@ using Zenject;
|
||||
namespace DanroJump.Settings
|
||||
{
|
||||
/// <summary>
|
||||
/// Инжектит сценовые ServiceSettingsActions из ProjectContext без прямого глобального поиска объектов.
|
||||
/// Инжектит сценовые AppUIFacade из ProjectContext без прямого глобального поиска объектов.
|
||||
/// </summary>
|
||||
public sealed class ServiceSettingsSceneInjector : IInitializable, IDisposable
|
||||
public sealed class AppUIFacadeInjector : IInitializable, IDisposable
|
||||
{
|
||||
private readonly DiContainer container;
|
||||
private readonly bool injectActionsInScene;
|
||||
private readonly List<GameObject> rootObjects = new();
|
||||
private readonly List<ServiceSettingsActions> actions = new();
|
||||
private readonly List<AppUIFacade> actions = new();
|
||||
private readonly HashSet<EntityId> injectedEntityIds = new();
|
||||
|
||||
public ServiceSettingsSceneInjector(DiContainer container, bool injectActionsInScene)
|
||||
public AppUIFacadeInjector(DiContainer container, bool injectActionsInScene)
|
||||
{
|
||||
this.container = container;
|
||||
this.injectActionsInScene = injectActionsInScene;
|
||||
@ -36,8 +36,12 @@ namespace DanroJump.Settings
|
||||
public const string CanContinueGame = "gameplay.canContinueGame";
|
||||
public const string InactivityTimeout = "gameplay.inactivityTimeout";
|
||||
public const string GameDifficulty = "gameplay.gameDifficulty";
|
||||
|
||||
public const string RequireSettingsPin = "security.requirePin";
|
||||
public const string SettingsPin = "security.pin";
|
||||
|
||||
public const string StatisticsButton = "btn.statistics";
|
||||
public const string SettingsPinButton = "btn.settingsPin";
|
||||
public const string PhoneNumberButton = "btn.phoneNumber";
|
||||
public const string BigPrizeButton = "btn.bigPrize";
|
||||
public const string SupportNumberButton = "btn.supportNumber";
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
using DanroJump.Audio;
|
||||
|
||||
namespace DanroJump.UI.Gameplay
|
||||
{
|
||||
@ -16,15 +17,13 @@ namespace DanroJump.UI.Gameplay
|
||||
private readonly Label detailsLabel;
|
||||
private readonly Button continueButton;
|
||||
private readonly Button menuButton;
|
||||
private readonly IGameAudioService audioService;
|
||||
private float inputEnabledAtTime = float.NegativeInfinity;
|
||||
|
||||
public ContinueGameOverlayWindow(VisualElement root)
|
||||
public ContinueGameOverlayWindow(VisualElement root, IGameAudioService audioService = null)
|
||||
{
|
||||
this.root = root;
|
||||
if (this.root != null)
|
||||
{
|
||||
this.root.focusable = true;
|
||||
}
|
||||
this.audioService = audioService;
|
||||
|
||||
titleLabel = root?.Q<Label>("ContinueGameTitle");
|
||||
detailsLabel = root?.Q<Label>("ContinueGameDetails");
|
||||
@ -34,11 +33,15 @@ namespace DanroJump.UI.Gameplay
|
||||
if (continueButton != null)
|
||||
{
|
||||
continueButton.clicked += HandleContinueClicked;
|
||||
continueButton.RegisterCallback<FocusInEvent>(HandleButtonFocusIn);
|
||||
continueButton.RegisterCallback<FocusOutEvent>(HandleButtonFocusOut);
|
||||
}
|
||||
|
||||
if (menuButton != null)
|
||||
{
|
||||
menuButton.clicked += HandleMenuClicked;
|
||||
menuButton.RegisterCallback<FocusInEvent>(HandleButtonFocusIn);
|
||||
menuButton.RegisterCallback<FocusOutEvent>(HandleButtonFocusOut);
|
||||
}
|
||||
}
|
||||
|
||||
@ -78,7 +81,20 @@ namespace DanroJump.UI.Gameplay
|
||||
root.SetEnabled(true);
|
||||
IsOpen = true;
|
||||
inputEnabledAtTime = Time.unscaledTime + OpenInputGuardSeconds;
|
||||
root.Focus();
|
||||
|
||||
FocusDefaultButton();
|
||||
}
|
||||
|
||||
private void FocusDefaultButton()
|
||||
{
|
||||
if (continueButton != null && continueButton.enabledSelf)
|
||||
{
|
||||
continueButton.Focus();
|
||||
}
|
||||
else if (menuButton != null)
|
||||
{
|
||||
menuButton.Focus();
|
||||
}
|
||||
}
|
||||
|
||||
public void Close()
|
||||
@ -98,11 +114,35 @@ namespace DanroJump.UI.Gameplay
|
||||
if (continueButton != null)
|
||||
{
|
||||
continueButton.clicked -= HandleContinueClicked;
|
||||
continueButton.UnregisterCallback<FocusInEvent>(HandleButtonFocusIn);
|
||||
continueButton.UnregisterCallback<FocusOutEvent>(HandleButtonFocusOut);
|
||||
}
|
||||
|
||||
if (menuButton != null)
|
||||
{
|
||||
menuButton.clicked -= HandleMenuClicked;
|
||||
menuButton.UnregisterCallback<FocusInEvent>(HandleButtonFocusIn);
|
||||
menuButton.UnregisterCallback<FocusOutEvent>(HandleButtonFocusOut);
|
||||
}
|
||||
}
|
||||
|
||||
private static readonly Color FocusedButtonTint = new Color32(0xCE, 0xFF, 0x1A, 0xFF);
|
||||
private static readonly Color NormalButtonTint = Color.white;
|
||||
|
||||
private void HandleButtonFocusIn(FocusInEvent evt)
|
||||
{
|
||||
if (evt.currentTarget is Button button)
|
||||
{
|
||||
audioService?.Play(GameAudioEvent.UiNavigate);
|
||||
button.style.unityBackgroundImageTintColor = new StyleColor(FocusedButtonTint);
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleButtonFocusOut(FocusOutEvent evt)
|
||||
{
|
||||
if (evt.currentTarget is Button button)
|
||||
{
|
||||
button.style.unityBackgroundImageTintColor = new StyleColor(NormalButtonTint);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -203,7 +203,7 @@ namespace DanroJump.UI.Gameplay
|
||||
|
||||
prizeResultOverlay?.Dispose();
|
||||
prizeOverlayRoot = overlayRoot;
|
||||
prizeResultOverlay = new PrizeResultOverlayWindow(overlayRoot);
|
||||
prizeResultOverlay = new PrizeResultOverlayWindow(overlayRoot, audioService);
|
||||
prizeResultOverlay.ReturnRequested += HandlePrizeReturnRequested;
|
||||
}
|
||||
|
||||
@ -223,7 +223,7 @@ namespace DanroJump.UI.Gameplay
|
||||
|
||||
continueGameOverlay?.Dispose();
|
||||
continueOverlayRoot = overlayRoot;
|
||||
continueGameOverlay = new ContinueGameOverlayWindow(overlayRoot);
|
||||
continueGameOverlay = new ContinueGameOverlayWindow(overlayRoot, audioService);
|
||||
continueGameOverlay.ContinueRequested += HandleContinueRequested;
|
||||
continueGameOverlay.MenuRequested += HandleContinueMenuRequested;
|
||||
}
|
||||
@ -476,6 +476,12 @@ namespace DanroJump.UI.Gameplay
|
||||
return;
|
||||
}
|
||||
|
||||
if (!session.IsContinueEnabled())
|
||||
{
|
||||
continueGameOverlay?.Close();
|
||||
return;
|
||||
}
|
||||
|
||||
EnsureDocument();
|
||||
BindContinueOverlay();
|
||||
|
||||
|
||||
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using DanroJump.Hardware.Com;
|
||||
using DanroJump.Prizes;
|
||||
using DanroJump.Prizes.Qr;
|
||||
using DanroJump.Audio;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
@ -25,15 +26,13 @@ namespace DanroJump.UI.Gameplay
|
||||
private readonly Label qrMessageLabel;
|
||||
private readonly VisualElement prizeStandContainer;
|
||||
private readonly Button returnButton;
|
||||
private readonly IGameAudioService audioService;
|
||||
private float inputEnabledAtTime = float.NegativeInfinity;
|
||||
|
||||
public PrizeResultOverlayWindow(VisualElement root)
|
||||
public PrizeResultOverlayWindow(VisualElement root, IGameAudioService audioService = null)
|
||||
{
|
||||
this.root = root;
|
||||
if (this.root != null)
|
||||
{
|
||||
this.root.focusable = true;
|
||||
}
|
||||
this.audioService = audioService;
|
||||
|
||||
titleLabel = root?.Q<Label>("PrizeResultTitle");
|
||||
subtitleLabel = root?.Q<Label>("PrizeResultSubtitle");
|
||||
@ -57,6 +56,8 @@ namespace DanroJump.UI.Gameplay
|
||||
if (returnButton != null)
|
||||
{
|
||||
returnButton.clicked += HandleReturnClicked;
|
||||
returnButton.RegisterCallback<FocusInEvent>(HandleButtonFocusIn);
|
||||
returnButton.RegisterCallback<FocusOutEvent>(HandleButtonFocusOut);
|
||||
}
|
||||
}
|
||||
|
||||
@ -99,7 +100,11 @@ namespace DanroJump.UI.Gameplay
|
||||
root.SetEnabled(true);
|
||||
IsOpen = true;
|
||||
inputEnabledAtTime = Time.unscaledTime + OpenInputGuardSeconds;
|
||||
root.Focus();
|
||||
|
||||
if (returnButton != null)
|
||||
{
|
||||
returnButton.Focus();
|
||||
}
|
||||
}
|
||||
|
||||
public void Close()
|
||||
@ -196,6 +201,28 @@ namespace DanroJump.UI.Gameplay
|
||||
if (returnButton != null)
|
||||
{
|
||||
returnButton.clicked -= HandleReturnClicked;
|
||||
returnButton.UnregisterCallback<FocusInEvent>(HandleButtonFocusIn);
|
||||
returnButton.UnregisterCallback<FocusOutEvent>(HandleButtonFocusOut);
|
||||
}
|
||||
}
|
||||
|
||||
private static readonly Color FocusedButtonTint = new Color32(0xCE, 0xFF, 0x1A, 0xFF);
|
||||
private static readonly Color NormalButtonTint = Color.white;
|
||||
|
||||
private void HandleButtonFocusIn(FocusInEvent evt)
|
||||
{
|
||||
if (evt.currentTarget is Button button)
|
||||
{
|
||||
audioService?.Play(GameAudioEvent.UiNavigate);
|
||||
button.style.unityBackgroundImageTintColor = new StyleColor(FocusedButtonTint);
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleButtonFocusOut(FocusOutEvent evt)
|
||||
{
|
||||
if (evt.currentTarget is Button button)
|
||||
{
|
||||
button.style.unityBackgroundImageTintColor = new StyleColor(NormalButtonTint);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -138,6 +138,7 @@ namespace DanroJump.UI.MainMenu
|
||||
RegisterCreditCallbacks();
|
||||
RegisterInputActions();
|
||||
RefreshStaticLabels();
|
||||
audioService?.PlayMusic(GameMusicCue.Menu);
|
||||
FocusDefaultButtonNextFrameAsync(this.GetCancellationTokenOnDestroy()).Forget(Debug.LogException);
|
||||
}
|
||||
|
||||
@ -276,7 +277,8 @@ namespace DanroJump.UI.MainMenu
|
||||
var currentValue = serviceSettingsService.GetString(targetDefinition.Key);
|
||||
var profile = ResolveTextInputProfile(targetDefinition.Key);
|
||||
serviceTextInputModal.SetContext(
|
||||
targetDefinition,
|
||||
result.Title,
|
||||
targetDefinition.DisplayName,
|
||||
currentValue,
|
||||
profile,
|
||||
value =>
|
||||
@ -379,6 +381,7 @@ namespace DanroJump.UI.MainMenu
|
||||
{
|
||||
return settingKey switch
|
||||
{
|
||||
ServiceSettingsKeys.SettingsPin => new ArcadeStringInputProfile("0123456789", 4),
|
||||
ServiceSettingsKeys.SupportNumber => ArcadeStringInputProfile.Phone(),
|
||||
ServiceSettingsKeys.PrizePhoneNumber => ArcadeStringInputProfile.Phone(),
|
||||
ServiceSettingsKeys.Currency => ArcadeStringInputProfile.ShortText(maxLength: 10),
|
||||
@ -925,7 +928,14 @@ namespace DanroJump.UI.MainMenu
|
||||
audioService?.Play(GameAudioEvent.UiSubmit);
|
||||
ResolveServiceSettingsIfNeeded();
|
||||
|
||||
if (serviceTextInputModal != null && serviceTextInputModal.Root != null)
|
||||
bool requirePin = serviceSettings == null || serviceSettings.GetBool(ServiceSettingsKeys.RequireSettingsPin);
|
||||
string correctPin = serviceSettings != null ? serviceSettings.GetString(ServiceSettingsKeys.SettingsPin) : "1234";
|
||||
if (string.IsNullOrEmpty(correctPin))
|
||||
{
|
||||
correctPin = "1234";
|
||||
}
|
||||
|
||||
if (requirePin && serviceTextInputModal != null && serviceTextInputModal.Root != null)
|
||||
{
|
||||
var profile = new ArcadeStringInputProfile("0123456789", 4);
|
||||
serviceTextInputModal.SetContext(
|
||||
@ -935,7 +945,7 @@ namespace DanroJump.UI.MainMenu
|
||||
profile,
|
||||
pin =>
|
||||
{
|
||||
if (pin == "1234")
|
||||
if (pin == correctPin)
|
||||
{
|
||||
if (settingsModal != null && settingsModal.Root != null)
|
||||
{
|
||||
|
||||
@ -1,11 +1,12 @@
|
||||
using DanroJump.Prizes;
|
||||
using DanroJump.Settings;
|
||||
|
||||
namespace DanroJump.Settings
|
||||
namespace DanroJump.UI.MainMenu
|
||||
{
|
||||
/// <summary>
|
||||
/// Формирует операторскую сводку призовых уровней и legacy-флагов.
|
||||
/// </summary>
|
||||
internal static class ServiceSettingsPrizeSummaryBuilder
|
||||
internal static class PrizeInfoFormatter
|
||||
{
|
||||
public static string Build(IReadOnlyServiceSettings settings)
|
||||
{
|
||||
@ -1,11 +1,12 @@
|
||||
using DanroJump.Prizes.Qr;
|
||||
using DanroJump.Settings;
|
||||
|
||||
namespace DanroJump.Settings
|
||||
namespace DanroJump.UI.MainMenu
|
||||
{
|
||||
/// <summary>
|
||||
/// Формирует операторскую сводку QR-выдачи и коротких текстов призов.
|
||||
/// Формирует операторскую сводку по конфигурации QR-кодов.
|
||||
/// </summary>
|
||||
internal static class ServiceSettingsQrSummaryBuilder
|
||||
internal static class QrInfoFormatter
|
||||
{
|
||||
public static string Build(IReadOnlyServiceSettings settings)
|
||||
{
|
||||
@ -403,12 +403,19 @@ namespace DanroJump.UI.MainMenu
|
||||
: FormatAction(state.SelectedAction);
|
||||
}
|
||||
|
||||
RefreshActionButton(confirmButton, ArcadeStringInputAction.Confirm);
|
||||
RefreshActionButton(deleteButton, ArcadeStringInputAction.Delete);
|
||||
RefreshActionButton(cancelButton, ArcadeStringInputAction.Cancel);
|
||||
bool isAnyActionSelected = false;
|
||||
|
||||
RefreshActionButton(confirmButton, ArcadeStringInputAction.Confirm, ref isAnyActionSelected);
|
||||
RefreshActionButton(deleteButton, ArcadeStringInputAction.Delete, ref isAnyActionSelected);
|
||||
RefreshActionButton(cancelButton, ArcadeStringInputAction.Cancel, ref isAnyActionSelected);
|
||||
|
||||
if (!isAnyActionSelected && Root != null)
|
||||
{
|
||||
Root.Focus();
|
||||
}
|
||||
}
|
||||
|
||||
private void RefreshActionButton(Button button, ArcadeStringInputAction action)
|
||||
private void RefreshActionButton(Button button, ArcadeStringInputAction action, ref bool isAnyActionSelected)
|
||||
{
|
||||
if (button == null)
|
||||
{
|
||||
@ -418,6 +425,8 @@ namespace DanroJump.UI.MainMenu
|
||||
if (state.IsActionSelected(action))
|
||||
{
|
||||
button.AddToClassList(ActiveActionClass);
|
||||
button.Focus();
|
||||
isAnyActionSelected = true;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@ -3,209 +3,51 @@ using UnityEngine;
|
||||
namespace DanroJump.Vfx
|
||||
{
|
||||
/// <summary>
|
||||
/// Служба визуальных эффектов, программно создающая и настраивающая системы частиц Unity.
|
||||
/// Позволяет избежать зависимости от префабов в редакторе и обеспечивает высокую переносимость.
|
||||
/// Служба визуальных эффектов, загружающая и инстанцирующая префабы систем частиц из Resources/Vfx/.
|
||||
/// </summary>
|
||||
public sealed class GameVfxService : IVfxService
|
||||
{
|
||||
public void SpawnJumpEffect(Vector3 position)
|
||||
{
|
||||
var go = new GameObject("VFX_Jump");
|
||||
go.transform.position = position;
|
||||
var ps = go.AddComponent<ParticleSystem>();
|
||||
|
||||
var main = ps.main;
|
||||
main.startColor = new Color(0.9f, 0.9f, 0.9f, 0.5f);
|
||||
main.startSize = new ParticleSystem.MinMaxCurve(0.08f, 0.22f);
|
||||
main.startSpeed = new ParticleSystem.MinMaxCurve(1.5f, 3.5f);
|
||||
main.startLifetime = new ParticleSystem.MinMaxCurve(0.2f, 0.45f);
|
||||
main.duration = 0.25f;
|
||||
main.loop = false;
|
||||
main.gravityModifier = 0.6f;
|
||||
|
||||
var shape = ps.shape;
|
||||
shape.shapeType = ParticleSystemShapeType.Cone;
|
||||
shape.angle = 35f;
|
||||
shape.radius = 0.15f;
|
||||
shape.rotation = new Vector3(90f, 0f, 0f); // Направление вниз под ноги
|
||||
|
||||
var emission = ps.emission;
|
||||
emission.rateOverTime = 0;
|
||||
emission.SetBursts(new ParticleSystem.Burst[] { new ParticleSystem.Burst(0f, 12) });
|
||||
|
||||
var colorOverLifetime = ps.colorOverLifetime;
|
||||
colorOverLifetime.enabled = true;
|
||||
var gradient = new Gradient();
|
||||
gradient.SetKeys(
|
||||
new GradientColorKey[] { new GradientColorKey(Color.white, 0f), new GradientColorKey(Color.white, 1f) },
|
||||
new GradientAlphaKey[] { new GradientAlphaKey(0.6f, 0f), new GradientAlphaKey(0f, 1f) }
|
||||
);
|
||||
colorOverLifetime.color = gradient;
|
||||
|
||||
ps.Play();
|
||||
if (Application.isPlaying)
|
||||
{
|
||||
Object.Destroy(go, main.duration + main.startLifetime.constantMax);
|
||||
}
|
||||
SpawnVfx("VFX_Jump", position);
|
||||
}
|
||||
|
||||
public void SpawnCoinCollectedEffect(Vector3 position)
|
||||
{
|
||||
var go = new GameObject("VFX_CoinCollected");
|
||||
go.transform.position = position;
|
||||
var ps = go.AddComponent<ParticleSystem>();
|
||||
|
||||
var main = ps.main;
|
||||
main.startColor = new Color(1.0f, 0.85f, 0.0f, 0.9f); // Золотой цвет
|
||||
main.startSize = new ParticleSystem.MinMaxCurve(0.1f, 0.25f);
|
||||
main.startSpeed = new ParticleSystem.MinMaxCurve(2f, 4f);
|
||||
main.startLifetime = new ParticleSystem.MinMaxCurve(0.3f, 0.6f);
|
||||
main.duration = 0.3f;
|
||||
main.loop = false;
|
||||
main.gravityModifier = -0.2f; // Легкий подъем вверх
|
||||
|
||||
var shape = ps.shape;
|
||||
shape.shapeType = ParticleSystemShapeType.Sphere;
|
||||
shape.radius = 0.1f;
|
||||
|
||||
var emission = ps.emission;
|
||||
emission.rateOverTime = 0;
|
||||
emission.SetBursts(new ParticleSystem.Burst[] { new ParticleSystem.Burst(0f, 18) });
|
||||
|
||||
var colorOverLifetime = ps.colorOverLifetime;
|
||||
colorOverLifetime.enabled = true;
|
||||
var gradient = new Gradient();
|
||||
gradient.SetKeys(
|
||||
new GradientColorKey[] { new GradientColorKey(new Color(1f, 0.9f, 0.2f), 0f), new GradientColorKey(new Color(1f, 0.5f, 0f), 1f) },
|
||||
new GradientAlphaKey[] { new GradientAlphaKey(0.9f, 0f), new GradientAlphaKey(0f, 1f) }
|
||||
);
|
||||
colorOverLifetime.color = gradient;
|
||||
|
||||
ps.Play();
|
||||
if (Application.isPlaying)
|
||||
{
|
||||
Object.Destroy(go, main.duration + main.startLifetime.constantMax);
|
||||
}
|
||||
SpawnVfx("VFX_CoinCollected", position);
|
||||
}
|
||||
|
||||
public void SpawnPlayerDeathEffect(Vector3 position)
|
||||
{
|
||||
var go = new GameObject("VFX_PlayerDeath");
|
||||
go.transform.position = position;
|
||||
var ps = go.AddComponent<ParticleSystem>();
|
||||
|
||||
var main = ps.main;
|
||||
main.startColor = new Color(0.8f, 0.1f, 0.1f, 0.8f); // Красный / серый взрыв
|
||||
main.startSize = new ParticleSystem.MinMaxCurve(0.15f, 0.35f);
|
||||
main.startSpeed = new ParticleSystem.MinMaxCurve(3f, 7f);
|
||||
main.startLifetime = new ParticleSystem.MinMaxCurve(0.4f, 0.8f);
|
||||
main.duration = 0.5f;
|
||||
main.loop = false;
|
||||
main.gravityModifier = 0.8f;
|
||||
|
||||
var shape = ps.shape;
|
||||
shape.shapeType = ParticleSystemShapeType.Sphere;
|
||||
shape.radius = 0.25f;
|
||||
|
||||
var emission = ps.emission;
|
||||
emission.rateOverTime = 0;
|
||||
emission.SetBursts(new ParticleSystem.Burst[] { new ParticleSystem.Burst(0f, 35) });
|
||||
|
||||
var colorOverLifetime = ps.colorOverLifetime;
|
||||
colorOverLifetime.enabled = true;
|
||||
var gradient = new Gradient();
|
||||
gradient.SetKeys(
|
||||
new GradientColorKey[] { new GradientColorKey(new Color(0.9f, 0.2f, 0.2f), 0f), new GradientColorKey(new Color(0.3f, 0.3f, 0.3f), 1f) },
|
||||
new GradientAlphaKey[] { new GradientAlphaKey(0.9f, 0f), new GradientAlphaKey(0f, 1f) }
|
||||
);
|
||||
colorOverLifetime.color = gradient;
|
||||
|
||||
ps.Play();
|
||||
if (Application.isPlaying)
|
||||
{
|
||||
Object.Destroy(go, main.duration + main.startLifetime.constantMax);
|
||||
}
|
||||
SpawnVfx("VFX_PlayerDeath", position);
|
||||
}
|
||||
|
||||
public void SpawnPrizeEffect(Vector3 position)
|
||||
{
|
||||
var go = new GameObject("VFX_PrizeWin");
|
||||
go.transform.position = position;
|
||||
var ps = go.AddComponent<ParticleSystem>();
|
||||
|
||||
var main = ps.main;
|
||||
main.startColor = Color.white; // Конфетти будут разных цветов
|
||||
main.startSize = new ParticleSystem.MinMaxCurve(0.12f, 0.28f);
|
||||
main.startSpeed = new ParticleSystem.MinMaxCurve(4f, 8f);
|
||||
main.startLifetime = new ParticleSystem.MinMaxCurve(0.6f, 1.2f);
|
||||
main.duration = 0.8f;
|
||||
main.loop = false;
|
||||
main.gravityModifier = 0.4f;
|
||||
|
||||
var shape = ps.shape;
|
||||
shape.shapeType = ParticleSystemShapeType.Hemisphere; // Разлет вверх полусферой
|
||||
shape.radius = 0.3f;
|
||||
shape.rotation = new Vector3(-90f, 0f, 0f); // Поворот вверх
|
||||
|
||||
var emission = ps.emission;
|
||||
emission.rateOverTime = 0;
|
||||
emission.SetBursts(new ParticleSystem.Burst[] { new ParticleSystem.Burst(0f, 50) });
|
||||
|
||||
// Добавим смену цветов
|
||||
var colorBySpeed = ps.colorBySpeed; // Используем градиент для создания разноцветных конфетти
|
||||
var colorOverLifetime = ps.colorOverLifetime;
|
||||
colorOverLifetime.enabled = true;
|
||||
|
||||
// Настроим случайный цвет при рождении через градиент с множеством ключей или Random Between Two Colors
|
||||
main.startColor = new ParticleSystem.MinMaxGradient(
|
||||
new Color(0.2f, 0.6f, 1.0f), // Голубой
|
||||
new Color(1.0f, 0.2f, 0.6f) // Розовый
|
||||
);
|
||||
|
||||
ps.Play();
|
||||
if (Application.isPlaying)
|
||||
{
|
||||
Object.Destroy(go, main.duration + main.startLifetime.constantMax);
|
||||
}
|
||||
SpawnVfx("VFX_PrizeWin", position);
|
||||
}
|
||||
|
||||
public void SpawnComErrorEffect(Vector3 position)
|
||||
{
|
||||
var go = new GameObject("VFX_ComError");
|
||||
go.transform.position = position;
|
||||
var ps = go.AddComponent<ParticleSystem>();
|
||||
SpawnVfx("VFX_ComError", position);
|
||||
}
|
||||
|
||||
var main = ps.main;
|
||||
main.startColor = new Color(1.0f, 0.3f, 0.0f, 0.9f); // Оранжевые тревожные искры
|
||||
main.startSize = new ParticleSystem.MinMaxCurve(0.06f, 0.18f);
|
||||
main.startSpeed = new ParticleSystem.MinMaxCurve(3f, 6f);
|
||||
main.startLifetime = new ParticleSystem.MinMaxCurve(0.25f, 0.5f);
|
||||
main.duration = 0.4f;
|
||||
main.loop = false;
|
||||
main.gravityModifier = 0.3f;
|
||||
|
||||
var shape = ps.shape;
|
||||
shape.shapeType = ParticleSystemShapeType.Cone;
|
||||
shape.angle = 60f;
|
||||
shape.radius = 0.1f;
|
||||
|
||||
var emission = ps.emission;
|
||||
emission.rateOverTime = 0;
|
||||
emission.SetBursts(new ParticleSystem.Burst[] { new ParticleSystem.Burst(0f, 20) });
|
||||
|
||||
var colorOverLifetime = ps.colorOverLifetime;
|
||||
colorOverLifetime.enabled = true;
|
||||
var gradient = new Gradient();
|
||||
gradient.SetKeys(
|
||||
new GradientColorKey[] { new GradientColorKey(new Color(1f, 0.5f, 0f), 0f), new GradientColorKey(new Color(0.8f, 0.1f, 0f), 1f) },
|
||||
new GradientAlphaKey[] { new GradientAlphaKey(0.9f, 0f), new GradientAlphaKey(0f, 1f) }
|
||||
);
|
||||
colorOverLifetime.color = gradient;
|
||||
private void SpawnVfx(string prefabName, Vector3 position)
|
||||
{
|
||||
var prefab = Resources.Load<ParticleSystem>($"Vfx/{prefabName}");
|
||||
if (prefab == null)
|
||||
{
|
||||
Debug.LogWarning($"[GameVfxService] Prefab Resources/Vfx/{prefabName} not found. Attempting to generate default assets.");
|
||||
return;
|
||||
}
|
||||
|
||||
var ps = Object.Instantiate(prefab, position, Quaternion.identity);
|
||||
ps.Play();
|
||||
|
||||
if (Application.isPlaying)
|
||||
{
|
||||
Object.Destroy(go, main.duration + main.startLifetime.constantMax);
|
||||
var main = ps.main;
|
||||
Object.Destroy(ps.gameObject, main.duration + main.startLifetime.constantMax);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -32,7 +32,7 @@ MonoBehaviour:
|
||||
intStep: 1
|
||||
minFloat: 0
|
||||
maxFloat: 1
|
||||
floatStep: 0.01
|
||||
floatStep: 0.05
|
||||
displayFloatAsPercentage: 1
|
||||
options: []
|
||||
buttonText:
|
||||
@ -59,7 +59,7 @@ MonoBehaviour:
|
||||
intStep: 1
|
||||
minFloat: 0
|
||||
maxFloat: 1
|
||||
floatStep: 0.01
|
||||
floatStep: 0.05
|
||||
displayFloatAsPercentage: 1
|
||||
options: []
|
||||
buttonText:
|
||||
@ -985,3 +985,80 @@ MonoBehaviour:
|
||||
buttonData:
|
||||
buttonColor: {r: 0.22352943, g: 0.9803922, b: 1, a: 1}
|
||||
buttonSprite: {fileID: 0}
|
||||
- key: security.requirePin
|
||||
displayName: "Запрос PIN-кода"
|
||||
description: "Требовать ввод PIN-кода для входа в меню настроек"
|
||||
group: "Безопасность"
|
||||
shownInServiceMenu: 1
|
||||
exposedForExternalChanges: 0
|
||||
valueType: 0
|
||||
displayMode: 1
|
||||
defaultBool: 1
|
||||
defaultInt: 0
|
||||
defaultFloat: 1
|
||||
defaultString:
|
||||
defaultOptionIndex: 0
|
||||
minInt: 0
|
||||
maxInt: 1
|
||||
intStep: 1
|
||||
minFloat: 0
|
||||
maxFloat: 1
|
||||
floatStep: 0.1
|
||||
displayFloatAsPercentage: 0
|
||||
options: []
|
||||
buttonText:
|
||||
buttonData:
|
||||
buttonColor: {r: 0, g: 0, b: 0, a: 0}
|
||||
buttonSprite: {fileID: 0}
|
||||
- key: security.pin
|
||||
displayName: "PIN-код"
|
||||
description: "PIN-код для доступа к меню настроек (4 цифры)"
|
||||
group: "Безопасность"
|
||||
shownInServiceMenu: 0
|
||||
exposedForExternalChanges: 0
|
||||
valueType: 3
|
||||
displayMode: 4
|
||||
defaultBool: 1
|
||||
defaultInt: 0
|
||||
defaultFloat: 1
|
||||
defaultString: "1234"
|
||||
defaultOptionIndex: 0
|
||||
minInt: 0
|
||||
maxInt: 10
|
||||
intStep: 1
|
||||
minFloat: 0
|
||||
maxFloat: 1
|
||||
floatStep: 0.1
|
||||
displayFloatAsPercentage: 0
|
||||
options: []
|
||||
buttonText:
|
||||
buttonData:
|
||||
buttonColor: {r: 0, g: 0, b: 0, a: 0}
|
||||
buttonSprite: {fileID: 0}
|
||||
- key: btn.settingsPin
|
||||
displayName: "PIN-код"
|
||||
description: "PIN-код для доступа к меню настроек (4 цифры)"
|
||||
group: "Безопасность"
|
||||
shownInServiceMenu: 1
|
||||
exposedForExternalChanges: 0
|
||||
valueType: 4
|
||||
displayMode: 5
|
||||
defaultBool: 1
|
||||
defaultInt: 0
|
||||
defaultFloat: 1
|
||||
defaultString:
|
||||
defaultOptionIndex: 0
|
||||
minInt: 0
|
||||
maxInt: 10
|
||||
intStep: 1
|
||||
minFloat: 0
|
||||
maxFloat: 1
|
||||
floatStep: 0.1
|
||||
displayFloatAsPercentage: 0
|
||||
options: []
|
||||
buttonText:
|
||||
buttonData:
|
||||
buttonColor: {r: 0, g: 0, b: 0, a: 0}
|
||||
buttonSprite: {fileID: 0}
|
||||
|
||||
|
||||
|
||||
@ -9,7 +9,7 @@ using Zenject;
|
||||
|
||||
namespace DanroJump.Tests.EditMode
|
||||
{
|
||||
public sealed class ServiceSettingsSceneInjectorTests
|
||||
public sealed class AppUIFacadeInjectorTests
|
||||
{
|
||||
private readonly List<GameObject> createdObjects = new();
|
||||
|
||||
@ -31,12 +31,12 @@ namespace DanroJump.Tests.EditMode
|
||||
public void Initialize_InjectsActionsAlreadyPresentInLoadedScene()
|
||||
{
|
||||
var gameObject = CreateGameObject("Service Settings Actions");
|
||||
var actions = gameObject.AddComponent<ServiceSettingsActions>();
|
||||
var actions = gameObject.AddComponent<AppUIFacade>();
|
||||
var sceneFlow = new RecordingSceneFlowService();
|
||||
var container = new DiContainer();
|
||||
container.Bind<IServiceSettingsService>().FromInstance(new NoopServiceSettingsService()).AsSingle();
|
||||
container.Bind<ISceneFlowService>().FromInstance(sceneFlow).AsSingle();
|
||||
var injector = new ServiceSettingsSceneInjector(container, true);
|
||||
var injector = new AppUIFacadeInjector(container, true);
|
||||
|
||||
injector.Initialize();
|
||||
actions.LoadScene("Game");
|
||||
@ -51,15 +51,15 @@ namespace DanroJump.Tests.EditMode
|
||||
public void Initialize_DoesNothingWhenSceneActionInjectionIsDisabled()
|
||||
{
|
||||
var gameObject = CreateGameObject("Disabled Service Settings Actions");
|
||||
var actions = gameObject.AddComponent<ServiceSettingsActions>();
|
||||
var actions = gameObject.AddComponent<AppUIFacade>();
|
||||
var sceneFlow = new RecordingSceneFlowService();
|
||||
var container = new DiContainer();
|
||||
container.Bind<IServiceSettingsService>().FromInstance(new NoopServiceSettingsService()).AsSingle();
|
||||
container.Bind<ISceneFlowService>().FromInstance(sceneFlow).AsSingle();
|
||||
var injector = new ServiceSettingsSceneInjector(container, false);
|
||||
var injector = new AppUIFacadeInjector(container, false);
|
||||
|
||||
injector.Initialize();
|
||||
LogAssert.Expect(LogType.Warning, "ServiceSettingsActions requires ISceneFlowService from DI.");
|
||||
LogAssert.Expect(LogType.Warning, "AppUIFacade requires ISceneFlowService from DI.");
|
||||
actions.LoadMainMenu();
|
||||
injector.Dispose();
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user