diff --git a/Assets/Scripts/EventCaller.cs b/Assets/Scripts/EventCaller.cs index 8460cf56..65426e95 100644 --- a/Assets/Scripts/EventCaller.cs +++ b/Assets/Scripts/EventCaller.cs @@ -8,6 +8,7 @@ namespace HeavenStudio { public class EventCaller : MonoBehaviour { + public GameManager gameManager { get; private set; } public Transform GamesHolder; public RiqEntity currentEntity = new RiqEntity(); public string currentSwitchGame; @@ -18,6 +19,7 @@ namespace HeavenStudio public Dictionary minigames = new(); + public Minigames.Minigame GetMinigame(string gameName) { if (!minigames.ContainsKey(gameName)) @@ -55,34 +57,14 @@ namespace HeavenStudio return GetGameAction(gameName, action).parameters.Find(c => c.propertyName == param); } - public void Init() + public void Init(GameManager mgr) { + gameManager = mgr; instance = this; currentEntity = new RiqEntity(); Minigames.Init(this); - - List minigamesInBeatmap = new List(); - for (int i = 0; i < GameManager.instance.Beatmap.Entities.Count; i++) - { - //go through every entity in the timeline and add the game that they're from to the minigamesInBeatmap list (ignore entities from FX only categories, i.e. Game Manager and Count-Ins) - Minigames.Minigame game = GetMinigame(GameManager.instance.Beatmap.Entities[i].datamodel.Split('/')[0]); - if (!minigamesInBeatmap.Contains(game) && !FXOnlyGames().Contains(game)) - { - minigamesInBeatmap.Add(game); - } - } - - for (int i = 0; i < minigamesInBeatmap.Count; i++) - { - // minigames[minigames.FindIndex(c => c.name == minigamesInBeatmap[i].name)].holder = Resources.Load($"Games/{minigamesInBeatmap[i].name}"); - } - } - - private void Update() - { - } public void CallEvent(RiqEntity entity, bool gameActive) @@ -128,30 +110,9 @@ namespace HeavenStudio } } - static bool StringStartsWith(string a, string b) - { - int aLen = a.Length; - int bLen = b.Length; - - int ap = 0; int bp = 0; - - while (ap < aLen && bp < bLen && a [ap] == b [bp]) - { - ap++; - bp++; - } - - return (bp == bLen); - } - - public static bool IsGameSwitch(RiqEntity entity) - { - return StringStartsWith(entity.datamodel, "gameManager/switchGame"); - } - public static List GetAllInGameManagerList(string gameName, string[] include) { - List temp1 = GameManager.instance.Beatmap.Entities.FindAll(c => c.datamodel.Split('/')[0] == gameName); + List temp1 = instance.gameManager.Beatmap.Entities.FindAll(c => c.datamodel.Split('/')[0] == gameName); List temp2 = new List(); foreach (string s in include) { @@ -162,7 +123,7 @@ namespace HeavenStudio public static List GetAllInGameManagerListExclude(string gameName, string[] exclude) { - List temp1 = GameManager.instance.Beatmap.Entities.FindAll(c => c.datamodel.Split('/')[0] == gameName); + List temp1 = instance.gameManager.Beatmap.Entities.FindAll(c => c.datamodel.Split('/')[0] == gameName); List temp2 = new List(); foreach (string s in exclude) { diff --git a/Assets/Scripts/GameInitializer.cs b/Assets/Scripts/GameInitializer.cs index eba226c0..18eff4d8 100644 --- a/Assets/Scripts/GameInitializer.cs +++ b/Assets/Scripts/GameInitializer.cs @@ -68,7 +68,7 @@ namespace HeavenStudio GameObject Games = new GameObject(); Games.name = "Games"; - gameManager.playMode = playOnStart; + gameManager.TogglePlayMode(playOnStart); gameManager.GamesHolder = Games; gameManager.CircleCursor = Cursor.transform.GetChild(0).GetComponent(); diff --git a/Assets/Scripts/GameManager.cs b/Assets/Scripts/GameManager.cs index 821d0124..007c4385 100644 --- a/Assets/Scripts/GameManager.cs +++ b/Assets/Scripts/GameManager.cs @@ -32,30 +32,31 @@ namespace HeavenStudio [NonSerialized] public Games.Global.Filter filter; [Header("Games")] - [NonSerialized] public string currentGame; Coroutine currentGameSwitchIE; - [Header("Properties")] - [NonSerialized] public string txt = null; - [NonSerialized] public string ext = null; - [NonSerialized] public int currentEvent, currentTempoEvent, currentVolumeEvent, currentSectionEvent, currentPreEvent, currentPreSwitch, currentPreSequence; - [NonSerialized] public double endBeat; - [NonSerialized] public float startOffset; - [NonSerialized] public bool playMode; - [NonSerialized] public double startBeat; - [NonSerialized] public GameObject currentGameO; - private Minigame _currentMinigame; - [NonSerialized] public bool autoplay; - [NonSerialized] public bool canInput = true; - [NonSerialized] public RiqEntity lastSection, currentSection; - [NonSerialized] public double nextSectionBeat; + + public string currentGame { get; private set; } + public GameObject minigameObj { get; private set; } + public Minigame minigame { get; private set; } + public RiqEntity lastSection { get; private set; } + public RiqEntity currentSection { get; private set; } + + public double endBeat { get; private set; } + public double startBeat { get; private set; } + + public double nextSectionBeat { get; private set; } public double SectionProgress { get; private set; } public float MarkerWeight { get; private set; } + public int MarkerCategory { get; private set; } + public bool playMode { get; private set; } + public bool autoplay { get; private set; } + public bool canInput { get; private set; } + public bool GameHasSplitColours { get @@ -138,7 +139,9 @@ namespace HeavenStudio eventCaller = this.gameObject.AddComponent(); eventCaller.GamesHolder = GamesHolder.transform; - eventCaller.Init(); + eventCaller.Init(this); + + canInput = true; // note: serialize this shit in the inspector // GameObject textbox = Instantiate(Resources.Load("Prefabs/Common/Textbox")); @@ -429,9 +432,10 @@ namespace HeavenStudio { if (currentPreSequence < Beatmap.Entities.Count && currentPreSequence >= 0) { - if (start >= preSequenceBeats[currentPreSequence]) + List entitiesInRange = ListPool.Get(); + while (currentPreSequence < preSequenceBeats.Count && start >= preSequenceBeats[currentPreSequence]) { - List entitiesInRange = ListPool.Get(); + entitiesInRange.Clear(); foreach (RiqEntity entity in Beatmap.Entities) { string[] entityDatamodel = entity.datamodel.Split('/'); @@ -449,14 +453,14 @@ namespace HeavenStudio var inf = GetGameInfo(gameName); if (inf != null && inf.usesAssetBundle && inf.AssetsLoaded && !inf.SequencesPreloaded) { - Debug.Log($"Preloading game {gameName}"); + Debug.Log($"Preparing game {gameName}"); PreloadGameSequences(gameName); } eventCaller.CallPreEvent(entity); currentPreSequence++; } - ListPool.Release(entitiesInRange); } + ListPool.Release(entitiesInRange); } } @@ -533,7 +537,7 @@ namespace HeavenStudio if (cond.songPositionInBeatsAsDouble >= Math.Ceiling(_playStartBeat) + _pulseTally) { - if (_currentMinigame != null) _currentMinigame.OnBeatPulse(Math.Ceiling(_playStartBeat) + _pulseTally); + if (minigame != null) minigame.OnBeatPulse(Math.Ceiling(_playStartBeat) + _pulseTally); onBeatPulse?.Invoke(Math.Ceiling(_playStartBeat) + _pulseTally); _pulseTally++; } @@ -545,12 +549,13 @@ namespace HeavenStudio if (currentEvent < Beatmap.Entities.Count && currentEvent >= 0) { - if (clampedBeat >= eventBeats[currentEvent]) + List entitiesInRange = ListPool.Get(); + List fxEntities = ListPool.Get(); + // allows for multiple events on the same beat to be executed on the same frame, so no more 1-frame delay + while (currentEvent < eventBeats.Count && clampedBeat >= eventBeats[currentEvent] && Conductor.instance.isPlaying) { - List entitiesInRange = ListPool.Get(); - List fxEntities = ListPool.Get(); - - // allows for multiple events on the same beat to be executed on the same frame, so no more 1-frame delay + fxEntities.Clear(); + entitiesInRange.Clear(); using (PooledObject> pool = ListPool.Get(out List currentBeatEntities)) { currentBeatEntities = Beatmap.Entities.FindAll(c => c.beat == eventBeats[currentEvent]); @@ -592,10 +597,9 @@ namespace HeavenStudio // Thank you to @shshwdr for bring this to my attention currentEvent++; } - - ListPool.Release(entitiesInRange); - ListPool.Release(fxEntities); } + ListPool.Release(entitiesInRange); + ListPool.Release(fxEntities); } if (currentSection == null) @@ -619,7 +623,7 @@ namespace HeavenStudio if (Conductor.instance.songPositionInBeatsAsDouble >= Math.Ceiling(_playStartBeat) + _latePulseTally) { - if (_currentMinigame != null) _currentMinigame.OnLateBeatPulse(Math.Ceiling(_playStartBeat) + _latePulseTally); + if (minigame != null) minigame.OnLateBeatPulse(Math.Ceiling(_playStartBeat) + _latePulseTally); onBeatPulse?.Invoke(Math.Ceiling(_playStartBeat) + _latePulseTally); _latePulseTally++; } @@ -630,6 +634,16 @@ namespace HeavenStudio canInput = inputs; } + public void ToggleAutoplay(bool auto) + { + autoplay = auto; + } + + public void TogglePlayMode(bool mode) + { + playMode = mode; + } + #region Play Events private double _playStartBeat = 0; @@ -701,7 +715,7 @@ namespace HeavenStudio { Conductor.instance.PlaySetup(beat); Minigame miniGame = null; - if (currentGameO != null && currentGameO.TryGetComponent(out miniGame)) + if (minigameObj != null && minigameObj.TryGetComponent(out miniGame)) { if (miniGame != null) { @@ -761,7 +775,7 @@ namespace HeavenStudio } Minigame miniGame; - if (currentGameO != null && currentGameO.TryGetComponent(out miniGame)) + if (minigameObj != null && minigameObj.TryGetComponent(out miniGame)) { if (miniGame != null) { @@ -1065,7 +1079,7 @@ namespace HeavenStudio SetGame(game, false); Minigame miniGame; - if (currentGameO != null && currentGameO.TryGetComponent(out miniGame)) + if (minigameObj != null && minigameObj.TryGetComponent(out miniGame)) { if (miniGame != null) { @@ -1095,19 +1109,19 @@ namespace HeavenStudio GameObject prefab = GetGame(game); if (prefab == null) return; - Destroy(currentGameO); - currentGameO = Instantiate(prefab); - if (currentGameO.TryGetComponent(out var minigame)) + Destroy(minigameObj); + minigameObj = Instantiate(prefab); + if (minigameObj.TryGetComponent(out var minigame)) { - _currentMinigame = minigame; + this.minigame = minigame; minigame.minigameName = game; minigame.gameManager = this; minigame.conductor = Conductor.instance; } - Vector3 originalScale = currentGameO.transform.localScale; - currentGameO.transform.parent = eventCaller.GamesHolder.transform; - currentGameO.transform.localScale = originalScale; - currentGameO.name = game; + Vector3 originalScale = minigameObj.transform.localScale; + minigameObj.transform.parent = eventCaller.GamesHolder.transform; + minigameObj.transform.localScale = originalScale; + minigameObj.name = game; SetCurrentGame(game, useMinigameColor); } diff --git a/Assets/Scripts/Games/TrickClass/TrickClass.cs b/Assets/Scripts/Games/TrickClass/TrickClass.cs index d05d7ad3..ef319e7a 100644 --- a/Assets/Scripts/Games/TrickClass/TrickClass.cs +++ b/Assets/Scripts/Games/TrickClass/TrickClass.cs @@ -29,8 +29,9 @@ namespace HeavenStudio.Games.Loaders { preFunction = delegate { - var e = eventCaller.currentEntity; - TrickClass.PreTossObject(e.beat, (int)e["obj"], e["nx"]); + EventCaller ec = eventCaller; + var e = ec.currentEntity; + TrickClass.PreTossObject(ec.gameManager, e.beat, (int)e["obj"], e["nx"]); }, defaultLength = 2, parameters = new List() @@ -46,7 +47,9 @@ namespace HeavenStudio.Games.Loaders { preFunction = delegate { - TrickClass.PreTossObject(eventCaller.currentEntity.beat, (int)TrickClass.TrickObjType.Plane); + EventCaller ec = eventCaller; + var e = ec.currentEntity; + TrickClass.PreTossObject(ec.gameManager, e.beat, (int)TrickClass.TrickObjType.Plane); }, defaultLength = 3, }, @@ -62,7 +65,9 @@ namespace HeavenStudio.Games.Loaders { preFunction = delegate { - TrickClass.PreTossObject(eventCaller.currentEntity.beat, (int)TrickClass.TrickObjType.Chair); + EventCaller ec = eventCaller; + var e = ec.currentEntity; + TrickClass.PreTossObject(ec.gameManager, e.beat, (int)TrickClass.TrickObjType.Chair); }, defaultLength = 2, hidden = true, @@ -71,7 +76,9 @@ namespace HeavenStudio.Games.Loaders { preFunction = delegate { - TrickClass.PreTossObject(eventCaller.currentEntity.beat, (int)TrickClass.TrickObjType.Phone, eventCaller.currentEntity["nx"]); + EventCaller ec = eventCaller; + var e = ec.currentEntity; + TrickClass.PreTossObject(ec.gameManager, e.beat, (int)TrickClass.TrickObjType.Phone, eventCaller.currentEntity["nx"]); }, defaultLength = 2, hidden = true, @@ -84,7 +91,9 @@ namespace HeavenStudio.Games.Loaders { preFunction = delegate { - TrickClass.PreTossObject(eventCaller.currentEntity.beat, (int)TrickClass.TrickObjType.Shock); + EventCaller ec = eventCaller; + var e = ec.currentEntity; + TrickClass.PreTossObject(ec.gameManager, e.beat, (int)TrickClass.TrickObjType.Shock); }, defaultLength = 2, hidden = true, @@ -283,23 +292,23 @@ namespace HeavenStudio.Games instance.showBubble = !instance.showBubble; } - public static void PreTossObject(double beat, int type, bool variant = false) + public static void PreTossObject(GameManager gm, double beat, int type, bool variant = false) { - if (GameManager.instance.currentGame == "trickClass") + if (gm.currentGame == "trickClass" && gm.minigameObj.TryGetComponent(out TrickClass tc)) { - BeatAction.New(instance, new List() + BeatAction.New(tc, new List() { new BeatAction.Action(beat - 1, delegate { - if (instance.showBubble == true) + if (tc.showBubble == true) { - instance.warnAnim.Play(variant ? instance.objWarnAnimVariant[type] : instance.objWarnAnim[type], 0, 0); + tc.warnAnim.Play(variant ? tc.objWarnAnimVariant[type] : tc.objWarnAnim[type], 0, 0); } }), new BeatAction.Action(beat, delegate { - instance.warnAnim.Play("NoPose", 0, 0); - instance.TossObject(beat, type, variant); + tc.warnAnim.Play("NoPose", 0, 0); + tc.TossObject(beat, type, variant); }) }); } diff --git a/Assets/Scripts/LevelEditor/Editor.cs b/Assets/Scripts/LevelEditor/Editor.cs index 30fca09f..48a9d245 100644 --- a/Assets/Scripts/LevelEditor/Editor.cs +++ b/Assets/Scripts/LevelEditor/Editor.cs @@ -522,7 +522,7 @@ namespace HeavenStudio.Editor public void ToggleDebugCam() { - var game = GameManager.instance.currentGameO; + var game = GameManager.instance.minigameObj; if (game != null) { diff --git a/Assets/Scripts/LevelEditor/Timeline/Timeline.cs b/Assets/Scripts/LevelEditor/Timeline/Timeline.cs index 602e1f82..a3ca8889 100644 --- a/Assets/Scripts/LevelEditor/Timeline/Timeline.cs +++ b/Assets/Scripts/LevelEditor/Timeline/Timeline.cs @@ -353,12 +353,12 @@ namespace HeavenStudio.Editor.Track if (!GameManager.instance.autoplay) { AutoplayBTN.GetComponent().Play("Idle", 0, 0); - GameManager.instance.autoplay = true; + GameManager.instance.ToggleAutoplay(true); } else { AutoplayBTN.GetComponent().Play("Disabled", 0, 0); - GameManager.instance.autoplay = false; + GameManager.instance.ToggleAutoplay(false); } } diff --git a/Assets/Scripts/Minigames.cs b/Assets/Scripts/Minigames.cs index 98542264..969e36c5 100644 --- a/Assets/Scripts/Minigames.cs +++ b/Assets/Scripts/Minigames.cs @@ -497,7 +497,7 @@ namespace HeavenStudio if (!usesAssetBundle) return; if (bundleCommon != null) return; - AssetBundle bundle = await AssetBundle.LoadFromFileAsync(Path.Combine(Application.streamingAssetsPath, wantAssetBundle + "/common")).ToUniTask(); + AssetBundle bundle = await AssetBundle.LoadFromFileAsync(Path.Combine(Application.streamingAssetsPath, wantAssetBundle + "/common")).ToUniTask(timing: PlayerLoopTiming.PreLateUpdate); bundleCommon = bundle; commonLoaded = true; @@ -519,7 +519,7 @@ namespace HeavenStudio if (!usesAssetBundle) return; if (localeLoaded && bundleLocalized != null && currentLoadedLocale == defaultLocale) return; - AssetBundle bundle = await AssetBundle.LoadFromFileAsync(Path.Combine(Application.streamingAssetsPath, wantAssetBundle + "/locale." + defaultLocale)).ToUniTask(); + AssetBundle bundle = await AssetBundle.LoadFromFileAsync(Path.Combine(Application.streamingAssetsPath, wantAssetBundle + "/locale." + defaultLocale)).ToUniTask(timing: PlayerLoopTiming.PreLateUpdate); if (localeLoaded && bundleLocalized != null && currentLoadedLocale == defaultLocale) return; bundleLocalized = bundle; @@ -533,7 +533,7 @@ namespace HeavenStudio if (!commonLoaded) return; if (bundleCommon == null) return; - UnityEngine.Object asset = await bundleCommon.LoadAssetAsync(name).ToUniTask(); + UnityEngine.Object asset = await bundleCommon.LoadAssetAsync(name).ToUniTask(timing: PlayerLoopTiming.PreLateUpdate); loadedPrefab = asset as GameObject; // load sound sequences here for now diff --git a/ProjectSettings/SatorImaging.UnitySourceGenerator.Editor.ProjectSettingsData.asset b/ProjectSettings/SatorImaging.UnitySourceGenerator.Editor.ProjectSettingsData.asset index a7875bb4..77a2c203 100644 --- a/ProjectSettings/SatorImaging.UnitySourceGenerator.Editor.ProjectSettingsData.asset +++ b/ProjectSettings/SatorImaging.UnitySourceGenerator.Editor.ProjectSettingsData.asset @@ -51,5 +51,9 @@ MonoBehaviour: - Assets/Scripts/UI/PauseMenu.cs - Assets/Scripts/Util/Sound.cs - Assets/Scripts/Conductor.cs + - Assets/Scripts/EventCaller.cs + - Assets/Scripts/Games/TrickClass/TrickClass.cs + - Assets/Scripts/GameInitializer.cs + - Assets/Scripts/LevelEditor/Timeline/Timeline.cs PathsToSkipImportEvent: [] PathsToIgnoreOverwriteSettingOnAttribute: []