53 Commits
Author SHA1 Message Date
ThomasCharester 1e31e1e8b1 Фикс трактора 2025-12-02 19:53:02 +03:00
ThomasCharester 2897eb88bf Звуки шагов, ядерный таракан, монстр дед 2025-12-01 18:36:22 +03:00
ThomasCharester 134adda787 Недочин недопил но переполошил аудио 2025-12-01 14:52:19 +03:00
ThomasCharester 2f56a5758d Мобы на уровнях, анимации 2025-12-01 12:59:15 +03:00
ThomasCharester fb9510a6b2 Починка генерации + небольшой прикол дверей 2025-12-01 00:02:00 +03:00
ThomasCharester aa4a9e69dd Подогреваем коллизии 2025-11-29 00:41:07 +03:00
ThomasCharester 34d7fa3791 Блять 2025-11-28 15:13:03 +03:00
ThomasCharester 26804e08f7 Да, теперь нормально 2025-11-28 15:04:56 +03:00
ThomasCharester e96dcf3e0d Merge branch 'Dev' of https://notscam.serveminecraft.net/Tetramino/CourierOld into Dev 2025-11-28 15:04:25 +03:00
ThomasCharester 94f0522f89 Да, теперь нормально 2025-11-28 14:51:38 +03:00
xrust1k eefcf6eabc Merge branch 'Dev' of https://notscam.serveminecraft.net/Tetramino/CourierOld into Dev 2025-11-28 14:48:59 +03:00
xrust1k c85638fda0 Бля ебать рот этих дверей 2025-11-28 14:47:29 +03:00
ThomasCharester 1de117622e Фикс пива 2025-11-28 14:32:37 +03:00
ThomasCharester e2f8984e6f Merge remote-tracking branch 'origin/mobs-and-levels-dev' into Dev 2025-11-28 14:25:02 +03:00
ThomasCharester 32c6e0630a Солнышко 2025-11-28 14:20:51 +03:00
MrTorex 870a4743c6 дрочка лёжа на рельсах 2025-11-28 14:14:55 +03:00
MrTorex 2fc8e249f5 Merge branch 'mobs-and-levels-dev' into Dev 2025-11-28 13:56:35 +03:00
MrTorex 280eb3754c МЕНЯ ТРАХАЛИ ВСЕМ ДЕТДОМОМ 2025-11-28 13:56:02 +03:00
xrust1k 6eff3ef9a9 AAAAAAAAAAAAAAAAAAA 2025-11-28 13:51:32 +03:00
xrust1k 6b4792393a Merge branch 'Dev' of https://notscam.serveminecraft.net/Tetramino/CourierOld into Dev 2025-11-28 13:33:00 +03:00
xrust1k a547c39db7 Комнаты 2025-11-28 13:26:52 +03:00
ThomasCharester 0cab2eda74 Добавлена механика Initial Room 2025-11-28 13:21:56 +03:00
xrust1k 5d075034b5 Я со старой версии запушил снова, ломаться не должно 2025-11-28 12:10:30 +03:00
xrust1k 7f7ba0d9c5 Merge branch 'Dev' of https://notscam.serveminecraft.net/Tetramino/CourierOld into Dev 2025-11-28 11:52:49 +03:00
xrust1k ab0b41a318 Я боюсь 2025-11-28 11:52:15 +03:00
MrTorex a5ce8522ab мержим 2025-11-28 11:46:04 +03:00
MrTorex 97aea0fde1 Merge branch 'Dev' into movement-dev 2025-11-28 11:42:30 +03:00
MrTorex e9e8e091b2 письки 2025-11-28 11:42:08 +03:00
ThomasCharester 9e1c1177e0 Фикс геймплея? 2025-11-28 11:39:59 +03:00
ThomasCharester 07535982ba Dimka Bakery 2025-11-28 11:09:31 +03:00
MrTorex df0c2b3157 Merge branch 'Dev' into movement-dev 2025-11-28 10:49:11 +03:00
MrTorex d51527b7f3 это спермаггедон 2025-11-28 10:47:28 +03:00
xrust1k 13aca5a86f Merge branch 'Dev' of https://notscam.serveminecraft.net/Tetramino/CourierOld into Dev 2025-11-28 10:43:47 +03:00
xrust1k 9cc77d5c67 Уровни (Да ничего я не сделал) 2025-11-28 10:42:00 +03:00
ThomasCharester c1a0e94fe3 Merge branch 'Generator' into Dev 2025-11-28 10:28:10 +03:00
ThomasCharester acd9cc1a32 Ахуеть, я сделал генерацию уровней на основе идеи Димки 2025-11-28 10:27:49 +03:00
MrTorex d14f9c2a9f анус рвётся не по-детски 2025-11-28 09:45:49 +03:00
MrTorex 4b6909fe84 Допил наклонов (они такое себе)
Хуже, чем были раньше, но лучше, чем ничего. Плавность переходов имеется, и на том спасибо
2025-11-28 01:15:44 +03:00
MrTorex 766609489d Я ненавижу наклоны (не прорвёмся) 2025-11-28 00:51:20 +03:00
ThomasCharester b7e9a26462 Комнаты, вся хуйня 2025-11-27 23:39:57 +03:00
ThomasCharester 3782a0b568 Фикс отпуска звуков 2025-11-27 23:01:12 +03:00
ThomasCharester 000985ee9b Фикс отпуска звуков 2025-11-27 22:59:50 +03:00
ThomasCharester abde1d5ba9 Merge branch 'Dev' into Generator 2025-11-27 22:36:55 +03:00
MrTorex d10d2cdca6 прорвёмся (добавлен walljump) 2025-11-27 21:36:19 +03:00
MrTorex 01d3b0adec чел не липнет к воздуху 2025-11-27 21:10:23 +03:00
MrTorex b271042137 инишиал титан падать второй мувмент (но пока очень говно) 2025-11-27 20:37:16 +03:00
Pe4enega cea36c0cda Триггеры на вход в комнату 2025-11-25 20:04:36 +03:00
Pe4enega ff8ed96138 Merge branch 'Dev' into Generator 2025-11-24 18:00:18 +03:00
Pe4enega 01505de4c3 Проверка расстановки 2025-11-18 14:45:43 +03:00
Pe4enega 52edef92e3 Вроде ок, осталось проверить на практике нормально, когда комнаты будут готовы 2025-11-15 21:31:40 +03:00
Pe4enega c6b097a879 Промежуточный 2025-11-15 17:25:09 +03:00
Pe4enega a243ad53d6 Вставка лестниц(не доделана) 2025-11-12 14:26:16 +03:00
Pe4enega 85a07065d9 Комнаты ставятся, но криво 2025-11-10 21:08:54 +03:00
455 changed files with 144220 additions and 11783 deletions

No files matched your search

