49 Commits
Author SHA1 Message Date
ThomasCharester a1c2c5fd18 Музыка меня отменила 2025-12-03 20:15:34 +03:00
ThomasCharester 485d54f272 Поудалял важные компоненты 2025-12-03 20:07:36 +03:00
ThomasCharester 0d0787b887 Звуки поражения 2025-12-03 19:32:10 +03:00
ThomasCharester 5d856ae162 Получение урона теперь чуть более заметно (плейсхолдер) 2025-12-03 17:39:26 +03:00
ThomasCharester dd1399e015 Урон курьера 2025-12-03 14:13:45 +03:00
ThomasCharester 2b656412d5 Фикс звуков, только аккуратно
Звуки от 0.01 до 1 ставим, иначе +уши
2025-12-03 14:04:08 +03:00
ThomasCharester 36e6bc3bc2 Звуки шагов в моей голове 2025-12-02 21:50:33 +03:00
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
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 3782a0b568 Фикс отпуска звуков 2025-11-27 23:01:12 +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
599 changed files with 956304 additions and 13784 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_currentHash:
serializedVersion: 2
Hash: 00000000000000000000000000000000
Hash: 1ec1ee985689145b755c859b69691cb0
m_OptimizeCatalogSize: 0
m_BuildRemoteCatalog: 0
m_CatalogRequestsTimeout: 0
@@ -32,6 +32,11 @@ MonoBehaviour:
m_ReadOnly: 0
m_SerializedLabels: []
FlaggedDuringContentUpdateRestriction: 0
- m_GUID: 1cc66c0b13a946e1c9ec37026268e144
m_Address: Audio/Enemies/pl_metal2
m_ReadOnly: 0
m_SerializedLabels: []
FlaggedDuringContentUpdateRestriction: 0
- m_GUID: 1d4767c722c05b5d6b96bb226d378c65
m_Address: Assets/Resources_moved/Prefabs/Player/ArmsMesh.prefab
m_ReadOnly: 0
@@ -52,6 +57,11 @@ MonoBehaviour:
m_ReadOnly: 0
m_SerializedLabels: []
FlaggedDuringContentUpdateRestriction: 0
- m_GUID: 26d4e4c556527924490b8018cd510eda
m_Address: Assets/Resources_moved/Audio/Enemies/bc_bite2.wav
m_ReadOnly: 0
m_SerializedLabels: []
FlaggedDuringContentUpdateRestriction: 0
- m_GUID: 28a6c7a4124141341ab7c2b7dfd3e95b
m_Address: Assets/Resources_moved/Prefabs/Levels/Level1 2.prefab
m_ReadOnly: 0
@@ -67,6 +77,11 @@ MonoBehaviour:
m_ReadOnly: 0
m_SerializedLabels: []
FlaggedDuringContentUpdateRestriction: 0
- m_GUID: 2c6a984e4a1b42647b48e6b7bc69b158
m_Address: Prefabs/Levels/Level6
m_ReadOnly: 0
m_SerializedLabels: []
FlaggedDuringContentUpdateRestriction: 0
- m_GUID: 2ed2d93a9f39d4edba511cb7396c7bb6
m_Address: Assets/Resources_moved/Prefabs/Enemies/Cockroach.prefab
m_ReadOnly: 0
@@ -87,13 +102,8 @@ MonoBehaviour:
m_ReadOnly: 0
m_SerializedLabels: []
FlaggedDuringContentUpdateRestriction: 0
- m_GUID: 3d195945b1fbf114a88457cba466bc2b
m_Address: Assets/Resources_moved/Rooms/Room2.prefab
m_ReadOnly: 0
m_SerializedLabels: []
FlaggedDuringContentUpdateRestriction: 0
- m_GUID: 4472dd84628855c4085cacaec19efa29
m_Address: Assets/Resources_moved/Rooms/Room1.prefab
- m_GUID: 3f8f2171cc252d953b82083cc16bd1ae
m_Address: Assets/Resources_moved/Prefabs/Levels/Level6_1.prefab
m_ReadOnly: 0
m_SerializedLabels: []
FlaggedDuringContentUpdateRestriction: 0
@@ -102,13 +112,18 @@ MonoBehaviour:
m_ReadOnly: 0
m_SerializedLabels: []
FlaggedDuringContentUpdateRestriction: 0
- m_GUID: 4b279429428a13040b6d1713122cd0de
m_Address: Assets/Resources_moved/Audio/SFX/pl_pain5.wav
m_ReadOnly: 0
m_SerializedLabels: []
FlaggedDuringContentUpdateRestriction: 0
- m_GUID: 4bd64d1fcecc9c6b09d81e78b7dcfebe
m_Address: Audio/Dispatcher/take_damage1
m_ReadOnly: 0
m_SerializedLabels: []
FlaggedDuringContentUpdateRestriction: 0
- m_GUID: 4f660559d76c3ed42a7c34a0b16487f7
m_Address: Assets/Resources_moved/Rooms/Room3.prefab
- m_GUID: 7067a5248027e74478f4f0f53ddf06a4
m_Address: Prefabs/Rooms/Save1
m_ReadOnly: 0
m_SerializedLabels: []
FlaggedDuringContentUpdateRestriction: 0
@@ -163,11 +178,26 @@ MonoBehaviour:
m_ReadOnly: 0
m_SerializedLabels: []
FlaggedDuringContentUpdateRestriction: 0
- m_GUID: 9d78f017876abed4c9cd8957f1e140cb
m_Address: Prefabs/Rooms/Level1_2
m_ReadOnly: 0
m_SerializedLabels: []
FlaggedDuringContentUpdateRestriction: 0
- m_GUID: a306df57f348ce7cf900d0b9431739ee
m_Address: launch_selectmenu
m_ReadOnly: 0
m_SerializedLabels: []
FlaggedDuringContentUpdateRestriction: 0
- m_GUID: aa138b2e21adfbf4bbbfa5bf9d54b8f2
m_Address: Assets/Resources_moved/Audio/UI/buttonclickrelease.wav
m_ReadOnly: 0
m_SerializedLabels: []
FlaggedDuringContentUpdateRestriction: 0
- m_GUID: ae6ab2c88ae248ce1b6efca892f17659
m_Address: Assets/Resources_moved/Audio/Music/TestDeath.ogg
m_ReadOnly: 0
m_SerializedLabels: []
FlaggedDuringContentUpdateRestriction: 0
- m_GUID: b2e8dc2aeb0311cd8a826b51cf8e94dc
m_Address: GameOver
m_ReadOnly: 0
@@ -178,8 +208,13 @@ MonoBehaviour:
m_ReadOnly: 0
m_SerializedLabels: []
FlaggedDuringContentUpdateRestriction: 0
- m_GUID: b3471d165fe389f479380f61034bea57
m_Address: Assets/Resources_moved/Prefabs/Levels/Level1 1.prefab
- m_GUID: b37ea8c61cc322afdad529d678612d22
m_Address: Assets/Resources_moved/Audio/Enemies/zo_attack2.wav
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
@@ -188,13 +223,28 @@ MonoBehaviour:
m_ReadOnly: 0
m_SerializedLabels: []
FlaggedDuringContentUpdateRestriction: 0
- m_GUID: c5a0ad8a615841547ac2ee613af526d8
m_Address: Assets/Resources_moved/Audio/SFX/pl_pain2.wav
m_ReadOnly: 0
m_SerializedLabels: []
FlaggedDuringContentUpdateRestriction: 0
- m_GUID: c938de3174f184741925c407a43a47f2
m_Address: Prefabs/Rooms/Level1
m_ReadOnly: 0
m_SerializedLabels: []
FlaggedDuringContentUpdateRestriction: 0
- m_GUID: cab4b1ff78dd6b1fba61aa165aa17b4d
m_Address: Audio/Dispatcher/receiving_an_order2
m_ReadOnly: 0
m_SerializedLabels: []
FlaggedDuringContentUpdateRestriction: 0
- m_GUID: d4eaf1439c2788c458127b9ba67e4fbf
m_Address: Prefabs/Levels/Level1
- m_GUID: e3a3840a7963bf841872cddb02e90151
m_Address: Prefabs/Levels/MainMenu 1
m_ReadOnly: 0
m_SerializedLabels: []
FlaggedDuringContentUpdateRestriction: 0
- m_GUID: e84e3a3c26ccbd50d92f13627403f148
m_Address: Audio/Enemies/rch_walk
m_ReadOnly: 0
m_SerializedLabels: []
FlaggedDuringContentUpdateRestriction: 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:
@@ -1,6 +1,9 @@
using Code.App.StateMachine;
using Code.Audio;
using Code.Gameplay.Player;
using Code.Input;
using Code.Scenes;
using Code.Scenes.SceneEnvironments;
using Code.StateMachine;
using Code.UI;
using Cysharp.Threading.Tasks;
@@ -30,7 +33,11 @@ namespace Code.App.AppStates
Context.InputService.EnableMap(ActionMappings.UI);
Context.InputService.DebugBindAction((int)ActionMappings.UI,(int)UIActions.Continue, TryToExit);
GameOver();
Context.AudioService.PlayRandomMusicUntilHumanityWillBeDestroyedForTheySins(MusicType.Death);
Context.AudioService.ApplyStun(5000,0.5f);
GameOver().Forget();
base.EnterState();
}
@@ -45,7 +52,7 @@ namespace Code.App.AppStates
await Context.UIService.AsyncSwitchPanelTo(UIPanel.GameOver);
_gameOverPanel = (GameOverPanel)Context.UIService.CurrentPanel;
_gameOverPanel.Show();
}
private void ToMainMenu()
@@ -71,6 +78,8 @@ namespace Code.App.AppStates
Context.InputService.DisableMap(ActionMappings.UI);
Context.InputService.DebugUnbindAction((int)ActionMappings.UI,(int)UIActions.Continue, TryToExit);
Context.AudioService.GladlyAskToStopMusic(MusicType.Death, callback: Context.AudioFactory.ReleaseDeathMusic);
Context.AudioService.TransitToSnapshot(AudioSnapshotState.None);
base.ExitState();
}
}
@@ -13,10 +13,12 @@ using Code.StateMachine;
using Code.UI;
using Code.UI.Panels;
using Cysharp.Threading.Tasks;
using DG.Tweening;
using Reflex.Core;
using Reflex.Extensions;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.Rendering;
using UnityEngine.SceneManagement;
namespace Code.App.AppStates
@@ -43,24 +45,17 @@ namespace Code.App.AppStates
.RegisterLoading(LoadingWork.LoadModelResource)
.RegisterLoading(LoadingWork.LoadAudio);
//_playerHealth = Context.PlayerFactory.CreatePlayerHealth();
//_playerHealth.OnDamage += PlayerDamageTaken;
//_playerHealth.OnDeath += EndGame;
Context.AudioService.TransitToSnapshot(AudioSnapshotState.None);
Context.InputService.EnableMap(ActionMappings.Gameplay);
Context.InputService.DebugBindAction((int)ActionMappings.Debug, (int)DebugActions.Debug1, InstaKillDEBUG);
Context.InputService.DebugBindAction((int)ActionMappings.Debug, (int)DebugActions.Debug4, RoomPassedDEBUG);
Context.InputService.DebugBindAction((int)ActionMappings.Debug, (int)DebugActions.Debug4, TakeGamageDEBUG);
Context.SceneLoaderService.LoadSceneAsyncAwaitable((int)SceneIds.DevGen);
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
WaitForLoad();
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
WaitForLoad().Forget();
}
private async UniTask WaitForPlayerCharacterLoad() => _playerCharacter = await Context.PlayerFactory.CreatePlayer();
@@ -69,8 +64,11 @@ namespace Code.App.AppStates
await UniTask.WhenAll(
Context.UIService.AsyncSwitchPanelTo(UIPanel.Gameplay),
Context.AudioFactory.WarmGameplayMusic(),
Context.AudioFactory.WarmDeathMusic(),
Context.AudioFactory.WarmSFX(),
Context.AudioFactory.WarmDispatcher()
Context.AudioFactory.WarmDispatcher(),
Context.AudioFactory.WarmEnemies(),
Context.AudioFactory.WarmCourier()
);
Context.LoadingManager
@@ -90,6 +88,9 @@ namespace Code.App.AppStates
Context.LoadingManager.OnLoadingEnded -= AfterSceneLoaded;
Context.LoadingManager.OnLoadingEnded += AfterPlayerLoaded;
Context.PlayerProvider = SceneManager.GetActiveScene().GetSceneContainer().Resolve<IPlayerProvider>();
Context.PlayerFactory = SceneManager.GetActiveScene().GetSceneContainer().Resolve<IPlayerFactory>();
await UniTask.WhenAll(
WaitForPlayerArmsToInitialize(),
WaitForPlayerCharacterLoad()
@@ -111,6 +112,8 @@ namespace Code.App.AppStates
GameplaySceneEnvironment sceneEnvironment = SceneEnvironmentVariables(sceneContainer);
_volume = sceneEnvironment.volume;
PlayerInitialize(sceneEnvironment);
CameraInitialize();
@@ -152,15 +155,30 @@ namespace Code.App.AppStates
private void PlayerDamageTaken(int damage, PlayerHealth health)
{
Context.AudioService.PlayDispatcher((DispatcherSounds)Random.Range((int)DispatcherSounds.TakeDamage1,(int)DispatcherSounds.TakeDamage4));
Context.AudioService.PlayCourier((CourierSounds)Random.Range((int)CourierSounds.Damage1,(int)CourierSounds.Damage2));
DamageEffectProcess().Forget();
}
// TODO В конфиг
private async UniTaskVoid DamageEffectProcess()
{
_damagePanel.Show();
Context.AudioService.ApplyStun(200, 0.5f);
DOTween.To(() => _volume.weight, x => _volume.weight = x, 1f, 0.5f);
await UniTask.WaitForSeconds(3f);
DOTween.To(() => _volume.weight, x => _volume.weight = x, 0f, 1f);
Context.AudioService.ApplyStun(5000, 1f);
_damagePanel.Hide();
}
// DEBUG
private void InstaKillDEBUG(InputAction.CallbackContext context)
{
_playerHealth.InstaKill();
}
private void RoomPassedDEBUG(InputAction.CallbackContext context)
private void TakeGamageDEBUG(InputAction.CallbackContext context)
{
_orderService.RoomPassed();
_playerHealth.GetDamage(1);
}
// DEBUG
private bool _tickEnabled;
@@ -194,12 +212,16 @@ namespace Code.App.AppStates
Context.AudioService.OnDispatcherEnded -= _gameplayPanel.CloseDispatcher;
Context.InputService.DisableMap(ActionMappings.Gameplay);
Context.AudioService.GladlyAskToStopMusic(MusicType.Action, callback: Context.AudioFactory.ReleaseActionMusic);
Context.AudioService.GladlyAskToStopMusic(MusicType.Peaceful, callback: Context.AudioFactory.ReleasePeacefulMusic);
Context.AudioService.GladlyAskToStopMusic(MusicType.Action, time: 0f, callback: Context.AudioFactory.ReleaseActionMusic);
Context.AudioService.GladlyAskToStopMusic(MusicType.Peaceful, time: 0f, 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.Debug4, RoomPassedDEBUG);
Context.InputService.DebugUnbindAction((int)ActionMappings.Debug, (int)DebugActions.Debug4, TakeGamageDEBUG);
base.ExitState();
}
@@ -216,13 +238,15 @@ namespace Code.App.AppStates
private GameplayPanel _gameplayPanel;
private ArmsMeshProvider _armsMesh;
private DamagePanel _damagePanel;
private void UIInitialize()
{
_gameplayPanel = (GameplayPanel)Context.UIService.CurrentPanel;
_gameplayPanel.Initialize(_playerScore, _playerHealth, _orderService);
Context.AudioService.OnDispatcherStarted += _gameplayPanel.SummonDispatcher;
Context.AudioService.OnDispatcherEnded += _gameplayPanel.CloseDispatcher;
_damagePanel = _gameplayPanel.DamagePanel;
}
private void MusicInitialize()
{
@@ -244,6 +268,8 @@ namespace Code.App.AppStates
_orderService.OnOrderDelivered += OrderDelivered;
_orderService.OnOrderFailure += OrderFailure;
}
private Volume _volume;
private GameplaySceneEnvironment SceneEnvironmentVariables(Container sceneContainer)
{
var sceneEnvironment = (GameplaySceneEnvironment)sceneContainer.Resolve<CurrentSceneEnvironment>();
@@ -33,11 +33,7 @@ namespace Code.App
containerBuilder.AddSingleton(typeof(LoadingManager), typeof(ILoadingManager));
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);
containerBuilder.AddSingleton(typeof(UIFactory), typeof(IUIFactory));
@@ -71,6 +67,7 @@ namespace Code.App
containerBuilder.AddSingleton(infrastructureUnit.AddComponent<CameraStateMachine>());
}
// TODO Часть в сцены
private void InstallStaticData(ContainerBuilder containerBuilder, out IStaticDataService staticDataService)
{
staticDataService = new StaticDataService();
@@ -97,10 +94,13 @@ namespace Code.App
containerBuilder.AddSingleton(staticDataService.SoundtrackListConfig, typeof(SoundtrackListConfig));
containerBuilder.AddSingleton(staticDataService.AudioTestClipsConfig, typeof(AudioTestClipsConfig));
containerBuilder.AddSingleton(staticDataService.SFXListConfig, typeof(SFXListConfig));
containerBuilder.AddSingleton(staticDataService.CourierSoundListConfig, typeof(CourierSoundListConfig));
containerBuilder.AddSingleton(staticDataService.DispatcherSoundListConfig, typeof(DispatcherSoundListConfig));
containerBuilder.AddSingleton(staticDataService.EnemiesSoundListConfig, typeof(EnemiesSoundListConfig));
containerBuilder.AddSingleton(staticDataService.AudioSourceSettingsConfigs, typeof(Dictionary<AudioSourceType, AudioSourceSettingsConfig>));
containerBuilder.AddSingleton(staticDataService.DefaultAudioSettingsConfig, typeof(DefaultAudioSettingsConfig));
containerBuilder.AddSingleton(staticDataService.OrderServiceConfig, typeof(OrderServiceConfig));
containerBuilder.AddSingleton(staticDataService.OrderBoxConfig, typeof(OrderBoxConfig));
@@ -119,9 +119,7 @@ namespace Code.App
AttributeInjector.Inject(cameraStateMachine.StateMachineContext, container);
cameraStateMachine.Initialize();
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
BootstrapFinish(container);
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
BootstrapFinish(container).Forget();
}
private async UniTaskVoid BootstrapFinish(Container container)
{
@@ -1,4 +1,5 @@
using Code.App.Loading;
using Code.Gameplay.Enemies;
using Code.Gameplay.Orders.Order;
using Code.Gameplay.Player;
using Code.Generator;
@@ -21,6 +22,9 @@ namespace Code.App.SceneInstallers
containerBuilder.AddScoped(typeof(PlayerScore), typeof(IPlayerScore));
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;
@@ -37,7 +41,7 @@ namespace Code.App.SceneInstallers
loadingManager
.UnregisterLoading(LoadingWork.LoadScene);
LoadRooms(container,loadingManager);
LoadRooms(container,loadingManager).Forget();
}
private async UniTaskVoid LoadRooms(Container container, ILoadingManager loadingManager)
@@ -19,10 +19,10 @@ namespace Code.App.StateMachine
[Inject] public AppStateMachine StateMachine { get; private set; }
[Inject] public CameraStateMachine CameraStateMachine { 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 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; }
}
}
@@ -11,8 +11,10 @@ namespace Code.Audio
}
public enum EnemiesSounds
{
Bastard,
Bravo
GrandpaAttack,
RoachAttack,
RoachStep,
GrandpaStep
}
public enum DispatcherSounds
{
@@ -28,4 +30,10 @@ namespace Code.Audio
Late4,
Late5
}
public enum CourierSounds
{
Step,
Damage1,
Damage2
}
}
@@ -19,24 +19,28 @@ namespace Code.Audio
private AssetReference[] _audioTestClipsReferences;
private AssetReference[] _peacefulSoundtrack;
private AssetReference[] _actionSoundtrack;
private AssetReference[] _deathSoundtrack;
private AssetReference[] _menuSoundtrack;
private AssetReference[] _SFX;
private AssetReference[] _enemies;
private AssetReference[] _dispatcher;
private AssetReference[] _character;
private AssetReference[] _courier;
private AsyncOperationHandle<IList<AudioClip>> _audioTestClipsHandle;
private AsyncOperationHandle<IList<AudioClip>> _menuMusicHandle;
private AsyncOperationHandle<IList<AudioClip>> _deathMusicHandle;
private AsyncOperationHandle<IList<AudioClip>> _actionMusicHandle;
private AsyncOperationHandle<IList<AudioClip>> _peacefulMusicHandle;
private AsyncOperationHandle<IList<AudioClip>> _SFXHandle;
private AsyncOperationHandle<IList<AudioClip>> _enemiesHandle;
private AsyncOperationHandle<IList<AudioClip>> _dispatcherHandle;
private AsyncOperationHandle<IList<AudioClip>> _courierHandle;
public Dictionary<AudioType, AudioClip> AudioTestClips { 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> EnemiesAudios { get; private set; } = new();
public List<AudioClip> CourierAudios { get; private set; } = new();
public List<AudioClip> DispatcherAudios { get; private set; } = new();
public AudioFactory(AudioMixerConfig audioMixerConfig,
@@ -44,7 +48,8 @@ namespace Code.Audio
SFXListConfig sfxListConfig,
EnemiesSoundListConfig enemiesSoundListConfig,
DispatcherSoundListConfig dispatcherSoundListConfig,
AudioTestClipsConfig audioTestClipsConfig
AudioTestClipsConfig audioTestClipsConfig,
CourierSoundListConfig courierSoundListConfig
)
{
AudioMixer = audioMixerConfig.audioMixerAsset;
@@ -52,15 +57,18 @@ namespace Code.Audio
_peacefulSoundtrack = soundtrackListConfig.peacefulSoundtrack;
_actionSoundtrack = soundtrackListConfig.actionSoundtrack;
_deathSoundtrack = soundtrackListConfig.deathSoundtrack;
_menuSoundtrack = soundtrackListConfig.menuSoundtrack;
_SFX = sfxListConfig.SFX;
_enemies = enemiesSoundListConfig.enemies;
_dispatcher = dispatcherSoundListConfig.dispatcher;
_courier = courierSoundListConfig.courierSounds;
_audioTestClipsReferences = audioTestClipsConfig.audioTestClips;
MusicDictionary.Add(MusicType.Menu, new ());
MusicDictionary.Add(MusicType.Peaceful, new ());
MusicDictionary.Add(MusicType.Death, new ());
MusicDictionary.Add(MusicType.Action, new ());
MusicDictionary.Add(MusicType.Peaceful, new ());
}
public async UniTask LoadAudioSourcePrefab(Action<GameObject> callback) =>
@@ -112,6 +120,16 @@ namespace Code.Audio
// foreach (var assetReference in _menuSoundtrack) assetReference.ReleaseAsset();
_menuMusicHandle.Release();
}
public async UniTask WarmDeathMusic()
{
_deathMusicHandle = Addressables.LoadAssetsAsync<AudioClip>(_deathSoundtrack, OnDeathTrackLoaded, Addressables.MergeMode.Union);
await _deathMusicHandle.ToUniTask();
}
public void ReleaseDeathMusic()
{
MusicDictionary[MusicType.Death].Clear();
_deathMusicHandle.Release();
}
public async UniTask WarmSFX( )
{
_SFXHandle = Addressables.LoadAssetsAsync<AudioClip>(_SFX, OnSFXLoaded, Addressables.MergeMode.Union);
@@ -137,6 +155,18 @@ namespace Code.Audio
EnemiesAudios.Clear();
_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( )
{
@@ -156,6 +186,10 @@ namespace Code.Audio
{
MusicDictionary[MusicType.Menu].Add(audioClip);
}
private void OnDeathTrackLoaded(AudioClip audioClip)
{
MusicDictionary[MusicType.Death].Add(audioClip);
}
// private int _audioTestClipCounter;
private void OnAudioTestClipLoaded(AudioClip audioClip)
@@ -182,5 +216,9 @@ namespace Code.Audio
{
DispatcherAudios.Add(audioClip);
}
private void OnCourierLoaded(AudioClip audioClip)
{
CourierAudios.Add(audioClip);
}
}
}
+87 -179
View File
@@ -22,134 +22,104 @@ namespace Code.Audio
private AudioSource _actionMusicSource;
private AudioSource _peacefulMusicSource;
private AudioMixerGroup _masterGroup,
// _musicGroup,
_actionMusicGroup,
_menuMusicGroup,
_peacefulMusicGroup,
_SFXGroup,
_creaturesGroup,
_dispatcherGroup,
_courierGroup,
_enemiesGroup;
private Dictionary<AudioType, AudioMixerGroup> _audioMixerGroups = new();
private readonly AudioSourcePool _audioSourcePool;
private Dictionary<AudioSnapshotState, AudioMixerSnapshot> _snapshots = new();
// Юнити не может - говнокод поможет.
private Dictionary<AudioSnapshotState, Dictionary<AudioType, float>> _snapshotsVolumes = new();
private Dictionary<AudioSourceType, AudioSourceSettingsConfig> _settings;
public AudioService(IAudioFactory audioFactory, Dictionary<AudioSourceType, AudioSourceSettingsConfig> settings)
public AudioService(IAudioFactory audioFactory,
Dictionary<AudioSourceType, AudioSourceSettingsConfig> settings,
DefaultAudioSettingsConfig defaultAudioSettingsConfig)
{
_audioFactory = audioFactory;
_audioSourcePool = new(settings);
_settings = settings;
_snapshotsVolumes.Add(AudioSnapshotState.None,defaultAudioSettingsConfig.noneVolume);
_snapshotsVolumes.Add(AudioSnapshotState.Menu,defaultAudioSettingsConfig.menuVolume);
_snapshotsVolumes.Add(AudioSnapshotState.Action,defaultAudioSettingsConfig.actionVolume);
_snapshotsVolumes.Add(AudioSnapshotState.Peaceful,defaultAudioSettingsConfig.peacefulVolume);
}
// TODO Грязно, убрать снапшоты НАХУЙ
public float GetSetting(AudioType type)
{
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;
}
_mixer.GetFloat(_audioMixerGroups[type].name, out float value);
value = Mathf.Pow(10f, value / 20);
return value;
}
// TODO Грязно, убрать снапшоты НАХУЙ
public void ChangeSetting(AudioType type, float value)
{
float volume = Mathf.Log10(value) * 20;
switch (type)
{
case AudioType.SFX:
_snapshots[AudioSnapshotState.Peaceful].audioMixer.SetFloat(_SFXGroup.name, volume);
_snapshots[AudioSnapshotState.Action].audioMixer.SetFloat(_SFXGroup.name, volume);
break;
case AudioType.DeathMusic:
case AudioType.Master:
_snapshots[AudioSnapshotState.Menu].audioMixer.SetFloat(_masterGroup.name, volume);
_snapshots[AudioSnapshotState.Peaceful].audioMixer.SetFloat(_masterGroup.name, volume);
_snapshots[AudioSnapshotState.Action].audioMixer.SetFloat(_masterGroup.name, volume);
_snapshotsVolumes[AudioSnapshotState.Menu][type] = value;
_snapshotsVolumes[AudioSnapshotState.Action][type] = value;
_snapshotsVolumes[AudioSnapshotState.Peaceful][type] = value;
_mixer.SetFloat(_audioMixerGroups[type].name, volume);
break;
case AudioType.Creatures:
_snapshots[AudioSnapshotState.Peaceful].audioMixer.SetFloat(_creaturesGroup.name, volume);
_snapshots[AudioSnapshotState.Action].audioMixer.SetFloat(_creaturesGroup.name, volume);
case AudioType.ActionMusic:
_snapshotsVolumes[AudioSnapshotState.Action][type] = value;
_mixer.SetFloat(_audioMixerGroups[type].name, volume);
break;
case AudioType.GameplayMusic:
_snapshots[AudioSnapshotState.Peaceful].audioMixer.SetFloat(_peacefulMusicGroup.name, volume);
_snapshots[AudioSnapshotState.Action].audioMixer.SetFloat(_actionMusicGroup.name, volume);
case AudioType.PeacefulMusic:
_snapshotsVolumes[AudioSnapshotState.Peaceful][type] = value;
_mixer.SetFloat(_audioMixerGroups[type].name, volume);
break;
case AudioType.MenuMusic:
_snapshots[AudioSnapshotState.Menu].audioMixer.SetFloat(_menuMusicGroup.name, volume);
_snapshotsVolumes[AudioSnapshotState.Menu][type] = value;
_mixer.SetFloat(_audioMixerGroups[type].name, volume);
break;
case AudioType.DispatcherSounds:
_snapshots[AudioSnapshotState.Peaceful].audioMixer.SetFloat(_dispatcherGroup.name, volume);
_snapshots[AudioSnapshotState.Action].audioMixer.SetFloat(_dispatcherGroup.name, volume);
case AudioType.SFX:
case AudioType.Dispatcher:
case AudioType.Courier:
case AudioType.Enemies:
_snapshotsVolumes[AudioSnapshotState.Action][type] = value;
_snapshotsVolumes[AudioSnapshotState.Peaceful][type] = value;
_mixer.SetFloat(_audioMixerGroups[type].name, volume);
break;
}
// _mixer.FindSnapshot("Action").audioMixer.SetFloat("music", volume);
}
public async UniTask Initialize()
{
// _mixer = await _audioFactory.CreateMixer();
_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.Death, _mixer.FindMatchingGroups(AudioGroups.DeathMusicGroup)[0]);
_musicAudioGroups.Add(MusicType.Action, _mixer.FindMatchingGroups(AudioGroups.ActionMusicGroup)[0]);
_musicAudioGroups.Add(MusicType.Peaceful, _mixer.FindMatchingGroups(AudioGroups.PeacefulMusicGroup)[0]);
_cancellationTokenSources.Add(MusicType.Menu, new());
_cancellationTokenSources.Add(MusicType.Death, new());
_cancellationTokenSources.Add(MusicType.Action, new());
_cancellationTokenSources.Add(MusicType.Peaceful, new());
_musicAudioSources.Add(MusicType.Menu, null);
_musicAudioSources.Add(MusicType.Death, null);
_musicAudioSources.Add(MusicType.Action, null);
_musicAudioSources.Add(MusicType.Peaceful, null);
_SFXGroup = _mixer.FindMatchingGroups(AudioGroups.SFXGroup)[0];
_creaturesGroup = _mixer.FindMatchingGroups(AudioGroups.CreaturesGroup)[0];
_dispatcherGroup = _mixer.FindMatchingGroups(AudioGroups.DispatcherMusicGroup)[0];
_courierGroup = _mixer.FindMatchingGroups(AudioGroups.CourierMusicGroup)[0];
_enemiesGroup = _mixer.FindMatchingGroups(AudioGroups.EnemiesMusicGroup)[0];
_audioMixerGroups.Add(AudioType.Master, _mixer.FindMatchingGroups(AudioGroups.MasterGroup)[0]);
_audioMixerGroups.Add(AudioType.SFX, _mixer.FindMatchingGroups(AudioGroups.SFXGroup)[0]);
_audioMixerGroups.Add(AudioType.Dispatcher, _mixer.FindMatchingGroups(AudioGroups.DispatcherMusicGroup)[0]);
_audioMixerGroups.Add(AudioType.Courier, _mixer.FindMatchingGroups(AudioGroups.CourierGroup)[0]);
_audioMixerGroups.Add(AudioType.Enemies, _mixer.FindMatchingGroups(AudioGroups.EnemiesGroup)[0]);
_audioMixerGroups.Add(AudioType.MenuMusic, _musicAudioGroups[MusicType.Menu]);
_audioMixerGroups.Add(AudioType.DeathMusic, _musicAudioGroups[MusicType.Death]);
_audioMixerGroups.Add(AudioType.ActionMusic, _musicAudioGroups[MusicType.Action]);
_audioMixerGroups.Add(AudioType.PeacefulMusic, _musicAudioGroups[MusicType.Peaceful]);
_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);
await _audioFactory.LoadAudioSourcePrefab(_audioSourcePool.Initialize);
}
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
private Dictionary<MusicType, CancellationTokenSource> _cancellationTokenSources = new();
private Dictionary<MusicType, AudioSource> _musicAudioSources = new();
private Dictionary<MusicType, AudioMixerGroup> _musicAudioGroups = new();
@@ -169,19 +139,13 @@ namespace Code.Audio
_musicAudioSources[musicType].Play();
// await UniTask.WaitUntilValueChanged(_musicAudioSources[musicType],
// _ => !_musicAudioSources[musicType].isPlaying,
// cancellationToken: _cancellationTokenSources[musicType].Token);
await UniTask.NextFrame();
// Debug.Log($"Playing {musicType}");
var (isCanceled, _) = await UniTask.WaitUntilValueChanged(_musicAudioSources[musicType],
_ => !_musicAudioSources[musicType].isPlaying,
cancellationToken: _cancellationTokenSources[musicType].Token).SuppressCancellationThrow();
// Debug.Log($"Finished {musicType}");
Debug.LogError("Music skipping");
if (isCanceled)
{
// Debug.Log($"Cancelled {musicType}");
_cancellationTokenSources[musicType].Dispose();
_cancellationTokenSources[musicType] = new();
@@ -191,13 +155,13 @@ namespace Code.Audio
return;
}
PlayRandomMusicUntilHumanityWillBeDestroyedForTheySins(musicType);
PlayRandomMusicUntilHumanityWillBeDestroyedForTheySins(musicType).Forget();
}
public async UniTaskVoid GladlyAskToStopMusic(MusicType musicType,
AudioSnapshotState audioSnapshotState = AudioSnapshotState.None, float time = 1f, Action callback = null)
{
TransitToSnapshot(audioSnapshotState, time);
//TransitToSnapshot(audioSnapshotState, time);
await UniTask.WaitForSeconds(time);
@@ -205,39 +169,56 @@ namespace Code.Audio
callback?.Invoke();
}
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
public void StopMusic()
{
_peacefulMusicSource.Stop();
_actionMusicSource.Stop();
_cancellationTokenSources[MusicType.Peaceful].Cancel();
_cancellationTokenSources[MusicType.Action].Cancel();
}
public void GladlyAskToStopMusic(Action callback = null)
{
TransitToSnapshot(AudioSnapshotState.None);
// TransitToSnapshot(AudioSnapshotState.None);
_peacefulMusicSource.Stop();
_actionMusicSource.Stop();
callback?.Invoke();
}
public void TransitToSnapshot(AudioSnapshotState state, float time = 1f)
public void TransitToSnapshot(AudioSnapshotState state, float time = 1)
{
_snapshots[state].TransitionTo(time);
foreach (var key in _audioMixerGroups.Keys)
_mixer.DOSetFloat(_audioMixerGroups[key].name, Mathf.Log10(_snapshotsVolumes[state][key]) * 20, 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)
{
_audioSourcePool.PlayOneShot(_audioFactory.SFXAudios[(int)sfxId], position, _SFXGroup);
_audioSourcePool
.PlayOneShot(_audioFactory.SFXAudios[(int)sfxId], position, _audioMixerGroups[AudioType.SFX]).Forget();
}
public void ApplyStun(float value, float time)
{
_mixer.DOSetFloat("Stun", value, time);
}
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)
{
AudioSource source = _audioSourcePool.GetSource();
source.outputAudioMixerGroup = _audioMixerGroups[group];
return source;
}
public void ReleaseSourceOfGroup(AudioSource source) => _audioSourcePool.ReleaseSource(source);
// Чинить долго и дорого пусть Артёмов будет много, ведь он наш друг
public event IAudioService.OnAudioPlayingDelegate OnDispatcherStarted;
public event IAudioService.OnAudioPlayingDelegate OnDispatcherEnded;
@@ -245,108 +226,35 @@ namespace Code.Audio
public void PlayDispatcher(DispatcherSounds dispatcherSoundId)
{
OnDispatcherStarted?.Invoke();
_audioSourcePool.PlayOneShot(_audioFactory.DispatcherAudios[(int)dispatcherSoundId], _dispatcherGroup,
AudioSourceType.NoBlend, () => OnDispatcherEnded?.Invoke());
_audioSourcePool.PlayOneShot(_audioFactory.DispatcherAudios[(int)dispatcherSoundId],
_audioMixerGroups[AudioType.Dispatcher],
AudioSourceType.NoBlend, () => OnDispatcherEnded?.Invoke()).Forget();
}
public void PlayCourier(CourierSounds courierSounds)
{
_audioSourcePool.PlayOneShot(_audioFactory.CourierAudios[(int)courierSounds],
_audioMixerGroups[AudioType.Courier],
AudioSourceType.NoBlend).Forget();
}
private CancellationTokenSource _testClipCancellationTokenSource = new();
private void ResetCurrentTestAudioSource() => _currentTestClipAudioType = AudioType.Master;
private AudioType _currentTestClipAudioType;
// TODO Засунуть в словарь
public void PlayTestClip(AudioType audioType)
{
if(_currentTestClipAudioType == audioType) return;
if (_currentTestClipAudioType == audioType) return;
_testClipCancellationTokenSource.Cancel();
_testClipCancellationTokenSource = new();
_currentTestClipAudioType = audioType;
switch (audioType)
{
case AudioType.SFX:
_audioSourcePool.PlayOneShot(_audioFactory.AudioTestClips[audioType],
_SFXGroup, _testClipCancellationTokenSource,
AudioSourceType.NoBlend, ResetCurrentTestAudioSource);
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;
}
_audioSourcePool.PlayOneShot(_audioFactory.AudioTestClips[audioType],
_audioMixerGroups[audioType], _testClipCancellationTokenSource,
AudioSourceType.NoBlend, ResetCurrentTestAudioSource).Forget();
}
}
}
@@ -14,6 +14,7 @@ namespace Code.Audio
List<AudioClip> SFXAudios { get; }
List<AudioClip> EnemiesAudios { get; }
List<AudioClip> DispatcherAudios { get; }
List<AudioClip> CourierAudios { get; }
UniTask LoadAudioSourcePrefab(Action<GameObject> callback);
UniTask WarmGameplayMusic( );
void ReleaseActionMusic();
@@ -28,5 +29,9 @@ namespace Code.Audio
void ReleaseEnemies();
UniTask WarmDispatcher( );
void ReleaseDispatcher();
UniTask WarmCourier();
void ReleaseCourier();
UniTask WarmDeathMusic( );
void ReleaseDeathMusic();
}
}
@@ -23,5 +23,9 @@ namespace Code.Audio
void ChangeSetting(AudioType type, float value);
float GetSetting(AudioType type);
void PlayTestClip(AudioType audioType);
AudioSource GetSourceOfGroup(AudioType group);
void ReleaseSourceOfGroup(AudioSource source);
void PlayCourier(CourierSounds range);
void ApplyStun(float value, float time);
}
}
@@ -4,15 +4,19 @@ namespace Code.Audio
{
Menu,
Peaceful,
Action
Action,
Death
}
public enum AudioType
{
Master,
MenuMusic,
GameplayMusic,
Creatures,
DispatcherSounds,
SFX
Dispatcher,
SFX,
Courier,
Enemies,
ActionMusic,
PeacefulMusic,
DeathMusic
}
}
@@ -23,17 +23,11 @@ namespace Code.Configs
slideDuration = 0.8f, // Длительность слайда в секундах
slideCooldown = 1.5f; // Время перезарядки слайда в секундах
// Залазание на стены
public float
wallClimbSpeedFactor = 0.8f, // Коэффициент преобразования горизонтальной скорости в вертикальную при залазании на стену
minWallClimbSpeed = 9f, // Минимальная горизонтальная скорость для начала залазания на стену
wallDetectionAngleThreshold = 80f; // Максимальный угол (в градусах) от вертикали, при котором поверхность считается "стеной"
// Наклон при залазании на стены
public float
maxWallLeanAngle = 45f, // Максимальный угол наклона от стены (в градусах)
wallLeanSharpness = 50f, // Скорость наклона/выпрямления (чем выше — тем резче)
wallLeanHeightScale = 0.1f; // Множитель: на сколько метров подъёма = 1 единица "наклона"
leanAngle = 25f,
leanThreshold = 0.3f,
leanSmoothSpeed = 10f;
// Гравитация
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,27 @@
using System.Collections.Generic;
using AYellowpaper.SerializedCollections;
using UnityEngine;
using AudioType = Code.Audio.AudioType;
namespace Code.Configs
{
[CreateAssetMenu(fileName = "DefaultAudioSettingsConfig", menuName = "Audio/DefaultAudioSettings")]
public class DefaultAudioSettingsConfig : ScriptableObject
{
[Header("Menu")]
[SerializedDictionary("AudioType", "Volume")]
public SerializedDictionary<Audio.AudioType, float> menuVolume = new();
[Header("Action")]
[SerializedDictionary("AudioType", "Volume")]
public SerializedDictionary<Audio.AudioType, float> actionVolume = new();
[Header("Peaceful")]
[SerializedDictionary("AudioType", "Volume")]
public SerializedDictionary<Audio.AudioType, float> peacefulVolume = new();
[Header("None")]
[SerializedDictionary("AudioType", "Volume")]
public SerializedDictionary<Audio.AudioType, float> noneVolume = new();
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 36d35c52933d4d4ba836f75b05c4810f
timeCreated: 1764754933
@@ -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
@@ -8,6 +8,7 @@ namespace Code.Configs
{
public AssetReference[] peacefulSoundtrack;
public AssetReference[] actionSoundtrack;
public AssetReference[] deathSoundtrack;
public AssetReference[] menuSoundtrack;
}
}
@@ -19,13 +19,14 @@ namespace Code.Constants
public const string PeacefulMusicGroup = "Peaceful";
public const string ActionMusicGroup = "Action";
public const string DispatcherMusicGroup = "Dispatcher";
public const string CourierMusicGroup = "Courier";
public const string EnemiesMusicGroup = "Enemies";
public const string CourierGroup = "Courier";
public const string EnemiesGroup = "Enemies";
public const string PeacefulSnapshot = "Peaceful";
public const string ActionSnapshot = "Action";
public const string NoneSnapshot = "None";
public const string MenuSnapshot = "Menu";
public const string MenuMusicGroup = "Menu";
public const string DeathMusicGroup = "Death";
}
}
@@ -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;
Camera.fieldOfView = Context.CameraSettingsConfigs[CameraMode.FirstPerson].fov;
Cursor.lockState = CursorLockMode.Locked;
}
protected override void HandlePosition(float deltaTime, float zoomInput, Quaternion targetRotation)
@@ -11,6 +11,7 @@ namespace Code.Gameplay.Camera.CameraStates
base.EnterState();
Camera.fieldOfView = Context.CameraSettingsConfigs[CameraMode.MainMenu].fov;
Cursor.lockState = CursorLockMode.None;
}
protected override void HandlePosition(float deltaTime, float zoomInput, Quaternion targetRotation)
@@ -12,6 +12,7 @@ namespace Code.Gameplay.Camera.CameraStates
base.EnterState();
Camera.fieldOfView = Context.CameraSettingsConfigs[CameraMode.Static].fov;
Cursor.lockState = CursorLockMode.None;
}
protected override void HandlePosition(float deltaTime, float zoomInput, Quaternion targetRotation)
@@ -1,147 +1,78 @@
using UnityEngine;
using KinematicCharacterController;
namespace Code.Gameplay.Character.Controller.Abilities
{
/*
* Механика наклона персонажа при контакте со стеной
* Управляет визуальным наклоном модели в зависимости от высоты подъёма по стене
*/
public class WallLeanMechanic
{
private readonly float _maxLeanAngle;
private readonly float _leanSharpness;
private readonly float _heightScale;
private readonly float _leanAngle;
private readonly float _threshold;
private readonly float _smoothSpeed;
private Transform _characterTransform;
private Vector3 _lastWallNormal;
private float _lastWallContactHeight;
private float _leanFactor;
private float _leanSign;
private Vector3 _leanDirection;
private Transform _model;
private Vector3 _lastWallContactPoint;
private bool _isLeaningOnWall;
private const float WallProximityThreshold = 0.6f;
public WallLeanMechanic(float maxLeanAngle, float leanSharpness, float heightScale)
public WallLeanMechanic(
float leanAngle,
float threshold,
float smoothSpeed)
{
_maxLeanAngle = maxLeanAngle;
_leanSharpness = leanSharpness;
_heightScale = heightScale;
_leanAngle = leanAngle;
_threshold = threshold;
_smoothSpeed = smoothSpeed;
}
// Назначаем трансформ визуальной модели один раз
public void SetCharacterTransform(Transform transform)
public void SetModel(Transform model) => _model = model;
public void Update(bool isWallRunning, Vector3 wallNormal, Vector3 characterForward)
{
_characterTransform = transform;
}
// Вызывается из OnMovementHit
public void OnWallContact(KinematicCharacterMotor motor, Vector3 wallNormal, float contactHeight)
{
// Только если это действительно стена (не пол/потолок)
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)
if (!_model)
{
switch (_leanDirection.x)
{
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;
_model.localRotation = Quaternion.identity;
return;
}
if (_leanDirection.sqrMagnitude < 0.01f) return;
var targetRotation = Quaternion.identity;
var leanAngle = _leanSign * _leanFactor * _maxLeanAngle;
var leanAxis = Vector3.Cross(motor.CharacterUp, _leanDirection);
var leanRotation = Quaternion.AngleAxis(leanAngle, leanAxis);
_characterTransform.localRotation = leanRotation;
if (isWallRunning)
{
var n = new Vector3(wallNormal.x, 0f, wallNormal.z).normalized;
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 SlideMechanic _slideMechanic;
private WallClimbMechanic _wallClimbMechanic;
// private WallClimbMechanic _wallClimbMechanic;
private WallRunningMechanic _wallRunningMechanic;
private WallLeanMechanic _wallLeanMechanic;
private GroundMovementSystem _groundMovement;
private AirMovementSystem _airMovement;
public bool IsSliding => _slideMechanic.IsSliding;
public bool IsWallRunning => _wallRunningMechanic.IsWallRunning;
private float abilityBlockTimer;
private bool isAbilitiesBlocked;
private CharacterInputs _lastInputs;
public void SetPosition(Vector3 position) => motor.SetPosition(position);
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]
private void Construct(CharacterConfig characterConfig)
{
@@ -84,16 +58,25 @@ namespace Code.Gameplay.Character.Controller
_characterConfig.slideDuration,
_characterConfig.slideCooldown
);
_wallClimbMechanic = new WallClimbMechanic(
_characterConfig.wallClimbSpeedFactor,
_characterConfig.minWallClimbSpeed,
_characterConfig.wallDetectionAngleThreshold
);
// _wallClimbMechanic = new WallClimbMechanic(
// _characterConfig.wallClimbSpeedFactor,
// _characterConfig.minWallClimbSpeed,
// _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(
_characterConfig.maxWallLeanAngle,
_characterConfig.wallLeanSharpness,
_characterConfig.wallLeanHeightScale
);
_characterConfig.leanAngle,
_characterConfig.leanThreshold,
_characterConfig.leanSmoothSpeed
);
_groundMovement = new GroundMovementSystem(
_characterConfig.maxStableMoveSpeed,
_characterConfig.sprintMoveSpeed,
@@ -106,31 +89,24 @@ namespace Code.Gameplay.Character.Controller
motor.CharacterController = this; // Регистрация этого контроллера в движке
_inputHandler.FirstPersonCameraRotation =
motor.Transform.rotation; // Начальное вращение совпадает с персонажемс
_wallLeanMechanic.SetCharacterTransform(characterTransform);
_wallLeanMechanic.SetModel(characterTransform);
_wallRunningMechanic.Initialize(motor, _inputHandler);
}
// Текущий режим камеры для адаптации поведения
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)
{
// Обновляем таймер перезарядки слайда
_lastInputs = inputs;
// Обновляем таймеры механик
_slideMechanic.TickCooldown(Time.deltaTime);
_wallClimbMechanic.TickCooldown(Time.deltaTime);
// _wallClimbMechanic.TickCooldown(Time.deltaTime);
_wallRunningMechanic.Tick(Time.deltaTime);
// Если активен слайд - игнорируем весь остальной ввод
if (_slideMechanic.IsSliding)
{
// Во время слайда не обрабатываем движение, прыжки и спринт
_inputHandler.MoveInputVector = Vector3.zero;
_inputHandler.LookInputVector = Vector3.one;
_inputHandler.IsSprinting = false;
@@ -138,7 +114,6 @@ namespace Code.Gameplay.Character.Controller
return;
}
// Сохраняем текущий режим камеры
_currentCameraMode = inputs.CameraMode;
if (isAbilitiesBlocked)
@@ -161,42 +136,33 @@ namespace Code.Gameplay.Character.Controller
// Обработка остального ввода
_inputHandler.ProcessInputs(ref inputs, motor);
// Передаём запрос прыжка напрямую в систему движения по земле
// Передаём запрос прыжка
_groundMovement.RequestJump(inputs.JumpPressed);
}
// Обновление вращения персонажа на основе входных данных
public void UpdateRotation(ref Quaternion currentRotation, float deltaTime)
{
if (_slideMechanic.IsSliding || _wallClimbMechanic.IsClimbingActive) return;
if (_slideMechanic.IsSliding) return;
switch (_currentCameraMode)
{
// В FirstPerson режиме применяем вращение камеры напрямую к персонажу (только горизонталь)
case CameraMode.FirstPerson when _inputHandler.ShouldApplyCameraRotation:
// Немедленно применяем горизонтальное вращение камеры к персонажу
currentRotation = _inputHandler.FirstPersonCameraRotation;
break;
// В ThirdPerson режиме плавно поворачиваем персонаж в направлении движения
case CameraMode.ThirdPerson:
{
// Вращение применяется только если есть направление движения и разрешена резкость вращения
if (_inputHandler.LookInputVector.sqrMagnitude > 0 && _characterConfig.orientationSharpness > 0)
{
// Плавная интерполяция текущего направления к целевому с экспоненциальным сглаживанием
var smoothedLookInputDirection = Vector3.Slerp(
motor.CharacterForward,
_inputHandler.LookInputVector,
1f - Mathf.Exp(-_characterConfig.orientationSharpness * deltaTime)
).normalized;
// Установка нового вращения смотря в сглаженном направлении
currentRotation = Quaternion.LookRotation(smoothedLookInputDirection, motor.CharacterUp);
}
break;
}
// Заготовка на будущее (если понадобится)
case CameraMode.Static:
case CameraMode.Cinematic:
default:
@@ -204,38 +170,49 @@ namespace Code.Gameplay.Character.Controller
}
}
// Обновление скорости движения персонажа
public void UpdateVelocity(ref Vector3 currentVelocity, float deltaTime)
{
// Если во время слайда запрошен прыжок — прерываем слайд
if (_slideMechanic.IsSliding && _groundMovement.JumpRequested)
{
_slideMechanic.EndSlide();
}
// Проверяем запрос слайда и запускаем его если можно
if (!_slideMechanic.IsSliding)
{
_slideMechanic.TryStartSlide(motor, _currentCameraMode, _inputHandler.FirstPersonCameraRotation,
_inputHandler.LookInputVector);
}
// Если активен слайд - обрабатываем отдельно
else
{
_slideMechanic.HandleSlide(ref currentVelocity, deltaTime, motor);
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)
{
_groundMovement.UpdateVelocity(ref currentVelocity, _inputHandler, motor, deltaTime);
}
// Если персонаж не находится на земле
// Если персонаж не на земле — стандартное воздушное движение
else
{
_airMovement.UpdateVelocity(ref currentVelocity, deltaTime);
// Отменяем прыжок (фикс проблемы с двойным прыжком после приземления)
_groundMovement.CancelJumpRequest();
}
}
@@ -246,60 +223,51 @@ namespace Code.Gameplay.Character.Controller
abilityBlockTimer = duration;
}
// Метод вызывается перед обновлением персонажа (можно использовать для подготовки)
public void BeforeCharacterUpdate(float deltaTime)
{
}
// Метод вызывается после обработки столкновения с землей
public void PostGroundingUpdate(float deltaTime)
{
// Если во время слайда персонаж оторвался от земли - заканчиваем слайд
if (_slideMechanic.IsSliding && !motor.GroundingStatus.IsStableOnGround)
{
_slideMechanic.EndSlide();
}
if (motor.GroundingStatus.IsStableOnGround)
{
_wallClimbMechanic.ResetWallClimbSession();
}
}
// Метод вызывается после обновления персонажа
public void AfterCharacterUpdate(float deltaTime)
{
_wallLeanMechanic.UpdateLean(motor, deltaTime);
_wallLeanMechanic.Update(
_wallRunningMechanic.IsWallRunning,
_wallRunningMechanic.GetWallNormal(),
motor.CharacterForward
);
}
// Проверка валидности коллайдера для обработки столкновений
public bool IsColliderValidForCollisions(Collider coll)
{
return true; // Все коллайдеры считаются валидными для столкновений
return true;
}
// Обработка столкновения с землей (вызывается при приземлении)
public void OnGroundHit(Collider hitCollider, Vector3 hitNormal, Vector3 hitPoint,
ref HitStabilityReport hitStabilityReport)
{
}
// Обработка столкновения при движении (вызывается при ударе о препятствие)
public void OnMovementHit(Collider hitCollider, Vector3 hitNormal, Vector3 hitPoint,
ref HitStabilityReport hitStabilityReport)
{
if (_wallClimbMechanic.TryClimbWall(motor, hitNormal))
_wallLeanMechanic.OnWallContact(motor, hitNormal, motor.TransientPosition.y);
if (_wallRunningMechanic.TryStartWallRun(hitNormal, hitPoint))
{
}
}
// Обработка отчета о стабильности столкновения
public void ProcessHitStabilityReport(Collider hitCollider, Vector3 hitNormal, Vector3 hitPoint,
Vector3 atCharacterPosition,
Quaternion atCharacterRotation, ref HitStabilityReport hitStabilityReport)
{
}
// Обработка дискретных столкновений (для триггеров и специальных коллайдеров)
public void OnDiscreteCollisionDetected(Collider hitCollider)
{
}
@@ -1,9 +1,13 @@
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;
@@ -15,9 +19,19 @@ namespace Code.Gameplay.Door
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,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.AI;
using Code.Gameplay.Player;
using Code.Gameplay.Character.Controller;
using Code.Gameplay.Character.Core;
using Code.Gameplay.Enemies.Animators;
using Reflex.Attributes;
using Reflex.Core;
using Reflex.Injectors;
@@ -13,6 +15,7 @@ namespace Code.Gameplay.Enemies
{
[SerializeField] protected NavMeshAgent agent;
[SerializeField] protected Collider enemyCollider;
[Inject] protected IAudioService audioService;
protected int Damage;
protected float AttackCooldown;
@@ -35,7 +38,7 @@ namespace Code.Gameplay.Enemies
private bool _isStunned;
private float _currentStunTimer;
private bool _canAttack = true;
protected bool _canAttack = true;
private float _attackCooldownTimer;
private enum IdleState { Moving, Paused }
@@ -50,10 +53,11 @@ namespace Code.Gameplay.Enemies
protected virtual void Awake()
{
if (_playerProvider == null)
{
AttributeInjector.Inject(this, Container.ProjectContainer);
}
// // TODO Мешает
// if (_playerProvider == null)
// {
// AttributeInjector.Inject(this, Container.ProjectContainer);
// }
}
protected virtual void Update()
@@ -164,19 +168,19 @@ namespace Code.Gameplay.Enemies
protected virtual void HandleAttackCooldown()
{
if (!_canAttack)
if (_canAttack) return;
_attackCooldownTimer -= Time.deltaTime;
if (_attackCooldownTimer <= 0)
{
_attackCooldownTimer -= Time.deltaTime;
if (_attackCooldownTimer <= 0)
{
_canAttack = true;
}
_canAttack = true;
}
}
protected virtual void DealDamage()
{
if (!_canAttack || PlayerHealth == null) return;
if (PlayerHealth == null) return;
PlayerHealth.GetDamage(Damage);
ApplyEffectsToPlayer();
@@ -184,11 +188,10 @@ namespace Code.Gameplay.Enemies
_canAttack = false;
_attackCooldownTimer = AttackCooldown;
}
protected virtual void ApplyEffectsToPlayer()
{
if (PlayerController)
PlayerController.BlockAbilities(3f);
PlayerController.BlockAbilities(3f); // TODO в конфиг
}
private void OnDrawGizmosSelected()
@@ -1,3 +1,4 @@
using Code.Audio;
using Code.Configs;
using Reflex.Attributes;
using UnityEngine;
@@ -35,7 +36,7 @@ namespace Code.Gameplay.Enemies
{
base.Awake();
if (agent == null) return;
if (!agent) return;
var walkableArea = NavMesh.GetAreaFromName("Cockroach");
agent.areaMask = 1 << walkableArea;
@@ -43,12 +44,14 @@ namespace Code.Gameplay.Enemies
protected override void HandleAttack()
{
if (!Player) return;
if (!Player || !_canAttack) return;
var distance = Vector3.Distance(transform.position, Player.transform.position);
if (!(distance <= AttackRange)) return;
audioService.PlayEnemy(EnemiesSounds.RoachAttack, agent.transform.position);
DealDamage();
}
}
@@ -1,4 +1,6 @@
using Code.Audio;
using Code.Configs;
using Code.Gameplay.Enemies.Animators;
using Reflex.Attributes;
using UnityEngine;
using UnityEngine.AI;
@@ -40,15 +42,16 @@ namespace Code.Gameplay.Enemies
var walkableArea = NavMesh.GetAreaFromName("Walkable");
agent.areaMask = 1 << walkableArea;
}
protected override void HandleAttack()
{
if (!Player) return;
if (!Player || !_canAttack) return;
var distance = Vector3.Distance(transform.position, Player.transform.position);
if (!(distance <= AttackRange)) return;
audioService.PlayEnemy(EnemiesSounds.GrandpaAttack,agent.transform.position);
if (Player.CustomCharacterController.IsSliding)
ApplyStun();
else
@@ -0,0 +1,34 @@
using Code.Audio;
using Reflex.Attributes;
using UnityEngine;
namespace Code.Gameplay.Enemies
{
public class EnemyAudio : MonoBehaviour
{
private IAudioService _audioService;
private IAudioFactory _audioFactory;
[SerializeField] private AudioSource _audioSource;
[SerializeField] private EnemiesSounds stepId;
[Inject]
private void Construct(IAudioService audioService, IAudioFactory audioFactory)
{
_audioService = audioService;
_audioSource = audioService.GetSourceOfGroup(Audio.AudioType.Enemies);
_audioSource.transform.position = transform.position;
_audioSource.spatialBlend = 0;
_audioFactory = audioFactory;
}
public void PlayStep()
{
_audioSource.transform.position = transform.position;
_audioSource.PlayOneShot(_audioFactory.EnemiesAudios[(int)stepId]);
}
private void OnDestroy()
{
_audioService.ReleaseSourceOfGroup(_audioSource);
}
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 91cb250df1b24fc4825ee791a12dda11
timeCreated: 1764695102
@@ -3,9 +3,11 @@ using Code.Configs;
using Cysharp.Threading.Tasks;
using Reflex.Attributes;
using Reflex.Core;
using Reflex.Extensions;
using Reflex.Injectors;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.SceneManagement;
namespace Code.Gameplay.Enemies
{
@@ -27,14 +29,14 @@ namespace Code.Gameplay.Enemies
)
.ToUniTask();
AttributeInjector.Inject(enemyObj, Container.ProjectContainer);
GameObjectInjector.InjectRecursive(enemyObj, SceneManager.GetActiveScene().GetSceneContainer());
return enemyObj.GetComponent<BaseEnemy>();
}
public void ReleaseEnemy(BaseEnemy enemy)
{
if (enemy == null) return;
if (!enemy) return;
enemy.gameObject.SetActive(false);
@@ -1,8 +1,6 @@
using Code.Gameplay.Player;
using Cysharp.Threading.Tasks;
using Reflex.Attributes;
using Reflex.Core;
using Reflex.Injectors;
using UnityEngine;
namespace Code.Gameplay.Enemies
@@ -20,13 +18,14 @@ namespace Code.Gameplay.Enemies
private bool _isSpawning;
private bool _isPlayerInRange;
private void Awake()
{
if (_playerProvider == null || _enemyFactory == null)
{
AttributeInjector.Inject(this, Container.ProjectContainer);
}
}
// GameObjectSelfInjector существует
// private void Awake()
// {
// if (_playerProvider == null || _enemyFactory == null)
// {
// AttributeInjector.Inject(this, Container.ProjectContainer);
// }
// }
private void Update()
{
@@ -64,9 +63,14 @@ namespace Code.Gameplay.Enemies
_isSpawning = false;
}
private void OnDestroy()
{
Despawn();
}
private void Despawn()
{
if (_spawnedEnemy == null) return;
if (!_spawnedEnemy) return;
_enemyFactory.ReleaseEnemy(_spawnedEnemy);
_spawnedEnemy = null;
@@ -10,7 +10,7 @@ namespace Code.Gameplay.Orders.Order
private bool _playerEntered;
private void OnTriggerEnter(Collider other)
{
if (_playerEntered) return;
if (_playerEntered ) return;
_playerEntered = true;
_orderService.OrderDelivered();
@@ -9,7 +9,7 @@ namespace Code.Gameplay.Orders.Order
private bool _playerEntered;
private void OnTriggerEnter(Collider other)
{
if (_playerEntered) return;
if (_playerEntered ) return;
_playerEntered = true;
_orderService.OrderGive();
@@ -9,7 +9,7 @@ namespace Code.Gameplay.Orders.Order
private void OnTriggerEnter(Collider other)
{
if (_playerEntered || !other.CompareTag("Player")) return;
if (_playerEntered ) return;
orderDispenser.ThrowOrder();
_playerEntered = true;
}
@@ -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);
}
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);
}
}
@@ -12,5 +12,6 @@ namespace Code.Generator
Room CreateRoomByIndex(int index, RoomType roomType);
void ReleaseRooms();
GameObject GetRandomCachedPrefabOfType(RoomType roomType, out int index);
int GetRandomIndexOfType(RoomType roomType);
}
}
@@ -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
+14 -15
View File
@@ -1,33 +1,32 @@
using System;
using Code.Gameplay.Door;
using Code.Gameplay.Orders.Order;
using Code.UI;
using UnityEngine;
namespace Code.Generator
{
[RequireComponent(typeof(Transform))]
// Для написания нормальной системы комнат нужен другой подход в корне, это уже не исправить, только залатать большие дыры
public class Room : MonoBehaviour
{
[SerializeField] private RoomType roomType;
[SerializeField] protected RoomType roomType;
public RoomType RoomType => roomType;
[SerializeField] private float roomTimer;
[SerializeField] protected float roomTimer;
public float RoomTimer => roomTimer;
[SerializeField] private Transform enterMarker;
[SerializeField] protected Transform enterMarker;
public Transform EnterMarker => enterMarker;
[SerializeField] private Transform exitMarker;
[SerializeField] protected Transform exitMarker;
[SerializeField] protected Transform doorSlot;
public Transform ExitMarker => exitMarker;
[SerializeField] private Door door;
[SerializeField] protected Door door;
private void Awake()
public void Initialize(IOrderService orderService)
{
if (EnterMarker == null || ExitMarker == null)
{
Debug.LogError($"Але маркеры не найдены у комнаты {gameObject.name}");
}
door.TranslationMode(false);
if(roomTrigger) roomTrigger.OrderService = orderService;
}
public void Initialize() => door.TranslationMode(false);
//PIZDEC
public void Seal() => door.CloseTheDoor();
[SerializeField] public RoomTrigger roomTrigger;
}
}
@@ -1,6 +1,7 @@
using System.Collections.Generic;
using Code.Gameplay.Orders.Order;
using Cysharp.Threading.Tasks;
using Code.Scenes;
using Code.Scenes.SceneEnvironments;
using Reflex.Attributes;
using UnityEngine;
@@ -34,52 +35,30 @@ namespace Code.Generator
public void Initialize()
{
// _orderService.OrderGive();
_spawnedRooms = new List<Room>();
_roomIndexesStack = new();
Debug.LogWarning($"КОТЛЫ ГЕНЕРАЛЬСКИЕ{_orderService.DeliveryTimer}");
// CreateRoomsStack();
// SpawnInitialRoomsAsync();
_orderService.OnOrderGiven += CreateRoomsStack;
RoomTrigger.PlayerEnteredRoom += OnPlayerEntered;
CreateSaveRoom();
SpawnNextRoomAsync();
CreateInitialRoom();
}
private void OnEnable()
private void OnPlayerEntered()
{
RoomTrigger.PlayerEnteredRoom += OnPlayerEntered;
}
private void OnDisable()
{
RoomTrigger.PlayerEnteredRoom -= OnPlayerEntered;
}
public void OnPlayerEntered()
{
SpawnNextRoomAsync();
SpawnNextRoom();
if (_spawnedRooms.Count > 3)
{
Room roomToRemove = _spawnedRooms[0];
_spawnedRooms.RemoveAt(0);
// _factory.ReleaseRoom(roomToRemove);
Object.Destroy(roomToRemove.gameObject);
}
}
private void CreateRoomsStack(float timer)
{
var currentSaveRoom = _roomIndexesStack[^1];
_nextRoomStackIndex = 0;
_roomIndexesStack.Clear();
_roomIndexesStack.Add(currentSaveRoom);
var remainingTime = timer;
@@ -91,35 +70,48 @@ namespace Code.Generator
_roomIndexesStack.Add(new(RoomType.Basic, roomIndex));
remainingTime -= room.RoomTimer;
Debug.Log($"комната {room.name} время {room.RoomTimer} осталось: {remainingTime}");
}
AddPickupRoom();
CreateSaveRoom();
AddSaveRoom();
Debug.Log($"стек комнат: {_roomIndexesStack.Count}");
SpawnNextRoom();
}
private void CreateSaveRoom()
private void AddSaveRoom()
{
var prefab = _factory.GetRandomCachedPrefabOfType(RoomType.Save, out int roomIndex);
Room saveRoom = prefab.GetComponent<Room>();
_roomIndexesStack.Add(new(RoomType.Save, roomIndex));
int saveRoomIndex = _factory.GetRandomIndexOfType(RoomType.Save);
Debug.Log($"Первая комната: {saveRoom.name}");
_roomIndexesStack.Add(new(RoomType.Save, saveRoomIndex));
}
private async UniTask SpawnInitialRoomsAsync()
private void AddPickupRoom()
{
_nextRoomStackIndex = 0;
int pickupIndex = _factory.GetRandomIndexOfType(RoomType.PickUp);
SpawnNextRoomAsync();
int insertPos = Random.Range(1, _roomIndexesStack.Count + 1);
SpawnNextRoomAsync();
_roomIndexesStack.Insert(insertPos, new(RoomType.PickUp, pickupIndex));
}
private void SpawnNextRoomAsync()
[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);
}
private void SpawnNextRoom()
{
if (_nextRoomStackIndex >= _roomIndexesStack.Count)
return;
@@ -138,28 +130,14 @@ namespace Code.Generator
PlaceRoom(room, previousRoom);
}
// Отписываться можно, но Хатико никогда не дождётся вызова уничтоженного объекта.
room.roomTrigger.OnEnter += OnPlayerEntered;
room.roomTrigger.OnExit += _spawnedRooms[^1].Seal;
_spawnedRooms.Add(room);
_nextRoomStackIndex++;
}
private void AddPickupRoom()
{
var prefab = _factory.GetRandomCachedPrefabOfType(RoomType.PickUp, out int pickupIndex);
Room pickupRoom = prefab.GetComponent<Room>();
if (_roomIndexesStack.Count == 0)
{
Debug.LogWarning("Стек пуст, нет позиции после первой");
return;
}
int insertPos = Random.Range(1, _roomIndexesStack.Count + 1);
_roomIndexesStack.Insert(insertPos, new(RoomType.PickUp, pickupIndex));
Debug.Log($"PickUp комната '{pickupRoom.name}' позиция {insertPos}");
}
private void PlaceRoom(Room current, Room previous)
{
@@ -211,17 +189,7 @@ namespace Code.Generator
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();
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;
current.Initialize(_orderService);
}
}
}
@@ -30,6 +30,7 @@ namespace Code.Generator
_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)
@@ -58,6 +59,7 @@ namespace Code.Generator
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)
{
@@ -1,33 +1,36 @@
using System;
using Code.Gameplay.Orders.Order;
using Reflex.Attributes;
using UnityEngine;
namespace Code.Generator
{
public class RoomTrigger : MonoBehaviour
{
[Inject] private IOrderService _orderService;
public IOrderService OrderService;
public event Action OnEnter;
public event Action OnExit;
public static event Action PlayerEnteredRoom;
private bool _playerEntered, _playerExited;
private bool _playerEntered;
// [Inject]
// private void Construct(IOrderService orderService)
// {
// _orderService = orderService;
// }
private void OnTriggerEnter(Collider other)
{
if (_playerEntered) return;
if (!other.CompareTag("Player")) return;
_playerEntered = true;
_orderService.RoomPassed();
OrderService.RoomPassed();
PlayerEnteredRoom?.Invoke();
OnEnter?.Invoke();
}
private void OnTriggerExit(Collider other)
{
if (_playerExited) return;
Debug.Log(other.name);
_playerExited = true;
OnExit?.Invoke();
}
}
}
@@ -1,3 +1,3 @@
fileFormatVersion: 2
guid: 4207b7568dc3482393ac1860a31909b4
timeCreated: 1764087485
guid: 0d6940d73d544f0a8e4a45d956bc2364
timeCreated: 1764525516
@@ -3,8 +3,8 @@ namespace Code.Generator
public enum RoomType
{
Basic,
Ladder,
Save,
PickUp
PickUp,
Initial
}
}
@@ -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
@@ -1,5 +1,6 @@
using Code.Gameplay.Orders.Order;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Serialization;
namespace Code.Scenes.SceneEnvironments
@@ -8,10 +9,12 @@ namespace Code.Scenes.SceneEnvironments
public class GameplaySceneEnvironment : CurrentSceneEnvironment
{
public Transform playerSpawnPoint;
public Volume volume;
public void TransitVariables(GameplaySceneEnvironment env)
{
playerSpawnPoint = env.playerSpawnPoint;
volume = env.volume;
}
}
}
@@ -33,6 +33,8 @@ namespace Code.StaticData
Dictionary<AudioSourceType, AudioSourceSettingsConfig> AudioSourceSettingsConfigs { get; }
AudioTestClipsConfig AudioTestClipsConfig { get; }
GeneratorConfig GeneratorConfig { get; }
CourierSoundListConfig CourierSoundListConfig { get; }
DefaultAudioSettingsConfig DefaultAudioSettingsConfig { get; }
void Load();
Task<T> InstantiateAsset<T>(AssetReference assetReference) where T : Behaviour;
}
@@ -29,6 +29,8 @@ namespace Code.StaticData
public DispatcherSoundListConfig DispatcherSoundListConfig { get; private set; }
public EnemiesSoundListConfig EnemiesSoundListConfig { get; private set; }
public AudioTestClipsConfig AudioTestClipsConfig { get; private set; }
public CourierSoundListConfig CourierSoundListConfig { get; private set; }
public DefaultAudioSettingsConfig DefaultAudioSettingsConfig { get; private set; }
public DrunkenGrandpaConfig DrunkenGrandpaConfig {get; private set;}
public CockroachConfig CockroachConfig { get; private set; }
@@ -66,9 +68,11 @@ namespace Code.StaticData
private void LoadAudioConfigs()
{
AudioMixerConfig = Resources.Load<AudioMixerConfig>(string.Format(StringPaths.ConfigSingle, "Audio", "AudioMixerConfig"));
DefaultAudioSettingsConfig = Resources.Load<DefaultAudioSettingsConfig>(string.Format(StringPaths.ConfigSingle, "Audio", "DefaultAudioSettingsConfig"));
SoundtrackListConfig = Resources.Load<SoundtrackListConfig>(string.Format(StringPaths.ConfigSingle, "Audio", "SoundtrackListConfig"));
AudioTestClipsConfig = Resources.Load<AudioTestClipsConfig>(string.Format(StringPaths.ConfigSingle, "Audio", "AudioTestClipsConfig"));
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"));
EnemiesSoundListConfig = Resources.Load<EnemiesSoundListConfig>(string.Format(StringPaths.ConfigSingle, "Audio", "EnemiesSoundListConfig"));
AudioSourceSettingsConfigs = Resources
@@ -0,0 +1,25 @@
using DG.Tweening;
using UnityEngine;
using UnityEngine.UI;
namespace Code.UI.Panels
{
public class DamagePanel : UIElement
{
[SerializeField] private Image background;
[SerializeField] private Color shownColor;
[SerializeField] private Color hiddenColor;
public override void Hide()
{
Shown = false;
// background.enabled = false;
background.DOColor(hiddenColor, 2f);
}
public override void Show()
{
Shown = true;
// background.enabled = true;
background.DOColor(shownColor, 0.3f);
}
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: b586dbc292c44261892460f578a38e50
timeCreated: 1764769541
@@ -1,3 +1,4 @@
using DG.Tweening;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
@@ -9,21 +10,27 @@ namespace Code.UI
[SerializeField] private TMP_Text scoreText;
[SerializeField] private TMP_Text gameOverText;
[SerializeField] private Image _background;
[SerializeField] private Color shownColor;
[SerializeField] private Color hiddenColor;
public void UpdateScoreText(int score) => scoreText.text = score.ToString();
public override void Hide()
{
_background.enabled = false;
scoreText.enabled = false;
gameOverText.enabled = false;
// scoreText.enabled = true;
// gameOverText.enabled = false;
scoreText.DOColor(hiddenColor, 3f);
// gameOverText.DOColor(hiddenColor, 3f);
base.Hide();
}
public override void Show()
{
_background.enabled = true;
scoreText.enabled = true;
gameOverText.enabled = true;
// _background.enabled = true;
// scoreText.enabled = true;
// gameOverText.enabled = true;
scoreText.DOColor(shownColor, 5f);
// gameOverText.DOColor(shownColor, 5f);
base.Show();
}
}
@@ -26,6 +26,9 @@ namespace Code.UI.Panels
[Header("MoneyBar")]
[SerializeField] private TMP_Text moneyText;
[SerializeField] private DamagePanel damagePanel;
public DamagePanel DamagePanel => damagePanel;
private void ScoreUpdate(int count, int money)
{
// TODO Анимация получения\потери
@@ -7,21 +7,24 @@ namespace Code.UI.Panels
public class LoadingScreen : UIElement
{
[SerializeField] private Image background;
[SerializeField] private TMP_Text loadingTitle;
[SerializeField] private TMP_Text vyapWatermark;
[SerializeField] private Image loadingImage;
// [SerializeField] private TMP_Text loadingTitle;
// [SerializeField] private TMP_Text vyapWatermark;
public override void Hide()
{
Shown = false;
background.enabled = false;
loadingTitle.enabled = false;
vyapWatermark.enabled = false;
loadingImage.enabled = false;
// loadingTitle.enabled = false;
// vyapWatermark.enabled = false;
}
public override void Show()
{
Shown = true;
background.enabled = true;
loadingTitle.enabled = true;
vyapWatermark.enabled = true;
loadingImage.enabled = true;
// loadingTitle.enabled = true;
// vyapWatermark.enabled = true;
}
}
}
@@ -14,6 +14,7 @@ namespace Code.UI
[SerializeField] private Slider master;
[SerializeField] private Slider sfx;
[SerializeField] private Slider dispatcher;
[SerializeField] private Slider courier;
[SerializeField] private Slider creatures;
[SerializeField] private Slider menuMusic;
[SerializeField] private Slider gameplayMusic;
@@ -28,16 +29,19 @@ namespace Code.UI
sfx.value = _audioService.GetSetting(AudioType.SFX);
sfx.onValueChanged.AddListener(OnSFXUpdate);
dispatcher.value = _audioService.GetSetting(AudioType.DispatcherSounds);
dispatcher.value = _audioService.GetSetting(AudioType.Dispatcher);
dispatcher.onValueChanged.AddListener(OnDispatcherUpdate);
creatures.value = _audioService.GetSetting(AudioType.Creatures);
courier.value = _audioService.GetSetting(AudioType.Courier);
courier.onValueChanged.AddListener(OnCourierUpdate);
creatures.value = _audioService.GetSetting(AudioType.Enemies);
creatures.onValueChanged.AddListener(OnEnemiesUpdate);
menuMusic.value = _audioService.GetSetting(AudioType.MenuMusic);
menuMusic.onValueChanged.AddListener(OnMenuMusicUpdate);
gameplayMusic.value = _audioService.GetSetting(AudioType.GameplayMusic);
gameplayMusic.value = _audioService.GetSetting(AudioType.ActionMusic);
gameplayMusic.onValueChanged.AddListener(OnGameplayUpdate);
}
@@ -51,25 +55,32 @@ namespace Code.UI
_audioService.ChangeSetting(AudioType.SFX, value);
_audioService.PlayTestClip(AudioType.SFX);
}
private void OnCourierUpdate(float value)
{
_audioService.ChangeSetting(AudioType.Courier, value);
_audioService.PlayTestClip(AudioType.Courier);
}
private void OnDispatcherUpdate(float value)
{
_audioService.ChangeSetting(AudioType.DispatcherSounds, value);
_audioService.PlayTestClip(AudioType.DispatcherSounds);
_audioService.ChangeSetting(AudioType.Dispatcher, value);
_audioService.PlayTestClip(AudioType.Dispatcher);
}
private void OnEnemiesUpdate(float value)
{
_audioService.ChangeSetting(AudioType.Creatures, value);
_audioService.PlayTestClip(AudioType.Creatures);
_audioService.ChangeSetting(AudioType.Enemies, value);
_audioService.PlayTestClip(AudioType.Enemies);
}
private void OnMenuMusicUpdate(float value)
{
_audioService.ChangeSetting(AudioType.MenuMusic, value);
_audioService.ChangeSetting(AudioType.DeathMusic, value);
_audioService.PlayTestClip(AudioType.MenuMusic);
}
private void OnGameplayUpdate(float value)
{
_audioService.ChangeSetting(AudioType.GameplayMusic, value);
_audioService.PlayTestClip(AudioType.GameplayMusic);
_audioService.ChangeSetting(AudioType.ActionMusic, value);
_audioService.ChangeSetting(AudioType.PeacefulMusic, value);
_audioService.PlayTestClip(AudioType.ActionMusic);
}
public override void Hide()
+8
View File
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 45b4aa0e7c33e934493bb7d2a15a9add
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 767316a9a37abc34694c3086d846f668
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 43bd94852ddc6b34dbe9fec318fb54d8
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,17 @@
{
"name": "AYellowpaper.SerializedCollections.Editor",
"references": [
"GUID:d525ad6bd40672747bde77962f1c401e"
],
"includePlatforms": [
"Editor"
],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}
@@ -0,0 +1,14 @@
fileFormatVersion: 2
guid: 234340c04eed5674a988bc6ebde7d248
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 243052
packageName: Serialized Dictionary
packageVersion: 1.0.13
assetPath: Assets/Plugins/SerializedCollections/Editor/AYellowpaper.SerializedCollections.Editor.asmdef
uploadId: 632226
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: edb739dfb1824234681f6480c75cd523
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,177 @@
fileFormatVersion: 2
guid: 8deddfed9f39d7740879d2cb0fcf7ce0
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 11
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMasterTextureLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 1
wrapV: 1
wrapW: 0
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 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: 1
spriteTessellationDetail: -1
textureType: 2
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 8192
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Standalone
maxTextureSize: 8192
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: iPhone
maxTextureSize: 8192
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Android
maxTextureSize: 8192
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Windows Store Apps
maxTextureSize: 8192
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Server
maxTextureSize: 8192
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: WebGL
maxTextureSize: 8192
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID:
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
nameFileIdTable: {}
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 243052
packageName: Serialized Dictionary
packageVersion: 1.0.13
assetPath: Assets/Plugins/SerializedCollections/Editor/Assets/BurgerMenu@2x.png
uploadId: 632226
@@ -0,0 +1,110 @@
.sc-close-button {
background-image: resource('d_winbtn_win_close@2x');
width: 16px;
height: 16px;
position: absolute;
right: 2px;
top: 2px;
background-color: rgba(0, 0, 0, 0);
border-left-width: 0;
border-right-width: 0;
border-top-width: 0;
border-bottom-width: 0;
}
.sc-close-button:hover {
background-color: rgba(80, 80, 80, 255);
}
.sc-close-button:active {
background-color: rgba(0, 0, 0, 0);
}
.sc-text-toggle {
margin: 0;
padding: 0;
justify-content: center;
}
.sc-text-toggle:checked {
-unity-font-style: bold;
}
.sc-text-toggle > Label {
min-width: auto;
width: 100%;
height: 100%;
}
.sc-text-toggle > .unity-radio-button__input {
display: none;
}
.sc-title {
background-color: rgba(40, 40, 40, 0.35);
padding-left: 4px;
padding-right: 3px;
padding-top: 3px;
padding-bottom: 3px;
border-left-color: rgb(25, 25, 25);
border-right-color: rgb(25, 25, 25);
border-top-color: rgb(25, 25, 25);
border-bottom-color: rgb(25, 25, 25);
border-bottom-width: 1px;
-unity-font-style: bold;
}
.sc-generator-toggle {
padding-left: 3px;
padding-right: 3px;
padding-top: 3px;
padding-bottom: 3px;
}
.sc-generator-toggle:hover {
background-color: rgb(48, 48, 48);
}
.sc-generator-toggle:checked {
background-color: rgb(77, 77, 77);
}
.sc-modification-toggle {
flex-basis: 100%;
flex-shrink: 1;
border-left-color: rgb(41, 41, 41);
border-right-color: rgb(41, 41, 41);
border-top-color: rgb(41, 41, 41);
border-bottom-color: rgb(41, 41, 41);
border-left-width: 1px;
border-right-width: 1px;
border-top-width: 1px;
border-bottom-width: 1px;
-unity-font-style: normal;
-unity-text-align: middle-center;
padding-left: 2px;
padding-right: 2px;
padding-top: 2px;
padding-bottom: 2px;
}
.sc-modification-toggle:hover {
background-color: rgb(70, 70, 70);
}
.sc-modification-toggle:checked {
background-color: rgb(80, 80, 80);
}
.sc-radio-button-group {
padding: 0;
margin: 0;
}
.sc-radio-button-group > Label {
display: none;
}
#generators-group {
flex-direction: column;
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: df6c2ef835e40c94c976442569324029
ScriptedImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 2
userData:
assetBundleName:
assetBundleVariant:
script: {fileID: 12385, guid: 0000000000000000e000000000000000, type: 0}
disableValidation: 0
AssetOrigin:
serializedVersion: 1
productId: 243052
packageName: Serialized Dictionary
packageVersion: 1.0.13
assetPath: Assets/Plugins/SerializedCollections/Editor/Assets/KeysGeneratorSelectorWindow.uss
uploadId: 632226
@@ -0,0 +1,26 @@
<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" xsi="http://www.w3.org/2001/XMLSchema-instance" engine="UnityEngine.UIElements" editor="UnityEditor.UIElements" noNamespaceSchemaLocation="../../../../../UIElementsSchema/UIElements.xsd" editor-extension-mode="False">
<Style src="project://database/Assets/Plugins/SerializedCollections/Editor/Assets/KeysGeneratorSelectorWindow.uss?fileID=7433441132597879392&amp;guid=df6c2ef835e40c94c976442569324029&amp;type=3#KeysGeneratorSelectorWindow" />
<ui:VisualElement style="flex-direction: row; flex-grow: 1; border-left-color: rgb(97, 97, 97); border-right-color: rgb(97, 97, 97); border-top-color: rgb(97, 97, 97); border-bottom-color: rgb(97, 97, 97); border-left-width: 2px; border-right-width: 2px; border-top-width: 2px; border-bottom-width: 2px;">
<ui:VisualElement name="LeftContent" style="flex-basis: 66%; border-left-color: rgb(25, 25, 25); border-right-color: rgb(25, 25, 25); border-top-color: rgb(25, 25, 25); border-bottom-color: rgb(25, 25, 25); border-right-width: 1px;">
<ui:Label text="Generators" display-tooltip-when-elided="true" class="sc-title" />
<ui:ScrollView scroll-deceleration-rate="0,135" elasticity="0,1" name="generators-content" style="flex-grow: 1;" />
</ui:VisualElement>
<ui:VisualElement name="RightContent" style="flex-basis: 100%;">
<ui:Label text="Inspector" display-tooltip-when-elided="true" class="sc-title" />
<ui:IMGUIContainer name="imgui-inspector" style="flex-grow: 1; margin-left: 4px; margin-right: 4px; margin-top: 4px; margin-bottom: 4px;" />
<ui:Label text="4 Elements " display-tooltip-when-elided="true" name="generated-count-label" style="padding-left: 2px; padding-right: 2px; padding-top: 2px; padding-bottom: 2px;" />
<ui:VisualElement style="flex-direction: row;">
<ui:RadioButtonGroup label="Radio Button Group" value="-1" name="modification-group" class="sc-radio-button-group" style="flex-grow: 1;">
<ui:RadioButton label="Add" name="add-modification" tooltip="Add the generated missing keys to the target." class="sc-text-toggle sc-modification-toggle" />
<ui:RadioButton label="Remove" name="remove-modification" tooltip="Remove the generated keys form the target." class="sc-text-toggle sc-modification-toggle" />
<ui:RadioButton label="Confine" name="confine-modification" tooltip="Remove all keys that are not part of the generated keys from the target." class="sc-text-toggle sc-modification-toggle" />
</ui:RadioButtonGroup>
</ui:VisualElement>
<ui:VisualElement style="flex-direction: row;">
<ui:Label display-tooltip-when-elided="true" name="result-label" style="flex-grow: 1; -unity-text-align: middle-left; padding-left: 2px; padding-right: 2px; padding-top: 2px; padding-bottom: 2px;" />
<ui:Button text="Apply" display-tooltip-when-elided="true" name="apply-button" style="width: 100px;" />
</ui:VisualElement>
</ui:VisualElement>
<ui:Button display-tooltip-when-elided="true" class="sc-close-button" />
</ui:VisualElement>
</ui:UXML>
@@ -0,0 +1,17 @@
fileFormatVersion: 2
guid: 681c8a924c8b1e14b9fe53bb7397ec3d
ScriptedImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 2
userData:
assetBundleName:
assetBundleVariant:
script: {fileID: 13804, guid: 0000000000000000e000000000000000, type: 0}
AssetOrigin:
serializedVersion: 1
productId: 243052
packageName: Serialized Dictionary
packageVersion: 1.0.13
assetPath: Assets/Plugins/SerializedCollections/Editor/Assets/KeysGeneratorSelectorWindow.uxml
uploadId: 632226
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 6398825db0c1d5348b5ec85b0c12d9c0
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 81bf46994f9232b4e8dcf467c109f046
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,23 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace AYellowpaper.SerializedCollections.Editor.Data
{
[System.Serializable]
internal class ElementData
{
[SerializeField]
private bool _isListToggleActive = false;
public ElementSettings Settings { get; }
public bool ShowAsList => Settings.HasListDrawerToggle && IsListToggleActive;
public bool IsListToggleActive { get => _isListToggleActive; set => _isListToggleActive = value; }
public DisplayType EffectiveDisplayType => ShowAsList ? DisplayType.List : Settings.DisplayType;
public ElementData(ElementSettings elementSettings)
{
Settings = elementSettings;
}
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 650a80186cc93b54aa5627197c23ea6e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 243052
packageName: Serialized Dictionary
packageVersion: 1.0.13
assetPath: Assets/Plugins/SerializedCollections/Editor/Scripts/Data/ElementData.cs
uploadId: 632226
@@ -0,0 +1,15 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace AYellowpaper.SerializedCollections.Editor.Data
{
public class ElementSettings
{
public const string DefaultName = "Not Set";
public string DisplayName { get; set; } = DefaultName;
public DisplayType DisplayType { get; set; } = DisplayType.PropertyNoLabel;
public bool HasListDrawerToggle { get; set; } = false;
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 12edfc8006691b7498459540b832c5eb
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 243052
packageName: Serialized Dictionary
packageVersion: 1.0.13
assetPath: Assets/Plugins/SerializedCollections/Editor/Scripts/Data/ElementSettings.cs
uploadId: 632226
@@ -0,0 +1,44 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace AYellowpaper.SerializedCollections.Editor.Data
{
[System.Serializable]
internal class PropertyData
{
[SerializeField]
private float _keyLabelWidth;
[SerializeField]
private ElementData _keyData;
[SerializeField]
private ElementData _valueData;
[SerializeField]
private bool _alwaysShowSearch = false;
public bool AlwaysShowSearch
{
get => _alwaysShowSearch;
set => _alwaysShowSearch = value;
}
public float KeyLabelWidth
{
get => _keyLabelWidth;
set => _keyLabelWidth = value;
}
public ElementData GetElementData(bool fieldType)
{
return fieldType == SCEditorUtility.KeyFlag ? _keyData : _valueData;
}
public PropertyData() : this(new ElementSettings(), new ElementSettings()) { }
public PropertyData(ElementSettings keySettings, ElementSettings valueSettings)
{
_keyData = new ElementData(keySettings);
_valueData = new ElementData(valueSettings);
}
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: ba2d792dfc6653e46bee7c027202acd3
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 243052
packageName: Serialized Dictionary
packageVersion: 1.0.13
assetPath: Assets/Plugins/SerializedCollections/Editor/Scripts/Data/PropertyData.cs
uploadId: 632226
Loaded 100 of 599 files, more files were not shown because too many files have changed in this diff. Show more