using System; using System.Collections; using Components; using Core; using Panels; using PermanentSystems; using Settings; using Sirenix.OdinInspector; using UnityEngine; using Application = Core.Application; namespace Systems { public class GameManager : SystemBase, ITick { [SerializeField] private HighScoreField scoreField; private bool _fieldPassed; private GameConfiguration _config; private int _currentStageIndex; private DifficultyStage _stageConfig; private bool _lastStageReached; private float _startTime; private float _distanceTravelled; // private readonly WaitForSeconds _delay = new (.25f); public bool HasNewScore { get; private set; } public float CurrentScore => _distanceTravelled; private EnvironmentController _environmentController; private EnvironmentController EnvironmentController { get { if (_environmentController == null) _environmentController = Application.GetSystem(); return _environmentController; } } private SpawnerSystem _spawner; private SpawnerSystem Spawner { get { _spawner = Application.GetSystem(); return _spawner; } } private PlayerController _controller; private PlayerController Controller { get { if (_controller == null) _controller = Application.GetSystem(); return _controller; } } private CameraController _cameraController; private CameraController CameraController { get { if (_cameraController == null) _cameraController = Application.GetSystem(); return _cameraController; } } private HUDPanel _hudPanel; private HUDPanel HudPanel { get { if (_hudPanel == null) _hudPanel = Application.GetPanel(); return _hudPanel; } } private PersistantDataController _dataController; private PersistantDataController DataController { get { if (_dataController == null) _dataController = Application.GetSystem(); return _dataController; } } protected override void ReleaseReferences() { _cameraController = null; _hudPanel = null; _environmentController = null; _controller = null; _spawner = null; } public override void Initialize() { UnityEngine.Application.targetFrameRate = 60; _config = Application.Configuration; _stageConfig = _config.GetStage(_currentStageIndex); if (_config.IsLastStage(_currentStageIndex)) _lastStageReached = true; scoreField.Initialize(); } public override void StartSystem() { EnvironmentController.InitializeEnvironment(_stageConfig); Spawner.UpdateSettings(_stageConfig); } public void StartGame() { TinySauce.OnGameStarted("RunStarted"); HudPanel.OpenPanel(); // Controller.StartSystem(); EnableControls(); EnvironmentController.StartSystem(); CameraController.PlayCameraTransition(() => { Spawner.StartSystem(); _startTime = Time.time; IsRun = true; }); } [GUIColor(1, 0, 0)] [Button(ButtonSizes.Medium)] [ButtonGroup("Game Controls")] public void PauseGame() { IsRun = false; scoreField.PauseSequence(); Controller.StopSystem(); EnvironmentController.StopSystem(); Spawner.StopSystem(); } [GUIColor(0, 1, 0)] [ButtonGroup("Game Controls")] public void ResumeGame() { // Controller.StartSystem(); EnableControls(); EnvironmentController.StartSystem(); scoreField.ResumeSequence(); Spawner.StartSystem(); _startTime = Time.time; IsRun = true; } private void EnableControls() { StartCoroutine(StartController()); return; IEnumerator StartController() { // yield return _delay; yield return new WaitForEndOfFrame(); Controller.StartSystem(); } } // TODO: // Major Refactors here + Spawning // Vibrations option in settings + change vibration method? // Hints Panel to support multiple hints public void Tick() { if (!IsRun) return; _distanceTravelled += Time.deltaTime * _stageConfig.environmentSpeed * 10; var highestScore = DataController.PlayerData.highestScore; if (!_fieldPassed && DataController.PlayerData.playSessions > 0) { var timeToReachHighScore = (highestScore - _distanceTravelled) / (_stageConfig.environmentSpeed * 10); if (timeToReachHighScore <= 5f) { _fieldPassed = true; scoreField.StartScoreSequence(timeToReachHighScore, (int) highestScore); } } if (_distanceTravelled > highestScore) { DataController.UpdateHighScore(_distanceTravelled); HasNewScore = true; } HudPanel.UpdateDistance((int) _distanceTravelled); if (Time.time < _startTime + _stageConfig.duration) return; if (_boostStageActive) { OnBoostEnd?.Invoke(); _boostStageActive = false; if (_lastStageReached) Spawner.UpdateSettings(_config.GetLastStage()); } else if (_config.IsLastStage(++_currentStageIndex)) { _lastStageReached = true; _currentStageIndex = 0; } _stageConfig = _config.GetStage(_currentStageIndex); EnvironmentController.TransitionEnvironment(_stageConfig); if (!_lastStageReached) Spawner.UpdateSettings(_stageConfig); _startTime = Time.time; } // Temp public event Action OnBoostEnd; private bool _boostStageActive; public float EnterBoostStage() { _stageConfig = _config.GetBoostStage(); EnvironmentController.TransitionEnvironment(_stageConfig); Spawner.UpdateSettings(_stageConfig); _startTime = Time.time; _boostStageActive = true; return _stageConfig.duration; } } }