Files
CourierOld/Game/CourierOld/Assets/Code/App/AppStates/GameplayState.cs
T
MrTorex 7130513471 Допил спавнера мобов
Работает как скрипт на emptyGameObject, через сериалайзы задаётся радиус спавна/деспавна и тип моба на спавн
2025-11-27 10:13:02 +03:00

263 lines
10 KiB
C#

using Code.App.Loading;
using Code.App.StateMachine;
using Code.Audio;
using Code.Gameplay.Camera;
using Code.Gameplay.Camera.CameraStates;
using Code.Gameplay.Character.Core;
using Code.Gameplay.Orders.Order;
using Code.Gameplay.Player;
using Code.Input;
using Code.Scenes;
using Code.Scenes.SceneEnvironments;
using Code.StateMachine;
using Code.UI;
using Code.UI.Panels;
using Cysharp.Threading.Tasks;
using Reflex.Core;
using Reflex.Extensions;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.SceneManagement;
namespace Code.App.AppStates
{
public class GameplayState : BaseState<AppStateMachineContext>
{
private PlayerHealth _playerHealth;
private IPlayerScore _playerScore;
private IOrderService _orderService;
private CharacterProvider _playerCharacter;
public GameplayState(AppStateMachineContext context) : base(context)
{
}
public override void EnterState()
{
Context.UIService.LoadingScreen.Show();
Context.LoadingManager
.RegisterLoading(LoadingWork.LoadScene)
.RegisterLoading(LoadingWork.LoadUI)
// .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.Debug5, Tube);
Context.SceneLoaderService.LoadSceneAsyncAwaitable((int)SceneIds.Gameplay);
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
}
private async UniTask WaitForPlayerCharacterLoad() => _playerCharacter = await Context.PlayerFactory.CreatePlayer();
private async UniTaskVoid WaitForLoad()
{
await UniTask.WhenAll(
Context.UIService.AsyncSwitchPanelTo(UIPanel.Gameplay),
Context.AudioFactory.WarmGameplayMusic(),
Context.AudioFactory.WarmSFX(),
Context.AudioFactory.WarmDispatcher()
);
Context.LoadingManager
.UnregisterLoading(LoadingWork.LoadUI)
.UnregisterLoading(LoadingWork.LoadAudio);
InputServiceInitialize();
MusicInitialize();
}
private async void AfterSceneLoaded()
{
Context.LoadingManager
.RegisterLoading(LoadingWork.LoadModelResource);
Context.LoadingManager.OnLoadingEnded -= AfterSceneLoaded;
Context.LoadingManager.OnLoadingEnded += AfterPlayerLoaded;
await UniTask.WhenAll(
WaitForPlayerArmsToInitialize(),
WaitForPlayerCharacterLoad()
);
_playerHealth = Context.PlayerProvider.Health;
_playerHealth.OnDamage += PlayerDamageTaken;
_playerHealth.OnDeath += EndGame;
Context.LoadingManager
.UnregisterLoading(LoadingWork.LoadModelResource);
}
private void AfterPlayerLoaded()
{
Container sceneContainer = SceneManager.GetActiveScene().GetSceneContainer();
_playerScore = sceneContainer.Resolve<IPlayerScore>();
GameplaySceneEnvironment sceneEnvironment = SceneEnvironmentVariables(sceneContainer);
PlayerInitialize(sceneEnvironment);
CameraInitialize();
GameplayServicesInitialize(sceneContainer);
UIInitialize();
Context.LoadingManager.OnLoadingEnded -= AfterPlayerLoaded;
_tickEnabled = true;
}
private async UniTask WaitForPlayerArmsToInitialize() => _armsMesh = await Context.PlayerFactory.CreateArms(Context.CameraStateMachine.Camera.transform);
private void OrderGiven(float time)
{
_gameplayPanel.ShowTimer();
Context.AudioService.TransitToSnapshot(AudioSnapshotState.Action);
}
private void OrderFailure()
{
_playerHealth.InstaKill();
}
private void OrderRecieved(float time)
{
Context.AudioService.PlayDispatcher((DispatcherSounds)Random.Range((int)DispatcherSounds.Recieve1,(int)DispatcherSounds.Recieve2));
}
private void OrderDelivered(int score, float time)
{
_gameplayPanel.HideTimer();
if(time < 0f) Context.AudioService.PlayDispatcher((DispatcherSounds)Random.Range((int)DispatcherSounds.Late1,(int)DispatcherSounds.Late2));
_playerScore.UpdateScore(score);
Context.AudioService.TransitToSnapshot(AudioSnapshotState.Peaceful);
}
private void PlayerDamageTaken(int damage, PlayerHealth health)
{
Context.AudioService.PlayDispatcher((DispatcherSounds)Random.Range((int)DispatcherSounds.TakeDamage1,(int)DispatcherSounds.TakeDamage4));
}
// DEBUG
private void InstaKillDEBUG(InputAction.CallbackContext context)
{
_playerHealth.InstaKill();
}
private void RoomPassedDEBUG(InputAction.CallbackContext context)
{
_orderService.RoomPassed();
}
private OrderDispenser _debugTube;
private void Tube(InputAction.CallbackContext context)
{
_debugTube.ThrowOrder();
}
// DEBUG
private bool _tickEnabled;
public override void Tick()
{
if (!_tickEnabled) return;
_orderService.DecreaseTimer(Time.deltaTime);
}
private void EndGame()
{
Context.StateMachine.SwitchState(AppState.GameOver)
.AllowStateTransition(AppState.MainMenu);
}
public override void ExitState()
{
_playerHealth = null;
_playerScore = null;
_tickEnabled = false;
Context.PlayerFactory.ReleasePlayer(_playerCharacter);
_playerCharacter = null;
Context.PlayerFactory.ReleaseArms(_armsMesh);
_armsMesh = null;
_orderService = null;
Context.AudioService.OnDispatcherStarted -= _gameplayPanel.SummonDispatcher;
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.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.Debug5, Tube);
base.ExitState();
}
private void InputServiceInitialize()
{
Context.InputService.EnableMap(ActionMappings.Gameplay);
}
private void CameraInitialize()
{
Context.CameraStateMachine.SwitchState(CameraMode.FirstPerson);
((BaseCameraState)Context.CameraStateMachine.CurrentBaseState).SetFollowTransform(_playerCharacter.GetFollowTransform());
}
private GameplayPanel _gameplayPanel;
private ArmsMeshProvider _armsMesh;
private void UIInitialize()
{
_gameplayPanel = (GameplayPanel)Context.UIService.CurrentPanel;
_gameplayPanel.Initialize(_playerScore, _playerHealth, _orderService);
Context.AudioService.OnDispatcherStarted += _gameplayPanel.SummonDispatcher;
Context.AudioService.OnDispatcherEnded += _gameplayPanel.CloseDispatcher;
}
private void MusicInitialize()
{
Context.AudioService.PlayRandomMusicUntilHumanityWillBeDestroyedForTheySins(MusicType.Peaceful);
Context.AudioService.PlayRandomMusicUntilHumanityWillBeDestroyedForTheySins(MusicType.Action);
Context.AudioService.TransitToSnapshot(AudioSnapshotState.Peaceful);
}
private void PlayerInitialize(GameplaySceneEnvironment sceneEnvironment)
{
_playerCharacter.Teleport(sceneEnvironment.playerSpawnPoint.position, sceneEnvironment.playerSpawnPoint.rotation);
_playerCharacter.PlayerAnimator.SetAnimator(_armsMesh.ArmsAnimator);
}
private void GameplayServicesInitialize(Container sceneContainer)
{
_orderService = sceneContainer.Resolve<IOrderService>();
_orderService.OnOrderGiven += OrderGiven;
_orderService.OnOrderRecieved += OrderRecieved;
_orderService.OnOrderDelivered += OrderDelivered;
_orderService.OnOrderFailure += OrderFailure;
}
private GameplaySceneEnvironment SceneEnvironmentVariables(Container sceneContainer)
{
var sceneEnvironment = (GameplaySceneEnvironment)sceneContainer.Resolve<CurrentSceneEnvironment>();
_debugTube = sceneEnvironment.debugTube;
return sceneEnvironment;
}
}
}