+6
View File
@@ -0,0 +1,6 @@
{
"version": "1.0",
"components": [
"Microsoft.VisualStudio.Workload.ManagedGame"
]
}
@@ -15,7 +15,7 @@ MonoBehaviour:
m_DefaultGroup: d447fc60305c17a17bf20948ab295a45 m_DefaultGroup: d447fc60305c17a17bf20948ab295a45
m_currentHash: m_currentHash:
serializedVersion: 2 serializedVersion: 2
Hash: 00000000000000000000000000000000 Hash: a9d2f067d3215f124d04a5eb72485a3f
m_OptimizeCatalogSize: 0 m_OptimizeCatalogSize: 0
m_BuildRemoteCatalog: 0 m_BuildRemoteCatalog: 0
m_CatalogRequestsTimeout: 0 m_CatalogRequestsTimeout: 0
@@ -32,6 +32,11 @@ MonoBehaviour:
m_ReadOnly: 0 m_ReadOnly: 0
m_SerializedLabels: [] m_SerializedLabels: []
FlaggedDuringContentUpdateRestriction: 0 FlaggedDuringContentUpdateRestriction: 0
- m_GUID: 19bfe93240786974ea9d7cd70a7bb635
m_Address: Prefabs/Rooms/Level5
m_ReadOnly: 0
m_SerializedLabels: []
FlaggedDuringContentUpdateRestriction: 0
- m_GUID: 1d4767c722c05b5d6b96bb226d378c65 - m_GUID: 1d4767c722c05b5d6b96bb226d378c65
m_Address: Assets/Resources_moved/Prefabs/Player/ArmsMesh.prefab m_Address: Assets/Resources_moved/Prefabs/Player/ArmsMesh.prefab
m_ReadOnly: 0 m_ReadOnly: 0
@@ -52,6 +57,11 @@ MonoBehaviour:
m_ReadOnly: 0 m_ReadOnly: 0
m_SerializedLabels: [] m_SerializedLabels: []
FlaggedDuringContentUpdateRestriction: 0 FlaggedDuringContentUpdateRestriction: 0
- m_GUID: 28a6c7a4124141341ab7c2b7dfd3e95b
m_Address: Assets/Resources_moved/Prefabs/Levels/Level1 2.prefab
m_ReadOnly: 0
m_SerializedLabels: []
FlaggedDuringContentUpdateRestriction: 0
- m_GUID: 29bff8011973e4e519906b9da8fca0fc - m_GUID: 29bff8011973e4e519906b9da8fca0fc
m_Address: Audio/Dispatcher/late3 m_Address: Audio/Dispatcher/late3
m_ReadOnly: 0 m_ReadOnly: 0
@@ -62,6 +72,11 @@ MonoBehaviour:
m_ReadOnly: 0 m_ReadOnly: 0
m_SerializedLabels: [] m_SerializedLabels: []
FlaggedDuringContentUpdateRestriction: 0 FlaggedDuringContentUpdateRestriction: 0
- m_GUID: 2c6a984e4a1b42647b48e6b7bc69b158
m_Address: Prefabs/Levels/Level6
m_ReadOnly: 0
m_SerializedLabels: []
FlaggedDuringContentUpdateRestriction: 0
- m_GUID: 2ed2d93a9f39d4edba511cb7396c7bb6 - m_GUID: 2ed2d93a9f39d4edba511cb7396c7bb6
m_Address: Assets/Resources_moved/Prefabs/Enemies/Cockroach.prefab m_Address: Assets/Resources_moved/Prefabs/Enemies/Cockroach.prefab
m_ReadOnly: 0 m_ReadOnly: 0
@@ -82,6 +97,11 @@ MonoBehaviour:
m_ReadOnly: 0 m_ReadOnly: 0
m_SerializedLabels: [] m_SerializedLabels: []
FlaggedDuringContentUpdateRestriction: 0 FlaggedDuringContentUpdateRestriction: 0
- m_GUID: 4283d6553fc7f3f4583b9bb0be9d7979
m_Address: Prefabs/Rooms/Box1
m_ReadOnly: 0
m_SerializedLabels: []
FlaggedDuringContentUpdateRestriction: 0
- m_GUID: 48aebfe8826dc0df79d047b5afbf8f5b - m_GUID: 48aebfe8826dc0df79d047b5afbf8f5b
m_Address: Canvas m_Address: Canvas
m_ReadOnly: 0 m_ReadOnly: 0
@@ -92,6 +112,11 @@ MonoBehaviour:
m_ReadOnly: 0 m_ReadOnly: 0
m_SerializedLabels: [] m_SerializedLabels: []
FlaggedDuringContentUpdateRestriction: 0 FlaggedDuringContentUpdateRestriction: 0
- m_GUID: 7067a5248027e74478f4f0f53ddf06a4
m_Address: Prefabs/Rooms/Save1
m_ReadOnly: 0
m_SerializedLabels: []
FlaggedDuringContentUpdateRestriction: 0
- m_GUID: 735f38402ea347fa381408293503a24e - m_GUID: 735f38402ea347fa381408293503a24e
m_Address: Audio/Dispatcher/receiving_an_order1 m_Address: Audio/Dispatcher/receiving_an_order1
m_ReadOnly: 0 m_ReadOnly: 0
@@ -143,11 +168,26 @@ MonoBehaviour:
m_ReadOnly: 0 m_ReadOnly: 0
m_SerializedLabels: [] m_SerializedLabels: []
FlaggedDuringContentUpdateRestriction: 0 FlaggedDuringContentUpdateRestriction: 0
- m_GUID: 9d78f017876abed4c9cd8957f1e140cb
m_Address: Prefabs/Rooms/Level1_2
m_ReadOnly: 0
m_SerializedLabels: []
FlaggedDuringContentUpdateRestriction: 0
- m_GUID: a1d9e5a04ac11a1468c744b27d442a00
m_Address: Prefabs/Rooms/Stars1
m_ReadOnly: 0
m_SerializedLabels: []
FlaggedDuringContentUpdateRestriction: 0
- m_GUID: a306df57f348ce7cf900d0b9431739ee - m_GUID: a306df57f348ce7cf900d0b9431739ee
m_Address: launch_selectmenu m_Address: launch_selectmenu
m_ReadOnly: 0 m_ReadOnly: 0
m_SerializedLabels: [] m_SerializedLabels: []
FlaggedDuringContentUpdateRestriction: 0 FlaggedDuringContentUpdateRestriction: 0
- m_GUID: ab5926b5200bedc49aec36c0afe6b028
m_Address: Prefabs/Rooms/Level3_Big
m_ReadOnly: 0
m_SerializedLabels: []
FlaggedDuringContentUpdateRestriction: 0
- m_GUID: b2e8dc2aeb0311cd8a826b51cf8e94dc - m_GUID: b2e8dc2aeb0311cd8a826b51cf8e94dc
m_Address: GameOver m_Address: GameOver
m_ReadOnly: 0 m_ReadOnly: 0
@@ -158,16 +198,51 @@ MonoBehaviour:
m_ReadOnly: 0 m_ReadOnly: 0
m_SerializedLabels: [] m_SerializedLabels: []
FlaggedDuringContentUpdateRestriction: 0 FlaggedDuringContentUpdateRestriction: 0
- m_GUID: b3471d165fe389f479380f61034bea57
m_Address: Assets/Resources_moved/Prefabs/Levels/Level1 1.prefab
m_ReadOnly: 0
m_SerializedLabels: []
FlaggedDuringContentUpdateRestriction: 0
- m_GUID: bf87bc9ac43df86be8c818de81d44a54
m_Address: Assets/Resources_moved/Audio/SFX/pl_step1.wav
m_ReadOnly: 0
m_SerializedLabels: []
FlaggedDuringContentUpdateRestriction: 0
- m_GUID: c566fc932edefbbee9e53271eac3c560 - m_GUID: c566fc932edefbbee9e53271eac3c560
m_Address: MainMenu m_Address: MainMenu
m_ReadOnly: 0 m_ReadOnly: 0
m_SerializedLabels: [] m_SerializedLabels: []
FlaggedDuringContentUpdateRestriction: 0 FlaggedDuringContentUpdateRestriction: 0
- m_GUID: c938de3174f184741925c407a43a47f2
m_Address: Prefabs/Rooms/Level1
m_ReadOnly: 0
m_SerializedLabels: []
FlaggedDuringContentUpdateRestriction: 0
- m_GUID: cab4b1ff78dd6b1fba61aa165aa17b4d - m_GUID: cab4b1ff78dd6b1fba61aa165aa17b4d
m_Address: Audio/Dispatcher/receiving_an_order2 m_Address: Audio/Dispatcher/receiving_an_order2
m_ReadOnly: 0 m_ReadOnly: 0
m_SerializedLabels: [] m_SerializedLabels: []
FlaggedDuringContentUpdateRestriction: 0 FlaggedDuringContentUpdateRestriction: 0
- m_GUID: d4eaf1439c2788c458127b9ba67e4fbf
m_Address: Prefabs/Levels/Level1
m_ReadOnly: 0
m_SerializedLabels: []
FlaggedDuringContentUpdateRestriction: 0
- m_GUID: d5b22c0e6700543419ae667d77aadaa2
m_Address: Prefabs/Rooms/Level2_Down
m_ReadOnly: 0
m_SerializedLabels: []
FlaggedDuringContentUpdateRestriction: 0
- m_GUID: dc328d8aadb0e8545978741d451e0544
m_Address: Prefabs/Rooms/Level4_Parkur
m_ReadOnly: 0
m_SerializedLabels: []
FlaggedDuringContentUpdateRestriction: 0
- m_GUID: e3a3840a7963bf841872cddb02e90151
m_Address: Prefabs/Levels/MainMenu 1
m_ReadOnly: 0
m_SerializedLabels: []
FlaggedDuringContentUpdateRestriction: 0
- m_GUID: ebe18293a5ef86704b23dad3a1786476 - m_GUID: ebe18293a5ef86704b23dad3a1786476
m_Address: Half-Life01 m_Address: Half-Life01
m_ReadOnly: 0 m_ReadOnly: 0
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: d36aab6707c518f5abfd60065165eb35
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: d982316b2b4c99747b9e953ae7b9b42f
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -40,7 +40,7 @@ namespace Code.App.AppStates
Context.LoadingManager Context.LoadingManager
.RegisterLoading(LoadingWork.LoadScene) .RegisterLoading(LoadingWork.LoadScene)
.RegisterLoading(LoadingWork.LoadUI) .RegisterLoading(LoadingWork.LoadUI)
// .RegisterLoading(LoadingWork.LoadModelResource) .RegisterLoading(LoadingWork.LoadModelResource)
.RegisterLoading(LoadingWork.LoadAudio); .RegisterLoading(LoadingWork.LoadAudio);
//_playerHealth = Context.PlayerFactory.CreatePlayerHealth(); //_playerHealth = Context.PlayerFactory.CreatePlayerHealth();
@@ -56,7 +56,8 @@ namespace Code.App.AppStates
Context.InputService.DebugBindAction((int)ActionMappings.Debug, (int)DebugActions.Debug4, RoomPassedDEBUG); Context.InputService.DebugBindAction((int)ActionMappings.Debug, (int)DebugActions.Debug4, RoomPassedDEBUG);
Context.InputService.DebugBindAction((int)ActionMappings.Debug, (int)DebugActions.Debug5, Tube); Context.InputService.DebugBindAction((int)ActionMappings.Debug, (int)DebugActions.Debug5, Tube);
Context.SceneLoaderService.LoadSceneAsyncAwaitable((int)SceneIds.Gameplay); // Context.SceneLoaderService.LoadSceneAsyncAwaitable((int)SceneIds.DevGen);
Context.SceneLoaderService.LoadSceneAsyncAwaitable((int)SceneIds.DevGen);
Context.LoadingManager.OnLoadingEnded += AfterSceneLoaded; Context.LoadingManager.OnLoadingEnded += AfterSceneLoaded;
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed #pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
@@ -71,7 +72,9 @@ namespace Code.App.AppStates
Context.UIService.AsyncSwitchPanelTo(UIPanel.Gameplay), Context.UIService.AsyncSwitchPanelTo(UIPanel.Gameplay),
Context.AudioFactory.WarmGameplayMusic(), Context.AudioFactory.WarmGameplayMusic(),
Context.AudioFactory.WarmSFX(), Context.AudioFactory.WarmSFX(),
Context.AudioFactory.WarmDispatcher() Context.AudioFactory.WarmDispatcher(),
Context.AudioFactory.WarmEnemies(),
Context.AudioFactory.WarmCourier()
); );
Context.LoadingManager Context.LoadingManager
@@ -91,6 +94,9 @@ namespace Code.App.AppStates
Context.LoadingManager.OnLoadingEnded -= AfterSceneLoaded; Context.LoadingManager.OnLoadingEnded -= AfterSceneLoaded;
Context.LoadingManager.OnLoadingEnded += AfterPlayerLoaded; Context.LoadingManager.OnLoadingEnded += AfterPlayerLoaded;
Context.PlayerProvider = SceneManager.GetActiveScene().GetSceneContainer().Resolve<IPlayerProvider>();
Context.PlayerFactory = SceneManager.GetActiveScene().GetSceneContainer().Resolve<IPlayerFactory>();
await UniTask.WhenAll( await UniTask.WhenAll(
WaitForPlayerArmsToInitialize(), WaitForPlayerArmsToInitialize(),
WaitForPlayerCharacterLoad() WaitForPlayerCharacterLoad()
@@ -203,6 +209,10 @@ namespace Code.App.AppStates
Context.InputService.DisableMap(ActionMappings.Gameplay); Context.InputService.DisableMap(ActionMappings.Gameplay);
Context.AudioService.GladlyAskToStopMusic(MusicType.Action, callback: Context.AudioFactory.ReleaseActionMusic); Context.AudioService.GladlyAskToStopMusic(MusicType.Action, callback: Context.AudioFactory.ReleaseActionMusic);
Context.AudioService.GladlyAskToStopMusic(MusicType.Peaceful, callback: Context.AudioFactory.ReleasePeacefulMusic); Context.AudioService.GladlyAskToStopMusic(MusicType.Peaceful, callback: Context.AudioFactory.ReleasePeacefulMusic);
Context.AudioFactory.ReleaseCourier();
Context.AudioFactory.ReleaseDispatcher();
Context.AudioFactory.ReleaseEnemies();
Context.AudioFactory.ReleaseSFX();
Context.InputService.DebugUnbindAction((int)ActionMappings.Debug, (int)DebugActions.Debug1, InstaKillDEBUG); Context.InputService.DebugUnbindAction((int)ActionMappings.Debug, (int)DebugActions.Debug1, InstaKillDEBUG);
@@ -256,7 +266,7 @@ namespace Code.App.AppStates
{ {
var sceneEnvironment = (GameplaySceneEnvironment)sceneContainer.Resolve<CurrentSceneEnvironment>(); var sceneEnvironment = (GameplaySceneEnvironment)sceneContainer.Resolve<CurrentSceneEnvironment>();
_debugTube = sceneEnvironment.debugTube;
return sceneEnvironment; return sceneEnvironment;
} }
} }
@@ -123,7 +123,6 @@ namespace Code.App.AppStates
Context.AudioService.GladlyAskToStopMusic(MusicType.Menu, callback: Context.AudioFactory.ReleaseMenuMusic); Context.AudioService.GladlyAskToStopMusic(MusicType.Menu, callback: Context.AudioFactory.ReleaseMenuMusic);
Context.AudioFactory.ReleaseAudioTestClips(); Context.AudioFactory.ReleaseAudioTestClips();
Context.AudioFactory.ReleaseMenuMusic();
base.ExitState(); base.ExitState();
} }
} }
@@ -8,6 +8,7 @@ using Code.Gameplay.Camera;
using Code.Gameplay.Enemies; using Code.Gameplay.Enemies;
using Code.Gameplay.Orders.Order; using Code.Gameplay.Orders.Order;
using Code.Gameplay.Player; using Code.Gameplay.Player;
using Code.Generator;
using Code.Input; using Code.Input;
using Code.Scenes; using Code.Scenes;
using Code.StaticData; using Code.StaticData;
@@ -32,11 +33,7 @@ namespace Code.App
containerBuilder.AddSingleton(typeof(LoadingManager), typeof(ILoadingManager)); containerBuilder.AddSingleton(typeof(LoadingManager), typeof(ILoadingManager));
containerBuilder.AddSingleton(typeof(InputService), typeof(IInputService)); containerBuilder.AddSingleton(typeof(InputService), typeof(IInputService));
// Перенести нахуй в контейнер геймплея
containerBuilder.AddSingleton(typeof(PlayerFactory), typeof(IPlayerFactory));
containerBuilder.AddSingleton(typeof(EnemyFactory), typeof(IEnemyFactory));
containerBuilder.AddSingleton(typeof(PlayerProvider), typeof(IPlayerProvider));
//
InitializeCamera(containerBuilder, staticDataService); InitializeCamera(containerBuilder, staticDataService);
containerBuilder.AddSingleton(typeof(UIFactory), typeof(IUIFactory)); containerBuilder.AddSingleton(typeof(UIFactory), typeof(IUIFactory));
@@ -96,12 +93,15 @@ namespace Code.App
containerBuilder.AddSingleton(staticDataService.SoundtrackListConfig, typeof(SoundtrackListConfig)); containerBuilder.AddSingleton(staticDataService.SoundtrackListConfig, typeof(SoundtrackListConfig));
containerBuilder.AddSingleton(staticDataService.AudioTestClipsConfig, typeof(AudioTestClipsConfig)); containerBuilder.AddSingleton(staticDataService.AudioTestClipsConfig, typeof(AudioTestClipsConfig));
containerBuilder.AddSingleton(staticDataService.SFXListConfig, typeof(SFXListConfig)); containerBuilder.AddSingleton(staticDataService.SFXListConfig, typeof(SFXListConfig));
containerBuilder.AddSingleton(staticDataService.CourierSoundListConfig, typeof(CourierSoundListConfig));
containerBuilder.AddSingleton(staticDataService.DispatcherSoundListConfig, typeof(DispatcherSoundListConfig)); containerBuilder.AddSingleton(staticDataService.DispatcherSoundListConfig, typeof(DispatcherSoundListConfig));
containerBuilder.AddSingleton(staticDataService.EnemiesSoundListConfig, typeof(EnemiesSoundListConfig)); containerBuilder.AddSingleton(staticDataService.EnemiesSoundListConfig, typeof(EnemiesSoundListConfig));
containerBuilder.AddSingleton(staticDataService.AudioSourceSettingsConfigs, typeof(Dictionary<AudioSourceType, AudioSourceSettingsConfig>)); containerBuilder.AddSingleton(staticDataService.AudioSourceSettingsConfigs, typeof(Dictionary<AudioSourceType, AudioSourceSettingsConfig>));
containerBuilder.AddSingleton(staticDataService.OrderServiceConfig, typeof(OrderServiceConfig)); containerBuilder.AddSingleton(staticDataService.OrderServiceConfig, typeof(OrderServiceConfig));
containerBuilder.AddSingleton(staticDataService.OrderBoxConfig, typeof(OrderBoxConfig)); containerBuilder.AddSingleton(staticDataService.OrderBoxConfig, typeof(OrderBoxConfig));
containerBuilder.AddSingleton(staticDataService.GeneratorConfig, typeof(GeneratorConfig));
} }
private AppStateMachine _appStateMachine; private AppStateMachine _appStateMachine;
@@ -1,8 +1,11 @@
using Code.App.Loading; using Code.App.Loading;
using Code.Gameplay.Enemies;
using Code.Gameplay.Orders.Order; using Code.Gameplay.Orders.Order;
using Code.Gameplay.Player; using Code.Gameplay.Player;
using Code.Generator;
using Code.Scenes; using Code.Scenes;
using Code.Scenes.SceneEnvironments; using Code.Scenes.SceneEnvironments;
using Cysharp.Threading.Tasks;
using Reflex.Core; using Reflex.Core;
using UnityEngine; using UnityEngine;
using IPlayerScore = Code.Gameplay.Player.IPlayerScore; using IPlayerScore = Code.Gameplay.Player.IPlayerScore;
@@ -18,6 +21,11 @@ namespace Code.App.SceneInstallers
containerBuilder.AddScoped(typeof(GameplaySceneEnvironment), typeof(CurrentSceneEnvironment)); containerBuilder.AddScoped(typeof(GameplaySceneEnvironment), typeof(CurrentSceneEnvironment));
containerBuilder.AddScoped(typeof(PlayerScore), typeof(IPlayerScore)); containerBuilder.AddScoped(typeof(PlayerScore), typeof(IPlayerScore));
containerBuilder.AddScoped(typeof(OrderService), typeof(IOrderService)); containerBuilder.AddScoped(typeof(OrderService), typeof(IOrderService));
containerBuilder.AddScoped(typeof(RoomGeneratorFactory), typeof(IRoomGeneratorFactory));
containerBuilder.AddScoped(typeof(PlayerProvider), typeof(IPlayerProvider));
containerBuilder.AddScoped(typeof(PlayerFactory), typeof(IPlayerFactory));
containerBuilder.AddScoped(typeof(EnemyFactory), typeof(IEnemyFactory));
containerBuilder.AddScoped(typeof(RoomGenerator));
containerBuilder.OnContainerBuilt += Initialize; containerBuilder.OnContainerBuilt += Initialize;
} }
@@ -32,6 +40,17 @@ namespace Code.App.SceneInstallers
loadingManager loadingManager
.UnregisterLoading(LoadingWork.LoadScene); .UnregisterLoading(LoadingWork.LoadScene);
LoadRooms(container,loadingManager).Forget();
}
private async UniTaskVoid LoadRooms(Container container, ILoadingManager loadingManager)
{
await container.Resolve<IRoomGeneratorFactory>().PreloadRooms(container.Resolve<IOrderService>());
container.Resolve<RoomGenerator>().Initialize();
loadingManager.UnregisterLoading(LoadingWork.LoadModelResource);
} }
} }
} }
@@ -3,6 +3,7 @@ using Code.Audio;
using Code.Gameplay.Camera; using Code.Gameplay.Camera;
using Code.Gameplay.Enemies; using Code.Gameplay.Enemies;
using Code.Gameplay.Player; using Code.Gameplay.Player;
using Code.Generator;
using Code.Input; using Code.Input;
using Code.Scenes; using Code.Scenes;
using Code.UI; using Code.UI;
@@ -18,10 +19,10 @@ namespace Code.App.StateMachine
[Inject] public AppStateMachine StateMachine { get; private set; } [Inject] public AppStateMachine StateMachine { get; private set; }
[Inject] public CameraStateMachine CameraStateMachine { get; private set; } [Inject] public CameraStateMachine CameraStateMachine { get; private set; }
[Inject] public IUIService UIService { get; private set; } [Inject] public IUIService UIService { get; private set; }
[Inject] public IPlayerFactory PlayerFactory { get; private set; }
[Inject] public IPlayerProvider PlayerProvider { get; private set; }
[Inject] public IAudioFactory AudioFactory { get; private set; } [Inject] public IAudioFactory AudioFactory { get; private set; }
[Inject] public IAudioService AudioService { get; private set; } [Inject] public IAudioService AudioService { get; private set; }
[Inject] public IEnemyFactory EnemyFactory { get; private set; } /*[Inject]*/public IPlayerFactory PlayerFactory { get; set; }
/*[Inject]*/public IPlayerProvider PlayerProvider { get; set; }
// [Inject] public IEnemyFactory EnemyFactory { get; private set; }
} }
} }
@@ -12,7 +12,8 @@ namespace Code.Audio
public enum EnemiesSounds public enum EnemiesSounds
{ {
Bastard, Bastard,
Bravo Bravo,
GrandpaStep
} }
public enum DispatcherSounds public enum DispatcherSounds
{ {
@@ -28,4 +29,8 @@ namespace Code.Audio
Late4, Late4,
Late5 Late5
} }
public enum CourierSounds
{
Step
}
} }
@@ -23,7 +23,7 @@ namespace Code.Audio
private AssetReference[] _SFX; private AssetReference[] _SFX;
private AssetReference[] _enemies; private AssetReference[] _enemies;
private AssetReference[] _dispatcher; private AssetReference[] _dispatcher;
private AssetReference[] _character; private AssetReference[] _courier;
private AsyncOperationHandle<IList<AudioClip>> _audioTestClipsHandle; private AsyncOperationHandle<IList<AudioClip>> _audioTestClipsHandle;
private AsyncOperationHandle<IList<AudioClip>> _menuMusicHandle; private AsyncOperationHandle<IList<AudioClip>> _menuMusicHandle;
@@ -32,11 +32,13 @@ namespace Code.Audio
private AsyncOperationHandle<IList<AudioClip>> _SFXHandle; private AsyncOperationHandle<IList<AudioClip>> _SFXHandle;
private AsyncOperationHandle<IList<AudioClip>> _enemiesHandle; private AsyncOperationHandle<IList<AudioClip>> _enemiesHandle;
private AsyncOperationHandle<IList<AudioClip>> _dispatcherHandle; private AsyncOperationHandle<IList<AudioClip>> _dispatcherHandle;
private AsyncOperationHandle<IList<AudioClip>> _courierHandle;
public Dictionary<AudioType, AudioClip> AudioTestClips { get; private set; } = new(); public Dictionary<AudioType, AudioClip> AudioTestClips { get; private set; } = new();
public Dictionary<MusicType, List<AudioClip>> MusicDictionary { get; private set; } = new(); public Dictionary<MusicType, List<AudioClip>> MusicDictionary { get; private set; } = new();
public List<AudioClip> SFXAudios { get; private set; } = new(); public List<AudioClip> SFXAudios { get; private set; } = new();
public List<AudioClip> EnemiesAudios { get; private set; } = new(); public List<AudioClip> EnemiesAudios { get; private set; } = new();
public List<AudioClip> CourierAudios { get; private set; } = new();
public List<AudioClip> DispatcherAudios { get; private set; } = new(); public List<AudioClip> DispatcherAudios { get; private set; } = new();
public AudioFactory(AudioMixerConfig audioMixerConfig, public AudioFactory(AudioMixerConfig audioMixerConfig,
@@ -44,7 +46,8 @@ namespace Code.Audio
SFXListConfig sfxListConfig, SFXListConfig sfxListConfig,
EnemiesSoundListConfig enemiesSoundListConfig, EnemiesSoundListConfig enemiesSoundListConfig,
DispatcherSoundListConfig dispatcherSoundListConfig, DispatcherSoundListConfig dispatcherSoundListConfig,
AudioTestClipsConfig audioTestClipsConfig AudioTestClipsConfig audioTestClipsConfig,
CourierSoundListConfig courierSoundListConfig
) )
{ {
AudioMixer = audioMixerConfig.audioMixerAsset; AudioMixer = audioMixerConfig.audioMixerAsset;
@@ -56,6 +59,7 @@ namespace Code.Audio
_SFX = sfxListConfig.SFX; _SFX = sfxListConfig.SFX;
_enemies = enemiesSoundListConfig.enemies; _enemies = enemiesSoundListConfig.enemies;
_dispatcher = dispatcherSoundListConfig.dispatcher; _dispatcher = dispatcherSoundListConfig.dispatcher;
_courier = courierSoundListConfig.courierSounds;
_audioTestClipsReferences = audioTestClipsConfig.audioTestClips; _audioTestClipsReferences = audioTestClipsConfig.audioTestClips;
MusicDictionary.Add(MusicType.Menu, new ()); MusicDictionary.Add(MusicType.Menu, new ());
@@ -137,6 +141,18 @@ namespace Code.Audio
EnemiesAudios.Clear(); EnemiesAudios.Clear();
_enemiesHandle.Release(); _enemiesHandle.Release();
} }
public async UniTask WarmCourier()
{
_courierHandle = Addressables.LoadAssetsAsync<AudioClip>(_courier, OnCourierLoaded, Addressables.MergeMode.Union);
await _courierHandle.ToUniTask();
}
public void ReleaseCourier()
{
CourierAudios.Clear();
_courierHandle.Release();
}
public async UniTask WarmDispatcher( ) public async UniTask WarmDispatcher( )
{ {
@@ -182,5 +198,9 @@ namespace Code.Audio
{ {
DispatcherAudios.Add(audioClip); DispatcherAudios.Add(audioClip);
} }
private void OnCourierLoaded(AudioClip audioClip)
{
CourierAudios.Add(audioClip);
}
} }
} }
+37 -159
View File
@@ -22,17 +22,7 @@ namespace Code.Audio
private AudioSource _actionMusicSource; private AudioSource _actionMusicSource;
private AudioSource _peacefulMusicSource; private AudioSource _peacefulMusicSource;
private AudioMixerGroup _masterGroup, private Dictionary<AudioType,AudioMixerGroup> _audioMixerGroups = new ();
// _musicGroup,
_actionMusicGroup,
_menuMusicGroup,
_peacefulMusicGroup,
_SFXGroup,
_creaturesGroup,
_dispatcherGroup,
_courierGroup,
_enemiesGroup;
private readonly AudioSourcePool _audioSourcePool; private readonly AudioSourcePool _audioSourcePool;
private Dictionary<AudioSnapshotState, AudioMixerSnapshot> _snapshots = new(); private Dictionary<AudioSnapshotState, AudioMixerSnapshot> _snapshots = new();
@@ -48,81 +38,47 @@ namespace Code.Audio
// TODO Грязно, убрать снапшоты НАХУЙ // TODO Грязно, убрать снапшоты НАХУЙ
public float GetSetting(AudioType type) public float GetSetting(AudioType type)
{ {
float value; _snapshots[AudioSnapshotState.Peaceful].audioMixer.GetFloat(_audioMixerGroups[type].name, out float value);
switch (type)
{
case AudioType.SFX:
_snapshots[AudioSnapshotState.Peaceful].audioMixer.GetFloat(_SFXGroup.name, out value);
break;
case AudioType.Master:
_snapshots[AudioSnapshotState.Menu].audioMixer.GetFloat(_masterGroup.name, out value);
break;
case AudioType.Creatures:
_snapshots[AudioSnapshotState.Peaceful].audioMixer.GetFloat(_creaturesGroup.name, out value);
break;
case AudioType.GameplayMusic:
_snapshots[AudioSnapshotState.Peaceful].audioMixer.GetFloat(_peacefulMusicGroup.name, out value);
break;
case AudioType.MenuMusic:
_snapshots[AudioSnapshotState.Menu].audioMixer.GetFloat(_menuMusicGroup.name, out value);
break;
case AudioType.DispatcherSounds:
_snapshots[AudioSnapshotState.Action].audioMixer.GetFloat(_dispatcherGroup.name, out value);
break;
default:
value = 1;
break;
}
value = Mathf.Pow(10f, value / 20); value = Mathf.Pow(10f, value / 20);
return value; return value;
} }
// TODO Грязно, убрать снапшоты НАХУЙ
public void ChangeSetting(AudioType type, float value) public void ChangeSetting(AudioType type, float value)
{ {
float volume = Mathf.Log10(value) * 20; float volume = Mathf.Log10(value) * 20;
switch (type) switch (type)
{ {
case AudioType.SFX:
_snapshots[AudioSnapshotState.Peaceful].audioMixer.SetFloat(_SFXGroup.name, volume);
_snapshots[AudioSnapshotState.Action].audioMixer.SetFloat(_SFXGroup.name, volume);
break;
case AudioType.Master: case AudioType.Master:
_snapshots[AudioSnapshotState.Menu].audioMixer.SetFloat(_masterGroup.name, volume); _snapshots[AudioSnapshotState.Menu].audioMixer.SetFloat(_audioMixerGroups[type].name, volume);
_snapshots[AudioSnapshotState.Peaceful].audioMixer.SetFloat(_masterGroup.name, volume); _snapshots[AudioSnapshotState.Peaceful].audioMixer.SetFloat(_audioMixerGroups[type].name, volume);
_snapshots[AudioSnapshotState.Action].audioMixer.SetFloat(_masterGroup.name, volume); _snapshots[AudioSnapshotState.Action].audioMixer.SetFloat(_audioMixerGroups[type].name, volume);
break; break;
case AudioType.Creatures: case AudioType.ActionMusic:
_snapshots[AudioSnapshotState.Peaceful].audioMixer.SetFloat(_creaturesGroup.name, volume); _snapshots[AudioSnapshotState.Action].audioMixer.SetFloat(_audioMixerGroups[type].name, volume);
_snapshots[AudioSnapshotState.Action].audioMixer.SetFloat(_creaturesGroup.name, volume);
break; break;
case AudioType.GameplayMusic: case AudioType.PeacefulMusic:
_snapshots[AudioSnapshotState.Peaceful].audioMixer.SetFloat(_peacefulMusicGroup.name, volume); _snapshots[AudioSnapshotState.Peaceful].audioMixer.SetFloat(_audioMixerGroups[type].name, volume);
_snapshots[AudioSnapshotState.Action].audioMixer.SetFloat(_actionMusicGroup.name, volume);
break; break;
case AudioType.MenuMusic: case AudioType.MenuMusic:
_snapshots[AudioSnapshotState.Menu].audioMixer.SetFloat(_menuMusicGroup.name, volume); _snapshots[AudioSnapshotState.Menu].audioMixer.SetFloat(_audioMixerGroups[type].name, volume);
break; break;
case AudioType.Creatures:
case AudioType.SFX:
case AudioType.DispatcherSounds: case AudioType.DispatcherSounds:
_snapshots[AudioSnapshotState.Peaceful].audioMixer.SetFloat(_dispatcherGroup.name, volume); case AudioType.Courier:
_snapshots[AudioSnapshotState.Action].audioMixer.SetFloat(_dispatcherGroup.name, volume); case AudioType.Enemies:
_snapshots[AudioSnapshotState.Peaceful].audioMixer.SetFloat(_audioMixerGroups[type].name, volume);
_snapshots[AudioSnapshotState.Action].audioMixer.SetFloat(_audioMixerGroups[type].name, volume);
break; break;
} }
// _mixer.FindSnapshot("Action").audioMixer.SetFloat("music", volume);
} }
public async UniTask Initialize() public async UniTask Initialize()
{ {
// _mixer = await _audioFactory.CreateMixer();
_mixer = _audioFactory.AudioMixer; _mixer = _audioFactory.AudioMixer;
_masterGroup = _mixer.FindMatchingGroups(AudioGroups.MasterGroup)[0];
_menuMusicGroup = _mixer.FindMatchingGroups(AudioGroups.MenuMusicGroup)[0];
_actionMusicGroup = _mixer.FindMatchingGroups(AudioGroups.ActionMusicGroup)[0];
_peacefulMusicGroup = _mixer.FindMatchingGroups(AudioGroups.PeacefulMusicGroup)[0];
// _musicGroup = _mixer.FindMatchingGroups(AudioGroups.MusicGroup)[0];
_musicAudioGroups.Add(MusicType.Menu, _mixer.FindMatchingGroups(AudioGroups.MenuMusicGroup)[0]); _musicAudioGroups.Add(MusicType.Menu, _mixer.FindMatchingGroups(AudioGroups.MenuMusicGroup)[0]);
_musicAudioGroups.Add(MusicType.Action, _mixer.FindMatchingGroups(AudioGroups.ActionMusicGroup)[0]); _musicAudioGroups.Add(MusicType.Action, _mixer.FindMatchingGroups(AudioGroups.ActionMusicGroup)[0]);
_musicAudioGroups.Add(MusicType.Peaceful, _mixer.FindMatchingGroups(AudioGroups.PeacefulMusicGroup)[0]); _musicAudioGroups.Add(MusicType.Peaceful, _mixer.FindMatchingGroups(AudioGroups.PeacefulMusicGroup)[0]);
@@ -135,16 +91,20 @@ namespace Code.Audio
_musicAudioSources.Add(MusicType.Action, null); _musicAudioSources.Add(MusicType.Action, null);
_musicAudioSources.Add(MusicType.Peaceful, null); _musicAudioSources.Add(MusicType.Peaceful, null);
_SFXGroup = _mixer.FindMatchingGroups(AudioGroups.SFXGroup)[0]; _audioMixerGroups.Add(AudioType.Master, _mixer.FindMatchingGroups(AudioGroups.MasterGroup)[0]);
_creaturesGroup = _mixer.FindMatchingGroups(AudioGroups.CreaturesGroup)[0]; _audioMixerGroups.Add(AudioType.SFX, _mixer.FindMatchingGroups(AudioGroups.SFXGroup)[0]);
_dispatcherGroup = _mixer.FindMatchingGroups(AudioGroups.DispatcherMusicGroup)[0]; _audioMixerGroups.Add(AudioType.Creatures, _mixer.FindMatchingGroups(AudioGroups.CreaturesGroup)[0]);
_courierGroup = _mixer.FindMatchingGroups(AudioGroups.CourierMusicGroup)[0]; _audioMixerGroups.Add(AudioType.DispatcherSounds, _mixer.FindMatchingGroups(AudioGroups.DispatcherMusicGroup)[0]);
_enemiesGroup = _mixer.FindMatchingGroups(AudioGroups.EnemiesMusicGroup)[0]; _audioMixerGroups.Add(AudioType.Courier, _mixer.FindMatchingGroups(AudioGroups.CourierGroup)[0]);
_audioMixerGroups.Add(AudioType.Enemies, _mixer.FindMatchingGroups(AudioGroups.EnemiesMusicGroup)[0]);
_audioMixerGroups.Add(AudioType.MenuMusic, _musicAudioGroups[MusicType.Menu]);
_audioMixerGroups.Add(AudioType.ActionMusic, _musicAudioGroups[MusicType.Action]);
_audioMixerGroups.Add(AudioType.PeacefulMusic, _musicAudioGroups[MusicType.Peaceful]);
_snapshots[AudioSnapshotState.None] = _mixer.FindSnapshot(AudioGroups.NoneSnapshot); _snapshots[AudioSnapshotState.None] = _mixer.FindSnapshot(AudioGroups.NoneSnapshot);
_snapshots[AudioSnapshotState.Peaceful] = _mixer.FindSnapshot(AudioGroups.PeacefulSnapshot);
_snapshots[AudioSnapshotState.Action] = _mixer.FindSnapshot(AudioGroups.ActionSnapshot);
_snapshots[AudioSnapshotState.Menu] = _mixer.FindSnapshot(AudioGroups.MenuSnapshot); _snapshots[AudioSnapshotState.Menu] = _mixer.FindSnapshot(AudioGroups.MenuSnapshot);
_snapshots[AudioSnapshotState.Action] = _mixer.FindSnapshot(AudioGroups.ActionSnapshot);
_snapshots[AudioSnapshotState.Peaceful] = _mixer.FindSnapshot(AudioGroups.PeacefulSnapshot);
await _audioFactory.LoadAudioSourcePrefab(_audioSourcePool.Initialize); await _audioFactory.LoadAudioSourcePrefab(_audioSourcePool.Initialize);
} }
@@ -173,15 +133,12 @@ namespace Code.Audio
// _ => !_musicAudioSources[musicType].isPlaying, // _ => !_musicAudioSources[musicType].isPlaying,
// cancellationToken: _cancellationTokenSources[musicType].Token); // cancellationToken: _cancellationTokenSources[musicType].Token);
await UniTask.NextFrame(); await UniTask.NextFrame();
// Debug.Log($"Playing {musicType}");
var (isCanceled, _) = await UniTask.WaitUntilValueChanged(_musicAudioSources[musicType], var (isCanceled, _) = await UniTask.WaitUntilValueChanged(_musicAudioSources[musicType],
_ => !_musicAudioSources[musicType].isPlaying, _ => !_musicAudioSources[musicType].isPlaying,
cancellationToken: _cancellationTokenSources[musicType].Token).SuppressCancellationThrow(); cancellationToken: _cancellationTokenSources[musicType].Token).SuppressCancellationThrow();
// Debug.Log($"Finished {musicType}");
if (isCanceled) if (isCanceled)
{ {
// Debug.Log($"Cancelled {musicType}");
_cancellationTokenSources[musicType].Dispose(); _cancellationTokenSources[musicType].Dispose();
_cancellationTokenSources[musicType] = new(); _cancellationTokenSources[musicType] = new();
@@ -227,17 +184,19 @@ namespace Code.Audio
_snapshots[state].TransitionTo(time); _snapshots[state].TransitionTo(time);
} }
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
public void PlaySFX(SFXSounds sfxId, Vector3 position) public void PlaySFX(SFXSounds sfxId, Vector3 position)
{ {
_audioSourcePool.PlayOneShot(_audioFactory.SFXAudios[(int)sfxId], position, _SFXGroup); _audioSourcePool.PlayOneShot(_audioFactory.SFXAudios[(int)sfxId], position, _audioMixerGroups[AudioType.SFX]).Forget();
} }
public void PlayEnemy(EnemiesSounds enemySoundId, Vector3 position) public void PlayEnemy(EnemiesSounds enemySoundId, Vector3 position)
{ {
_audioSourcePool.PlayOneShot(_audioFactory.EnemiesAudios[(int)enemySoundId], position, _enemiesGroup); _audioSourcePool.PlayOneShot(_audioFactory.EnemiesAudios[(int)enemySoundId], position, _audioMixerGroups[AudioType.Enemies]).Forget();
} }
public AudioSource GetSourceOfGroup(AudioType group) => _audioSourcePool.GetSource();
public void ReleaseSourceOfGroup(AudioSource source) => _audioSourcePool.ReleaseSource(source);
// Чинить долго и дорого пусть Артёмов будет много, ведь он наш друг // Чинить долго и дорого пусть Артёмов будет много, ведь он наш друг
public event IAudioService.OnAudioPlayingDelegate OnDispatcherStarted; public event IAudioService.OnAudioPlayingDelegate OnDispatcherStarted;
public event IAudioService.OnAudioPlayingDelegate OnDispatcherEnded; public event IAudioService.OnAudioPlayingDelegate OnDispatcherEnded;
@@ -245,12 +204,13 @@ namespace Code.Audio
public void PlayDispatcher(DispatcherSounds dispatcherSoundId) public void PlayDispatcher(DispatcherSounds dispatcherSoundId)
{ {
OnDispatcherStarted?.Invoke(); OnDispatcherStarted?.Invoke();
_audioSourcePool.PlayOneShot(_audioFactory.DispatcherAudios[(int)dispatcherSoundId], _dispatcherGroup, _audioSourcePool.PlayOneShot(_audioFactory.DispatcherAudios[(int)dispatcherSoundId], _audioMixerGroups[AudioType.DispatcherSounds],
AudioSourceType.NoBlend, () => OnDispatcherEnded?.Invoke()); AudioSourceType.NoBlend, () => OnDispatcherEnded?.Invoke()).Forget();
} }
private CancellationTokenSource _testClipCancellationTokenSource = new(); private CancellationTokenSource _testClipCancellationTokenSource = new();
private void ResetCurrentTestAudioSource() => _currentTestClipAudioType = AudioType.Master; private void ResetCurrentTestAudioSource() => _currentTestClipAudioType = AudioType.Master;
private AudioType _currentTestClipAudioType;
// TODO Засунуть в словарь // TODO Засунуть в словарь
public void PlayTestClip(AudioType audioType) public void PlayTestClip(AudioType audioType)
{ {
@@ -261,92 +221,10 @@ namespace Code.Audio
_currentTestClipAudioType = audioType; _currentTestClipAudioType = audioType;
switch (audioType)
{
case AudioType.SFX:
_audioSourcePool.PlayOneShot(_audioFactory.AudioTestClips[audioType], _audioSourcePool.PlayOneShot(_audioFactory.AudioTestClips[audioType],
_SFXGroup, _testClipCancellationTokenSource, _audioMixerGroups[audioType], _testClipCancellationTokenSource,
AudioSourceType.NoBlend, ResetCurrentTestAudioSource); AudioSourceType.NoBlend, ResetCurrentTestAudioSource).Forget();
break;
case AudioType.Master:
_audioSourcePool.PlayOneShot(_audioFactory.AudioTestClips[audioType],
_masterGroup, _testClipCancellationTokenSource,
AudioSourceType.NoBlend, ResetCurrentTestAudioSource);
break;
case AudioType.Creatures:
_audioSourcePool.PlayOneShot( _audioFactory.AudioTestClips[audioType],
_creaturesGroup, _testClipCancellationTokenSource,
AudioSourceType.NoBlend, ResetCurrentTestAudioSource);
break;
case AudioType.GameplayMusic:
_audioSourcePool.PlayOneShot(_audioFactory.AudioTestClips[audioType],
_actionMusicGroup, _testClipCancellationTokenSource,
AudioSourceType.NoBlend, ResetCurrentTestAudioSource);
break;
case AudioType.MenuMusic:
_audioSourcePool.PlayOneShot(_audioFactory.AudioTestClips[audioType],
_menuMusicGroup, _testClipCancellationTokenSource,
AudioSourceType.NoBlend, ResetCurrentTestAudioSource);
break;
case AudioType.DispatcherSounds:
_audioSourcePool.PlayOneShot(_audioFactory.AudioTestClips[audioType],
_dispatcherGroup, _testClipCancellationTokenSource,
AudioSourceType.NoBlend, ResetCurrentTestAudioSource);
break;
}
} }
private AudioSource _testClipAudioSource;
private AudioType _currentTestClipAudioType;
// Эффективно и просто, может не так хитровыебано
private void ReleaseTestAudioClipSource()
{
_testClipAudioSource = null;
}
// TODO Засунуть в словарь
public void PlayTestClipDeprecated(AudioType audioType)
{
if (!_testClipAudioSource) _testClipAudioSource = _audioSourcePool.GetSource();
else if (_currentTestClipAudioType != audioType) _testClipAudioSource.Stop();
else return;
_currentTestClipAudioType = audioType;
switch (audioType)
{
case AudioType.SFX:
_audioSourcePool.PlayOneShot(_testClipAudioSource, _audioFactory.AudioTestClips[audioType],
_SFXGroup,
AudioSourceType.NoBlend, ReleaseTestAudioClipSource);
break;
case AudioType.Master:
_audioSourcePool.PlayOneShot(_testClipAudioSource, _audioFactory.AudioTestClips[audioType],
_masterGroup,
AudioSourceType.NoBlend, ReleaseTestAudioClipSource);
break;
case AudioType.Creatures:
_audioSourcePool.PlayOneShot(_testClipAudioSource, _audioFactory.AudioTestClips[audioType],
_creaturesGroup,
AudioSourceType.NoBlend, ReleaseTestAudioClipSource);
break;
case AudioType.GameplayMusic:
_audioSourcePool.PlayOneShot(_testClipAudioSource, _audioFactory.AudioTestClips[audioType],
_actionMusicGroup,
AudioSourceType.NoBlend, ReleaseTestAudioClipSource);
break;
case AudioType.MenuMusic:
_audioSourcePool.PlayOneShot(_testClipAudioSource, _audioFactory.AudioTestClips[audioType],
_menuMusicGroup,
AudioSourceType.NoBlend, ReleaseTestAudioClipSource);
break;
case AudioType.DispatcherSounds:
_audioSourcePool.PlayOneShot(_testClipAudioSource, _audioFactory.AudioTestClips[audioType],
_dispatcherGroup,
AudioSourceType.NoBlend, ReleaseTestAudioClipSource);
break;
}
}
} }
} }
@@ -14,6 +14,7 @@ namespace Code.Audio
List<AudioClip> SFXAudios { get; } List<AudioClip> SFXAudios { get; }
List<AudioClip> EnemiesAudios { get; } List<AudioClip> EnemiesAudios { get; }
List<AudioClip> DispatcherAudios { get; } List<AudioClip> DispatcherAudios { get; }
List<AudioClip> CourierAudios { get; }
UniTask LoadAudioSourcePrefab(Action<GameObject> callback); UniTask LoadAudioSourcePrefab(Action<GameObject> callback);
UniTask WarmGameplayMusic( ); UniTask WarmGameplayMusic( );
void ReleaseActionMusic(); void ReleaseActionMusic();
@@ -28,5 +29,7 @@ namespace Code.Audio
void ReleaseEnemies(); void ReleaseEnemies();
UniTask WarmDispatcher( ); UniTask WarmDispatcher( );
void ReleaseDispatcher(); void ReleaseDispatcher();
UniTask WarmCourier();
void ReleaseCourier();
} }
} }
@@ -23,5 +23,7 @@ namespace Code.Audio
void ChangeSetting(AudioType type, float value); void ChangeSetting(AudioType type, float value);
float GetSetting(AudioType type); float GetSetting(AudioType type);
void PlayTestClip(AudioType audioType); void PlayTestClip(AudioType audioType);
AudioSource GetSourceOfGroup(AudioType group);
void ReleaseSourceOfGroup(AudioSource source);
} }
} }
@@ -10,9 +10,12 @@ namespace Code.Audio
{ {
Master, Master,
MenuMusic, MenuMusic,
GameplayMusic,
Creatures, Creatures,
DispatcherSounds, DispatcherSounds,
SFX SFX,
Courier,
Enemies,
ActionMusic,
PeacefulMusic
} }
} }
@@ -23,17 +23,11 @@ namespace Code.Configs
slideDuration = 0.8f, // Длительность слайда в секундах slideDuration = 0.8f, // Длительность слайда в секундах
slideCooldown = 1.5f; // Время перезарядки слайда в секундах slideCooldown = 1.5f; // Время перезарядки слайда в секундах
// Залазание на стены
public float
wallClimbSpeedFactor = 0.8f, // Коэффициент преобразования горизонтальной скорости в вертикальную при залазании на стену
minWallClimbSpeed = 9f, // Минимальная горизонтальная скорость для начала залазания на стену
wallDetectionAngleThreshold = 80f; // Максимальный угол (в градусах) от вертикали, при котором поверхность считается "стеной"
// Наклон при залазании на стены // Наклон при залазании на стены
public float public float
maxWallLeanAngle = 45f, // Максимальный угол наклона от стены (в градусах) leanAngle = 25f,
wallLeanSharpness = 50f, // Скорость наклона/выпрямления (чем выше — тем резче) leanThreshold = 0.3f,
wallLeanHeightScale = 0.1f; // Множитель: на сколько метров подъёма = 1 единица "наклона" leanSmoothSpeed = 10f;
// Гравитация // Гравитация
public Vector3 gravity = new(0f, -30f, 0f); // Вектор, отвечающий за применение гравитации public Vector3 gravity = new(0f, -30f, 0f); // Вектор, отвечающий за применение гравитации
@@ -1,11 +0,0 @@
using UnityEngine;
using UnityEngine.AddressableAssets;
namespace Code.Configs
{
[CreateAssetMenu(menuName = "Config/Audio/CharacterSoundList", fileName = "CharacterSoundListConfig")]
public class CharacterSoundListConfig : ScriptableObject
{
public AssetReference[] character;
}
}
@@ -0,0 +1,11 @@
using UnityEngine;
using UnityEngine.AddressableAssets;
namespace Code.Configs
{
[CreateAssetMenu(menuName = "Config/Audio/CourierSoundListConfig", fileName = "CourierSoundListConfig")]
public class CourierSoundListConfig : ScriptableObject
{
public AssetReference[] courierSounds;
}
}
@@ -0,0 +1,10 @@
using UnityEngine;
namespace Code.Configs
{
[CreateAssetMenu(menuName = "Config/Audio/MusicPlayer", fileName = "MusicPlayerConfig")]
public class MusicPlayerConfig : ScriptableObject
{
public float threshold = 0.5f;
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 8708e3c129d241b08563f1a170bd3a44
timeCreated: 1764585060
@@ -19,7 +19,7 @@ namespace Code.Constants
public const string PeacefulMusicGroup = "Peaceful"; public const string PeacefulMusicGroup = "Peaceful";
public const string ActionMusicGroup = "Action"; public const string ActionMusicGroup = "Action";
public const string DispatcherMusicGroup = "Dispatcher"; public const string DispatcherMusicGroup = "Dispatcher";
public const string CourierMusicGroup = "Courier"; public const string CourierGroup = "Courier";
public const string EnemiesMusicGroup = "Enemies"; public const string EnemiesMusicGroup = "Enemies";
public const string PeacefulSnapshot = "Peaceful"; public const string PeacefulSnapshot = "Peaceful";
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: bb5ad0cc3a72448a93ee2adb560c35ad
timeCreated: 1764345160
@@ -0,0 +1,12 @@
using UnityEngine;
namespace Code.DebugAndTest
{
public class TriggerTest : MonoBehaviour
{
private void OnTriggerEnter(Collider other)
{
Debug.Log(gameObject.name + " found " + other.name);
}
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 6bb3c649d82049079d00b843a76aced8
timeCreated: 1764345168
@@ -24,6 +24,8 @@ namespace Code.Gameplay.Camera.CameraStates
CurrentDistance = 0f; CurrentDistance = 0f;
Camera.fieldOfView = Context.CameraSettingsConfigs[CameraMode.FirstPerson].fov; Camera.fieldOfView = Context.CameraSettingsConfigs[CameraMode.FirstPerson].fov;
Cursor.lockState = CursorLockMode.Locked;
} }
protected override void HandlePosition(float deltaTime, float zoomInput, Quaternion targetRotation) protected override void HandlePosition(float deltaTime, float zoomInput, Quaternion targetRotation)
@@ -11,6 +11,7 @@ namespace Code.Gameplay.Camera.CameraStates
base.EnterState(); base.EnterState();
Camera.fieldOfView = Context.CameraSettingsConfigs[CameraMode.MainMenu].fov; Camera.fieldOfView = Context.CameraSettingsConfigs[CameraMode.MainMenu].fov;
Cursor.lockState = CursorLockMode.None;
} }
protected override void HandlePosition(float deltaTime, float zoomInput, Quaternion targetRotation) protected override void HandlePosition(float deltaTime, float zoomInput, Quaternion targetRotation)
@@ -12,6 +12,7 @@ namespace Code.Gameplay.Camera.CameraStates
base.EnterState(); base.EnterState();
Camera.fieldOfView = Context.CameraSettingsConfigs[CameraMode.Static].fov; Camera.fieldOfView = Context.CameraSettingsConfigs[CameraMode.Static].fov;
Cursor.lockState = CursorLockMode.None;
} }
protected override void HandlePosition(float deltaTime, float zoomInput, Quaternion targetRotation) protected override void HandlePosition(float deltaTime, float zoomInput, Quaternion targetRotation)
@@ -1,147 +1,78 @@
using UnityEngine; using UnityEngine;
using KinematicCharacterController;
namespace Code.Gameplay.Character.Controller.Abilities namespace Code.Gameplay.Character.Controller.Abilities
{ {
/*
* Механика наклона персонажа при контакте со стеной
* Управляет визуальным наклоном модели в зависимости от высоты подъёма по стене
*/
public class WallLeanMechanic public class WallLeanMechanic
{ {
private readonly float _maxLeanAngle; private readonly float _leanAngle;
private readonly float _leanSharpness; private readonly float _threshold;
private readonly float _heightScale; private readonly float _smoothSpeed;
private Transform _characterTransform; private Transform _model;
private Vector3 _lastWallNormal;
private float _lastWallContactHeight;
private float _leanFactor;
private float _leanSign;
private Vector3 _leanDirection;
private Vector3 _lastWallContactPoint; public WallLeanMechanic(
private bool _isLeaningOnWall; float leanAngle,
private const float WallProximityThreshold = 0.6f; float threshold,
float smoothSpeed)
public WallLeanMechanic(float maxLeanAngle, float leanSharpness, float heightScale)
{ {
_maxLeanAngle = maxLeanAngle; _leanAngle = leanAngle;
_leanSharpness = leanSharpness; _threshold = threshold;
_heightScale = heightScale; _smoothSpeed = smoothSpeed;
} }
// Назначаем трансформ визуальной модели один раз public void SetModel(Transform model) => _model = model;
public void SetCharacterTransform(Transform transform)
{
_characterTransform = transform;
}
// Вызывается из OnMovementHit public void Update(bool isWallRunning, Vector3 wallNormal, Vector3 characterForward)
public void OnWallContact(KinematicCharacterMotor motor, Vector3 wallNormal, float contactHeight)
{ {
// Только если это действительно стена (не пол/потолок) if (!_model)
var dotWithUp = Vector3.Dot(wallNormal, motor.CharacterUp);
if (Mathf.Abs(dotWithUp) > 0.7f) // ~45°, можно настроить
return;
_lastWallNormal = wallNormal;
_lastWallContactHeight = contactHeight;
_lastWallContactPoint = motor.TransientPosition;
// Пересчитываем направление наклона
_leanDirection = -_lastWallNormal;
_leanDirection = Vector3.ProjectOnPlane(_leanDirection, motor.CharacterUp).normalized;
_leanSign = 1;
// what the fuck
if (_leanDirection.x != 0)
{ {
switch (_leanDirection.x) _model.localRotation = Quaternion.identity;
{
case -1 or 1 when motor.CharacterRight.x > 0.1f:
_leanSign = -1;
break;
case -1 or 1 when Mathf.Abs(motor.CharacterRight.x) < 0.1f:
_leanDirection = new Vector3(0, 0, -1);
break;
}
}
else
{
switch (_leanDirection.z)
{
case 1 when Mathf.Abs(motor.CharacterRight.z) < 0.1f:
_leanSign = -1;
break;
case -1 when motor.CharacterRight.z < -0.1f:
case 1 when motor.CharacterRight.z > 0.1f:
_leanDirection = new Vector3(-1, 0, 0);
break;
case -1 when motor.CharacterRight.z > 0.1f:
case 1 when motor.CharacterRight.z < -0.1f:
_leanDirection = new Vector3(1, 0, 0);
break;
}
}
_isLeaningOnWall = true;
}
// Обновление каждый кадр
public void UpdateLean(KinematicCharacterMotor motor, float deltaTime)
{
if (!_characterTransform) return;
var currentPosition = motor.TransientPosition;
var isStillNearWall = false;
if (_isLeaningOnWall && _lastWallNormal != Vector3.zero)
{
var toWall = currentPosition - _lastWallContactPoint;
var distanceToWallPlane = Mathf.Abs(Vector3.Dot(toWall, _lastWallNormal));
isStillNearWall = distanceToWallPlane <= WallProximityThreshold;
}
if (_isLeaningOnWall)
{
var isBelowContactHeight = currentPosition.y < _lastWallContactHeight;
if (!isStillNearWall || isBelowContactHeight)
{
_isLeaningOnWall = false;
}
else
{
var heightDelta = currentPosition.y - _lastWallContactHeight;
var targetLeanFactor = Mathf.Clamp01(heightDelta * _heightScale);
_leanFactor = Mathf.Lerp(_leanFactor, targetLeanFactor, 1f - Mathf.Exp(-_leanSharpness * deltaTime));
}
}
if (!_isLeaningOnWall)
{
_leanFactor = Mathf.Lerp(_leanFactor, 0f, 1f - Mathf.Exp(-_leanSharpness * deltaTime));
}
ApplyLeanRotation(motor);
}
private void ApplyLeanRotation(KinematicCharacterMotor motor)
{
if (_leanFactor <= 0.01f)
{
_characterTransform.localRotation = Quaternion.identity;
return; return;
} }
if (_leanDirection.sqrMagnitude < 0.01f) return; var targetRotation = Quaternion.identity;
var leanAngle = _leanSign * _leanFactor * _maxLeanAngle; if (isWallRunning)
var leanAxis = Vector3.Cross(motor.CharacterUp, _leanDirection); {
var leanRotation = Quaternion.AngleAxis(leanAngle, leanAxis); var n = new Vector3(wallNormal.x, 0f, wallNormal.z).normalized;
_characterTransform.localRotation = leanRotation; if (n.sqrMagnitude < 0.001f) n = Vector3.forward;
var bodyRight = Vector3.Cross(Vector3.up, characterForward).normalized;
var side = Vector3.Dot(n, bodyRight);
var front = Vector3.Dot(n, characterForward);
var axis = Vector3.right;
var angle = 0f;
if (side > _threshold)
{
axis = Vector3.forward;
angle = -_leanAngle;
}
else if (side < -_threshold)
{
axis = Vector3.forward;
angle = _leanAngle;
}
else if (front > _threshold)
{
axis = Vector3.right;
angle = -_leanAngle;
}
else if (front < -_threshold)
{
axis = Vector3.right;
angle = _leanAngle;
}
targetRotation = Quaternion.AngleAxis(angle, axis);
}
_model.localRotation = Quaternion.Slerp(
_model.localRotation,
targetRotation,
1f - Mathf.Exp(-_smoothSpeed * Time.deltaTime)
);
} }
} }
} }
@@ -0,0 +1,256 @@
using Code.Gameplay.Character.Controller.Input;
using Code.Gameplay.Character.Core;
using KinematicCharacterController;
using UnityEngine;
namespace Code.Gameplay.Character.Controller.Abilities
{
public class WallRunningMechanic
{
public float MaxWallRunTime = 1.75f;
public float WallRunSpeed = 8.0f;
public float WallRunAcceleration = 25.0f;
public float WallRunGravityScale = 0.25f;
public float WallDetachImpulse = 7.0f;
public float WallContactAngleThreshold = 45.0f;
private bool _isWallRunning;
private float _wallRunTimer;
private Vector3 _wallNormal;
private Vector3 _wallTangentRight;
private Vector3 _wallTangentUp;
private Vector3 _wallContactPoint;
private Vector3 _lastMoveInputInWallSpace;
private float _surfaceAngleCos;
private bool _canWallRun;
public float WallContactHeight { get; private set; }
public Vector3 WallRunStartForward { get; private set; }
private KinematicCharacterMotor _motor;
private CharacterInputHandler _inputHandler;
public bool IsWallRunning => _isWallRunning;
public void Initialize(KinematicCharacterMotor motor, CharacterInputHandler inputHandler)
{
_motor = motor;
_inputHandler = inputHandler;
_surfaceAngleCos = Mathf.Cos(Mathf.Deg2Rad * WallContactAngleThreshold);
}
public void Reset()
{
_isWallRunning = false;
_wallRunTimer = 0f;
_wallNormal = Vector3.zero;
}
public void Tick(float deltaTime)
{
if (_isWallRunning)
{
_wallRunTimer += deltaTime;
if (_wallRunTimer > MaxWallRunTime)
{
DetachFromWall(false);
}
}
}
public bool TryStartWallRun(Vector3 hitNormal, Vector3 hitPoint)
{
if (_isWallRunning) return false;
float dotWithUp = Vector3.Dot(hitNormal, _motor.CharacterUp);
bool isWall = Mathf.Abs(dotWithUp) < _surfaceAngleCos;
if (!isWall) return false;
if (_motor.GroundingStatus.IsStableOnGround) return false;
float velocityIntoWall = Vector3.Dot(_motor.Velocity, -hitNormal);
if (velocityIntoWall < 1f) return false;
StartWallRun(hitNormal, hitPoint);
return true;
}
private void StartWallRun(Vector3 wallNormal, Vector3 contactPoint)
{
_isWallRunning = true;
_wallRunTimer = 0f;
_wallNormal = wallNormal.normalized;
_wallContactPoint = contactPoint;
WallContactHeight = contactPoint.y;
//_wallTangentUp = Vector3.ProjectOnPlane(_motor.CharacterUp, _wallNormal).normalized;
if (_wallTangentUp.sqrMagnitude < 0.01f) _wallTangentUp = Vector3.up;
_wallTangentRight = Vector3.Cross(_wallNormal, _wallTangentUp).normalized;
_wallTangentUp = Vector3.Cross(_wallTangentRight, _wallNormal).normalized;
if (Vector3.Dot(_wallTangentUp, Vector3.up) < 0)
_wallTangentUp = -_wallTangentUp;
WallRunStartForward = _motor.CharacterForward;
_motor.ForceUnground();
}
public void HandleWallRun(ref Vector3 currentVelocity, CharacterInputs inputs, float deltaTime)
{
if (!_isWallRunning) return;
if (!IsWallStillPresent()) { DetachFromWall(false); return; }
Vector3 moveInputWorld = _inputHandler.MoveInputVector;
Vector3 moveInWallPlane = Vector3.ProjectOnPlane(moveInputWorld, _wallNormal);
Vector3 wsMove = Vector3.Project(moveInWallPlane, _wallTangentRight);
float ad = inputs.MoveAxisRight;
float sideDot = Vector3.Dot(_wallNormal, _motor.CharacterRight);
if (sideDot < 0)
ad = -ad;
Vector3 adMove = _wallTangentUp * (-ad);
Vector3 finalMove = wsMove + adMove;
finalMove = finalMove.normalized * moveInputWorld.magnitude;
Vector3 targetVelocity = finalMove * WallRunSpeed;
currentVelocity = Vector3.Lerp(
currentVelocity,
targetVelocity,
1f - Mathf.Exp(-WallRunAcceleration * deltaTime)
);
currentVelocity += Physics.gravity * (WallRunGravityScale * deltaTime);
float distanceToWall = Vector3.Dot(_motor.TransientPosition - _wallContactPoint, _wallNormal);
if (Mathf.Abs(distanceToWall) > 0.8f)
{
DetachFromWall(false);
return;
}
if (inputs.JumpPressed)
{
DetachFromWall(true);
}
}
private bool IsWallStillPresent()
{
if (_motor == null) return false;
Vector3 characterCenter = _motor.TransientPosition;
Vector3 characterForward = _motor.CharacterForward;
Vector3 characterRight = _motor.CharacterRight;
Vector3 characterUp = _motor.CharacterUp;
float checkDistance = 0.45f;
Vector3 rayOrigin = characterCenter + characterUp * 0.2f;
Vector3 rayDir = -_wallNormal;
Vector3[] offsets = {
Vector3.zero,
characterUp * 0.3f,
-characterUp * 0.3f,
characterRight * 0.2f,
-characterRight * 0.2f
};
foreach (var offset in offsets)
{
if (Physics.Raycast(rayOrigin + offset, rayDir, out RaycastHit hit, checkDistance,
_motor.CollidableLayers, QueryTriggerInteraction.Ignore))
{
float dotWithUp = Mathf.Abs(Vector3.Dot(hit.normal, characterUp));
if (dotWithUp < _surfaceAngleCos)
{
_wallNormal = hit.normal.normalized;
_wallContactPoint = hit.point;
/*_wallTangentUp = Vector3.ProjectOnPlane(_motor.CharacterUp, _wallNormal).normalized;
if (_wallTangentUp.sqrMagnitude < 0.01f) _wallTangentUp = Vector3.up;
_wallTangentRight = Vector3.Cross(_wallNormal, _wallTangentUp).normalized;
*/
return true;
}
}
}
return false;
}
public void DetachFromWall(bool withImpulse)
{
if (!_isWallRunning) return;
_isWallRunning = false;
if (withImpulse && _motor != null)
{
Vector3 detachImpulse = -_wallNormal * WallDetachImpulse;
_motor.BaseVelocity += detachImpulse;
}
}
public Vector3 GetWallNormal() => _wallNormal;
public bool TryGetWallTangents(out Vector3 up, out Vector3 right)
{
if (!_isWallRunning)
{
up = right = Vector3.zero;
return false;
}
up = _wallTangentUp;
right = _wallTangentRight;
return true;
}
public bool CanWallRun()
{
return !_isWallRunning && !_motor.GroundingStatus.IsStableOnGround;
}
public void PerformWallJump(CharacterInputs inputs, Quaternion cameraRotation)
{
if (!_isWallRunning || _motor == null) return;
_isWallRunning = false;
Vector3 wallAway = _wallNormal;
Vector3 wallUp = _wallTangentUp;
Vector3 playerForward = cameraRotation * Vector3.forward;
Vector3 forwardInWallPlane = Vector3.ProjectOnPlane(playerForward, _wallNormal).normalized;
if (forwardInWallPlane.sqrMagnitude < 0.01f) forwardInWallPlane = _wallTangentRight;
Vector3 jumpDirection =
forwardInWallPlane * 0.2f +
wallAway * 0.4f +
wallUp * 0.4f;
jumpDirection = jumpDirection.normalized;
float wallJumpForce = WallDetachImpulse * 2f;
Vector3 jumpImpulse = jumpDirection * wallJumpForce;
_motor.BaseVelocity += jumpImpulse;
_motor.SetPosition(_motor.TransientPosition + wallAway * 0.07f);
if (_motor.CharacterController is CustomCharacterController controller)
{
controller.BlockAbilities(0.12f);
}
}
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 4bef67aa9cf14753a63ea07eecc5ff67
timeCreated: 1764263348
@@ -28,49 +28,23 @@ namespace Code.Gameplay.Character.Controller
// Подсистемы // Подсистемы
private CharacterInputHandler _inputHandler; private CharacterInputHandler _inputHandler;
private SlideMechanic _slideMechanic; private SlideMechanic _slideMechanic;
private WallClimbMechanic _wallClimbMechanic; // private WallClimbMechanic _wallClimbMechanic;
private WallRunningMechanic _wallRunningMechanic;
private WallLeanMechanic _wallLeanMechanic; private WallLeanMechanic _wallLeanMechanic;
private GroundMovementSystem _groundMovement; private GroundMovementSystem _groundMovement;
private AirMovementSystem _airMovement; private AirMovementSystem _airMovement;
public bool IsSliding => _slideMechanic.IsSliding; public bool IsSliding => _slideMechanic.IsSliding;
public bool IsWallRunning => _wallRunningMechanic.IsWallRunning;
private float abilityBlockTimer; private float abilityBlockTimer;
private bool isAbilitiesBlocked; private bool isAbilitiesBlocked;
private CharacterInputs _lastInputs;
public void SetPosition(Vector3 position) => motor.SetPosition(position); public void SetPosition(Vector3 position) => motor.SetPosition(position);
public void SetRotation(Quaternion rotation) => motor.SetRotation(rotation); public void SetRotation(Quaternion rotation) => motor.SetRotation(rotation);
// Инициализация контроллера
// private void Awake()
// {
// // Инициализация подсистем с параметрами из конфига
// _inputHandler = new CharacterInputHandler(
// _characterConfig.sprintAngleThreshold
// );
// _slideMechanic = new SlideMechanic(
// _characterConfig.slideSpeed,
// _characterConfig.slideDuration,
// _characterConfig.slideCooldown
// );
// _wallClimbMechanic = new WallClimbMechanic(
// _characterConfig.wallClimbSpeedFactor,
// _characterConfig.minWallClimbSpeed,
// _characterConfig.wallDetectionAngleThreshold
// );
// _wallLeanMechanic = new WallLeanMechanic(
// _characterConfig.maxWallLeanAngle,
// _characterConfig.wallLeanSharpness,
// _characterConfig.wallLeanHeightScale
// );
// _groundMovement = new GroundMovementSystem(
// _characterConfig.maxStableMoveSpeed,
// _characterConfig.sprintMoveSpeed,
// _characterConfig.stableMovementSharpness,
// _characterConfig.jumpSpeed
// );
// _airMovement = new AirMovementSystem(_characterConfig.gravity);
// }
[Inject] [Inject]
private void Construct(CharacterConfig characterConfig) private void Construct(CharacterConfig characterConfig)
{ {
@@ -84,15 +58,24 @@ namespace Code.Gameplay.Character.Controller
_characterConfig.slideDuration, _characterConfig.slideDuration,
_characterConfig.slideCooldown _characterConfig.slideCooldown
); );
_wallClimbMechanic = new WallClimbMechanic( // _wallClimbMechanic = new WallClimbMechanic(
_characterConfig.wallClimbSpeedFactor, // _characterConfig.wallClimbSpeedFactor,
_characterConfig.minWallClimbSpeed, // _characterConfig.minWallClimbSpeed,
_characterConfig.wallDetectionAngleThreshold // _characterConfig.wallDetectionAngleThreshold
); // );
_wallRunningMechanic = new WallRunningMechanic();
// Настройка параметров WallRunningMechanic (можно вынести в конфиг позже)
_wallRunningMechanic.MaxWallRunTime = 1.75f;
_wallRunningMechanic.WallRunSpeed = 15.0f;
_wallRunningMechanic.WallRunAcceleration = 25.0f;
_wallRunningMechanic.WallRunGravityScale = 0.25f;
_wallRunningMechanic.WallDetachImpulse = 7.0f;
_wallRunningMechanic.WallContactAngleThreshold = 45.0f;
_wallLeanMechanic = new WallLeanMechanic( _wallLeanMechanic = new WallLeanMechanic(
_characterConfig.maxWallLeanAngle, _characterConfig.leanAngle,
_characterConfig.wallLeanSharpness, _characterConfig.leanThreshold,
_characterConfig.wallLeanHeightScale _characterConfig.leanSmoothSpeed
); );
_groundMovement = new GroundMovementSystem( _groundMovement = new GroundMovementSystem(
_characterConfig.maxStableMoveSpeed, _characterConfig.maxStableMoveSpeed,
@@ -106,31 +89,24 @@ namespace Code.Gameplay.Character.Controller
motor.CharacterController = this; // Регистрация этого контроллера в движке motor.CharacterController = this; // Регистрация этого контроллера в движке
_inputHandler.FirstPersonCameraRotation = _inputHandler.FirstPersonCameraRotation =
motor.Transform.rotation; // Начальное вращение совпадает с персонажемс motor.Transform.rotation; // Начальное вращение совпадает с персонажемс
_wallLeanMechanic.SetCharacterTransform(characterTransform); _wallLeanMechanic.SetModel(characterTransform);
_wallRunningMechanic.Initialize(motor, _inputHandler);
} }
// Текущий режим камеры для адаптации поведения // Текущий режим камеры для адаптации поведения
private CameraMode _currentCameraMode = CameraMode.FirstPerson; private CameraMode _currentCameraMode = CameraMode.FirstPerson;
// Инициализация контроллера
// private void Start()
// {
// motor.CharacterController = this; // Регистрация этого контроллера в движке
// _inputHandler.FirstPersonCameraRotation =
// motor.Transform.rotation; // Начальное вращение совпадает с персонажемс
// _wallLeanMechanic.SetCharacterTransform(characterTransform);
// }
// Обработка и преобразование входных данных от персонажа
public void SetInputs(ref CharacterInputs inputs) public void SetInputs(ref CharacterInputs inputs)
{ {
// Обновляем таймер перезарядки слайда _lastInputs = inputs;
// Обновляем таймеры механик
_slideMechanic.TickCooldown(Time.deltaTime); _slideMechanic.TickCooldown(Time.deltaTime);
_wallClimbMechanic.TickCooldown(Time.deltaTime); // _wallClimbMechanic.TickCooldown(Time.deltaTime);
_wallRunningMechanic.Tick(Time.deltaTime);
// Если активен слайд - игнорируем весь остальной ввод // Если активен слайд - игнорируем весь остальной ввод
if (_slideMechanic.IsSliding) if (_slideMechanic.IsSliding)
{ {
// Во время слайда не обрабатываем движение, прыжки и спринт
_inputHandler.MoveInputVector = Vector3.zero; _inputHandler.MoveInputVector = Vector3.zero;
_inputHandler.LookInputVector = Vector3.one; _inputHandler.LookInputVector = Vector3.one;
_inputHandler.IsSprinting = false; _inputHandler.IsSprinting = false;
@@ -138,7 +114,6 @@ namespace Code.Gameplay.Character.Controller
return; return;
} }
// Сохраняем текущий режим камеры
_currentCameraMode = inputs.CameraMode; _currentCameraMode = inputs.CameraMode;
if (isAbilitiesBlocked) if (isAbilitiesBlocked)
@@ -161,42 +136,33 @@ namespace Code.Gameplay.Character.Controller
// Обработка остального ввода // Обработка остального ввода
_inputHandler.ProcessInputs(ref inputs, motor); _inputHandler.ProcessInputs(ref inputs, motor);
// Передаём запрос прыжка напрямую в систему движения по земле // Передаём запрос прыжка
_groundMovement.RequestJump(inputs.JumpPressed); _groundMovement.RequestJump(inputs.JumpPressed);
} }
// Обновление вращения персонажа на основе входных данных
public void UpdateRotation(ref Quaternion currentRotation, float deltaTime) public void UpdateRotation(ref Quaternion currentRotation, float deltaTime)
{ {
if (_slideMechanic.IsSliding || _wallClimbMechanic.IsClimbingActive) return; if (_slideMechanic.IsSliding) return;
switch (_currentCameraMode) switch (_currentCameraMode)
{ {
// В FirstPerson режиме применяем вращение камеры напрямую к персонажу (только горизонталь)
case CameraMode.FirstPerson when _inputHandler.ShouldApplyCameraRotation: case CameraMode.FirstPerson when _inputHandler.ShouldApplyCameraRotation:
// Немедленно применяем горизонтальное вращение камеры к персонажу
currentRotation = _inputHandler.FirstPersonCameraRotation; currentRotation = _inputHandler.FirstPersonCameraRotation;
break; break;
// В ThirdPerson режиме плавно поворачиваем персонаж в направлении движения
case CameraMode.ThirdPerson: case CameraMode.ThirdPerson:
{ {
// Вращение применяется только если есть направление движения и разрешена резкость вращения
if (_inputHandler.LookInputVector.sqrMagnitude > 0 && _characterConfig.orientationSharpness > 0) if (_inputHandler.LookInputVector.sqrMagnitude > 0 && _characterConfig.orientationSharpness > 0)
{ {
// Плавная интерполяция текущего направления к целевому с экспоненциальным сглаживанием
var smoothedLookInputDirection = Vector3.Slerp( var smoothedLookInputDirection = Vector3.Slerp(
motor.CharacterForward, motor.CharacterForward,
_inputHandler.LookInputVector, _inputHandler.LookInputVector,
1f - Mathf.Exp(-_characterConfig.orientationSharpness * deltaTime) 1f - Mathf.Exp(-_characterConfig.orientationSharpness * deltaTime)
).normalized; ).normalized;
// Установка нового вращения смотря в сглаженном направлении
currentRotation = Quaternion.LookRotation(smoothedLookInputDirection, motor.CharacterUp); currentRotation = Quaternion.LookRotation(smoothedLookInputDirection, motor.CharacterUp);
} }
break; break;
} }
// Заготовка на будущее (если понадобится)
case CameraMode.Static: case CameraMode.Static:
case CameraMode.Cinematic: case CameraMode.Cinematic:
default: default:
@@ -204,38 +170,49 @@ namespace Code.Gameplay.Character.Controller
} }
} }
// Обновление скорости движения персонажа
public void UpdateVelocity(ref Vector3 currentVelocity, float deltaTime) public void UpdateVelocity(ref Vector3 currentVelocity, float deltaTime)
{ {
// Если во время слайда запрошен прыжок — прерываем слайд
if (_slideMechanic.IsSliding && _groundMovement.JumpRequested) if (_slideMechanic.IsSliding && _groundMovement.JumpRequested)
{ {
_slideMechanic.EndSlide(); _slideMechanic.EndSlide();
} }
// Проверяем запрос слайда и запускаем его если можно
if (!_slideMechanic.IsSliding) if (!_slideMechanic.IsSliding)
{ {
_slideMechanic.TryStartSlide(motor, _currentCameraMode, _inputHandler.FirstPersonCameraRotation, _slideMechanic.TryStartSlide(motor, _currentCameraMode, _inputHandler.FirstPersonCameraRotation,
_inputHandler.LookInputVector); _inputHandler.LookInputVector);
} }
// Если активен слайд - обрабатываем отдельно
else else
{ {
_slideMechanic.HandleSlide(ref currentVelocity, deltaTime, motor); _slideMechanic.HandleSlide(ref currentVelocity, deltaTime, motor);
return; return;
} }
// === WALL RUNNING: обработка состояния ===
if (_wallRunningMechanic.IsWallRunning)
{
// 🔄 Передаём актуальные данные для walljump
if (_groundMovement.JumpRequested) // или _lastInputs.JumpPressed — зависит от логики
{
_wallRunningMechanic.PerformWallJump(_lastInputs, _inputHandler.FirstPersonCameraRotation);
_groundMovement.CancelJumpRequest(); // сброс, чтобы не сработало дважды
}
else
{
_wallRunningMechanic.HandleWallRun(ref currentVelocity, _lastInputs, deltaTime);
}
return;
}
// Если персонаж находится на земле // Если персонаж находится на земле
if (motor.GroundingStatus.IsStableOnGround) if (motor.GroundingStatus.IsStableOnGround)
{ {
_groundMovement.UpdateVelocity(ref currentVelocity, _inputHandler, motor, deltaTime); _groundMovement.UpdateVelocity(ref currentVelocity, _inputHandler, motor, deltaTime);
} }
// Если персонаж не находится на земле // Если персонаж не на земле — стандартное воздушное движение
else else
{ {
_airMovement.UpdateVelocity(ref currentVelocity, deltaTime); _airMovement.UpdateVelocity(ref currentVelocity, deltaTime);
// Отменяем прыжок (фикс проблемы с двойным прыжком после приземления)
_groundMovement.CancelJumpRequest(); _groundMovement.CancelJumpRequest();
} }
} }
@@ -246,60 +223,51 @@ namespace Code.Gameplay.Character.Controller
abilityBlockTimer = duration; abilityBlockTimer = duration;
} }
// Метод вызывается перед обновлением персонажа (можно использовать для подготовки)
public void BeforeCharacterUpdate(float deltaTime) public void BeforeCharacterUpdate(float deltaTime)
{ {
} }
// Метод вызывается после обработки столкновения с землей
public void PostGroundingUpdate(float deltaTime) public void PostGroundingUpdate(float deltaTime)
{ {
// Если во время слайда персонаж оторвался от земли - заканчиваем слайд
if (_slideMechanic.IsSliding && !motor.GroundingStatus.IsStableOnGround) if (_slideMechanic.IsSliding && !motor.GroundingStatus.IsStableOnGround)
{ {
_slideMechanic.EndSlide(); _slideMechanic.EndSlide();
} }
if (motor.GroundingStatus.IsStableOnGround)
{
_wallClimbMechanic.ResetWallClimbSession();
}
} }
// Метод вызывается после обновления персонажа
public void AfterCharacterUpdate(float deltaTime) public void AfterCharacterUpdate(float deltaTime)
{ {
_wallLeanMechanic.UpdateLean(motor, deltaTime); _wallLeanMechanic.Update(
_wallRunningMechanic.IsWallRunning,
_wallRunningMechanic.GetWallNormal(),
motor.CharacterForward
);
} }
// Проверка валидности коллайдера для обработки столкновений
public bool IsColliderValidForCollisions(Collider coll) public bool IsColliderValidForCollisions(Collider coll)
{ {
return true; // Все коллайдеры считаются валидными для столкновений return true;
} }
// Обработка столкновения с землей (вызывается при приземлении)
public void OnGroundHit(Collider hitCollider, Vector3 hitNormal, Vector3 hitPoint, public void OnGroundHit(Collider hitCollider, Vector3 hitNormal, Vector3 hitPoint,
ref HitStabilityReport hitStabilityReport) ref HitStabilityReport hitStabilityReport)
{ {
} }
// Обработка столкновения при движении (вызывается при ударе о препятствие)
public void OnMovementHit(Collider hitCollider, Vector3 hitNormal, Vector3 hitPoint, public void OnMovementHit(Collider hitCollider, Vector3 hitNormal, Vector3 hitPoint,
ref HitStabilityReport hitStabilityReport) ref HitStabilityReport hitStabilityReport)
{ {
if (_wallClimbMechanic.TryClimbWall(motor, hitNormal)) if (_wallRunningMechanic.TryStartWallRun(hitNormal, hitPoint))
_wallLeanMechanic.OnWallContact(motor, hitNormal, motor.TransientPosition.y); {
}
} }
// Обработка отчета о стабильности столкновения
public void ProcessHitStabilityReport(Collider hitCollider, Vector3 hitNormal, Vector3 hitPoint, public void ProcessHitStabilityReport(Collider hitCollider, Vector3 hitNormal, Vector3 hitPoint,
Vector3 atCharacterPosition, Vector3 atCharacterPosition,
Quaternion atCharacterRotation, ref HitStabilityReport hitStabilityReport) Quaternion atCharacterRotation, ref HitStabilityReport hitStabilityReport)
{ {
} }
// Обработка дискретных столкновений (для триггеров и специальных коллайдеров)
public void OnDiscreteCollisionDetected(Collider hitCollider) public void OnDiscreteCollisionDetected(Collider hitCollider)
{ {
} }
@@ -0,0 +1,37 @@
using DG.Tweening;
using UnityEngine;
namespace Code.Gameplay.Door
{
public class Door : MonoBehaviour
{
[SerializeField] private Transform doorPolotno;
private Vector3 _doorInitialPosition;
private Quaternion _doorInitialRotation;
[SerializeField] private Transform hingeJointAnchor;
[SerializeField] private HingeJoint hingeJoint;
[SerializeField] private Rigidbody rigidbody;
public void TranslationMode(bool on)
{
if (on)
{
rigidbody.isKinematic = true;
return;
}
_doorInitialPosition = doorPolotno.position;
_doorInitialRotation = doorPolotno.rotation;
rigidbody.isKinematic = false;
hingeJoint.autoConfigureConnectedAnchor = false;
hingeJoint.connectedAnchor = hingeJointAnchor.position;
}
public void CloseTheDoor()
{
TranslationMode(true);
doorPolotno.DORotate(_doorInitialRotation.eulerAngles, 0.5f);
doorPolotno.DOMove(_doorInitialPosition, 0.5f);
}
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: bc9fc6ce2cc24b68b2b330e4fd029b80
timeCreated: 1764304430
@@ -0,0 +1,53 @@
using System;
using DG.Tweening;
using UnityEngine;
namespace Code.Gameplay.Door
{
public class DoorDebug : MonoBehaviour
{
[SerializeField] private Transform doorSelf;
[SerializeField] private Transform doorPolotno;
private Vector3 _doorInitialPosition;
private Quaternion _doorInitialRotation;
[SerializeField] private Transform hingeJointAnchor;
[SerializeField] private HingeJoint hingeJoint;
[SerializeField] private Rigidbody rigidbody;
[SerializeField] private bool debug;
[SerializeField] private bool closed;
private void Start()
{
_doorInitialPosition = doorPolotno.position;
_doorInitialRotation = doorPolotno.rotation;
}
private void Update()
{
if(debug && !closed)
{
CloseTheDoor();
}
}
public void TranslationMode(bool on)
{
if (on)
{
rigidbody.isKinematic = true;
return;
}
_doorInitialPosition = doorPolotno.position;
_doorInitialRotation = doorPolotno.rotation;
rigidbody.isKinematic = false;
hingeJoint.autoConfigureConnectedAnchor = false;
hingeJoint.connectedAnchor = hingeJointAnchor.position;
}
public void CloseTheDoor()
{
// TranslationMode(true);
doorPolotno.DORotate(_doorInitialRotation.eulerAngles, 0.5f);
doorPolotno.DOMove(_doorInitialPosition, 0.5f);
}
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: ed06ed70c7924ca9bc59f33ee7e6cdfa
timeCreated: 1764533216
@@ -0,0 +1,7 @@
namespace Code.Gameplay.Door
{
public class DoorPooler
{
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: acfad6f51f224b51abb761fc22e4356f
timeCreated: 1764521809
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: f17ace0fa75741f2a730ff21181c6e8c
timeCreated: 1764575680
@@ -0,0 +1,23 @@
using UnityEngine;
using UnityEngine.AI;
namespace Code.Gameplay.Enemies.Animators
{
public class EnemyAnimator : MonoBehaviour
{
private static readonly int Velocity = Animator.StringToHash("Velocity");
[SerializeField] private Animator animator;
[SerializeField] private NavMeshAgent agent;
private void SetVelocity(float velocity)
{
animator.SetFloat(Velocity, velocity);
}
private void Update()
{
if(agent) SetVelocity(agent.velocity.magnitude);
}
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 936125a7ed844674b0e0586a484253ce
timeCreated: 1764575708
@@ -1,8 +1,10 @@
using Code.Audio;
using UnityEngine; using UnityEngine;
using UnityEngine.AI; using UnityEngine.AI;
using Code.Gameplay.Player; using Code.Gameplay.Player;
using Code.Gameplay.Character.Controller; using Code.Gameplay.Character.Controller;
using Code.Gameplay.Character.Core; using Code.Gameplay.Character.Core;
using Code.Gameplay.Enemies.Animators;
using Reflex.Attributes; using Reflex.Attributes;
using Reflex.Core; using Reflex.Core;
using Reflex.Injectors; using Reflex.Injectors;
@@ -13,6 +15,7 @@ namespace Code.Gameplay.Enemies
{ {
[SerializeField] protected NavMeshAgent agent; [SerializeField] protected NavMeshAgent agent;
[SerializeField] protected Collider enemyCollider; [SerializeField] protected Collider enemyCollider;
[Inject] protected IAudioService audioService;
protected int Damage; protected int Damage;
protected float AttackCooldown; protected float AttackCooldown;
@@ -35,7 +38,7 @@ namespace Code.Gameplay.Enemies
private bool _isStunned; private bool _isStunned;
private float _currentStunTimer; private float _currentStunTimer;
private bool _canAttack = true; protected bool _canAttack = true;
private float _attackCooldownTimer; private float _attackCooldownTimer;
private enum IdleState { Moving, Paused } private enum IdleState { Moving, Paused }
@@ -50,10 +53,11 @@ namespace Code.Gameplay.Enemies
protected virtual void Awake() protected virtual void Awake()
{ {
if (_playerProvider == null) // // TODO Мешает
{ // if (_playerProvider == null)
AttributeInjector.Inject(this, Container.ProjectContainer); // {
} // AttributeInjector.Inject(this, Container.ProjectContainer);
// }
} }
protected virtual void Update() protected virtual void Update()
@@ -164,19 +168,19 @@ namespace Code.Gameplay.Enemies
protected virtual void HandleAttackCooldown() protected virtual void HandleAttackCooldown()
{ {
if (!_canAttack) if (_canAttack) return;
{
_attackCooldownTimer -= Time.deltaTime; _attackCooldownTimer -= Time.deltaTime;
if (_attackCooldownTimer <= 0) if (_attackCooldownTimer <= 0)
{ {
_canAttack = true; _canAttack = true;
} }
} }
}
protected virtual void DealDamage() protected virtual void DealDamage()
{ {
if (!_canAttack || PlayerHealth == null) return; if (PlayerHealth == null) return;
PlayerHealth.GetDamage(Damage); PlayerHealth.GetDamage(Damage);
ApplyEffectsToPlayer(); ApplyEffectsToPlayer();
@@ -1,3 +1,4 @@
using Code.Audio;
using Code.Configs; using Code.Configs;
using Reflex.Attributes; using Reflex.Attributes;
using UnityEngine; using UnityEngine;
@@ -43,12 +44,14 @@ namespace Code.Gameplay.Enemies
protected override void HandleAttack() protected override void HandleAttack()
{ {
if (!Player) return; if (!Player || !_canAttack) return;
var distance = Vector3.Distance(transform.position, Player.transform.position); var distance = Vector3.Distance(transform.position, Player.transform.position);
if (!(distance <= AttackRange)) return; if (!(distance <= AttackRange)) return;
audioService.PlayEnemy(EnemiesSounds.Bravo,agent.transform.position);
DealDamage(); DealDamage();
} }
} }
@@ -1,4 +1,6 @@
using Code.Audio;
using Code.Configs; using Code.Configs;
using Code.Gameplay.Enemies.Animators;
using Reflex.Attributes; using Reflex.Attributes;
using UnityEngine; using UnityEngine;
using UnityEngine.AI; using UnityEngine.AI;
@@ -40,15 +42,16 @@ namespace Code.Gameplay.Enemies
var walkableArea = NavMesh.GetAreaFromName("Walkable"); var walkableArea = NavMesh.GetAreaFromName("Walkable");
agent.areaMask = 1 << walkableArea; agent.areaMask = 1 << walkableArea;
} }
protected override void HandleAttack() protected override void HandleAttack()
{ {
if (!Player) return; if (!Player || !_canAttack) return;
var distance = Vector3.Distance(transform.position, Player.transform.position); var distance = Vector3.Distance(transform.position, Player.transform.position);
if (!(distance <= AttackRange)) return; if (!(distance <= AttackRange)) return;
audioService.PlayEnemy(EnemiesSounds.Bastard,agent.transform.position);
if (Player.CustomCharacterController.IsSliding) if (Player.CustomCharacterController.IsSliding)
ApplyStun(); ApplyStun();
else else
@@ -27,6 +27,7 @@ namespace Code.Gameplay.Enemies
) )
.ToUniTask(); .ToUniTask();
// Работает, пока не трогаю
AttributeInjector.Inject(enemyObj, Container.ProjectContainer); AttributeInjector.Inject(enemyObj, Container.ProjectContainer);
return enemyObj.GetComponent<BaseEnemy>(); return enemyObj.GetComponent<BaseEnemy>();
@@ -1,8 +1,6 @@
using Code.Gameplay.Player; using Code.Gameplay.Player;
using Cysharp.Threading.Tasks; using Cysharp.Threading.Tasks;
using Reflex.Attributes; using Reflex.Attributes;
using Reflex.Core;
using Reflex.Injectors;
using UnityEngine; using UnityEngine;
namespace Code.Gameplay.Enemies namespace Code.Gameplay.Enemies
@@ -20,13 +18,14 @@ namespace Code.Gameplay.Enemies
private bool _isSpawning; private bool _isSpawning;
private bool _isPlayerInRange; private bool _isPlayerInRange;
private void Awake() // GameObjectSelfInjector существует
{ // private void Awake()
if (_playerProvider == null || _enemyFactory == null) // {
{ // if (_playerProvider == null || _enemyFactory == null)
AttributeInjector.Inject(this, Container.ProjectContainer); // {
} // AttributeInjector.Inject(this, Container.ProjectContainer);
} // }
// }
private void Update() private void Update()
{ {
@@ -64,9 +63,14 @@ namespace Code.Gameplay.Enemies
_isSpawning = false; _isSpawning = false;
} }
private void OnDestroy()
{
Despawn();
}
private void Despawn() private void Despawn()
{ {
if (_spawnedEnemy == null) return; if (!_spawnedEnemy) return;
_enemyFactory.ReleaseEnemy(_spawnedEnemy); _enemyFactory.ReleaseEnemy(_spawnedEnemy);
_spawnedEnemy = null; _spawnedEnemy = null;
@@ -33,7 +33,7 @@ namespace Code.Gameplay.Orders.Order
} }
public void OnTriggerEnter(Collider other) public void OnTriggerEnter(Collider other)
{ {
if (!_pickupMode) return; if (!_pickupMode || !other.CompareTag("Player")) return;
_orderService.OrderRecieved(); _orderService.OrderRecieved();
Destroy(gameObject); Destroy(gameObject);
@@ -14,18 +14,20 @@ namespace Code.Gameplay.Orders.Order
hatch.DORotate(new Vector3(-130f, 0, 0), 0.2f); hatch.DORotate(new Vector3(-130f, 0, 0), 0.2f);
order.rigidbody.isKinematic = false; order.rigidbody.isKinematic = false;
order.rigidbody.AddForce(-transform.forward * 10f, ForceMode.Impulse); order.rigidbody.AddForce(-transform.forward * 1f, ForceMode.Impulse);
order.SwitchMode();
} }
// DEBUG TODO ДИМКА УДАЛИ И ПРОПИШИ В СВОЕЙ ЛОГИКЕ // DEBUG TODO ДИМКА УДАЛИ И ПРОПИШИ В СВОЕЙ ЛОГИКЕ
public void OnTriggerEnter(Collider other) // public void OnTriggerEnter(Collider other)
{ // {
if(_activated) return; // if(_activated) return;
_activated = true; // _activated = true;
//
ThrowOrder(); // ThrowOrder();
order.SwitchMode(); // order.SwitchMode();
} // }
// DEBUG // DEBUG
} }
} }
@@ -0,0 +1,17 @@
using UnityEngine;
namespace Code.Gameplay.Orders.Order
{
public class RoomDispenserTrigger : MonoBehaviour
{
[SerializeField] private OrderDispenser orderDispenser;
private bool _playerEntered;
private void OnTriggerEnter(Collider other)
{
if (_playerEntered ) return;
orderDispenser.ThrowOrder();
_playerEntered = true;
}
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 630780fe69aa45eda7d4bcf966516c7d
timeCreated: 1764313014
@@ -0,0 +1,32 @@
using Code.Audio;
using Reflex.Attributes;
using UnityEngine;
using AudioType = Code.Audio.AudioType;
namespace Code.Gameplay.Player
{
public class PlayerAudio : MonoBehaviour
{
private IAudioService _audioService;
private IAudioFactory _audioFactory;
private AudioSource _audioSource;
[Inject]
private void Construct(IAudioService audioService, IAudioFactory audioFactory)
{
_audioService = audioService;
_audioSource = audioService.GetSourceOfGroup(AudioType.Courier);
_audioFactory = audioFactory;
}
public void PlayStep()
{
_audioSource.PlayOneShot(_audioFactory.CourierAudios[(int)CourierSounds.Step]);
}
private void OnDestroy()
{
_audioService.ReleaseSourceOfGroup(_audioSource);
}
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 64f99dccce9d41df98accae0f355dbca
timeCreated: 1764584350
@@ -42,7 +42,13 @@ namespace Code.Gameplay.Player
Addressables.ReleaseInstance(characterProvider.gameObject); Addressables.ReleaseInstance(characterProvider.gameObject);
} }
public async UniTask<ArmsMeshProvider> CreateArms(Transform papochka) => (await Addressables.InstantiateAsync(_playerConfig.armsMeshPrefab, papochka).ToUniTask()).GetComponent<ArmsMeshProvider>(); public async UniTask<ArmsMeshProvider> CreateArms(Transform papochka)
{
var armsMesh = (await Addressables.InstantiateAsync(_playerConfig.armsMeshPrefab, papochka).ToUniTask());
GameObjectInjector.InjectRecursive(armsMesh, Container.ProjectContainer);
return armsMesh.GetComponent<ArmsMeshProvider>();
}
public void ReleaseArms(ArmsMeshProvider arms) => Addressables.ReleaseInstance(arms.gameObject); public void ReleaseArms(ArmsMeshProvider arms) => Addressables.ReleaseInstance(arms.gameObject);
} }
} }
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: b32d6ce440f44fd3abadaa489a44890c
timeCreated: 1762797763
@@ -0,0 +1,11 @@
using UnityEngine;
using UnityEngine.AddressableAssets;
namespace Code.Generator
{
[CreateAssetMenu(menuName = "Config/GeneratorConfig", fileName = "GeneratorConfig")]
public class GeneratorConfig : ScriptableObject
{
public AssetReference[] roomAssetReferences;
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 1a7c77305de54155b5b94b607531ee3c
timeCreated: 1762453750
@@ -0,0 +1,17 @@
using Code.Gameplay.Orders.Order;
using Cysharp.Threading.Tasks;
using UnityEngine;
namespace Code.Generator
{
public interface IRoomGeneratorFactory
{
UniTask PreloadRooms(IOrderService orderService);
GameObject GetCachedPrefab(int index, RoomType roomType);
Room CreateRoomByIndex(int index, RoomType roomType);
void ReleaseRooms();
GameObject GetRandomCachedPrefabOfType(RoomType roomType, out int index);
int GetRandomIndexOfType(RoomType roomType);
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: f3fca4115e714519b869eb72d856e89f
timeCreated: 1762453657
@@ -0,0 +1,9 @@
using UnityEngine;
namespace Code.Generator
{
public class InitialRoom : Room
{
public Transform playerSpawn;
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 4245aa5c87c7455ebad11edaad3b649e
timeCreated: 1764324045
@@ -0,0 +1,32 @@
using System;
using Code.Gameplay.Door;
using Code.Gameplay.Orders.Order;
using Code.UI;
using UnityEngine;
namespace Code.Generator
{
// Для написания нормальной системы комнат нужен другой подход в корне, это уже не исправить, только залатать большие дыры
public class Room : MonoBehaviour
{
[SerializeField] protected RoomType roomType;
public RoomType RoomType => roomType;
[SerializeField] protected float roomTimer;
public float RoomTimer => roomTimer;
[SerializeField] protected Transform enterMarker;
public Transform EnterMarker => enterMarker;
[SerializeField] protected Transform exitMarker;
[SerializeField] protected Transform doorSlot;
public Transform ExitMarker => exitMarker;
[SerializeField] protected Door door;
public void Initialize(IOrderService orderService)
{
door.TranslationMode(false);
if(roomTrigger) roomTrigger.OrderService = orderService;
}
public void Seal() => door.CloseTheDoor();
[SerializeField] public RoomTrigger roomTrigger;
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 5ba1a19c534f4401aa287d4b68ce470c
timeCreated: 1762014278
@@ -0,0 +1,303 @@
using System.Collections.Generic;
using Code.Gameplay.Orders.Order;
using Code.Scenes;
using Code.Scenes.SceneEnvironments;
using Cysharp.Threading.Tasks;
using Reflex.Attributes;
using UnityEngine;
namespace Code.Generator
{
public class RoomGenerator
{
[Inject] private IOrderService _orderService;
[Inject] private GeneratorConfig generatorConfig;
[Inject] private IRoomGeneratorFactory _factory;
private List<RoomIndex> _roomIndexesStack;
private struct RoomIndex
{
public RoomType RoomType;
public int Index;
public RoomIndex(RoomType roomType, int index)
{
RoomType = roomType;
Index = index;
}
}
private List<Room> _spawnedRooms;
private int _nextRoomStackIndex;
public void Initialize()
{
// _orderService.OrderGive();
_spawnedRooms = new List<Room>();
_roomIndexesStack = new();
Debug.LogWarning($"КОТЛЫ ГЕНЕРАЛЬСКИЕ{_orderService.DeliveryTimer}");
// CreateRoomsStack();
// SpawnInitialRoomsAsync();
_orderService.OnOrderGiven += CreateRoomsStack;
// RoomTrigger.PlayerEnteredRoom += OnPlayerEntered;
CreateInitialRoom();
}
private void OnPlayerEntered()
{
SpawnNextRoom();
if (_spawnedRooms.Count > 3)
{
Room roomToRemove = _spawnedRooms[0];
_spawnedRooms.RemoveAt(0);
// _factory.ReleaseRoom(roomToRemove);
Object.Destroy(roomToRemove.gameObject);
}
}
private void CreateRoomsStack(float timer)
{
_nextRoomStackIndex = 0;
_roomIndexesStack.Clear();
var remainingTime = timer;
while (remainingTime > 0)
{
var prefab = _factory.GetRandomCachedPrefabOfType(RoomType.Basic, out int roomIndex);
Room room = prefab.GetComponent<Room>();
_roomIndexesStack.Add(new(RoomType.Basic, roomIndex));
remainingTime -= room.RoomTimer;
Debug.Log($"комната {room.name} время {room.RoomTimer} осталось: {remainingTime}");
}
AddPickupRoom();
Debug.Log($"добавлена зона заказа");
AddSaveRoom();
Debug.Log($"добавлена сейв зона");
Debug.Log($"стек комнат: {_roomIndexesStack.Count}");
SpawnNextRoom();
}
private void AddSaveRoom()
{
int saveRoomIndex = _factory.GetRandomIndexOfType(RoomType.Save);
_roomIndexesStack.Add(new(RoomType.Save, saveRoomIndex));
}
private void AddPickupRoom()
{
int pickupIndex = _factory.GetRandomIndexOfType(RoomType.PickUp);
int insertPos = Random.Range(1, _roomIndexesStack.Count + 1);
_roomIndexesStack.Insert(insertPos, new(RoomType.PickUp, pickupIndex));
}
[Inject] private CurrentSceneEnvironment _currentSceneEnvironment;
private void CreateInitialRoom()
{
GameplaySceneEnvironment gameplaySceneEnvironment = (GameplaySceneEnvironment)_currentSceneEnvironment;
int roomIndex = _factory.GetRandomIndexOfType(RoomType.Initial);
InitialRoom instantiated = _factory.CreateRoomByIndex(roomIndex, RoomType.Initial).GetComponent<InitialRoom>();
_spawnedRooms.Add(instantiated);
instantiated.transform.position = Vector3.zero;
instantiated.transform.rotation = Quaternion.identity;
gameplaySceneEnvironment.playerSpawnPoint = instantiated.playerSpawn;
instantiated.Initialize(_orderService);
Debug.Log($"Первая комната: {instantiated.name}");
}
private void SpawnNextRoom()
{
if (_nextRoomStackIndex >= _roomIndexesStack.Count)
return;
RoomIndex index = _roomIndexesStack[_nextRoomStackIndex];
Room room = _factory.CreateRoomByIndex(index.Index, index.RoomType);
if (_spawnedRooms.Count == 0)
{
room.transform.position = Vector3.zero;
room.transform.rotation = Quaternion.identity;
}
else
{
Room previousRoom = _spawnedRooms[_spawnedRooms.Count - 1];
PlaceRoom(room, previousRoom);
}
// Отписываться можно, но Хатико никогда не дождётся вызова уничтоженного объекта.
room.roomTrigger.OnEnter += OnPlayerEntered;
room.roomTrigger.OnExit += _spawnedRooms[^1].Seal;
_spawnedRooms.Add(room);
_nextRoomStackIndex++;
}
private void PlaceRoom(Room current, Room previous)
{
if (current.EnterMarker == null || previous.ExitMarker == null)
return;
Vector3 segmentOriginPosition = previous.ExitMarker.transform.position;
Transform randomDoorOrigin = current.EnterMarker;
Vector3 randomDoorOriginPosition = randomDoorOrigin.localPosition * current.transform.localScale.x;
Quaternion randomDoorOriginRotation = randomDoorOrigin.localRotation;
float segmentOriginYRotation;
float entityRotation = previous.ExitMarker.transform.rotation.eulerAngles.y;
if (entityRotation > 305f) entityRotation -= 360f;
else if (entityRotation < -45f) entityRotation += 360f;
if (entityRotation > 135f)
segmentOriginYRotation = entityRotation - randomDoorOriginRotation.eulerAngles.y + 180f;
else
segmentOriginYRotation = entityRotation - randomDoorOriginRotation.eulerAngles.y - 180f;
if (segmentOriginYRotation < -45f) segmentOriginYRotation += 360f;
else if (segmentOriginYRotation > 305f) segmentOriginYRotation -= 360f;
else if (segmentOriginYRotation < -305f) segmentOriginYRotation += 720f;
if (segmentOriginYRotation is > -45f and < 45f)
{
segmentOriginPosition.x -= randomDoorOriginPosition.x;
segmentOriginPosition.z -= randomDoorOriginPosition.z;
}
else if (segmentOriginYRotation is >= 45f and < 135f)
{
segmentOriginPosition.x -= randomDoorOriginPosition.z;
segmentOriginPosition.z += randomDoorOriginPosition.x;
}
else if (segmentOriginYRotation is >= 135f and < 225f)
{
segmentOriginPosition.x += randomDoorOriginPosition.x;
segmentOriginPosition.z += randomDoorOriginPosition.z;
}
else if (segmentOriginYRotation is >= 225f and < 305f)
{
segmentOriginPosition.x += randomDoorOriginPosition.z;
segmentOriginPosition.z -= randomDoorOriginPosition.x;
}
segmentOriginPosition.y -= randomDoorOriginPosition.y;
current.transform.position = segmentOriginPosition;
current.transform.rotation = Quaternion.Euler(0, segmentOriginYRotation, 0);
// locationSegment.isNeedSomeDoors = true;
// locationSegment.AddBadDoorId(locationSegment.LocationSegment.GetDoorOrigins.IndexOf(randomDoorOrigin));
current.Initialize(_orderService);
// float frameOnTheBallRotation = segmentOriginYRotation + randomDoorOriginRotation.eulerAngles.y;
// if (frameOnTheBallRotation > 305f) frameOnTheBallRotation -= 360f;
// else if (frameOnTheBallRotation < -45f) frameOnTheBallRotation += 360f;
// heOnTheBall.AddSlaveLocationSegment(locationSegment.Id);
// heOnTheBall.ReplaceSlaveSegmentDoorOriginYRotation(frameOnTheBallRotation);
// heOnTheBall.isGotOnTheBall = false;
}
}
}
// private void CreateRoomsStackDimka()
// {
// _roomIndexesStack.Clear();
// var remainingTime = _orderService.DeliveryTimer;
// float ladderTimer = 0f;
// int totalRooms = generatorConfig.roomAssetReferences.Length;
// List<int> availableIndexes = new List<int>();
// for (int i = 0; i < totalRooms; i++)
// availableIndexes.Add(i);
//
// int saveIndex = FindRoomIndexByType(RoomType.Save);
// if (saveIndex != -1)
// {
// var prefab = _factory.GetCachedPrefab(saveIndex);
// if (prefab != null)
// {
// Room saveRoom = prefab.GetComponent<Room>();
// if (saveRoom != null)
// {
// _roomIndexesStack.Add(saveIndex);
// availableIndexes.Remove(saveIndex);
//
// Debug.Log($"Первая комната: {saveRoom.name}");
// }
// }
// }
//
// while (remainingTime > 0 && availableIndexes.Count > 0)
// {
// int randomIndex = Random.Range(0, availableIndexes.Count);
// int chosenOne = availableIndexes[randomIndex];
//
// var prefab = _factory.GetCachedPrefab(chosenOne);
// if (prefab == null)
// continue;
//
// Room room = prefab.GetComponent<Room>();
// if (room == null)
// continue;
//
// switch (room.RoomType)
// {
// case RoomType.Save or RoomType.PickUp:
// availableIndexes.RemoveAt(randomIndex);
// continue;
//
// case RoomType.Basic:
// float currentRoomTime = room.RoomTimer;
// if (remainingTime >= currentRoomTime && ladderTimer < 30f)
// {
// _roomIndexesStack.Add(chosenOne);
// remainingTime -= currentRoomTime;
// ladderTimer += currentRoomTime;
// Debug.Log($"комната {room.name} время {currentRoomTime} осталось: {remainingTime}");
// }
//
// availableIndexes.RemoveAt(randomIndex);
// break;
//
// case RoomType.Ladder:
// if (ladderTimer >= 30f)
// {
// _roomIndexesStack.Add(chosenOne);
// ladderTimer = 0f;
//
// availableIndexes.RemoveAt(randomIndex);
// Debug.Log($"Лестница ура {room.name}");
// }
//
// break;
//
// default:
// Debug.Log($"тип комнаты {room.RoomType}");
// availableIndexes.RemoveAt(randomIndex);
// break;
// }
// }
//
// AddPickupRoom();
// Debug.Log($"стек комнат: {_roomIndexesStack.Count}");
// }
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 353230beca35458dafc91c6409c25ab3
timeCreated: 1762014615
@@ -0,0 +1,74 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using Code.Configs;
using Code.Gameplay.Orders.Order;
using Cysharp.Threading.Tasks;
using Reflex.Extensions;
using Reflex.Injectors;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;
using UnityEngine.SceneManagement;
using Object = System.Object;
using Random = UnityEngine.Random;
namespace Code.Generator
{
public class RoomGeneratorFactory : IRoomGeneratorFactory
{
private AsyncOperationHandle<IList<GameObject>> _roomsHandle;
private readonly AssetReference[] _roomAssetReferences;
private Dictionary<RoomType, List<GameObject>> _cashedRooms = new();
public RoomGeneratorFactory(GeneratorConfig generatorConfig)
{
_roomAssetReferences = generatorConfig.roomAssetReferences;
// _cashedRooms = new GameObject[_roomAssetReferences.Length];
_cashedRooms.Add(RoomType.Basic, new());
_cashedRooms.Add(RoomType.Save, new ());
_cashedRooms.Add(RoomType.PickUp, new ());
_cashedRooms.Add(RoomType.Initial, new ());
}
public async UniTask PreloadRooms(IOrderService orderService)
{
_roomsHandle =
Addressables.LoadAssetsAsync<GameObject>(_roomAssetReferences, OnRoomLoaded, Addressables.MergeMode.Union);
await _roomsHandle.ToUniTask();
// _cashedRooms = rooms.ToArray(); var rooms =
// Debug.Log($"Комнат в памяти есть: {_cashedRooms.Length}");
}
private void OnRoomLoaded(GameObject room)
{
var temp = room.GetComponent<Room>();
_cashedRooms[temp.RoomType].Add(room);
}
public GameObject GetCachedPrefab(int index, RoomType roomType)
{
if (index < 0 || index >= _cashedRooms[roomType].Count)
return null;
return _cashedRooms[roomType][index];
}
public GameObject GetRandomCachedPrefabOfType(RoomType roomType, out int index)
{
index = Random.Range(0, _cashedRooms[roomType].Count);
return _cashedRooms[roomType][index];
}
public int GetRandomIndexOfType(RoomType roomType) => Random.Range(0, _cashedRooms[roomType].Count);
public Room CreateRoomByIndex(int index, RoomType roomType)
{
var room = UnityEngine.Object.Instantiate(_cashedRooms[roomType][index]);
return room.GetComponent<Room>();
}
public void ReleaseRooms()
{
_roomsHandle.Release();
}
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: d6e5b72284354ba79ec5b89cf06f1203
timeCreated: 1762454256
@@ -0,0 +1,36 @@
using System;
using Code.Gameplay.Orders.Order;
using UnityEngine;
namespace Code.Generator
{
public class RoomTrigger : MonoBehaviour
{
public IOrderService OrderService;
public event Action OnEnter;
public event Action OnExit;
private bool _playerEntered, _playerExited;
private void OnTriggerEnter(Collider other)
{
if (_playerEntered) return;
_playerEntered = true;
OrderService.RoomPassed();
OnEnter?.Invoke();
}
private void OnTriggerExit(Collider other)
{
if (_playerExited) return;
Debug.Log(other.name);
_playerExited = true;
OnExit?.Invoke();
}
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 0d6940d73d544f0a8e4a45d956bc2364
timeCreated: 1764525516
@@ -0,0 +1,10 @@
namespace Code.Generator
{
public enum RoomType
{
Basic,
Save,
PickUp,
Initial
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 304fa5ed27cc4bc3aabcfeb272206d89
timeCreated: 1762945420
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: e76fbbe72ad97cc4f9dfe770ddc79857
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,54 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering;
public class LightProbeRuntime : MonoBehaviour
{
public Color m_Ambient;
Light[] m_Lights;
// Start is called before the first frame update
IEnumerator Start()
{
yield return null;
m_Lights = FindObjectsOfType<Light>();
SphericalHarmonicsL2[] bakedProbes = LightmapSettings.lightProbes.bakedProbes;
Vector3[] probePositions = LightmapSettings.lightProbes.positions;
int probeCount = LightmapSettings.lightProbes.count;
// Clear all probes
for (int i = 0; i < probeCount; i++)
bakedProbes[i].Clear();
// Add ambient light to all probes
for (int i = 0; i < probeCount; i++)
bakedProbes[i].AddAmbientLight(m_Ambient);
// Add directional and point lights' contribution to all probes
foreach (Light l in m_Lights)
{
if (l.type == LightType.Directional)
{
for (int i = 0; i < probeCount; i++)
bakedProbes[i].AddDirectionalLight(-l.transform.forward, l.color, l.intensity);
}
else if (l.type == LightType.Point)
{
for (int i = 0; i < probeCount; i++)
SHAddPointLight(probePositions[i], l.transform.position, l.range, l.color, l.intensity, ref bakedProbes[i]);
}
}
LightmapSettings.lightProbes.bakedProbes = bakedProbes;
}
void SHAddPointLight(Vector3 probePosition, Vector3 position, float range, Color color, float intensity, ref SphericalHarmonicsL2 sh)
{
// From the point of view of an SH probe, point light looks no different than a directional light,
// just attenuated and coming from the right direction.
Vector3 probeToLight = position - probePosition;
float attenuation = 1.0F / (1.0F + 25.0F * probeToLight.sqrMagnitude / (range * range));
sh.AddDirectionalLight(probeToLight.normalized, color, intensity * attenuation);
}
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 9643888b3364f55439c6adf3309cc447
@@ -0,0 +1,295 @@
using UnityEngine;
using UnityEditor;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.SceneManagement;
[ExecuteAlways]
public class PrefabLightmapData : MonoBehaviour
{
[Tooltip("Reassigns shaders when applying the baked lightmaps. Might conflict with some shaders like transparent HDRP.")]
public bool releaseShaders = true;
[System.Serializable]
struct RendererInfo
{
public Renderer renderer;
public int lightmapIndex;
public Vector4 lightmapOffsetScale;
}
[System.Serializable]
struct LightInfo
{
public Light light;
public int lightmapBaketype;
public int mixedLightingMode;
}
[SerializeField]
RendererInfo[] m_RendererInfo;
[SerializeField]
Texture2D[] m_Lightmaps;
[SerializeField]
Texture2D[] m_LightmapsDir;
[SerializeField]
Texture2D[] m_ShadowMasks;
[SerializeField]
LightInfo[] m_LightInfo;
void Awake()
{
Init();
}
void Init()
{
if (m_RendererInfo == null || m_RendererInfo.Length == 0)
return;
var lightmaps = LightmapSettings.lightmaps;
int[] offsetsindexes = new int[m_Lightmaps.Length];
int counttotal = lightmaps.Length;
List<LightmapData> combinedLightmaps = new List<LightmapData>();
for (int i = 0; i < m_Lightmaps.Length; i++)
{
bool exists = false;
for (int j = 0; j < lightmaps.Length; j++)
{
if (m_Lightmaps[i] == lightmaps[j].lightmapColor)
{
exists = true;
offsetsindexes[i] = j;
}
}
if (!exists)
{
offsetsindexes[i] = counttotal;
var newlightmapdata = new LightmapData
{
lightmapColor = m_Lightmaps[i],
lightmapDir = m_LightmapsDir.Length == m_Lightmaps.Length ? m_LightmapsDir[i] : default(Texture2D),
shadowMask = m_ShadowMasks.Length == m_Lightmaps.Length ? m_ShadowMasks[i] : default(Texture2D),
};
combinedLightmaps.Add(newlightmapdata);
counttotal += 1;
}
}
var combinedLightmaps2 = new LightmapData[counttotal];
lightmaps.CopyTo(combinedLightmaps2, 0);
combinedLightmaps.ToArray().CopyTo(combinedLightmaps2, lightmaps.Length);
bool directional=true;
foreach(Texture2D t in m_LightmapsDir)
{
if (t == null)
{
directional = false;
break;
}
}
LightmapSettings.lightmapsMode = (m_LightmapsDir.Length == m_Lightmaps.Length && directional) ? LightmapsMode.CombinedDirectional : LightmapsMode.NonDirectional;
ApplyRendererInfo(m_RendererInfo, offsetsindexes, m_LightInfo);
LightmapSettings.lightmaps = combinedLightmaps2;
}
void OnEnable()
{
SceneManager.sceneLoaded += OnSceneLoaded;
}
// called second
void OnSceneLoaded(Scene scene, LoadSceneMode mode)
{
Init();
}
// called when the game is terminated
void OnDisable()
{
SceneManager.sceneLoaded -= OnSceneLoaded;
}
void ApplyRendererInfo(RendererInfo[] infos, int[] lightmapOffsetIndex, LightInfo[] lightsInfo)
{
for (int i = 0; i < infos.Length; i++)
{
var info = infos[i];
info.renderer.lightmapIndex = lightmapOffsetIndex[info.lightmapIndex];
info.renderer.lightmapScaleOffset = info.lightmapOffsetScale;
if (releaseShaders)
{
// You have to release shaders.
Material[] mat = info.renderer.sharedMaterials;
for (int j = 0; j < mat.Length; j++)
{
if (mat[j] != null && Shader.Find(mat[j].shader.name) != null)
{
mat[j].shader = Shader.Find(mat[j].shader.name);
}
}
}
}
for (int i = 0; i < lightsInfo.Length; i++)
{
LightBakingOutput bakingOutput = new LightBakingOutput();
bakingOutput.isBaked = true;
bakingOutput.lightmapBakeType = (LightmapBakeType)lightsInfo[i].lightmapBaketype;
bakingOutput.mixedLightingMode = (MixedLightingMode)lightsInfo[i].mixedLightingMode;
lightsInfo[i].light.bakingOutput = bakingOutput;
}
}
#if UNITY_EDITOR
[UnityEditor.MenuItem("Assets/Bake Prefab Lightmaps")]
static void GenerateLightmapInfo()
{
if (UnityEditor.Lightmapping.giWorkflowMode != UnityEditor.Lightmapping.GIWorkflowMode.OnDemand)
{
Debug.LogError("ExtractLightmapData requires that you have baked you lightmaps and Auto mode is disabled.");
return;
}
UnityEditor.Lightmapping.Bake();
PrefabLightmapData[] prefabs = FindObjectsOfType<PrefabLightmapData>();
foreach (var instance in prefabs)
{
var gameObject = instance.gameObject;
var rendererInfos = new List<RendererInfo>();
var lightmaps = new List<Texture2D>();
var lightmapsDir = new List<Texture2D>();
var shadowMasks = new List<Texture2D>();
var lightsInfos = new List<LightInfo>();
GenerateLightmapInfo(gameObject, rendererInfos, lightmaps, lightmapsDir, shadowMasks, lightsInfos);
instance.m_RendererInfo = rendererInfos.ToArray();
instance.m_Lightmaps = lightmaps.ToArray();
instance.m_LightmapsDir = lightmapsDir.ToArray();
instance.m_LightInfo = lightsInfos.ToArray();
instance.m_ShadowMasks = shadowMasks.ToArray();
#if UNITY_2018_3_OR_NEWER
var targetPrefab = PrefabUtility.GetCorrespondingObjectFromOriginalSource(instance.gameObject) as GameObject;
if (targetPrefab != null)
{
GameObject root = PrefabUtility.GetOutermostPrefabInstanceRoot(instance.gameObject);// 根结点
//如果当前预制体是是某个嵌套预制体的一部分(IsPartOfPrefabInstance)
if (root != null)
{
GameObject rootPrefab = PrefabUtility.GetCorrespondingObjectFromSource(instance.gameObject);
string rootPath = AssetDatabase.GetAssetPath(rootPrefab);
//打开根部预制体
PrefabUtility.UnpackPrefabInstanceAndReturnNewOutermostRoots(root, PrefabUnpackMode.OutermostRoot);
try
{
//Apply各个子预制体的改变
PrefabUtility.ApplyPrefabInstance(instance.gameObject, InteractionMode.AutomatedAction);
}
catch { }
finally
{
//重新更新根预制体
PrefabUtility.SaveAsPrefabAssetAndConnect(root, rootPath, InteractionMode.AutomatedAction);
}
}
else
{
PrefabUtility.ApplyPrefabInstance(instance.gameObject, InteractionMode.AutomatedAction);
}
}
#else
var targetPrefab = UnityEditor.PrefabUtility.GetPrefabParent(gameObject) as GameObject;
if (targetPrefab != null)
{
//UnityEditor.Prefab
UnityEditor.PrefabUtility.ReplacePrefab(gameObject, targetPrefab);
}
#endif
}
}
static void GenerateLightmapInfo(GameObject root, List<RendererInfo> rendererInfos, List<Texture2D> lightmaps, List<Texture2D> lightmapsDir, List<Texture2D> shadowMasks, List<LightInfo> lightsInfo)
{
var renderers = root.GetComponentsInChildren<MeshRenderer>();
foreach (MeshRenderer renderer in renderers)
{
if (renderer.lightmapIndex != -1)
{
RendererInfo info = new RendererInfo();
info.renderer = renderer;
if (renderer.lightmapScaleOffset != Vector4.zero)
{
//1ibrium's pointed out this issue : https://docs.unity3d.com/ScriptReference/Renderer-lightmapIndex.html
if(renderer.lightmapIndex < 0 || renderer.lightmapIndex == 0xFFFE) continue;
info.lightmapOffsetScale = renderer.lightmapScaleOffset;
Texture2D lightmap = LightmapSettings.lightmaps[renderer.lightmapIndex].lightmapColor;
Texture2D lightmapDir = LightmapSettings.lightmaps[renderer.lightmapIndex].lightmapDir;
Texture2D shadowMask = LightmapSettings.lightmaps[renderer.lightmapIndex].shadowMask;
info.lightmapIndex = lightmaps.IndexOf(lightmap);
if (info.lightmapIndex == -1)
{
info.lightmapIndex = lightmaps.Count;
lightmaps.Add(lightmap);
lightmapsDir.Add(lightmapDir);
shadowMasks.Add(shadowMask);
}
rendererInfos.Add(info);
}
}
}
var lights = root.GetComponentsInChildren<Light>(true);
foreach (Light l in lights)
{
LightInfo lightInfo = new LightInfo();
lightInfo.light = l;
lightInfo.lightmapBaketype = (int)l.lightmapBakeType;
#if UNITY_2020_1_OR_NEWER
lightInfo.mixedLightingMode = (int)UnityEditor.Lightmapping.lightingSettings.mixedBakeMode;
#elif UNITY_2018_1_OR_NEWER
lightInfo.mixedLightingMode = (int)UnityEditor.LightmapEditorSettings.mixedBakeMode;
#else
lightInfo.mixedLightingMode = (int)l.bakingOutput.lightmapBakeType;
#endif
lightsInfo.Add(lightInfo);
}
}
#endif
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: b91f32cd81021d24ab9ff545997e9666
@@ -8,12 +8,10 @@ namespace Code.Scenes.SceneEnvironments
public class GameplaySceneEnvironment : CurrentSceneEnvironment public class GameplaySceneEnvironment : CurrentSceneEnvironment
{ {
public Transform playerSpawnPoint; public Transform playerSpawnPoint;
public OrderDispenser debugTube;
public void TransitVariables(GameplaySceneEnvironment env) public void TransitVariables(GameplaySceneEnvironment env)
{ {
playerSpawnPoint = env.playerSpawnPoint; playerSpawnPoint = env.playerSpawnPoint;
debugTube = env.debugTube;
} }
} }
} }
@@ -4,6 +4,7 @@ using System.Threading.Tasks;
using Code.Audio; using Code.Audio;
using Code.Configs; using Code.Configs;
using Code.Gameplay.Camera; using Code.Gameplay.Camera;
using Code.Generator;
using Cysharp.Threading.Tasks; using Cysharp.Threading.Tasks;
using UnityEngine; using UnityEngine;
using UnityEngine.AddressableAssets; using UnityEngine.AddressableAssets;
@@ -31,6 +32,8 @@ namespace Code.StaticData
Dictionary<CameraMode, CameraSettingsConfig> CameraSettingsConfigs { get; } Dictionary<CameraMode, CameraSettingsConfig> CameraSettingsConfigs { get; }
Dictionary<AudioSourceType, AudioSourceSettingsConfig> AudioSourceSettingsConfigs { get; } Dictionary<AudioSourceType, AudioSourceSettingsConfig> AudioSourceSettingsConfigs { get; }
AudioTestClipsConfig AudioTestClipsConfig { get; } AudioTestClipsConfig AudioTestClipsConfig { get; }
GeneratorConfig GeneratorConfig { get; }
CourierSoundListConfig CourierSoundListConfig { get; }
void Load(); void Load();
Task<T> InstantiateAsset<T>(AssetReference assetReference) where T : Behaviour; Task<T> InstantiateAsset<T>(AssetReference assetReference) where T : Behaviour;
} }
@@ -5,6 +5,7 @@ using Code.Audio;
using Code.Configs; using Code.Configs;
using Code.Constants; using Code.Constants;
using Code.Gameplay.Camera; using Code.Gameplay.Camera;
using Code.Generator;
using Cysharp.Threading.Tasks; using Cysharp.Threading.Tasks;
using UnityEngine; using UnityEngine;
using UnityEngine.AddressableAssets; using UnityEngine.AddressableAssets;
@@ -28,6 +29,7 @@ namespace Code.StaticData
public DispatcherSoundListConfig DispatcherSoundListConfig { get; private set; } public DispatcherSoundListConfig DispatcherSoundListConfig { get; private set; }
public EnemiesSoundListConfig EnemiesSoundListConfig { get; private set; } public EnemiesSoundListConfig EnemiesSoundListConfig { get; private set; }
public AudioTestClipsConfig AudioTestClipsConfig { get; private set; } public AudioTestClipsConfig AudioTestClipsConfig { get; private set; }
public CourierSoundListConfig CourierSoundListConfig { get; private set; }
public DrunkenGrandpaConfig DrunkenGrandpaConfig {get; private set;} public DrunkenGrandpaConfig DrunkenGrandpaConfig {get; private set;}
public CockroachConfig CockroachConfig { get; private set; } public CockroachConfig CockroachConfig { get; private set; }
@@ -36,6 +38,8 @@ namespace Code.StaticData
public OrderServiceConfig OrderServiceConfig { get; private set; } public OrderServiceConfig OrderServiceConfig { get; private set; }
public OrderBoxConfig OrderBoxConfig { get; private set; } public OrderBoxConfig OrderBoxConfig { get; private set; }
public GeneratorConfig GeneratorConfig { get; private set; }
public Dictionary<CameraMode, CameraSettingsConfig> CameraSettingsConfigs { get; private set; } = new(); public Dictionary<CameraMode, CameraSettingsConfig> CameraSettingsConfigs { get; private set; } = new();
public Dictionary<AudioSourceType, AudioSourceSettingsConfig> AudioSourceSettingsConfigs { get; private set; } = new(); public Dictionary<AudioSourceType, AudioSourceSettingsConfig> AudioSourceSettingsConfigs { get; private set; } = new();
@@ -49,6 +53,7 @@ namespace Code.StaticData
PlayerConfig = Resources.Load<PlayerConfig>(string.Format(StringPaths.ConfigSingle, "App", "PlayerConfig")); PlayerConfig = Resources.Load<PlayerConfig>(string.Format(StringPaths.ConfigSingle, "App", "PlayerConfig"));
OrderServiceConfig = Resources.Load<OrderServiceConfig>(string.Format(StringPaths.ConfigSingle, "Gameplay", "OrderServiceConfig")); OrderServiceConfig = Resources.Load<OrderServiceConfig>(string.Format(StringPaths.ConfigSingle, "Gameplay", "OrderServiceConfig"));
OrderBoxConfig = Resources.Load<OrderBoxConfig>(string.Format(StringPaths.ConfigSingle, "Gameplay", "OrderBoxConfig")); OrderBoxConfig = Resources.Load<OrderBoxConfig>(string.Format(StringPaths.ConfigSingle, "Gameplay", "OrderBoxConfig"));
GeneratorConfig = Resources.Load<GeneratorConfig>(string.Format(StringPaths.ConfigSingle, "App", "GeneratorConfig"));
CameraConfig = Resources.Load<CameraConfig>(string.Format(StringPaths.ConfigSingle, "Camera", "CameraConfig")); CameraConfig = Resources.Load<CameraConfig>(string.Format(StringPaths.ConfigSingle, "Camera", "CameraConfig"));
CameraSettingsConfigs = Resources CameraSettingsConfigs = Resources
@@ -65,6 +70,7 @@ namespace Code.StaticData
SoundtrackListConfig = Resources.Load<SoundtrackListConfig>(string.Format(StringPaths.ConfigSingle, "Audio", "SoundtrackListConfig")); SoundtrackListConfig = Resources.Load<SoundtrackListConfig>(string.Format(StringPaths.ConfigSingle, "Audio", "SoundtrackListConfig"));
AudioTestClipsConfig = Resources.Load<AudioTestClipsConfig>(string.Format(StringPaths.ConfigSingle, "Audio", "AudioTestClipsConfig")); AudioTestClipsConfig = Resources.Load<AudioTestClipsConfig>(string.Format(StringPaths.ConfigSingle, "Audio", "AudioTestClipsConfig"));
SFXListConfig = Resources.Load<SFXListConfig>(string.Format(StringPaths.ConfigSingle, "Audio", "SFXListConfig")); SFXListConfig = Resources.Load<SFXListConfig>(string.Format(StringPaths.ConfigSingle, "Audio", "SFXListConfig"));
CourierSoundListConfig = Resources.Load<CourierSoundListConfig>(string.Format(StringPaths.ConfigSingle, "Audio", "CourierSoundListConfig"));
DispatcherSoundListConfig = Resources.Load<DispatcherSoundListConfig>(string.Format(StringPaths.ConfigSingle, "Audio", "DispatcherSoundListConfig")); DispatcherSoundListConfig = Resources.Load<DispatcherSoundListConfig>(string.Format(StringPaths.ConfigSingle, "Audio", "DispatcherSoundListConfig"));
EnemiesSoundListConfig = Resources.Load<EnemiesSoundListConfig>(string.Format(StringPaths.ConfigSingle, "Audio", "EnemiesSoundListConfig")); EnemiesSoundListConfig = Resources.Load<EnemiesSoundListConfig>(string.Format(StringPaths.ConfigSingle, "Audio", "EnemiesSoundListConfig"));
AudioSourceSettingsConfigs = Resources AudioSourceSettingsConfigs = Resources
@@ -37,7 +37,7 @@ namespace Code.UI
menuMusic.value = _audioService.GetSetting(AudioType.MenuMusic); menuMusic.value = _audioService.GetSetting(AudioType.MenuMusic);
menuMusic.onValueChanged.AddListener(OnMenuMusicUpdate); menuMusic.onValueChanged.AddListener(OnMenuMusicUpdate);
gameplayMusic.value = _audioService.GetSetting(AudioType.GameplayMusic); gameplayMusic.value = _audioService.GetSetting(AudioType.ActionMusic);
gameplayMusic.onValueChanged.AddListener(OnGameplayUpdate); gameplayMusic.onValueChanged.AddListener(OnGameplayUpdate);
} }
@@ -68,8 +68,9 @@ namespace Code.UI
} }
private void OnGameplayUpdate(float value) private void OnGameplayUpdate(float value)
{ {
_audioService.ChangeSetting(AudioType.GameplayMusic, value); _audioService.ChangeSetting(AudioType.ActionMusic, value);
_audioService.PlayTestClip(AudioType.GameplayMusic); _audioService.ChangeSetting(AudioType.PeacefulMusic, value);
_audioService.PlayTestClip(AudioType.ActionMusic);
} }
public override void Hide() public override void Hide()
@@ -0,0 +1,45 @@
%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: 1a7c77305de54155b5b94b607531ee3c, type: 3}
m_Name: GeneratorConfig
m_EditorClassIdentifier: Assembly-CSharp::Code.Generator.GeneratorConfig
roomAssetReferences:
- m_AssetGUID: d4eaf1439c2788c458127b9ba67e4fbf
m_SubObjectName:
m_SubObjectType:
m_SubObjectGUID:
m_EditorAssetChanged: 0
- m_AssetGUID: 28a6c7a4124141341ab7c2b7dfd3e95b
m_SubObjectName:
m_SubObjectType:
m_SubObjectGUID:
m_EditorAssetChanged: 1
- m_AssetGUID: e3a3840a7963bf841872cddb02e90151
m_SubObjectName:
m_SubObjectType:
m_SubObjectGUID:
m_EditorAssetChanged: 0
- m_AssetGUID: c938de3174f184741925c407a43a47f2
m_SubObjectName:
m_SubObjectType:
m_SubObjectGUID:
m_EditorAssetChanged: 0
- m_AssetGUID: 9d78f017876abed4c9cd8957f1e140cb
m_SubObjectName:
m_SubObjectType:
m_SubObjectGUID:
m_EditorAssetChanged: 0
- m_AssetGUID: 7067a5248027e74478f4f0f53ddf06a4
m_SubObjectName:
m_SubObjectType:
m_SubObjectGUID:
m_EditorAssetChanged: 0
@@ -1,5 +1,5 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: 5160d7af825d295229a3be611f44db76 guid: 417b092a73ab1034aa084c67a66c5847
NativeFormatImporter: NativeFormatImporter:
externalObjects: {} externalObjects: {}
mainObjectFileID: 11400000 mainObjectFileID: 11400000
@@ -43,3 +43,18 @@ MonoBehaviour:
m_SubObjectType: m_SubObjectType:
m_SubObjectGUID: m_SubObjectGUID:
m_EditorAssetChanged: 1 m_EditorAssetChanged: 1
- m_AssetGUID: 144ab5188f8ad7a0a92c75703bd12e60
m_SubObjectName:
m_SubObjectType:
m_SubObjectGUID:
m_EditorAssetChanged: 0
- m_AssetGUID: a306df57f348ce7cf900d0b9431739ee
m_SubObjectName:
m_SubObjectType:
m_SubObjectGUID:
m_EditorAssetChanged: 0
- m_AssetGUID: f74a409bf11b25148ad305acc05b14f5
m_SubObjectName:
m_SubObjectType:
m_SubObjectGUID:
m_EditorAssetChanged: 1
@@ -10,6 +10,11 @@ MonoBehaviour:
m_Enabled: 1 m_Enabled: 1
m_EditorHideFlags: 0 m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 83304a98bbdc4e7c9c7c643653ae1368, type: 3} m_Script: {fileID: 11500000, guid: 83304a98bbdc4e7c9c7c643653ae1368, type: 3}
m_Name: CharacterSoundListConfig m_Name: CourierSoundListConfig
m_EditorClassIdentifier: Assembly-CSharp::Code.Configs.CharacterSoundListConfig m_EditorClassIdentifier: Assembly-CSharp::Code.Configs.CourierSoundListConfig
character: [] courierSounds:
- m_AssetGUID: bf87bc9ac43df86be8c818de81d44a54
m_SubObjectName:
m_SubObjectType:
m_SubObjectGUID:
m_EditorAssetChanged: 0
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 377caa2d01eb3e54cb77ab98346ef669
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:
@@ -12,7 +12,7 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 6af4f53d425a41c78ef889fd7e5c3197, type: 3} m_Script: {fileID: 11500000, guid: 6af4f53d425a41c78ef889fd7e5c3197, type: 3}
m_Name: OrderBoxConfig m_Name: OrderBoxConfig
m_EditorClassIdentifier: Assembly-CSharp::Code.Configs.OrderBoxConfig m_EditorClassIdentifier: Assembly-CSharp::Code.Configs.OrderBoxConfig
activationTime: 2 activationTime: 0.7
floatingCurve: floatingCurve:
serializedVersion: 2 serializedVersion: 2
m_Curve: m_Curve:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 40e715b58d5696244a3585eb3f716b98
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,117 @@
fileFormatVersion: 2
guid: 8b1b9552e07ead246b92a6675daca188
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 13
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 0
aniso: 1
mipBias: 0
wrapU: 0
wrapV: 0
wrapW: 0
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 4
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
customData:
physicsShape: []
bones: []
spriteID:
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spriteCustomMetadata:
entries: []
nameFileIdTable: {}
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,117 @@
fileFormatVersion: 2
guid: 5aac8376096d51d47ba7c48613d58a3e
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 13
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 0
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 0
aniso: 1
mipBias: 0
wrapU: 0
wrapV: 0
wrapW: 0
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 1
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 4
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
customData:
physicsShape: []
bones: []
spriteID:
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spriteCustomMetadata:
entries: []
nameFileIdTable: {}
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,117 @@
fileFormatVersion: 2
guid: bbe77ae8c2639e0449ca8fb9055701fb
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 13
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 0
aniso: 1
mipBias: 0
wrapU: 0
wrapV: 0
wrapW: 0
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 4
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
customData:
physicsShape: []
bones: []
spriteID:
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spriteCustomMetadata:
entries: []
nameFileIdTable: {}
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,139 @@
%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: Divan
m_Shader: {fileID: 4800000, guid: 933532a4fcc9baf4fa0491de14d08ed7, type: 3}
m_Parent: {fileID: 0}
m_ModifiedSerializedProperties: 0
m_ValidKeywords:
- _METALLICSPECGLOSSMAP
- _NORMALMAP
m_InvalidKeywords: []
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap:
RenderType: Opaque
disabledShaderPasses:
- MOTIONVECTORS
m_LockedProperties:
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _BaseMap:
m_Texture: {fileID: 2800000, guid: 8b1b9552e07ead246b92a6675daca188, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _BumpMap:
m_Texture: {fileID: 2800000, guid: 5aac8376096d51d47ba7c48613d58a3e, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailAlbedoMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailMask:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailNormalMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _EmissionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 2800000, guid: 8b1b9552e07ead246b92a6675daca188, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MetallicGlossMap:
m_Texture: {fileID: 2800000, guid: bbe77ae8c2639e0449ca8fb9055701fb, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _OcclusionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _ParallaxMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SpecGlossMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- unity_Lightmaps:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- unity_LightmapsInd:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- unity_ShadowMasks:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Ints: []
m_Floats:
- _AddPrecomputedVelocity: 0
- _AlphaClip: 0
- _AlphaToMask: 0
- _Blend: 0
- _BlendModePreserveSpecular: 1
- _BumpScale: 1
- _ClearCoatMask: 0
- _ClearCoatSmoothness: 0
- _Cull: 2
- _Cutoff: 0.5
- _DetailAlbedoMapScale: 1
- _DetailNormalMapScale: 1
- _DstBlend: 0
- _DstBlendAlpha: 0
- _EnvironmentReflections: 1
- _GlossMapScale: 0
- _Glossiness: 0
- _GlossyReflections: 0
- _Metallic: 0
- _OcclusionStrength: 1
- _Parallax: 0.005
- _QueueOffset: 0
- _ReceiveShadows: 1
- _Smoothness: 0.5
- _SmoothnessTextureChannel: 0
- _SpecularHighlights: 1
- _SrcBlend: 1
- _SrcBlendAlpha: 1
- _Surface: 0
- _WorkflowMode: 1
- _XRMotionVectorsPass: 1
- _ZWrite: 1
m_Colors:
- _BaseColor: {r: 1, g: 1, b: 1, a: 1}
- _Color: {r: 1, g: 1, b: 1, a: 1}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1}
m_BuildTextureStacks: []
m_AllowLocking: 1
--- !u!114 &6170637302517857720
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
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: c42465f545622ec45bac72ca18d18155
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 2100000
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: a8eba23bc3e351d4982ba8ff0ab63d32
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,139 @@
%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: Glass
m_Shader: {fileID: 4800000, guid: 933532a4fcc9baf4fa0491de14d08ed7, type: 3}
m_Parent: {fileID: 0}
m_ModifiedSerializedProperties: 0
m_ValidKeywords:
- _METALLICSPECGLOSSMAP
- _NORMALMAP
m_InvalidKeywords: []
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap:
RenderType: Opaque
disabledShaderPasses:
- MOTIONVECTORS
m_LockedProperties:
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _BaseMap:
m_Texture: {fileID: 2800000, guid: 65fd108cef058954aa833036894fbdc9, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _BumpMap:
m_Texture: {fileID: 2800000, guid: 9a821ef1861cd6741ae9e14addede475, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailAlbedoMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailMask:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailNormalMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _EmissionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 2800000, guid: 65fd108cef058954aa833036894fbdc9, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MetallicGlossMap:
m_Texture: {fileID: 2800000, guid: 679da2915ac50974aaeb21b555cc7b28, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _OcclusionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _ParallaxMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SpecGlossMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- unity_Lightmaps:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- unity_LightmapsInd:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- unity_ShadowMasks:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Ints: []
m_Floats:
- _AddPrecomputedVelocity: 0
- _AlphaClip: 0
- _AlphaToMask: 0
- _Blend: 0
- _BlendModePreserveSpecular: 1
- _BumpScale: 1
- _ClearCoatMask: 0
- _ClearCoatSmoothness: 0
- _Cull: 2
- _Cutoff: 0.5
- _DetailAlbedoMapScale: 1
- _DetailNormalMapScale: 1
- _DstBlend: 0
- _DstBlendAlpha: 0
- _EnvironmentReflections: 1
- _GlossMapScale: 0
- _Glossiness: 0
- _GlossyReflections: 0
- _Metallic: 0
- _OcclusionStrength: 1
- _Parallax: 0.005
- _QueueOffset: 0
- _ReceiveShadows: 1
- _Smoothness: 0.5
- _SmoothnessTextureChannel: 0
- _SpecularHighlights: 1
- _SrcBlend: 1
- _SrcBlendAlpha: 1
- _Surface: 0
- _WorkflowMode: 1
- _XRMotionVectorsPass: 1
- _ZWrite: 1
m_Colors:
- _BaseColor: {r: 1, g: 1, b: 1, a: 1}
- _Color: {r: 1, g: 1, b: 1, a: 1}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1}
m_BuildTextureStacks: []
m_AllowLocking: 1
--- !u!114 &8839468315398433628
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
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: eb47a3d3ca2fcba4b82818f76212d2cb
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 2100000
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,130 @@
fileFormatVersion: 2
guid: 65fd108cef058954aa833036894fbdc9
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 13
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 0
aniso: 1
mipBias: 0
wrapU: 0
wrapV: 0
wrapW: 0
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 4
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: WebGL
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
customData:
physicsShape: []
bones: []
spriteID:
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spriteCustomMetadata:
entries: []
nameFileIdTable: {}
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:
Loaded 100 of 455 files, more files were not shown because too many files have changed in this diff. Show more