mirror of
https://github.com/RHeavenStudio/HeavenStudio.git
synced 2025-06-12 10:07:38 +02:00
Play Mode Features Part 1 (#413)
* add pause menu assets * layout and animation for pause * make play mode prefab function re-assign unused class inheritance * remove filepath * don't init medals twice * remove PlayerActionObject * initial attempt at anti-note lock TODO: circumvent inputs clearing themselves making the functionality not work * properly implement input lock prevention * fix error on editor open * functional pause menu * bugfix * make unpausing not reset current play statistics * serialize initializer components in inspector instead of procedurally generating * sanity check * note for fade * make flashes in the camera prefabs instead of in world space remove / reorganize script files address issue #411 * fix bug with perfect campaign make minigame transitions hide the game canvas adjust animation of the song credits textbox * fully functional intro scene (placeholder for future title screen) refactored entire game loading procedure re-organized some files * add interaction query to disclaimer text * reword legal * anchor section medals to section display more tempo change placement controls * operation order bugfix * prep for future ratings and stats * loading text * autoload opening scene * splash screen adjustments added setting to force enable splash screen * adjust setting entry
This commit is contained in:
@ -1,8 +1,8 @@
|
||||
using System;
|
||||
|
||||
public static class AppInfo {
|
||||
public const string Version = "0.0.969";
|
||||
public static readonly DateTime Date = new DateTime(2023, 04, 23, 17, 57, 04, 196, DateTimeKind.Utc);
|
||||
public const string Version = "0.0.974";
|
||||
public static readonly DateTime Date = new DateTime(2023, 05, 07, 18, 03, 45, 426, DateTimeKind.Utc);
|
||||
}
|
||||
|
||||
|
||||
|
@ -67,7 +67,7 @@ namespace HeavenStudio
|
||||
// pitch values
|
||||
private float timelinePitch = 1f;
|
||||
private float minigamePitch = 1f;
|
||||
public float SongPitch { get => timelinePitch * minigamePitch; }
|
||||
public float SongPitch { get => isPaused ? 0f : (timelinePitch * minigamePitch); }
|
||||
|
||||
public void SetTimelinePitch(float pitch)
|
||||
{
|
||||
@ -87,23 +87,23 @@ namespace HeavenStudio
|
||||
instance = this;
|
||||
}
|
||||
|
||||
public void SetBeat(float beat)
|
||||
public void SetBeat(double beat)
|
||||
{
|
||||
float secFromBeat = (float) GetSongPosFromBeat(beat);
|
||||
double secFromBeat = GetSongPosFromBeat(beat);
|
||||
|
||||
if (musicSource.clip != null)
|
||||
{
|
||||
if (secFromBeat < musicSource.clip.length)
|
||||
musicSource.time = secFromBeat;
|
||||
musicSource.time = (float) secFromBeat;
|
||||
else
|
||||
musicSource.time = 0;
|
||||
}
|
||||
|
||||
GameManager.instance.SetCurrentEventToClosest(beat);
|
||||
GameManager.instance.SetCurrentEventToClosest((float) beat);
|
||||
songPosBeat = beat;
|
||||
}
|
||||
|
||||
public void Play(float beat)
|
||||
public void Play(double beat)
|
||||
{
|
||||
GameManager.instance.SortEventsList();
|
||||
bool negativeOffset = firstBeatOffset < 0f;
|
||||
|
@ -1,13 +0,0 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class Destroy : MonoBehaviour
|
||||
{
|
||||
public float time;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
Destroy(this.gameObject, time);
|
||||
}
|
||||
}
|
@ -110,12 +110,9 @@ namespace HeavenStudio
|
||||
{
|
||||
List<DynamicBeatmap.DynamicEntity> temp1 = GameManager.instance.Beatmap.entities.FindAll(c => c.datamodel.Split('/')[0] == gameName);
|
||||
List<DynamicBeatmap.DynamicEntity> temp2 = new List<DynamicBeatmap.DynamicEntity>();
|
||||
for (int i = 0; i < temp1.Count; i++)
|
||||
foreach (string s in include)
|
||||
{
|
||||
if (include.Any(temp1[i].datamodel.Split('/')[1].Contains))
|
||||
{
|
||||
temp2.Add(temp1[i]);
|
||||
}
|
||||
temp2.AddRange(temp1.FindAll(c => c.datamodel.Split('/')[1].Equals(s)));
|
||||
}
|
||||
return temp2;
|
||||
}
|
||||
@ -124,32 +121,13 @@ namespace HeavenStudio
|
||||
{
|
||||
List<DynamicBeatmap.DynamicEntity> temp1 = GameManager.instance.Beatmap.entities.FindAll(c => c.datamodel.Split('/')[0] == gameName);
|
||||
List<DynamicBeatmap.DynamicEntity> temp2 = new List<DynamicBeatmap.DynamicEntity>();
|
||||
for (int i = 0; i < temp1.Count; i++)
|
||||
foreach (string s in exclude)
|
||||
{
|
||||
if (!exclude.Any(temp1[i].datamodel.Split('/')[1].Contains))
|
||||
{
|
||||
temp2.Add(temp1[i]);
|
||||
}
|
||||
temp2.AddRange(temp1.FindAll(c => !c.datamodel.Split('/')[1].Equals(s)));
|
||||
}
|
||||
return temp2;
|
||||
}
|
||||
|
||||
public static List<DynamicBeatmap.DynamicEntity> GetAllPlayerEntities(string gameName)
|
||||
{
|
||||
return GameManager.instance.playerEntities.FindAll(c => c.datamodel.Split('/')[0] == gameName);
|
||||
}
|
||||
|
||||
public static List<DynamicBeatmap.DynamicEntity> GetAllPlayerEntitiesExcept(string gameName)
|
||||
{
|
||||
return GameManager.instance.playerEntities.FindAll(c => c.datamodel.Split('/')[0] != gameName);
|
||||
}
|
||||
|
||||
// elaborate as fuck, boy
|
||||
public static List<DynamicBeatmap.DynamicEntity> GetAllPlayerEntitiesExceptBeforeBeat(string gameName, float beat)
|
||||
{
|
||||
return GameManager.instance.playerEntities.FindAll(c => c.datamodel.Split('/')[0] != gameName && c.beat < beat);
|
||||
}
|
||||
|
||||
public static List<Minigames.Minigame> FXOnlyGames()
|
||||
{
|
||||
return instance.minigames.FindAll(c => c.fxOnly == true).ToList();
|
||||
|
@ -4,7 +4,7 @@ MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: -20
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
|
@ -11,61 +11,64 @@ using UnityEngine.Audio;
|
||||
|
||||
namespace HeavenStudio
|
||||
{
|
||||
public class Initializer : MonoBehaviour
|
||||
public class GameInitializer : MonoBehaviour
|
||||
{
|
||||
[SerializeField] RenderTexture gameRenderTexture;
|
||||
[SerializeField] RenderTexture overlayRenderTexture;
|
||||
|
||||
public TextAsset level;
|
||||
public AudioClip music;
|
||||
public GameObject canvas;
|
||||
[SerializeField] HeavenStudio.Editor.Editor editorGO;
|
||||
[SerializeField] String debug_cmdFile;
|
||||
|
||||
[SerializeField] GameManager gameManager;
|
||||
|
||||
[SerializeField] GameObject MainCamera;
|
||||
[SerializeField] GameObject CursorCamera;
|
||||
[SerializeField] GameObject OverlayCamera;
|
||||
[SerializeField] GameObject StaticCamera;
|
||||
[SerializeField] GameObject Cursor;
|
||||
|
||||
[SerializeField] GameObject Profiler;
|
||||
|
||||
public bool debugUI;
|
||||
|
||||
public bool playOnStart = false;
|
||||
public bool editor = false;
|
||||
public bool fromCmd = false;
|
||||
|
||||
string json = "";
|
||||
string ext = "";
|
||||
|
||||
private void Start()
|
||||
{
|
||||
string[] args = System.Environment.GetCommandLineArgs();
|
||||
string input = "";
|
||||
for (int i = 1; i < args.Length; i++) {
|
||||
// first arg is always this executable
|
||||
Debug.Log(args[i]);
|
||||
if (args[i].IndexOfAny(Path.GetInvalidPathChars()) == -1)
|
||||
if (debug_cmdFile != string.Empty)
|
||||
{
|
||||
if (debug_cmdFile.IndexOfAny(Path.GetInvalidPathChars()) == -1)
|
||||
{
|
||||
if (File.Exists(args[i]))
|
||||
if (File.Exists(debug_cmdFile))
|
||||
{
|
||||
input = args[i];
|
||||
editor = false;
|
||||
input = debug_cmdFile;
|
||||
fromCmd = true;
|
||||
playOnStart = true;
|
||||
}
|
||||
}
|
||||
else if (args[i] == "-debug")
|
||||
{
|
||||
debugUI = true;
|
||||
}
|
||||
}
|
||||
|
||||
GameObject Cameras = Instantiate(Resources.Load<GameObject>("Prefabs/Cameras")); Cameras.name = "Cameras";
|
||||
GameObject MainCamera = Cameras.transform.GetChild(0).gameObject;
|
||||
GameObject CursorCamera = Cameras.transform.GetChild(1).gameObject;
|
||||
GameObject OverlayCamera = Cameras.transform.GetChild(2).gameObject;
|
||||
GameObject StaticCamera = Cameras.transform.GetChild(3).gameObject;
|
||||
GameObject GameLetterbox = Cameras.transform.GetChild(4).gameObject;
|
||||
|
||||
|
||||
GameObject Cursor = Instantiate(Resources.Load<GameObject>("Prefabs/Cursor"));
|
||||
Cursor.name = "Cursor";
|
||||
else if (OpeningManager.OnOpenFile is not null or "")
|
||||
{
|
||||
if (editorGO == null && OpeningManager.OnOpenFile.IndexOfAny(Path.GetInvalidPathChars()) == -1)
|
||||
{
|
||||
if (File.Exists(OpeningManager.OnOpenFile))
|
||||
{
|
||||
input = OpeningManager.OnOpenFile;
|
||||
fromCmd = true;
|
||||
playOnStart = true;
|
||||
}
|
||||
}
|
||||
OpeningManager.OnOpenFile = null;
|
||||
}
|
||||
|
||||
GameObject Games = new GameObject();
|
||||
Games.name = "Games";
|
||||
|
||||
GameObject GameManager = new GameObject();
|
||||
GameManager.name = "GameManager";
|
||||
GameManager gameManager = GameManager.AddComponent<GameManager>();
|
||||
gameManager.playOnStart = playOnStart;
|
||||
|
||||
gameManager.GamesHolder = Games;
|
||||
@ -75,9 +78,7 @@ namespace HeavenStudio
|
||||
gameManager.OverlayCamera = OverlayCamera.GetComponent<Camera>();
|
||||
gameManager.StaticCamera = StaticCamera.GetComponent<Camera>();
|
||||
|
||||
GameObject Profiler = Instantiate(Resources.Load<GameObject>("Prefabs/GameProfiler"));
|
||||
Profiler.name = "GameProfiler";
|
||||
if (!debugUI)
|
||||
if (!debugUI && Profiler != null)
|
||||
{
|
||||
Profiler.GetComponent<DebugUI>().enabled = false;
|
||||
Profiler.transform.GetChild(0).gameObject.SetActive(false);
|
||||
@ -86,7 +87,6 @@ namespace HeavenStudio
|
||||
GameObject Conductor = new GameObject();
|
||||
Conductor.name = "Conductor";
|
||||
AudioSource source = Conductor.AddComponent<AudioSource>();
|
||||
source.clip = music;
|
||||
Conductor.AddComponent<Conductor>();
|
||||
Conductor.GetComponent<Conductor>().musicSource = source;
|
||||
source.outputAudioMixerGroup = Settings.GetMusicMixer();
|
||||
@ -96,23 +96,18 @@ namespace HeavenStudio
|
||||
GlobalGameManager.OverlayRenderTexture = overlayRenderTexture;
|
||||
GlobalGameManager.ResetGameRenderTexture();
|
||||
|
||||
if (editor)
|
||||
if (editorGO == null)
|
||||
{
|
||||
this.GetComponent<HeavenStudio.Editor.Editor>().Init();
|
||||
}
|
||||
else
|
||||
{
|
||||
this.GetComponent<HeavenStudio.Editor.Editor>().enabled = false;
|
||||
this.GetComponent<HeavenStudio.Editor.EditorTheme>().enabled = false;
|
||||
this.GetComponent<HeavenStudio.Editor.BoxSelection>().enabled = false;
|
||||
canvas.SetActive(false);
|
||||
|
||||
OpenCmdRemix(input);
|
||||
Debug.Log(json);
|
||||
gameManager.txt = json;
|
||||
gameManager.ext = ext;
|
||||
gameManager.Init();
|
||||
}
|
||||
else
|
||||
{
|
||||
editorGO.Init();
|
||||
}
|
||||
}
|
||||
|
||||
public void OpenCmdRemix(string path)
|
@ -14,36 +14,35 @@ namespace HeavenStudio
|
||||
public class GameManager : MonoBehaviour
|
||||
{
|
||||
[Header("Lists")]
|
||||
public DynamicBeatmap Beatmap = new DynamicBeatmap();
|
||||
[HideInInspector] public List<DynamicBeatmap.DynamicEntity> playerEntities = new List<DynamicBeatmap.DynamicEntity>();
|
||||
[NonSerialized] public DynamicBeatmap Beatmap = new DynamicBeatmap();
|
||||
private List<GameObject> preloadedGames = new List<GameObject>();
|
||||
public List<GameObject> SoundObjects = new List<GameObject>();
|
||||
[NonSerialized] public List<GameObject> SoundObjects = new List<GameObject>();
|
||||
|
||||
[Header("Components")]
|
||||
public string txt;
|
||||
public string ext;
|
||||
public Camera GameCamera, CursorCam, OverlayCamera, StaticCamera;
|
||||
public CircleCursor CircleCursor;
|
||||
[HideInInspector] public GameObject GamesHolder;
|
||||
public Games.Global.Flash fade;
|
||||
public Games.Global.Filter filter;
|
||||
public GameObject textbox;
|
||||
[NonSerialized] public Camera GameCamera, CursorCam, OverlayCamera, StaticCamera;
|
||||
[NonSerialized] public CircleCursor CircleCursor;
|
||||
[NonSerialized] public GameObject GamesHolder;
|
||||
[NonSerialized] public Games.Global.Flash fade;
|
||||
[NonSerialized] public Games.Global.Filter filter;
|
||||
|
||||
[Header("Games")]
|
||||
public string currentGame;
|
||||
[NonSerialized] public string currentGame;
|
||||
Coroutine currentGameSwitchIE;
|
||||
|
||||
[Header("Properties")]
|
||||
public int currentEvent, currentTempoEvent, currentVolumeEvent, currentSectionEvent,
|
||||
[NonSerialized] public string txt = null;
|
||||
[NonSerialized] public string ext = null;
|
||||
|
||||
[NonSerialized] public int currentEvent, currentTempoEvent, currentVolumeEvent, currentSectionEvent,
|
||||
currentPreEvent, currentPreSwitch, currentPreSequence;
|
||||
public float endBeat;
|
||||
public float startOffset;
|
||||
public bool playOnStart;
|
||||
public float startBeat;
|
||||
[NonSerialized] public float endBeat;
|
||||
[NonSerialized] public float startOffset;
|
||||
[NonSerialized] public bool playOnStart;
|
||||
[NonSerialized] public float startBeat;
|
||||
[NonSerialized] public GameObject currentGameO;
|
||||
public bool autoplay;
|
||||
public bool canInput = true;
|
||||
public DynamicBeatmap.ChartSection currentSection, nextSection;
|
||||
[NonSerialized] public bool autoplay;
|
||||
[NonSerialized] public bool canInput = true;
|
||||
[NonSerialized] public DynamicBeatmap.ChartSection currentSection, nextSection;
|
||||
public float sectionProgress { get; private set; }
|
||||
|
||||
public event Action<float> onBeatChanged;
|
||||
@ -86,6 +85,16 @@ namespace HeavenStudio
|
||||
}
|
||||
bool skillStarCollected = false;
|
||||
|
||||
// cleared sections
|
||||
List<bool> clearedSections = new List<bool>();
|
||||
public bool ClearedSection
|
||||
{
|
||||
set
|
||||
{
|
||||
clearedSections.Add(value);
|
||||
}
|
||||
}
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
// autoplay = true;
|
||||
@ -97,24 +106,10 @@ namespace HeavenStudio
|
||||
currentPreEvent= 0;
|
||||
currentPreSwitch = 0;
|
||||
currentPreSequence = 0;
|
||||
|
||||
this.transform.localScale = new Vector3(30000000, 30000000);
|
||||
|
||||
SpriteRenderer sp = this.gameObject.AddComponent<SpriteRenderer>();
|
||||
sp.enabled = false;
|
||||
sp.color = Color.black;
|
||||
sp.sprite = Resources.Load<Sprite>("Sprites/GeneralPurpose/Square");
|
||||
sp.sortingOrder = 30000;
|
||||
gameObject.layer = LayerMask.NameToLayer("Flash");
|
||||
|
||||
GameObject fade = new GameObject("flash");
|
||||
this.fade = fade.AddComponent<Games.Global.Flash>();
|
||||
GameObject filter = new GameObject("filter");
|
||||
this.filter = filter.AddComponent<Games.Global.Filter>();
|
||||
|
||||
|
||||
GlobalGameManager.Init();
|
||||
|
||||
eventCaller = this.gameObject.AddComponent<EventCaller>();
|
||||
eventCaller.GamesHolder = GamesHolder.transform;
|
||||
eventCaller.Init();
|
||||
@ -123,23 +118,23 @@ namespace HeavenStudio
|
||||
Conductor.instance.firstBeatOffset = Beatmap.firstBeatOffset;
|
||||
|
||||
// note: serialize this shit in the inspector //
|
||||
GameObject textbox = Instantiate(Resources.Load<GameObject>("Prefabs/Common/Textbox"));
|
||||
textbox.name = "Textbox";
|
||||
GameObject textbox = Instantiate(Resources.Load<GameObject>("Prefabs/Common/Textbox"));
|
||||
textbox.name = "Textbox";
|
||||
|
||||
GameObject overlays = Instantiate(Resources.Load<GameObject>("Prefabs/Common/Overlays"));
|
||||
overlays.name = "Overlays";
|
||||
GameObject timingDisp = Instantiate(Resources.Load<GameObject>("Prefabs/Common/Overlays/TimingAccuracy"));
|
||||
timingDisp.name = "TimingDisplay";
|
||||
|
||||
GameObject timingDisp = Instantiate(Resources.Load<GameObject>("Prefabs/Common/Overlays/TimingAccuracy"));
|
||||
timingDisp.name = "TimingDisplay";
|
||||
GameObject skillStarDisp = Instantiate(Resources.Load<GameObject>("Prefabs/Common/Overlays/SkillStar"));
|
||||
skillStarDisp.name = "SkillStar";
|
||||
|
||||
GameObject skillStarDisp = Instantiate(Resources.Load<GameObject>("Prefabs/Common/Overlays/SkillStar"));
|
||||
skillStarDisp.name = "SkillStar";
|
||||
GameObject overlays = Instantiate(Resources.Load<GameObject>("Prefabs/Common/Overlays"));
|
||||
overlays.name = "Overlays";
|
||||
|
||||
GoForAPerfect.instance.Disable();
|
||||
GoForAPerfect.instance.Disable();
|
||||
/////
|
||||
|
||||
|
||||
if (txt != null && ext != null)
|
||||
if (txt != null && ext != null && txt.Length != 0 && ext.Length != 0)
|
||||
{
|
||||
LoadRemix(txt, ext);
|
||||
}
|
||||
@ -162,7 +157,7 @@ namespace HeavenStudio
|
||||
|
||||
if (playOnStart)
|
||||
{
|
||||
Play(startBeat);
|
||||
StartCoroutine(WaitReadyAndPlayCo(startBeat));
|
||||
}
|
||||
}
|
||||
|
||||
@ -204,7 +199,10 @@ namespace HeavenStudio
|
||||
Conductor.instance.SetBpm(Beatmap.bpm);
|
||||
Conductor.instance.SetVolume(Beatmap.musicVolume);
|
||||
Conductor.instance.firstBeatOffset = Beatmap.firstBeatOffset;
|
||||
Stop(0);
|
||||
if (!playOnStart)
|
||||
{
|
||||
Stop(0);
|
||||
}
|
||||
SetCurrentEventToClosest(0);
|
||||
|
||||
if (Beatmap.entities.Count >= 1)
|
||||
@ -319,8 +317,6 @@ namespace HeavenStudio
|
||||
|
||||
private void Update()
|
||||
{
|
||||
PlayerInput.UpdateInputControllers();
|
||||
|
||||
if (BeatmapEntities() < 1) //bruh really you forgot to ckeck tempo changes
|
||||
return;
|
||||
if (!Conductor.instance.isPlaying)
|
||||
@ -433,44 +429,52 @@ namespace HeavenStudio
|
||||
|
||||
#region Play Events
|
||||
|
||||
public void Play(float beat)
|
||||
public void Play(float beat, float delay = 0f)
|
||||
{
|
||||
bool paused = Conductor.instance.isPaused;
|
||||
Debug.Log("Playing at " + beat);
|
||||
canInput = true;
|
||||
inputOffsetSamples.Clear();
|
||||
averageInputOffset = 0;
|
||||
if (!paused)
|
||||
{
|
||||
inputOffsetSamples.Clear();
|
||||
averageInputOffset = 0;
|
||||
|
||||
totalInputs = 0;
|
||||
totalPlayerAccuracy = 0;
|
||||
totalInputs = 0;
|
||||
totalPlayerAccuracy = 0;
|
||||
|
||||
TimingAccuracyDisplay.instance.ResetArrow();
|
||||
SkillStarManager.instance.Reset();
|
||||
skillStarCollected = false;
|
||||
TimingAccuracyDisplay.instance.ResetArrow();
|
||||
SkillStarManager.instance.Reset();
|
||||
skillStarCollected = false;
|
||||
|
||||
GoForAPerfect.instance.perfect = true;
|
||||
GoForAPerfect.instance.Disable();
|
||||
GoForAPerfect.instance.perfect = true;
|
||||
GoForAPerfect.instance.Disable();
|
||||
|
||||
SectionMedalsManager.instance.Reset();
|
||||
SectionMedalsManager.instance.Reset();
|
||||
clearedSections.Clear();
|
||||
}
|
||||
|
||||
StartCoroutine(PlayCo(beat));
|
||||
StartCoroutine(PlayCo(beat, delay));
|
||||
onBeatChanged?.Invoke(beat);
|
||||
}
|
||||
|
||||
private IEnumerator PlayCo(float beat)
|
||||
private IEnumerator PlayCo(float beat, float delay = 0f)
|
||||
{
|
||||
yield return null;
|
||||
yield return new WaitForSeconds(delay);
|
||||
bool paused = Conductor.instance.isPaused;
|
||||
|
||||
Conductor.instance.SetBpm(Beatmap.bpm);
|
||||
Conductor.instance.SetVolume(Beatmap.musicVolume);
|
||||
Conductor.instance.firstBeatOffset = Beatmap.firstBeatOffset;
|
||||
|
||||
Conductor.instance.Play(beat);
|
||||
if (!paused)
|
||||
if (paused)
|
||||
{
|
||||
SetCurrentEventToClosest(beat);
|
||||
Util.Jukebox.UnpauseOneShots();
|
||||
}
|
||||
else
|
||||
{
|
||||
Conductor.instance.SetBpm(Beatmap.bpm);
|
||||
Conductor.instance.SetVolume(Beatmap.musicVolume);
|
||||
Conductor.instance.firstBeatOffset = Beatmap.firstBeatOffset;
|
||||
SetCurrentEventToClosest(beat);
|
||||
KillAllSounds();
|
||||
}
|
||||
|
||||
KillAllSounds();
|
||||
|
||||
Minigame miniGame = currentGameO.GetComponent<Minigame>();
|
||||
if (miniGame != null)
|
||||
@ -480,11 +484,16 @@ namespace HeavenStudio
|
||||
public void Pause()
|
||||
{
|
||||
Conductor.instance.Pause();
|
||||
KillAllSounds();
|
||||
Util.Jukebox.PauseOneShots();
|
||||
canInput = false;
|
||||
}
|
||||
|
||||
public void Stop(float beat)
|
||||
public void Stop(float beat, bool restart = false, float restartDelay = 0f)
|
||||
{
|
||||
Minigame miniGame = currentGameO.GetComponent<Minigame>();
|
||||
if (miniGame != null)
|
||||
miniGame.OnStop(beat);
|
||||
|
||||
Conductor.instance.Stop(beat);
|
||||
SetCurrentEventToClosest(beat);
|
||||
onBeatChanged?.Invoke(beat);
|
||||
@ -496,13 +505,40 @@ namespace HeavenStudio
|
||||
GoForAPerfect.instance.Disable();
|
||||
SectionMedalsManager.instance.OnRemixEnd();
|
||||
|
||||
// pass this data to rating screen + stats
|
||||
Debug.Log($"== Playthrough statistics of {Beatmap["remixtitle"]} (played at {System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}) ==");
|
||||
Debug.Log($"Average input offset for playthrough: {averageInputOffset}ms");
|
||||
Debug.Log($"Accuracy for playthrough: {(PlayerAccuracy * 100) : 0.00}");
|
||||
|
||||
if (playOnStart)
|
||||
Debug.Log($"Cleared {clearedSections.FindAll(c => c).Count} sections out of {Beatmap.beatmapSections.Count}");
|
||||
if (SkillStarManager.instance.IsCollected)
|
||||
Debug.Log($"Skill Star collected");
|
||||
else
|
||||
Debug.Log($"Skill Star not collected");
|
||||
if (GoForAPerfect.instance.perfect)
|
||||
Debug.Log($"Perfect Clear!");
|
||||
|
||||
if (playOnStart || restart)
|
||||
{
|
||||
Play(0);
|
||||
Play(0, restartDelay);
|
||||
}
|
||||
// when rating screen gets added playOnStart will instead move to that scene
|
||||
}
|
||||
|
||||
private IEnumerator WaitReadyAndPlayCo(float beat)
|
||||
{
|
||||
// wait for overlays to be ready
|
||||
yield return new WaitUntil(() => OverlaysManager.OverlaysReady);
|
||||
// wait for first game to be loaded
|
||||
yield return new WaitUntil(() => Beatmap != null && Beatmap.entities.Count > 0);
|
||||
|
||||
SkillStarManager.instance.KillStar();
|
||||
TimingAccuracyDisplay.instance.StopStarFlash();
|
||||
GoForAPerfect.instance.Disable();
|
||||
SectionMedalsManager.instance?.OnRemixEnd();
|
||||
|
||||
GlobalGameManager.UpdateDiscordStatus(Beatmap["remixtitle"], false, true);
|
||||
|
||||
Play(beat, 1f);
|
||||
}
|
||||
|
||||
public void KillAllSounds()
|
||||
@ -671,7 +707,7 @@ namespace HeavenStudio
|
||||
{
|
||||
if(flash == true)
|
||||
{
|
||||
this.GetComponent<SpriteRenderer>().enabled = true;
|
||||
HeavenStudio.StaticCamera.instance.ToggleCanvasVisibility(false);
|
||||
}
|
||||
|
||||
SetGame(game);
|
||||
@ -680,9 +716,10 @@ namespace HeavenStudio
|
||||
if (miniGame != null)
|
||||
miniGame.OnGameSwitch(beat);
|
||||
|
||||
//TODO: wait time in beats instead of seconds
|
||||
yield return new WaitForSeconds(0.1f);
|
||||
|
||||
this.GetComponent<SpriteRenderer>().enabled = false;
|
||||
HeavenStudio.StaticCamera.instance.ToggleCanvasVisibility(true);
|
||||
}
|
||||
|
||||
private void SetGame(string game)
|
||||
|
@ -8,7 +8,7 @@ using HeavenStudio.Util;
|
||||
|
||||
namespace HeavenStudio.Games.Scripts_BlueBear
|
||||
{
|
||||
public class Treat : PlayerActionObject
|
||||
public class Treat : MonoBehaviour
|
||||
{
|
||||
const float rotSpeed = 360f;
|
||||
|
||||
|
@ -6,7 +6,7 @@ using System;
|
||||
namespace HeavenStudio.Games.Scripts_BuiltToScaleDS
|
||||
{
|
||||
using HeavenStudio.Util;
|
||||
public class Blocks : PlayerActionObject
|
||||
public class Blocks : MonoBehaviour
|
||||
{
|
||||
public float createBeat;
|
||||
public float createLength;
|
||||
|
@ -7,7 +7,7 @@ using HeavenStudio.Util;
|
||||
|
||||
namespace HeavenStudio.Games.Scripts_CatchyTune
|
||||
{
|
||||
public class Fruit : PlayerActionObject
|
||||
public class Fruit : MonoBehaviour
|
||||
{
|
||||
|
||||
public bool isPineapple;
|
||||
|
@ -6,7 +6,7 @@ using HeavenStudio.Util;
|
||||
|
||||
namespace HeavenStudio.Games.Scripts_ClappyTrio
|
||||
{
|
||||
public class ClappyTrioPlayer : PlayerActionObject
|
||||
public class ClappyTrioPlayer : MonoBehaviour
|
||||
{
|
||||
ClappyTrio game;
|
||||
private float lastClapBeat;
|
||||
|
@ -6,7 +6,7 @@ using HeavenStudio.Util;
|
||||
|
||||
namespace HeavenStudio.Games.Scripts_CropStomp
|
||||
{
|
||||
public class Farmer : PlayerActionObject
|
||||
public class Farmer : MonoBehaviour
|
||||
{
|
||||
public float nextStompBeat;
|
||||
|
||||
|
@ -8,7 +8,7 @@ using HeavenStudio.Util;
|
||||
|
||||
namespace HeavenStudio.Games.Scripts_CropStomp
|
||||
{
|
||||
public class Veggie : PlayerActionObject
|
||||
public class Veggie : MonoBehaviour
|
||||
{
|
||||
static float pickedRotationSpeed = -1080f;
|
||||
|
||||
|
@ -9,7 +9,7 @@ using Starpelly;
|
||||
|
||||
namespace HeavenStudio.Games.Scripts_DJSchool
|
||||
{
|
||||
public class Student : PlayerActionObject
|
||||
public class Student : MonoBehaviour
|
||||
{
|
||||
public Animator anim;
|
||||
public static bool soundFX;
|
||||
|
@ -8,7 +8,7 @@ using HeavenStudio.Util;
|
||||
|
||||
namespace HeavenStudio.Games.Scripts_DogNinja
|
||||
{
|
||||
public class SpawnHalves : PlayerActionObject
|
||||
public class SpawnHalves : MonoBehaviour
|
||||
{
|
||||
public float startBeat;
|
||||
public Vector3 objPos;
|
||||
|
@ -8,7 +8,7 @@ using HeavenStudio.Util;
|
||||
|
||||
namespace HeavenStudio.Games.Scripts_DogNinja
|
||||
{
|
||||
public class ThrowObject : PlayerActionObject
|
||||
public class ThrowObject : MonoBehaviour
|
||||
{
|
||||
public float startBeat;
|
||||
public int type;
|
||||
|
@ -6,7 +6,7 @@ using HeavenStudio.Util;
|
||||
|
||||
namespace HeavenStudio.Games.Scripts_DrummingPractice
|
||||
{
|
||||
public class DrummerHit : PlayerActionObject
|
||||
public class DrummerHit : MonoBehaviour
|
||||
{
|
||||
DrummingPractice game;
|
||||
public float startBeat;
|
||||
|
@ -9,7 +9,7 @@ using HeavenStudio.Util;
|
||||
|
||||
namespace HeavenStudio.Games.Scripts_FanClub
|
||||
{
|
||||
public class NtrIdolFan : PlayerActionObject
|
||||
public class NtrIdolFan : MonoBehaviour
|
||||
{
|
||||
[Header("References")]
|
||||
[SerializeField] private GameObject motionRoot;
|
||||
|
@ -6,7 +6,7 @@ using NaughtyBezierCurves;
|
||||
|
||||
namespace HeavenStudio.Games.Scripts_Fireworks
|
||||
{
|
||||
public class FireworksBomb : PlayerActionObject
|
||||
public class FireworksBomb : MonoBehaviour
|
||||
{
|
||||
public BezierCurve3D curve;
|
||||
public bool applause;
|
||||
|
@ -6,7 +6,7 @@ using HeavenStudio.Util;
|
||||
|
||||
namespace HeavenStudio.Games.Scripts_Fireworks
|
||||
{
|
||||
public class Rocket : PlayerActionObject
|
||||
public class Rocket : MonoBehaviour
|
||||
{
|
||||
[SerializeField] ParticleSystem particleBarelyEffect;
|
||||
[SerializeField] private List<ParticleSystem> particleEffects = new List<ParticleSystem>();
|
||||
|
@ -8,7 +8,7 @@ using Starpelly;
|
||||
|
||||
namespace HeavenStudio.Games.Scripts_FirstContact
|
||||
{
|
||||
public class Translator : PlayerActionObject
|
||||
public class Translator : MonoBehaviour
|
||||
{
|
||||
public Animator anim;
|
||||
|
||||
|
@ -8,7 +8,7 @@ using DG.Tweening;
|
||||
|
||||
namespace HeavenStudio.Games.Scripts_ForkLifter
|
||||
{
|
||||
public class Pea : PlayerActionObject
|
||||
public class Pea : MonoBehaviour
|
||||
{
|
||||
ForkLifter game;
|
||||
private Animator anim;
|
||||
|
@ -5,7 +5,7 @@ using HeavenStudio.Util;
|
||||
|
||||
namespace HeavenStudio.Games.Scripts_GleeClub
|
||||
{
|
||||
public class GleeClubSingInput : PlayerActionObject
|
||||
public class GleeClubSingInput : MonoBehaviour
|
||||
{
|
||||
public float pitch = 1f;
|
||||
bool shouldClose = true;
|
||||
|
@ -1,6 +1,8 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
using HeavenStudio.Util;
|
||||
using System.Linq;
|
||||
@ -9,49 +11,40 @@ namespace HeavenStudio.Games.Global
|
||||
{
|
||||
public class Flash : MonoBehaviour
|
||||
{
|
||||
public float startBeat;
|
||||
public float length;
|
||||
[NonSerialized] public float startBeat;
|
||||
[NonSerialized] public float length;
|
||||
|
||||
public Color startColor;
|
||||
public Color endColor;
|
||||
[NonSerialized] public Color startColor;
|
||||
[NonSerialized] public Color endColor;
|
||||
|
||||
public EasingFunction.Ease ease;
|
||||
private EasingFunction.Function func;
|
||||
[NonSerialized] public EasingFunction.Ease ease;
|
||||
[NonSerialized] private EasingFunction.Function func;
|
||||
|
||||
private SpriteRenderer spriteRenderer;
|
||||
[NonSerialized] private Image spriteRenderer;
|
||||
|
||||
[SerializeField] private Color currentCol;
|
||||
|
||||
private List<DynamicBeatmap.DynamicEntity> allFadeEvents = new List<DynamicBeatmap.DynamicEntity>();
|
||||
[NonSerialized] private List<DynamicBeatmap.DynamicEntity> allFadeEvents = new List<DynamicBeatmap.DynamicEntity>();
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
this.gameObject.transform.SetParent(GameManager.instance.gameObject.transform);
|
||||
gameObject.layer = LayerMask.NameToLayer("Flash");
|
||||
this.gameObject.transform.localScale = new Vector3(1, 1);
|
||||
|
||||
spriteRenderer = this.gameObject.AddComponent<SpriteRenderer>();
|
||||
|
||||
spriteRenderer.color = startColor;
|
||||
spriteRenderer.sortingOrder = 30001;
|
||||
spriteRenderer.sprite = Resources.Load<Sprite>("Sprites/GeneralPurpose/Square");
|
||||
|
||||
spriteRenderer = GetComponent<Image>();
|
||||
spriteRenderer.color = currentCol;
|
||||
func = EasingFunction.GetEasingFunction(EasingFunction.Ease.Linear);
|
||||
|
||||
GameManager.instance.onBeatChanged += OnBeatChanged;
|
||||
}
|
||||
|
||||
public void OnBeatChanged(float beat)
|
||||
{
|
||||
allFadeEvents = EventCaller.GetAllInGameManagerList("vfx", new string[] { "flash" });
|
||||
Test(beat);
|
||||
|
||||
// backwards-compatibility baybee
|
||||
allFadeEvents.AddRange(EventCaller.GetAllInGameManagerList("gameManager", new string[] { "flash" }));
|
||||
Test(beat);
|
||||
allFadeEvents.Sort((x, y) => x.beat.CompareTo(y.beat));
|
||||
|
||||
FindFadeFromBeat(beat);
|
||||
}
|
||||
|
||||
private void Test(float beat)
|
||||
private void FindFadeFromBeat(float beat)
|
||||
{
|
||||
Color startCol = Color.white;
|
||||
Color endCol = Color.white;
|
||||
@ -105,7 +98,7 @@ namespace HeavenStudio.Games.Global
|
||||
|
||||
private void Update()
|
||||
{
|
||||
Test(Conductor.instance.songPositionInBeats);
|
||||
FindFadeFromBeat(Conductor.instance.songPositionInBeats);
|
||||
float normalizedBeat = Conductor.instance.GetPositionFromBeat(startBeat, length);
|
||||
// normalizedBeat = Mathf.Clamp01(normalizedBeat);
|
||||
|
||||
|
@ -32,7 +32,7 @@ namespace HeavenStudio.Games.Global
|
||||
private List<DynamicBeatmap.DynamicEntity> idolEvents = new List<DynamicBeatmap.DynamicEntity>();
|
||||
private List<DynamicBeatmap.DynamicEntity> closedCaptionsEvents = new List<DynamicBeatmap.DynamicEntity>();
|
||||
|
||||
Textbox instance;
|
||||
public static Textbox instance { get; private set; }
|
||||
|
||||
[Header("Objects")]
|
||||
public GameObject TextboxEnabler;
|
||||
|
@ -8,7 +8,7 @@ using HeavenStudio.Util;
|
||||
|
||||
namespace HeavenStudio.Games.Scripts_KarateMan
|
||||
{
|
||||
public class KarateManPot : PlayerActionObject
|
||||
public class KarateManPot : MonoBehaviour
|
||||
{
|
||||
public float startBeat;
|
||||
public ItemType type;
|
||||
|
@ -11,7 +11,7 @@ using static HeavenStudio.EntityTypes;
|
||||
|
||||
namespace HeavenStudio.Games.Scripts_LaunchParty
|
||||
{
|
||||
public class LaunchPartyRocket : PlayerActionObject
|
||||
public class LaunchPartyRocket : MonoBehaviour
|
||||
{
|
||||
public List<float> pitches = new List<float>();
|
||||
[SerializeField] Animator anim;
|
||||
|
@ -6,7 +6,7 @@ using HeavenStudio.Util;
|
||||
|
||||
namespace HeavenStudio.Games.Scripts_MarchingOrders
|
||||
{
|
||||
public class Cadet : PlayerActionObject
|
||||
public class Cadet : MonoBehaviour
|
||||
{
|
||||
public bool isSparkler;
|
||||
|
||||
|
@ -7,7 +7,7 @@ using NaughtyBezierCurves;
|
||||
|
||||
namespace HeavenStudio.Games.Scripts_MeatGrinder
|
||||
{
|
||||
public class MeatToss : PlayerActionObject
|
||||
public class MeatToss : MonoBehaviour
|
||||
{
|
||||
public float startBeat;
|
||||
public float cueLength;
|
||||
|
@ -120,7 +120,7 @@ namespace HeavenStudio.Games
|
||||
|
||||
if(closest == null)
|
||||
{
|
||||
if (input == InputType.ANY || toCompare.inputType.HasFlag(input))
|
||||
if (input == InputType.ANY || (toCompare.inputType & input) != 0)
|
||||
closest = toCompare;
|
||||
} else
|
||||
{
|
||||
@ -131,7 +131,7 @@ namespace HeavenStudio.Games
|
||||
|
||||
if (t2 < t1)
|
||||
{
|
||||
if (input == InputType.ANY || toCompare.inputType.HasFlag(input))
|
||||
if (input == InputType.ANY || (toCompare.inputType & input) != 0)
|
||||
closest = toCompare;
|
||||
}
|
||||
}
|
||||
@ -220,6 +220,14 @@ namespace HeavenStudio.Games
|
||||
|
||||
}
|
||||
|
||||
public virtual void OnStop(float beat)
|
||||
{
|
||||
foreach (var evt in scheduledInputs)
|
||||
{
|
||||
evt.Disable();
|
||||
}
|
||||
}
|
||||
|
||||
public int MultipleEventsAtOnce()
|
||||
{
|
||||
int sameTime = 0;
|
||||
|
@ -7,7 +7,7 @@ using NaughtyBezierCurves;
|
||||
|
||||
namespace HeavenStudio.Games.Scripts_MunchyMonk
|
||||
{
|
||||
public class Dumpling : PlayerActionObject
|
||||
public class Dumpling : MonoBehaviour
|
||||
{
|
||||
public Animator otherAnim;
|
||||
public float startBeat;
|
||||
|
@ -1,3 +1,4 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
@ -11,8 +12,9 @@ using HeavenStudio.Common;
|
||||
namespace HeavenStudio.Games
|
||||
{
|
||||
|
||||
public class PlayerActionEvent : PlayerActionObject
|
||||
public class PlayerActionEvent : MonoBehaviour
|
||||
{
|
||||
static List<PlayerActionEvent> allEvents = new List<PlayerActionEvent>();
|
||||
public static bool EnableAutoplayCheat = true;
|
||||
public delegate void ActionEventCallback(PlayerActionEvent caller);
|
||||
public delegate void ActionEventCallbackState(PlayerActionEvent caller, float state);
|
||||
@ -26,8 +28,12 @@ namespace HeavenStudio.Games
|
||||
public float startBeat;
|
||||
public float timer;
|
||||
|
||||
public bool isEligible = true;
|
||||
public bool canHit = true; //Indicates if you can still hit the cue or not. If set to false, it'll guarantee a miss
|
||||
public bool enabled = true; //Indicates if the PlayerActionEvent is enabled. If set to false, it'll not trigger any events and destroy itself AFTER it's not relevant anymore
|
||||
public bool triggersAutoplay = true;
|
||||
bool lockedByEvent = false;
|
||||
bool markForDeletion = false;
|
||||
|
||||
public bool autoplayOnly = false; //Indicates if the input event only triggers when it's autoplay. If set to true, NO Miss or Blank events will be triggered when you're not autoplaying.
|
||||
|
||||
@ -51,43 +57,72 @@ namespace HeavenStudio.Games
|
||||
|
||||
public void Enable() { enabled = true; }
|
||||
public void Disable() { enabled = false; }
|
||||
public void QueueDeletion() { markForDeletion = true; }
|
||||
|
||||
public bool IsCorrectInput() =>
|
||||
//General inputs, both down and up
|
||||
(PlayerInput.Pressed() && inputType.HasFlag(InputType.STANDARD_DOWN)) ||
|
||||
(PlayerInput.AltPressed() && inputType.HasFlag(InputType.STANDARD_ALT_DOWN)) ||
|
||||
(PlayerInput.GetAnyDirectionDown() && inputType.HasFlag(InputType.DIRECTION_DOWN)) ||
|
||||
(PlayerInput.PressedUp() && inputType.HasFlag(InputType.STANDARD_UP)) ||
|
||||
(PlayerInput.AltPressedUp() && inputType.HasFlag(InputType.STANDARD_ALT_UP)) ||
|
||||
(PlayerInput.GetAnyDirectionUp() && inputType.HasFlag(InputType.DIRECTION_UP)) ||
|
||||
//Specific directional inputs
|
||||
(PlayerInput.GetSpecificDirectionDown(PlayerInput.DOWN) && inputType.HasFlag(InputType.DIRECTION_DOWN_DOWN)) ||
|
||||
(PlayerInput.GetSpecificDirectionDown(PlayerInput.UP) && inputType.HasFlag(InputType.DIRECTION_UP_DOWN)) ||
|
||||
(PlayerInput.GetSpecificDirectionDown(PlayerInput.LEFT) && inputType.HasFlag(InputType.DIRECTION_LEFT_DOWN)) ||
|
||||
(PlayerInput.GetSpecificDirectionDown(PlayerInput.RIGHT) && inputType.HasFlag(InputType.DIRECTION_RIGHT_DOWN)) ||
|
||||
|
||||
(PlayerInput.GetSpecificDirectionUp(PlayerInput.DOWN) && inputType.HasFlag(InputType.DIRECTION_DOWN_UP)) ||
|
||||
(PlayerInput.GetSpecificDirectionUp(PlayerInput.UP) && inputType.HasFlag(InputType.DIRECTION_UP_UP)) ||
|
||||
(PlayerInput.GetSpecificDirectionUp(PlayerInput.LEFT) && inputType.HasFlag(InputType.DIRECTION_LEFT_UP)) ||
|
||||
(PlayerInput.GetSpecificDirectionUp(PlayerInput.RIGHT) && inputType.HasFlag(InputType.DIRECTION_RIGHT_UP));
|
||||
|
||||
public void CanHit(bool canHit)
|
||||
{
|
||||
this.canHit = canHit;
|
||||
}
|
||||
|
||||
public void Start()
|
||||
{
|
||||
allEvents.Add(this);
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
if(!Conductor.instance.NotStopped()){CleanUp();} // If the song is stopped entirely in the editor, destroy itself as we don't want duplicates
|
||||
if (markForDeletion) CleanUp();
|
||||
if(!Conductor.instance.NotStopped()) CleanUp(); // If the song is stopped entirely in the editor, destroy itself as we don't want duplicates
|
||||
|
||||
if (noAutoplay && autoplayOnly) autoplayOnly = false;
|
||||
if (noAutoplay && triggersAutoplay){ triggersAutoplay = false; }
|
||||
if (noAutoplay && triggersAutoplay) triggersAutoplay = false;
|
||||
if (!enabled) return;
|
||||
|
||||
double normalizedTime = GetNormalizedTime();
|
||||
double stateProg = ((normalizedTime - Minigame.PerfectTime()) / (Minigame.LateTime() - Minigame.PerfectTime()) - 0.5f) * 2;
|
||||
StateCheck(normalizedTime);
|
||||
if (GameManager.instance.autoplay)
|
||||
{
|
||||
AutoplayInput(normalizedTime);
|
||||
return;
|
||||
}
|
||||
|
||||
//BUGFIX: ActionEvents destroyed too early
|
||||
if (normalizedTime > Minigame.EndTime()) Miss();
|
||||
|
||||
|
||||
if (IsCorrectInput() && !autoplayOnly)
|
||||
if (lockedByEvent)
|
||||
{
|
||||
if (state.perfect)
|
||||
return;
|
||||
}
|
||||
if (!CheckEventLock())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!autoplayOnly && IsCorrectInput())
|
||||
{
|
||||
if (IsExpectingInputNow())
|
||||
{
|
||||
double stateProg = ((normalizedTime - Minigame.PerfectTime()) / (Minigame.LateTime() - Minigame.PerfectTime()) - 0.5f) * 2;
|
||||
Hit(stateProg, normalizedTime);
|
||||
}
|
||||
else if (state.early && !perfectOnly)
|
||||
{
|
||||
Hit(-1f, normalizedTime);
|
||||
}
|
||||
else if (state.late && !perfectOnly)
|
||||
{
|
||||
Hit(1f, normalizedTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
Blank();
|
||||
@ -95,6 +130,60 @@ namespace HeavenStudio.Games
|
||||
}
|
||||
}
|
||||
|
||||
public void LateUpdate() {
|
||||
if (markForDeletion) {
|
||||
CleanUp();
|
||||
Destroy(this.gameObject);
|
||||
}
|
||||
foreach (PlayerActionEvent evt in allEvents)
|
||||
{
|
||||
evt.lockedByEvent = false;
|
||||
}
|
||||
}
|
||||
|
||||
private bool CheckEventLock()
|
||||
{
|
||||
foreach(PlayerActionEvent toCompare in allEvents)
|
||||
{
|
||||
if (toCompare == this) continue;
|
||||
if (toCompare.autoplayOnly) continue;
|
||||
if ((toCompare.inputType & this.inputType) == 0) continue;
|
||||
if (!toCompare.IsExpectingInputNow()) continue;
|
||||
|
||||
double t1 = this.startBeat + this.timer;
|
||||
double t2 = toCompare.startBeat + toCompare.timer;
|
||||
double songPos = Conductor.instance.songPositionInBeatsAsDouble;
|
||||
|
||||
// compare distance between current time and the events
|
||||
// events that happen at the exact same time with the exact same inputs will return true
|
||||
if (Math.Abs(t1 - songPos) > Math.Abs(t2 - songPos))
|
||||
return false;
|
||||
else if (t1 != t2) // if they are the same time, we don't want to lock the event
|
||||
toCompare.lockedByEvent = true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void AutoplayInput(double normalizedTime, bool autoPlay = false)
|
||||
{
|
||||
if (triggersAutoplay && (GameManager.instance.autoplay || autoPlay) && GameManager.instance.canInput && normalizedTime >= 1f - (Time.deltaTime*0.5f))
|
||||
{
|
||||
AutoplayEvent();
|
||||
if (!autoPlay)
|
||||
TimelineAutoplay();
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: move this to timeline code instead
|
||||
private void TimelineAutoplay()
|
||||
{
|
||||
if (Editor.Editor.instance == null) return;
|
||||
if (Editor.Track.Timeline.instance != null && !Editor.Editor.instance.fullscreen)
|
||||
{
|
||||
Editor.Track.Timeline.instance.AutoplayBTN.GetComponent<Animator>().Play("Ace", 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsExpectingInputNow()
|
||||
{
|
||||
double normalizedBeat = GetNormalizedTime();
|
||||
@ -104,41 +193,15 @@ namespace HeavenStudio.Games
|
||||
double GetNormalizedTime()
|
||||
{
|
||||
var cond = Conductor.instance;
|
||||
double currTime = cond.GetSongPosFromBeat(cond.songPositionInBeatsAsDouble);
|
||||
double currTime = cond.songPositionAsDouble;
|
||||
double targetTime = cond.GetSongPosFromBeat(startBeat + timer);
|
||||
double min = targetTime - 1f;
|
||||
double max = targetTime + 1f;
|
||||
return 1f + (((currTime - min) / (max - min))-0.5f)*2;
|
||||
}
|
||||
|
||||
public bool IsCorrectInput()
|
||||
{
|
||||
// This one is a mouthful but it's an evil good to detect the correct input
|
||||
// Forgive me for those input type names
|
||||
return (
|
||||
//General inputs, both down and up
|
||||
(PlayerInput.Pressed() && inputType.HasFlag(InputType.STANDARD_DOWN)) ||
|
||||
(PlayerInput.AltPressed() && inputType.HasFlag(InputType.STANDARD_ALT_DOWN)) ||
|
||||
(PlayerInput.GetAnyDirectionDown() && inputType.HasFlag(InputType.DIRECTION_DOWN)) ||
|
||||
(PlayerInput.PressedUp() && inputType.HasFlag(InputType.STANDARD_UP)) ||
|
||||
(PlayerInput.AltPressedUp() && inputType.HasFlag(InputType.STANDARD_ALT_UP)) ||
|
||||
(PlayerInput.GetAnyDirectionUp() && inputType.HasFlag(InputType.DIRECTION_UP)) ||
|
||||
//Specific directional inputs
|
||||
(PlayerInput.GetSpecificDirectionDown(PlayerInput.DOWN) && inputType.HasFlag(InputType.DIRECTION_DOWN_DOWN)) ||
|
||||
(PlayerInput.GetSpecificDirectionDown(PlayerInput.UP) && inputType.HasFlag(InputType.DIRECTION_UP_DOWN)) ||
|
||||
(PlayerInput.GetSpecificDirectionDown(PlayerInput.LEFT) && inputType.HasFlag(InputType.DIRECTION_LEFT_DOWN)) ||
|
||||
(PlayerInput.GetSpecificDirectionDown(PlayerInput.RIGHT) && inputType.HasFlag(InputType.DIRECTION_RIGHT_DOWN)) ||
|
||||
|
||||
(PlayerInput.GetSpecificDirectionUp(PlayerInput.DOWN) && inputType.HasFlag(InputType.DIRECTION_DOWN_UP)) ||
|
||||
(PlayerInput.GetSpecificDirectionUp(PlayerInput.UP) && inputType.HasFlag(InputType.DIRECTION_UP_UP)) ||
|
||||
(PlayerInput.GetSpecificDirectionUp(PlayerInput.LEFT) && inputType.HasFlag(InputType.DIRECTION_LEFT_UP)) ||
|
||||
(PlayerInput.GetSpecificDirectionUp(PlayerInput.RIGHT) && inputType.HasFlag(InputType.DIRECTION_RIGHT_UP))
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
//For the Autoplay
|
||||
public override void OnAce()
|
||||
public void AutoplayEvent()
|
||||
{
|
||||
if (EnableAutoplayCheat)
|
||||
{
|
||||
@ -162,6 +225,7 @@ namespace HeavenStudio.Games
|
||||
double normalized = time - 1f;
|
||||
int offset = Mathf.CeilToInt((float)normalized * 1000);
|
||||
GameManager.instance.AvgInputOffset = offset;
|
||||
state = System.Math.Max(-1.0, System.Math.Min(1.0, state));
|
||||
OnHit(this, (float) state);
|
||||
|
||||
CleanUp();
|
||||
@ -256,9 +320,10 @@ namespace HeavenStudio.Games
|
||||
|
||||
public void CleanUp()
|
||||
{
|
||||
if (markForDeletion) return;
|
||||
allEvents.Remove(this);
|
||||
OnDestroy(this);
|
||||
Destroy(this.gameObject);
|
||||
markForDeletion = true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -1,169 +0,0 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
using HeavenStudio.Editor;
|
||||
using HeavenStudio.Editor.Track;
|
||||
|
||||
namespace HeavenStudio.Games
|
||||
{
|
||||
public class PlayerActionObject : MonoBehaviour
|
||||
{
|
||||
public bool inList = false;
|
||||
public Minigame.Eligible state = new Minigame.Eligible();
|
||||
|
||||
public List<Minigame.Eligible> eligibleHitsList = new List<Minigame.Eligible>();
|
||||
|
||||
//the variables below seem to be mostly unused (they are never used in any meaningful way)
|
||||
public int aceTimes; //always set to 0 no matter what (also, the one time it's used doesn't seem to make sense)
|
||||
public bool isEligible = true;
|
||||
private bool autoPlayEnabledOnStart; //value never used for anything
|
||||
|
||||
public bool triggersAutoplay = true;
|
||||
|
||||
public void PlayerActionInit(GameObject g, float createBeat)
|
||||
{
|
||||
state.gameObject = g;
|
||||
state.createBeat = createBeat;
|
||||
|
||||
autoPlayEnabledOnStart = GameManager.instance.autoplay;
|
||||
}
|
||||
|
||||
private void CheckForAce(double normalizedBeat, bool autoPlay = false)
|
||||
{
|
||||
if (aceTimes == 0)
|
||||
{
|
||||
if (triggersAutoplay && (GameManager.instance.autoplay || autoPlay) && GameManager.instance.canInput && normalizedBeat >= 1f - (Time.deltaTime*0.5f))
|
||||
{
|
||||
OnAce();
|
||||
if (!autoPlay)
|
||||
AceVisuals();
|
||||
// aceTimes++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void ResetAce()
|
||||
{
|
||||
aceTimes = 0;
|
||||
}
|
||||
|
||||
public void ResetState()
|
||||
{
|
||||
ResetAce();
|
||||
}
|
||||
|
||||
// could possibly add support for custom early, perfect, and end times if needed.
|
||||
public void StateCheck(double normalizedBeat, bool autoPlay = false)
|
||||
{
|
||||
CheckForAce(normalizedBeat, autoPlay);
|
||||
if (normalizedBeat > Minigame.EarlyTime() && normalizedBeat < Minigame.PerfectTime())
|
||||
{
|
||||
MakeEligible(true, false, false);
|
||||
}
|
||||
// Perfect State
|
||||
else if (normalizedBeat > Minigame.PerfectTime() && normalizedBeat < Minigame.LateTime())
|
||||
{
|
||||
MakeEligible(false, true, false);
|
||||
}
|
||||
// Late State
|
||||
else if (normalizedBeat > Minigame.LateTime() && normalizedBeat < Minigame.EndTime())
|
||||
{
|
||||
MakeEligible(false, false, true);
|
||||
}
|
||||
else if (normalizedBeat < Minigame.EarlyTime() || normalizedBeat > Minigame.EndTime())
|
||||
{
|
||||
MakeInEligible();
|
||||
}
|
||||
}
|
||||
|
||||
public void MakeEligible(bool early, bool perfect, bool late)
|
||||
{
|
||||
if (!inList)
|
||||
{
|
||||
state.early = early;
|
||||
state.perfect = perfect;
|
||||
state.late = late;
|
||||
|
||||
eligibleHitsList.Add(state);
|
||||
inList = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Minigame.Eligible es = eligibleHitsList[eligibleHitsList.IndexOf(state)];
|
||||
es.early = early;
|
||||
es.perfect = perfect;
|
||||
es.late = late;
|
||||
}
|
||||
}
|
||||
|
||||
public void MakeInEligible()
|
||||
{
|
||||
state.early = false;
|
||||
state.perfect = false;
|
||||
state.late = false;
|
||||
if (!inList) return;
|
||||
|
||||
eligibleHitsList.Remove(state);
|
||||
inList = false;
|
||||
}
|
||||
|
||||
public void RemoveObject(int currentHitInList, bool destroyObject = false)
|
||||
{
|
||||
if (currentHitInList < eligibleHitsList.Count)
|
||||
{
|
||||
eligibleHitsList.Remove(eligibleHitsList[currentHitInList]);
|
||||
currentHitInList++;
|
||||
if (destroyObject) Destroy(this.gameObject);
|
||||
}
|
||||
}
|
||||
|
||||
// No list
|
||||
public void StateCheckNoList(float normalizedBeat)
|
||||
{
|
||||
CheckForAce(normalizedBeat);
|
||||
if (normalizedBeat > Minigame.EarlyTime() && normalizedBeat < Minigame.PerfectTime())
|
||||
{
|
||||
ModifyState(true, false, false);
|
||||
}
|
||||
// Perfect State
|
||||
else if (normalizedBeat > Minigame.PerfectTime() && normalizedBeat < Minigame.LateTime())
|
||||
{
|
||||
ModifyState(false, true, false);
|
||||
}
|
||||
// Late State
|
||||
else if (normalizedBeat > Minigame.LateTime() && normalizedBeat < Minigame.EndTime())
|
||||
{
|
||||
ModifyState(false, false, true);
|
||||
}
|
||||
else if (normalizedBeat < Minigame.EarlyTime() || normalizedBeat > Minigame.EndTime())
|
||||
{
|
||||
// ineligible
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void OnAce()
|
||||
{
|
||||
}
|
||||
|
||||
private void AceVisuals()
|
||||
{
|
||||
if (Timeline.instance != null && Editor.Editor.instance != null && !Editor.Editor.instance.fullscreen)
|
||||
{
|
||||
Timeline.instance.AutoplayBTN.GetComponent<Animator>().Play("Ace", 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
private void ModifyState(bool early, bool perfect, bool late)
|
||||
{
|
||||
state.early = early;
|
||||
state.perfect = perfect;
|
||||
state.late = late;
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
MakeInEligible();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0f6efa2756faaa740b7f4f81da94a909
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -8,7 +8,7 @@ using HeavenStudio.Util;
|
||||
|
||||
namespace HeavenStudio.Games.Scripts_RhythmRally
|
||||
{
|
||||
public class Paddlers : PlayerActionObject
|
||||
public class Paddlers : MonoBehaviour
|
||||
{
|
||||
private RhythmRally game;
|
||||
private Animator playerAnim;
|
||||
|
@ -5,7 +5,7 @@ using System;
|
||||
|
||||
namespace HeavenStudio.Games.Scripts_RhythmTweezers
|
||||
{
|
||||
public class Hair : PlayerActionObject
|
||||
public class Hair : MonoBehaviour
|
||||
{
|
||||
public float createBeat;
|
||||
public GameObject hairSprite;
|
||||
|
@ -6,7 +6,7 @@ using HeavenStudio.Util;
|
||||
|
||||
namespace HeavenStudio.Games.Scripts_RhythmTweezers
|
||||
{
|
||||
public class LongHair : PlayerActionObject
|
||||
public class LongHair : MonoBehaviour
|
||||
{
|
||||
public float createBeat;
|
||||
public GameObject hairSprite;
|
||||
@ -44,7 +44,7 @@ namespace HeavenStudio.Games.Scripts_RhythmTweezers
|
||||
if (endInput == InputType.DIRECTION_UP) input = PlayerInput.GetAnyDirectionUp();
|
||||
if (input && !game.IsExpectingInputNow(endInput))
|
||||
{
|
||||
endEvent.MakeInEligible();
|
||||
endEvent.isEligible = false;
|
||||
EndEarly();
|
||||
return;
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ using UnityEngine;
|
||||
|
||||
using HeavenStudio.Util;
|
||||
|
||||
namespace HeavenStudio
|
||||
namespace HeavenStudio.Games
|
||||
{
|
||||
public class SoundEffects : MonoBehaviour
|
||||
{
|
@ -6,7 +6,7 @@ using HeavenStudio.Util;
|
||||
|
||||
namespace HeavenStudio.Games.Scripts_SpaceSoccer
|
||||
{
|
||||
public class Kicker : PlayerActionObject
|
||||
public class Kicker : MonoBehaviour
|
||||
{
|
||||
SpaceSoccer game;
|
||||
|
||||
@ -82,7 +82,6 @@ namespace HeavenStudio.Games.Scripts_SpaceSoccer
|
||||
public void Kick(bool hit, bool highKick = false)
|
||||
{
|
||||
if (stopBall) return;
|
||||
aceTimes = 0;
|
||||
|
||||
if (player)
|
||||
{
|
||||
|
@ -9,7 +9,7 @@ using NaughtyBezierCurves;
|
||||
|
||||
namespace HeavenStudio.Games.Scripts_Spaceball
|
||||
{
|
||||
public class SpaceballBall : PlayerActionObject
|
||||
public class SpaceballBall : MonoBehaviour
|
||||
{
|
||||
#region Public
|
||||
|
||||
@ -46,8 +46,6 @@ namespace HeavenStudio.Games.Scripts_Spaceball
|
||||
e.gameObject = this.gameObject;
|
||||
|
||||
startRot = Random.Range(0, 360);
|
||||
|
||||
isEligible = true;
|
||||
}
|
||||
|
||||
private void Start()
|
||||
|
@ -1,61 +0,0 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
using HeavenStudio.Util;
|
||||
|
||||
namespace HeavenStudio.Games.Scripts_TapTrial
|
||||
{
|
||||
public class Tap : PlayerActionObject
|
||||
{
|
||||
public float startBeat;
|
||||
|
||||
public int type;
|
||||
|
||||
void Awake()
|
||||
{
|
||||
PlayerActionInit(this.gameObject, startBeat);
|
||||
}
|
||||
|
||||
public override void OnAce()
|
||||
{
|
||||
Hit(true);
|
||||
}
|
||||
|
||||
// Update is called once per frame
|
||||
void Update()
|
||||
{
|
||||
if (Conductor.instance.GetPositionFromBeat(startBeat, 2) >= 1)
|
||||
CleanUp();
|
||||
|
||||
float normalizedBeat = Conductor.instance.GetPositionFromBeat(startBeat, 1f);
|
||||
StateCheck(normalizedBeat);
|
||||
|
||||
if(PlayerInput.Pressed())
|
||||
{
|
||||
if(state.perfect)
|
||||
{
|
||||
Hit(true);
|
||||
}
|
||||
else if(state.notPerfect())
|
||||
{
|
||||
Hit(false);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void Hit(bool hit)
|
||||
{
|
||||
TapTrial.instance.player.Tap(hit, type);
|
||||
|
||||
if (hit)
|
||||
CleanUp();
|
||||
}
|
||||
|
||||
public void CleanUp()
|
||||
{
|
||||
Destroy(this.gameObject);
|
||||
}
|
||||
}
|
||||
}
|
@ -8,7 +8,7 @@ using HeavenStudio.Util;
|
||||
|
||||
namespace HeavenStudio.Games.Scripts_TrickClass
|
||||
{
|
||||
public class MobTrickObj : PlayerActionObject
|
||||
public class MobTrickObj : MonoBehaviour
|
||||
{
|
||||
public bool flyType;
|
||||
public float startBeat;
|
||||
|
@ -5,7 +5,7 @@ using System;
|
||||
|
||||
namespace HeavenStudio.Games.Scripts_WizardsWaltz
|
||||
{
|
||||
public class Plant : PlayerActionObject
|
||||
public class Plant : MonoBehaviour
|
||||
{
|
||||
public Animator animator;
|
||||
public SpriteRenderer spriteRenderer;
|
||||
|
@ -7,7 +7,7 @@ using HeavenStudio.Util;
|
||||
|
||||
namespace HeavenStudio.Games.Scripts_WorkingDough
|
||||
{
|
||||
public class BGBall : PlayerActionObject
|
||||
public class BGBall : MonoBehaviour
|
||||
{
|
||||
public float startBeat;
|
||||
public float firstBeatsToTravel = 3f;
|
||||
|
@ -14,7 +14,7 @@ namespace HeavenStudio.Games.Scripts_WorkingDough
|
||||
ExitingUp = 2,
|
||||
ExitingDown = 3
|
||||
}
|
||||
public class NPCDoughBall : PlayerActionObject
|
||||
public class NPCDoughBall : MonoBehaviour
|
||||
{
|
||||
public float startBeat;
|
||||
|
||||
|
@ -7,7 +7,7 @@ using HeavenStudio.Util;
|
||||
|
||||
namespace HeavenStudio.Games.Scripts_WorkingDough
|
||||
{
|
||||
public class PlayerEnterDoughBall : PlayerActionObject
|
||||
public class PlayerEnterDoughBall : MonoBehaviour
|
||||
{
|
||||
public float startBeat;
|
||||
public float firstBeatsToTravel = 0.5f;
|
||||
|
@ -1,9 +1,11 @@
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.SceneManagement;
|
||||
using UnityEngine.UI;
|
||||
using DG.Tweening;
|
||||
using TMPro;
|
||||
|
||||
using HeavenStudio.Common;
|
||||
|
||||
@ -12,19 +14,22 @@ namespace HeavenStudio
|
||||
public class GlobalGameManager : MonoBehaviour
|
||||
{
|
||||
public static GlobalGameManager instance { get; set; }
|
||||
[SerializeField] Image fadeImage;
|
||||
[SerializeField] TMP_Text loadingText;
|
||||
|
||||
public static string buildTime = "00/00/0000 00:00:00";
|
||||
|
||||
public static int loadedScene;
|
||||
public int lastLoadedScene;
|
||||
public static float fadeDuration;
|
||||
public static bool discordDuringTesting = false;
|
||||
|
||||
public GameObject loadScenePrefab;
|
||||
public GameObject hourGlass;
|
||||
static string loadedScene;
|
||||
static string lastLoadedScene;
|
||||
static AsyncOperation asyncLoad;
|
||||
|
||||
public static string levelLocation;
|
||||
public static bool officialLevel;
|
||||
|
||||
public static bool IsFirstBoot = false;
|
||||
|
||||
public static int CustomScreenWidth = 1280;
|
||||
public static int CustomScreenHeight = 720;
|
||||
|
||||
@ -56,13 +61,12 @@ namespace HeavenStudio
|
||||
Game = 3
|
||||
}
|
||||
|
||||
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
|
||||
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
|
||||
public static void Init()
|
||||
{
|
||||
BasicCheck();
|
||||
|
||||
loadedScene = 0;
|
||||
fadeDuration = 0;
|
||||
loadedScene = SceneManager.GetActiveScene().name;
|
||||
|
||||
PersistentDataManager.LoadSettings();
|
||||
|
||||
@ -91,13 +95,6 @@ namespace HeavenStudio
|
||||
Screen.fullScreen = false;
|
||||
ChangeScreenSize();
|
||||
}
|
||||
}
|
||||
|
||||
public void Awake()
|
||||
{
|
||||
Init();
|
||||
DontDestroyOnLoad(this.gameObject);
|
||||
instance = this;
|
||||
QualitySettings.maxQueuedFrames = 1;
|
||||
PlayerInput.InitInputControllers();
|
||||
#if UNITY_EDITOR
|
||||
@ -106,59 +103,100 @@ namespace HeavenStudio
|
||||
#else
|
||||
Starpelly.OS.ChangeWindowTitle("Heaven Studio (INDEV) " + Application.buildGUID.Substring(0, 8));
|
||||
buildTime = Application.buildGUID.Substring(0, 8) + " " + AppInfo.Date.ToString("dd/MM/yyyy hh:mm:ss");
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
// todo: make this part of the camera prefab instead of generated in code
|
||||
public static GameObject CreateFade()
|
||||
public void Awake()
|
||||
{
|
||||
GameObject fade = new GameObject();
|
||||
DontDestroyOnLoad(fade);
|
||||
fade.transform.localScale = new Vector3(4000, 4000);
|
||||
SpriteRenderer sr = fade.AddComponent<SpriteRenderer>();
|
||||
sr.sprite = Resources.Load<Sprite>("Sprites/GeneralPurpose/Square");
|
||||
sr.sortingOrder = 20000;
|
||||
fade.layer = 5;
|
||||
return fade;
|
||||
DontDestroyOnLoad(this.gameObject);
|
||||
instance = this;
|
||||
fadeImage.gameObject.SetActive(false);
|
||||
loadingText.enabled = false;
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
PlayerInput.UpdateInputControllers();
|
||||
}
|
||||
|
||||
IEnumerator LoadSceneAsync(string scene, float fadeOut)
|
||||
{
|
||||
//TODO: create flow mem loading icon
|
||||
asyncLoad = SceneManager.LoadSceneAsync(scene);
|
||||
while (!asyncLoad.isDone)
|
||||
{
|
||||
yield return null;
|
||||
}
|
||||
|
||||
//TODO: fade out flow mem loading icon
|
||||
instance.fadeImage.DOKill();
|
||||
instance.loadingText.enabled = false;
|
||||
instance.fadeImage.DOFade(0, fadeOut).OnComplete(() =>
|
||||
{
|
||||
instance.fadeImage.gameObject.SetActive(false);
|
||||
});
|
||||
}
|
||||
|
||||
IEnumerator ForceFadeAsync(float hold, float fadeOut)
|
||||
{
|
||||
yield return new WaitForSeconds(hold);
|
||||
instance.fadeImage.DOKill();
|
||||
instance.loadingText.enabled = false;
|
||||
instance.fadeImage.DOFade(0, fadeOut).OnComplete(() =>
|
||||
{
|
||||
instance.fadeImage.gameObject.SetActive(false);
|
||||
});
|
||||
}
|
||||
|
||||
public static void BasicCheck()
|
||||
{
|
||||
if (FindGGM() == null)
|
||||
{
|
||||
GameObject GlobalGameManager = new GameObject("GlobalGameManager");
|
||||
GlobalGameManager.name = "GlobalGameManager";
|
||||
GlobalGameManager.AddComponent<GlobalGameManager>();
|
||||
// load the global game manager prefab
|
||||
GameObject ggm = Instantiate(Resources.Load("Prefabs/GlobalGameManager") as GameObject);
|
||||
DontDestroyOnLoad(ggm);
|
||||
}
|
||||
}
|
||||
|
||||
public static GameObject FindGGM()
|
||||
{
|
||||
if (GameObject.Find("GlobalGameManager") != null)
|
||||
return GameObject.Find("GlobalGameManager");
|
||||
if (instance != null)
|
||||
return instance.gameObject;
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void LoadScene(int sceneIndex, float duration = 0.35f)
|
||||
public static void LoadScene(string scene, float fadeIn = 0.35f, float fadeOut = 0.35f)
|
||||
{
|
||||
print("bruh");
|
||||
BasicCheck();
|
||||
loadedScene = sceneIndex;
|
||||
fadeDuration = duration;
|
||||
if (scene == loadedScene)
|
||||
return;
|
||||
lastLoadedScene = loadedScene;
|
||||
loadedScene = scene;
|
||||
|
||||
// DOTween.Clear(true);
|
||||
// SceneManager.LoadScene(sceneIndex);
|
||||
instance.fadeImage.DOKill();
|
||||
instance.fadeImage.gameObject.SetActive(true);
|
||||
instance.fadeImage.color = new Color(0, 0, 0, 0);
|
||||
instance.fadeImage.DOFade(1, fadeIn).OnComplete(() =>
|
||||
{
|
||||
instance.StartCoroutine(instance.LoadSceneAsync(scene, fadeOut));
|
||||
instance.loadingText.enabled = true;
|
||||
});
|
||||
}
|
||||
|
||||
GameObject fade = CreateFade();
|
||||
fade.GetComponent<SpriteRenderer>().color = new Color(0, 0, 0, 0);
|
||||
fade.GetComponent<SpriteRenderer>().DOColor(Color.black, fadeDuration).OnComplete(() => { SceneManager.LoadScene(loadedScene); fade.GetComponent<SpriteRenderer>().DOColor(new Color(0, 0, 0, 0), fadeDuration).OnComplete(() => { Destroy(fade); }); });
|
||||
public static void ForceFade(float fadeIn, float hold, float fadeOut)
|
||||
{
|
||||
instance.fadeImage.DOKill();
|
||||
instance.fadeImage.gameObject.SetActive(true);
|
||||
instance.fadeImage.color = new Color(0, 0, 0, 0);
|
||||
instance.loadingText.enabled = false;
|
||||
instance.fadeImage.DOFade(1, fadeIn).OnComplete(() =>
|
||||
{
|
||||
instance.StartCoroutine(instance.ForceFadeAsync(hold, fadeOut));
|
||||
});
|
||||
}
|
||||
|
||||
public static void WindowFullScreen()
|
||||
{
|
||||
Debug.Log("WindowFullScreen");
|
||||
if (!Screen.fullScreen)
|
||||
{
|
||||
// Set the resolution to the display's current resolution
|
||||
@ -236,6 +274,18 @@ namespace HeavenStudio
|
||||
PersistentDataManager.gameSettings.sampleRate = currentSampleRate;
|
||||
}
|
||||
|
||||
public static void UpdateDiscordStatus(string details, bool editor = false, bool updateTime = false)
|
||||
{
|
||||
if (discordDuringTesting || !Application.isEditor)
|
||||
{
|
||||
if (PersistentDataManager.gameSettings.discordRPCEnable)
|
||||
{
|
||||
DiscordRPC.DiscordRPC.UpdateActivity(editor ? "In Editor " : "Playing ", details, updateTime);
|
||||
Debug.Log("Discord status updated");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OnApplicationQuit()
|
||||
{
|
||||
Debug.Log("Disconnecting JoyShocks...");
|
||||
|
@ -4,7 +4,7 @@ MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
executionOrder: -80
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
|
@ -24,7 +24,7 @@ namespace HeavenStudio.InputSystem
|
||||
KeyCode.U, // north face button
|
||||
KeyCode.C, // left shoulder button
|
||||
KeyCode.N, // right shoulder button
|
||||
KeyCode.Return, // start button
|
||||
KeyCode.Escape, // start button
|
||||
};
|
||||
|
||||
InputDirection hatDirectionCurrent;
|
||||
|
@ -9,12 +9,14 @@ namespace HeavenStudio.Editor
|
||||
{
|
||||
public class Dialog : MonoBehaviour
|
||||
{
|
||||
public bool IsOpen { get { return dialog.activeSelf; } }
|
||||
[SerializeField] protected GameObject dialog;
|
||||
public void ForceState(bool onoff = false)
|
||||
{
|
||||
dialog.SetActive(onoff);
|
||||
if (Editor.instance == null) return;
|
||||
Editor.instance.canSelect = !onoff;
|
||||
Editor.instance.inAuthorativeMenu = onoff;
|
||||
dialog.SetActive(onoff);
|
||||
}
|
||||
|
||||
public static void ResetAllDialogs()
|
||||
|
@ -25,7 +25,7 @@ namespace HeavenStudio.Editor
|
||||
{
|
||||
public class Editor : MonoBehaviour
|
||||
{
|
||||
private Initializer Initializer;
|
||||
private GameInitializer Initializer;
|
||||
|
||||
[SerializeField] public Canvas MainCanvas;
|
||||
[SerializeField] public Camera EditorCamera;
|
||||
@ -85,7 +85,7 @@ namespace HeavenStudio.Editor
|
||||
private void Start()
|
||||
{
|
||||
instance = this;
|
||||
Initializer = GetComponent<Initializer>();
|
||||
Initializer = GetComponent<GameInitializer>();
|
||||
canSelect = true;
|
||||
}
|
||||
|
||||
@ -517,13 +517,7 @@ namespace HeavenStudio.Editor
|
||||
|
||||
private void UpdateEditorStatus(bool updateTime)
|
||||
{
|
||||
if (discordDuringTesting || !Application.isEditor)
|
||||
{
|
||||
if (isDiscordEnabled)
|
||||
{ DiscordRPC.DiscordRPC.UpdateActivity("In Editor", $"{remixName}", updateTime);
|
||||
Debug.Log("Discord status updated");
|
||||
}
|
||||
}
|
||||
GlobalGameManager.UpdateDiscordStatus($"{remixName}", true, updateTime);
|
||||
}
|
||||
|
||||
public string GetJson()
|
||||
|
@ -4,7 +4,7 @@ MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: -40
|
||||
executionOrder: -20
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
|
@ -80,7 +80,6 @@ namespace HeavenStudio.Editor
|
||||
{
|
||||
currentEventIndex = amount;
|
||||
|
||||
EventRef.transform.parent.DOKill();
|
||||
CurrentSelected.transform.DOKill();
|
||||
|
||||
if (currentEventIndex < 0)
|
||||
@ -98,20 +97,36 @@ namespace HeavenStudio.Editor
|
||||
{
|
||||
selectorHeight = GameEventSelectorRect.rect.height;
|
||||
eventSize = EventRef.GetComponent<RectTransform>().rect.height;
|
||||
// EventRef.transform.parent.DOKill();
|
||||
float lastLocalY = EventRef.transform.parent.transform.localPosition.y;
|
||||
|
||||
if (currentEventIndex * eventSize >= selectorHeight/2 && eventsParent.childCount * eventSize >= selectorHeight)
|
||||
{
|
||||
if (currentEventIndex * eventSize < eventsParent.childCount * eventSize - selectorHeight/2)
|
||||
{
|
||||
EventRef.transform.parent.DOLocalMoveY((currentEventIndex * eventSize) - selectorHeight/2, 0.35f).SetEase(Ease.OutExpo);
|
||||
EventRef.transform.parent.transform.localPosition = new Vector3(
|
||||
EventRef.transform.parent.transform.localPosition.x,
|
||||
Mathf.Lerp(lastLocalY, (currentEventIndex * eventSize) - selectorHeight/2, 12 * Time.deltaTime),
|
||||
EventRef.transform.parent.transform.localPosition.z
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
EventRef.transform.parent.DOLocalMoveY((eventsParent.childCount * eventSize) - selectorHeight + (eventSize*0.33f), 0.35f).SetEase(Ease.OutExpo);
|
||||
EventRef.transform.parent.transform.localPosition = new Vector3(
|
||||
EventRef.transform.parent.transform.localPosition.x,
|
||||
Mathf.Lerp(lastLocalY, (eventsParent.childCount * eventSize) - selectorHeight + (eventSize*0.33f), 12 * Time.deltaTime),
|
||||
EventRef.transform.parent.transform.localPosition.z
|
||||
);
|
||||
}
|
||||
}
|
||||
else
|
||||
EventRef.transform.parent.DOLocalMoveY(0, 0.35f).SetEase(Ease.OutExpo);
|
||||
{
|
||||
EventRef.transform.parent.transform.localPosition = new Vector3(
|
||||
EventRef.transform.parent.transform.localPosition.x,
|
||||
Mathf.Lerp(lastLocalY, 0, 12 * Time.deltaTime),
|
||||
EventRef.transform.parent.transform.localPosition.z
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public void SelectGame(string gameName, int index)
|
||||
@ -134,7 +149,7 @@ namespace HeavenStudio.Editor
|
||||
currentEventIndex = 0;
|
||||
UpdateIndex(0, false);
|
||||
|
||||
Editor.instance.SetGameEventTitle($"Select game event for {gameName.Replace("\n", "")}");
|
||||
Editor.instance?.SetGameEventTitle($"Select game event for {gameName.Replace("\n", "")}");
|
||||
}
|
||||
|
||||
private void AddEvents()
|
||||
|
@ -133,7 +133,18 @@ namespace HeavenStudio.Editor.Track
|
||||
|
||||
DynamicBeatmap.TempoChange tempoC = new DynamicBeatmap.TempoChange();
|
||||
tempoC.beat = tempoChange.transform.localPosition.x;
|
||||
tempoC.tempo = GameManager.instance.Beatmap.bpm;
|
||||
if (Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift))
|
||||
{
|
||||
tempoC.tempo = GameManager.instance.Beatmap.bpm * 2f;
|
||||
}
|
||||
else if (Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.RightControl))
|
||||
{
|
||||
tempoC.tempo = GameManager.instance.Beatmap.bpm / 2f;
|
||||
}
|
||||
else
|
||||
{
|
||||
tempoC.tempo = GameManager.instance.Beatmap.bpm;
|
||||
}
|
||||
|
||||
tempoTimelineObj.tempoChange = tempoC;
|
||||
GameManager.instance.Beatmap.tempoChanges.Add(tempoC);
|
||||
|
102
Assets/Scripts/OpeningManager.cs
Normal file
102
Assets/Scripts/OpeningManager.cs
Normal file
@ -0,0 +1,102 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using TMPro;
|
||||
|
||||
using HeavenStudio.Common;
|
||||
|
||||
namespace HeavenStudio
|
||||
{
|
||||
public class OpeningManager : MonoBehaviour
|
||||
{
|
||||
[SerializeField] Animator openingAnim;
|
||||
[SerializeField] TMP_Text buildText;
|
||||
[SerializeField] TMP_Text versionDisclaimer;
|
||||
|
||||
public static string OnOpenFile;
|
||||
bool fastBoot = false;
|
||||
void Start()
|
||||
{
|
||||
string[] args = System.Environment.GetCommandLineArgs();
|
||||
for (int i = 1; i < args.Length; i++)
|
||||
{
|
||||
// first arg is always this executable
|
||||
Debug.Log(args[i]);
|
||||
if (args[i].IndexOfAny(Path.GetInvalidPathChars()) == -1)
|
||||
{
|
||||
if (File.Exists(args[i]) && (args[i].EndsWith(".riq") || args[i].EndsWith(".tengoku")))
|
||||
{
|
||||
OnOpenFile = args[i];
|
||||
}
|
||||
}
|
||||
if (args[i] == "--nosplash")
|
||||
{
|
||||
fastBoot = true;
|
||||
}
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
buildText.text = "EDITOR";
|
||||
#else
|
||||
buildText.text = Application.buildGUID.Substring(0, 8) + " " + AppInfo.Date.ToString("dd/MM/yyyy hh:mm:ss");
|
||||
#endif
|
||||
|
||||
if (Application.platform is RuntimePlatform.OSXPlayer or RuntimePlatform.OSXEditor)
|
||||
{
|
||||
versionDisclaimer.text = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
string ver = "<color=#FFFFCC>If you're coming from an older Heaven Studio build, copy your settings configs over from\n<color=#FFFF00>";
|
||||
if (Application.platform is RuntimePlatform.WindowsPlayer or RuntimePlatform.WindowsEditor)
|
||||
{
|
||||
ver += Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) + "\\AppData\\LocalLow\\Megaminerzero\\Heaven Studio\\";
|
||||
ver += "<color=#FFFFCC>\nto\n<color=#FFFF00>";
|
||||
ver += Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) + "\\AppData\\LocalLow\\RHeavenStudio\\Heaven Studio\\";
|
||||
}
|
||||
else if (Application.platform is RuntimePlatform.LinuxPlayer or RuntimePlatform.LinuxEditor)
|
||||
{
|
||||
ver += "~/.config/unity3d/Megaminerzero/Heaven Studio/";
|
||||
ver += "<color=#FFFFCC>\nto\n<color=#FFFF00>";
|
||||
ver += "~/.config/unity3d/RHeavenStudio/Heaven Studio/";
|
||||
}
|
||||
versionDisclaimer.text = ver;
|
||||
}
|
||||
|
||||
if (!GlobalGameManager.IsFirstBoot && !PersistentDataManager.gameSettings.showSplash)
|
||||
{
|
||||
fastBoot = true;
|
||||
}
|
||||
|
||||
if (fastBoot)
|
||||
{
|
||||
OnFinishDisclaimer(0.1f);
|
||||
}
|
||||
else
|
||||
{
|
||||
openingAnim.Play("FirstOpening", -1, 0);
|
||||
StartCoroutine(WaitAndFinishOpening());
|
||||
}
|
||||
}
|
||||
|
||||
IEnumerator WaitAndFinishOpening()
|
||||
{
|
||||
yield return new WaitForSeconds(8f);
|
||||
OnFinishDisclaimer(0.35f);
|
||||
}
|
||||
|
||||
void OnFinishDisclaimer(float fadeDuration = 0)
|
||||
{
|
||||
if (OnOpenFile is not null or "")
|
||||
{
|
||||
GlobalGameManager.LoadScene("Game", fadeDuration, 0.5f);
|
||||
}
|
||||
else
|
||||
{
|
||||
GlobalGameManager.LoadScene("Editor", fadeDuration, fadeDuration);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 01f0b70cc14be2e47998a680099e7986
|
||||
guid: 6282831a1c3a9d0429e232bbbe279a70
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
@ -23,6 +23,7 @@ namespace HeavenStudio.Common
|
||||
public static void CreateDefaultSettings()
|
||||
{
|
||||
gameSettings = new GameSettings(
|
||||
true,
|
||||
false,
|
||||
1,
|
||||
GlobalGameManager.DEFAULT_SCREEN_SIZES[1].width,
|
||||
@ -70,6 +71,7 @@ namespace HeavenStudio.Common
|
||||
}
|
||||
else
|
||||
{
|
||||
GlobalGameManager.IsFirstBoot = true;
|
||||
CreateDefaultSettings();
|
||||
}
|
||||
}
|
||||
@ -96,6 +98,7 @@ namespace HeavenStudio.Common
|
||||
{
|
||||
// default settings constructor
|
||||
public GameSettings(
|
||||
bool showSplash = false,
|
||||
bool isFullscreen = false,
|
||||
int resolutionIndex = 0,
|
||||
int resolutionWidth = 1280,
|
||||
@ -113,6 +116,7 @@ namespace HeavenStudio.Common
|
||||
bool letterboxFxEnable = true
|
||||
)
|
||||
{
|
||||
this.showSplash = showSplash;
|
||||
this.isFullscreen = isFullscreen;
|
||||
|
||||
this.resolutionIndex = resolutionIndex;
|
||||
@ -151,6 +155,7 @@ namespace HeavenStudio.Common
|
||||
}
|
||||
|
||||
// Display / Audio Settings
|
||||
public bool showSplash;
|
||||
public bool isFullscreen;
|
||||
|
||||
public int resolutionIndex;
|
||||
|
@ -1,24 +0,0 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class SpriteFlicker : MonoBehaviour
|
||||
{
|
||||
|
||||
public float flickerInterval;
|
||||
|
||||
SpriteRenderer sr;
|
||||
|
||||
// Start is called before the first frame update
|
||||
void Start()
|
||||
{
|
||||
sr = GetComponent<SpriteRenderer>();
|
||||
InvokeRepeating("ToggleVisibility", 0f, flickerInterval);
|
||||
}
|
||||
|
||||
// Update is called once per frame
|
||||
void ToggleVisibility()
|
||||
{
|
||||
sr.enabled = !sr.enabled;
|
||||
}
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e61c91c33ba01f1409c503668f734047
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -223,5 +223,10 @@ namespace HeavenStudio
|
||||
{
|
||||
ambientBgGO.SetActive(toggle);
|
||||
}
|
||||
|
||||
public void ToggleCanvasVisibility(bool toggle)
|
||||
{
|
||||
canvas.gameObject.SetActive(toggle);
|
||||
}
|
||||
}
|
||||
}
|
@ -85,11 +85,12 @@ namespace HeavenStudio.Common
|
||||
return;
|
||||
}
|
||||
|
||||
GameProfiler.instance.perfect = false;
|
||||
|
||||
texAnim.Play("GoForAPerfect_Miss");
|
||||
pAnim.Play("PerfectIcon_Miss", -1, 0);
|
||||
Jukebox.PlayOneShot("perfectMiss");
|
||||
|
||||
if (GameProfiler.instance != null)
|
||||
GameProfiler.instance.perfect = false;
|
||||
}
|
||||
|
||||
public void Enable(double startBeat)
|
||||
|
@ -19,17 +19,24 @@ namespace HeavenStudio.Common
|
||||
[SerializeField] GameObject TimingDisplayPrefab;
|
||||
[SerializeField] GameObject SkillStarPrefab;
|
||||
[SerializeField] GameObject ChartSectionPrefab;
|
||||
[SerializeField] SectionMedalsManager SectionMedalsManager;
|
||||
|
||||
[Header("Components")]
|
||||
[SerializeField] Transform ComponentHolder;
|
||||
|
||||
List<OverlaysManager.OverlayOption> lytElements = new List<OverlaysManager.OverlayOption>();
|
||||
|
||||
public static bool OverlaysReady {get { return instance != null &&
|
||||
TimingAccuracyDisplay.instance != null &&
|
||||
SkillStarManager.instance != null &&
|
||||
SectionMedalsManager.instance != null &&
|
||||
HeavenStudio.Games.Global.Textbox.instance != null;}}
|
||||
|
||||
// Start is called before the first frame update
|
||||
void Start()
|
||||
public void Start()
|
||||
{
|
||||
instance = this;
|
||||
RefreshOverlaysLayout();
|
||||
instance = this;
|
||||
}
|
||||
|
||||
// Update is called once per frame
|
||||
@ -82,12 +89,15 @@ namespace HeavenStudio.Common
|
||||
{
|
||||
if (c is TimingDisplayComponent) {
|
||||
c.CreateElement(TimingDisplayPrefab, ComponentHolder);
|
||||
Debug.Log("Create TimingDisplayComponent");
|
||||
}
|
||||
else if (c is SkillStarComponent) {
|
||||
c.CreateElement(SkillStarPrefab, ComponentHolder);
|
||||
Debug.Log("Create SkillStarComponent");
|
||||
}
|
||||
else if (c is SectionComponent) {
|
||||
c.CreateElement(ChartSectionPrefab, ComponentHolder);
|
||||
Debug.Log("Create SectionComponent");
|
||||
}
|
||||
c.PositionElement();
|
||||
}
|
||||
@ -225,6 +235,8 @@ namespace HeavenStudio.Common
|
||||
go.transform.localScale = Vector3.one * scale;
|
||||
go.transform.localRotation = Quaternion.Euler(0, 0, rotation);
|
||||
go.SetActive(enable && OverlaysManager.OverlaysEnabled);
|
||||
|
||||
HeavenStudio.Common.SectionMedalsManager.instance?.AnchorToOverlay(go);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -20,9 +20,13 @@ namespace HeavenStudio.Common
|
||||
bool isMedalsEligible = true;
|
||||
|
||||
// Start is called before the first frame update
|
||||
void Start()
|
||||
public void Awake()
|
||||
{
|
||||
instance = this;
|
||||
}
|
||||
|
||||
public void Start()
|
||||
{
|
||||
cond = Conductor.instance;
|
||||
GameManager.instance.onSectionChange += OnSectionChange;
|
||||
}
|
||||
@ -33,6 +37,13 @@ namespace HeavenStudio.Common
|
||||
|
||||
}
|
||||
|
||||
public void AnchorToOverlay(GameObject overlay)
|
||||
{
|
||||
transform.position = overlay.transform.position;
|
||||
transform.rotation = overlay.transform.rotation;
|
||||
transform.localScale = overlay.transform.localScale;
|
||||
}
|
||||
|
||||
public void MakeIneligible()
|
||||
{
|
||||
isMedalsEligible = false;
|
||||
@ -42,7 +53,7 @@ namespace HeavenStudio.Common
|
||||
{
|
||||
isMedalsStarted = false;
|
||||
isMedalsEligible = true;
|
||||
foreach (Transform child in MedalsHolder.transform)
|
||||
foreach (Transform child in MedalsHolder?.transform)
|
||||
{
|
||||
Destroy(child.gameObject);
|
||||
}
|
||||
@ -59,6 +70,7 @@ namespace HeavenStudio.Common
|
||||
}
|
||||
else
|
||||
{
|
||||
GameManager.instance.ClearedSection = isMedalsEligible;
|
||||
GameObject medal = Instantiate(isMedalsEligible ? MedalOkPrefab : MedalMissPrefab, MedalsHolder.transform);
|
||||
medal.SetActive(true);
|
||||
isMedalsEligible = true;
|
||||
@ -70,6 +82,7 @@ namespace HeavenStudio.Common
|
||||
if (!PersistentDataManager.gameSettings.isMedalOn) return;
|
||||
if (PersistentDataManager.gameSettings.isMedalOn && isMedalsStarted)
|
||||
{
|
||||
GameManager.instance.ClearedSection = isMedalsEligible;
|
||||
GameObject medal = Instantiate(isMedalsEligible ? MedalOkPrefab : MedalMissPrefab, MedalsHolder.transform);
|
||||
medal.SetActive(true);
|
||||
}
|
||||
|
@ -22,6 +22,7 @@ namespace HeavenStudio.Common
|
||||
|
||||
public float StarTargetTime { get { return starStart + starLength; } }
|
||||
public bool IsEligible { get; private set; }
|
||||
public bool IsCollected { get { return state == StarState.Collected; } }
|
||||
|
||||
float starStart = float.MaxValue;
|
||||
float starLength = float.MaxValue;
|
||||
@ -29,10 +30,10 @@ namespace HeavenStudio.Common
|
||||
Conductor cond;
|
||||
|
||||
// Start is called before the first frame update
|
||||
void Start()
|
||||
public void Start()
|
||||
{
|
||||
instance = this;
|
||||
cond = Conductor.instance;
|
||||
instance = this;
|
||||
}
|
||||
|
||||
// Update is called once per frame
|
||||
|
@ -35,7 +35,7 @@ namespace HeavenStudio.Common
|
||||
float targetArrowPos = 0f;
|
||||
|
||||
// Start is called before the first frame update
|
||||
void Start()
|
||||
public void Start()
|
||||
{
|
||||
instance = this;
|
||||
}
|
||||
|
192
Assets/Scripts/UI/PauseMenu.cs
Normal file
192
Assets/Scripts/UI/PauseMenu.cs
Normal file
@ -0,0 +1,192 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using TMPro;
|
||||
|
||||
using HeavenStudio.Util;
|
||||
using HeavenStudio.InputSystem;
|
||||
|
||||
namespace HeavenStudio.Common
|
||||
{
|
||||
public class PauseMenu : MonoBehaviour
|
||||
{
|
||||
public enum Options
|
||||
{
|
||||
Continue,
|
||||
StartOver,
|
||||
Settings,
|
||||
Quit
|
||||
}
|
||||
|
||||
// TODO
|
||||
// MAKE OPTIONS ACCEPT MOUSE INPUT
|
||||
|
||||
[SerializeField] float patternSpeed = 1f;
|
||||
[SerializeField] SettingsDialog settingsDialog;
|
||||
[SerializeField] Animator animator;
|
||||
[SerializeField] TMP_Text chartTitleText;
|
||||
[SerializeField] TMP_Text chartArtistText;
|
||||
[SerializeField] GameObject optionArrow;
|
||||
[SerializeField] GameObject optionHolder;
|
||||
|
||||
[SerializeField] RectTransform patternL;
|
||||
[SerializeField] RectTransform patternR;
|
||||
|
||||
public static bool IsPaused { get { return isPaused; } }
|
||||
|
||||
private static bool isPaused = false;
|
||||
private double pauseBeat;
|
||||
private bool canPick = false;
|
||||
private bool isQuitting = false;
|
||||
private int optionSelected = 0;
|
||||
|
||||
void Pause()
|
||||
{
|
||||
Conductor.instance.Pause();
|
||||
pauseBeat = Conductor.instance.songPositionInBeatsAsDouble;
|
||||
chartTitleText.text = GameManager.instance.Beatmap["remixtitle"];
|
||||
chartArtistText.text = GameManager.instance.Beatmap["remixauthor"];
|
||||
animator.Play("PauseShow");
|
||||
Jukebox.PlayOneShot("ui/PauseIn");
|
||||
|
||||
isPaused = true;
|
||||
canPick = false;
|
||||
optionSelected = 0;
|
||||
}
|
||||
|
||||
void UnPause(bool instant = false)
|
||||
{
|
||||
Conductor.instance.Play(pauseBeat);
|
||||
if (instant)
|
||||
{
|
||||
animator.Play("NoPose");
|
||||
}
|
||||
else
|
||||
{
|
||||
animator.Play("PauseHide");
|
||||
Jukebox.PlayOneShot("ui/PauseOut");
|
||||
}
|
||||
|
||||
isPaused = false;
|
||||
canPick = false;
|
||||
}
|
||||
|
||||
// Start is called before the first frame update
|
||||
void Start()
|
||||
{
|
||||
isPaused = false;
|
||||
isQuitting = false;
|
||||
}
|
||||
|
||||
// Update is called once per frame
|
||||
void Update()
|
||||
{
|
||||
if (isQuitting) return;
|
||||
if (PlayerInput.GetInputController(1).GetButtonDown((int) InputController.ButtonsPad.PadPause))
|
||||
{
|
||||
if (isPaused)
|
||||
{
|
||||
UnPause();
|
||||
}
|
||||
else
|
||||
{
|
||||
Pause();
|
||||
}
|
||||
}
|
||||
else if (isPaused && canPick && !settingsDialog.IsOpen)
|
||||
{
|
||||
if (Input.GetKeyDown(KeyCode.UpArrow) || PlayerInput.GetInputController(1).GetButtonDown((int)InputController.ButtonsPad.PadUp))
|
||||
{
|
||||
optionSelected--;
|
||||
if (optionSelected < 0)
|
||||
{
|
||||
optionSelected = optionHolder.transform.childCount - 1;
|
||||
}
|
||||
ChooseOption((Options) optionSelected);
|
||||
}
|
||||
else if (Input.GetKeyDown(KeyCode.DownArrow) || PlayerInput.GetInputController(1).GetButtonDown((int)InputController.ButtonsPad.PadDown))
|
||||
{
|
||||
optionSelected++;
|
||||
if (optionSelected > optionHolder.transform.childCount - 1)
|
||||
{
|
||||
optionSelected = 0;
|
||||
}
|
||||
ChooseOption((Options) optionSelected);
|
||||
}
|
||||
else if (Input.GetKeyDown(KeyCode.Return) || PlayerInput.GetInputController(1).GetButtonDown((int)InputController.ButtonsPad.PadE))
|
||||
{
|
||||
UseOption((Options) optionSelected);
|
||||
}
|
||||
}
|
||||
|
||||
if (isPaused)
|
||||
{
|
||||
patternL.anchoredPosition = new Vector2((Time.realtimeSinceStartup * patternSpeed) % 13, patternL.anchoredPosition.y);
|
||||
patternR.anchoredPosition = new Vector2(-(Time.realtimeSinceStartup * patternSpeed) % 13, patternR.anchoredPosition.y);
|
||||
}
|
||||
}
|
||||
|
||||
public void ChooseCurrentOption()
|
||||
{
|
||||
ChooseOption((Options) optionSelected, false);
|
||||
canPick = true;
|
||||
}
|
||||
|
||||
public void ChooseOption(Options option, bool sound = true)
|
||||
{
|
||||
optionArrow.transform.position = new Vector3(optionArrow.transform.position.x, optionHolder.transform.GetChild((int) option).position.y, optionArrow.transform.position.z);
|
||||
foreach (Transform child in optionHolder.transform)
|
||||
{
|
||||
child.transform.localScale = new Vector3(1f, 1f, 1f);
|
||||
}
|
||||
optionHolder.transform.GetChild((int) option).transform.localScale = new Vector3(1.2f, 1.2f, 1.2f);
|
||||
if (sound)
|
||||
Jukebox.PlayOneShot("ui/UIOption");
|
||||
}
|
||||
|
||||
void UseOption(Options option)
|
||||
{
|
||||
switch (option)
|
||||
{
|
||||
case Options.Continue:
|
||||
OnContinue();
|
||||
break;
|
||||
case Options.StartOver:
|
||||
OnRestart();
|
||||
break;
|
||||
case Options.Settings:
|
||||
OnSettings();
|
||||
Jukebox.PlayOneShot("ui/UISelect");
|
||||
break;
|
||||
case Options.Quit:
|
||||
OnQuit();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void OnContinue()
|
||||
{
|
||||
UnPause();
|
||||
}
|
||||
|
||||
void OnRestart()
|
||||
{
|
||||
UnPause(true);
|
||||
GlobalGameManager.ForceFade(0, 1f, 0.5f);
|
||||
GameManager.instance.Stop(0, true, 1.5f);
|
||||
Jukebox.PlayOneShot("ui/UIEnter");
|
||||
}
|
||||
|
||||
void OnQuit()
|
||||
{
|
||||
isQuitting = true;
|
||||
Jukebox.PlayOneShot("ui/PauseQuit");
|
||||
GlobalGameManager.LoadScene("Editor", 0, 0.1f);
|
||||
}
|
||||
|
||||
void OnSettings()
|
||||
{
|
||||
settingsDialog.SwitchSettingsDialog();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 54588eb7ee0680643aeaf61dcf609903
|
||||
guid: 013f3797143f4e241a6959ce253780f7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
@ -1,39 +0,0 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace HeavenStudio
|
||||
{
|
||||
public class Prologue : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private float waitSeconds;
|
||||
|
||||
public GameObject Holder;
|
||||
public GameObject pressAny;
|
||||
|
||||
bool inPrologue = false;
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (Input.anyKeyDown && !inPrologue)
|
||||
{
|
||||
pressAny.SetActive(false);
|
||||
Holder.SetActive(true);
|
||||
StartCoroutine(Wait());
|
||||
inPrologue = true;
|
||||
}
|
||||
}
|
||||
|
||||
IEnumerator Wait()
|
||||
{
|
||||
transform.GetChild(0).gameObject.SetActive(false);
|
||||
yield return new WaitForSeconds(1);
|
||||
transform.GetChild(0).gameObject.SetActive(true);
|
||||
yield return new WaitForSeconds(waitSeconds);
|
||||
transform.GetChild(0).gameObject.SetActive(false);
|
||||
yield return new WaitForSeconds(2);
|
||||
UnityEngine.SceneManagement.SceneManager.LoadScene(1);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 35da130f5b96d034885c14ed6ac9a2cf
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -1,145 +0,0 @@
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
using TMPro;
|
||||
using DG.Tweening;
|
||||
|
||||
using HeavenStudio.Util;
|
||||
|
||||
namespace HeavenStudio
|
||||
{
|
||||
public class Rating : MonoBehaviour
|
||||
{
|
||||
public GameObject Title;
|
||||
public GameObject Desc;
|
||||
public GameObject Rank;
|
||||
public GameObject Epilogue;
|
||||
public GameObject Perfect;
|
||||
|
||||
public GameObject RankingHolder;
|
||||
|
||||
public GameObject Fade;
|
||||
|
||||
private string rank;
|
||||
private int rankId;
|
||||
|
||||
public Sprite[] epilogueSprites;
|
||||
public Image epilogueImage;
|
||||
|
||||
public TMP_Text epilogueText;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
float score = GameProfiler.instance.score;
|
||||
TMP_Text desc = Desc.GetComponent<TMP_Text>();
|
||||
|
||||
if (GameProfiler.instance.perfect)
|
||||
{
|
||||
Perfect.SetActive(true);
|
||||
Jukebox.PlayOneShot("Rankings/ranking_perfect");
|
||||
StartCoroutine(PerfectIE());
|
||||
}
|
||||
else
|
||||
{
|
||||
if (score < 59)
|
||||
{
|
||||
// try again
|
||||
desc.text = "Your fork technique was rather uncouth. \nYour consecutive stabs needed work.";
|
||||
rank = "Rankings/ranking_tryagain";
|
||||
rankId = 2;
|
||||
}
|
||||
else if (score >= 59 && score < 79)
|
||||
{
|
||||
// ok
|
||||
desc.text = "Eh. Good enough.";
|
||||
rank = "Rankings/ranking_ok";
|
||||
rankId = 1;
|
||||
}
|
||||
else if (score >= 79)
|
||||
{
|
||||
// superb
|
||||
desc.text = "Your fork technique was quite elegant. \nYour consecutive stabs were excellent. \nYour triple-stab technique was sublime.";
|
||||
rank = "Rankings/ranking_superb";
|
||||
rankId = 0;
|
||||
}
|
||||
|
||||
StartCoroutine(ShowRank());
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerator ShowRank()
|
||||
{
|
||||
// Title
|
||||
yield return new WaitForSeconds(0.5f);
|
||||
|
||||
Jukebox.PlayOneShot("Rankings/ranking_title_show");
|
||||
Title.SetActive(true);
|
||||
|
||||
// Desc
|
||||
yield return new WaitForSeconds(2f);
|
||||
|
||||
Jukebox.PlayOneShot("Rankings/ranking_desc_show");
|
||||
Desc.SetActive(true);
|
||||
|
||||
// Rating
|
||||
yield return new WaitForSeconds(2f);
|
||||
|
||||
Jukebox.PlayOneShot(rank);
|
||||
Rank.transform.GetChild(rankId).gameObject.SetActive(true);
|
||||
|
||||
// Epilogue
|
||||
yield return new WaitForSeconds(5f);
|
||||
Fade.GetComponent<Image>().DOColor(Color.black, 0.75f).OnComplete(delegate
|
||||
{
|
||||
StartCoroutine(ShowEpilogue());
|
||||
});
|
||||
}
|
||||
|
||||
private IEnumerator ShowEpilogue()
|
||||
{
|
||||
epilogueImage.sprite = epilogueSprites[rankId];
|
||||
switch (rankId)
|
||||
{
|
||||
case 2:
|
||||
epilogueText.text = "Blood sugar...so...low...";
|
||||
break;
|
||||
case 1:
|
||||
epilogueText.text = "I could eat two more dinners!";
|
||||
break;
|
||||
case 0:
|
||||
epilogueText.text = "So full! So satisfied!";
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
yield return new WaitForSeconds(1);
|
||||
Fade.GetComponent<Image>().color = new Color(0, 0, 0, 0);
|
||||
RankingHolder.SetActive(false);
|
||||
Epilogue.SetActive(true);
|
||||
|
||||
switch (rankId)
|
||||
{
|
||||
case 0:
|
||||
Jukebox.PlayOneShot("Rankings/epilogue_superb");
|
||||
break;
|
||||
case 1:
|
||||
Jukebox.PlayOneShot("Rankings/epilogue_ok");
|
||||
break;
|
||||
case 2:
|
||||
Jukebox.PlayOneShot("Rankings/epilogue_tryagain");
|
||||
break;
|
||||
}
|
||||
|
||||
yield return new WaitForSeconds(8);
|
||||
GlobalGameManager.LoadScene(0);
|
||||
}
|
||||
|
||||
private IEnumerator PerfectIE()
|
||||
{
|
||||
yield return new WaitForSeconds(8);
|
||||
GlobalGameManager.LoadScene(0);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c00b45746e9b68744b76eb77268a0c61
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -3,9 +3,9 @@ using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using TMPro;
|
||||
|
||||
using HeavenStudio.Common;
|
||||
using HeavenStudio.Editor;
|
||||
|
||||
namespace HeavenStudio.Editor
|
||||
namespace HeavenStudio.Common
|
||||
{
|
||||
public class SettingsDialog : Dialog
|
||||
{
|
||||
@ -18,21 +18,25 @@ namespace HeavenStudio.Editor
|
||||
public void SwitchSettingsDialog()
|
||||
{
|
||||
if(dialog.activeSelf) {
|
||||
Editor.instance.canSelect = true;
|
||||
Editor.instance.inAuthorativeMenu = false;
|
||||
dialog.SetActive(false);
|
||||
|
||||
PersistentDataManager.SaveSettings();
|
||||
tabsManager.CleanTabs();
|
||||
|
||||
if (Editor.Editor.instance == null) return;
|
||||
Editor.Editor.instance.canSelect = true;
|
||||
Editor.Editor.instance.inAuthorativeMenu = false;
|
||||
} else {
|
||||
ResetAllDialogs();
|
||||
Editor.instance.canSelect = false;
|
||||
Editor.instance.inAuthorativeMenu = true;
|
||||
dialog.SetActive(true);
|
||||
|
||||
tabsManager.GenerateTabs(tabs);
|
||||
|
||||
BuildDateDisplay.text = GlobalGameManager.buildTime;
|
||||
|
||||
if (Editor.Editor.instance == null) return;
|
||||
Editor.Editor.instance.canSelect = false;
|
||||
Editor.Editor.instance.inAuthorativeMenu = true;
|
||||
}
|
||||
}
|
||||
|
@ -11,8 +11,8 @@ namespace HeavenStudio.Editor
|
||||
{
|
||||
public class CreditsLegalSettings : TabsContent
|
||||
{
|
||||
private int SecretCounter = 0;
|
||||
private bool SecretActive = false;
|
||||
private static int SecretCounter = 0;
|
||||
private static bool SecretActive = false;
|
||||
[SerializeField] private TextAsset creditsText;
|
||||
[SerializeField] private TMP_Text creditsDisplay;
|
||||
[SerializeField] private GameObject secretObject;
|
||||
@ -41,7 +41,14 @@ namespace HeavenStudio.Editor
|
||||
Jukebox.PlayOneShot("applause");
|
||||
Debug.Log("Activating Studio Dance...");
|
||||
|
||||
Editor.instance.StudioDanceManager.OpenDanceWindow();
|
||||
if (Editor.instance == null)
|
||||
{
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
Editor.instance.StudioDanceManager.OpenDanceWindow();
|
||||
}
|
||||
}
|
||||
|
||||
public void MakeSecretInactive()
|
||||
@ -49,7 +56,15 @@ namespace HeavenStudio.Editor
|
||||
SecretCounter = 0;
|
||||
secretObject.SetActive(false);
|
||||
SecretActive = false;
|
||||
Editor.instance.StudioDanceManager.CloseDanceWindow();
|
||||
|
||||
if (Editor.instance == null)
|
||||
{
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
Editor.instance.StudioDanceManager.CloseDanceWindow();
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnOpenTab()
|
@ -10,6 +10,7 @@ namespace HeavenStudio.Editor
|
||||
{
|
||||
public class DispAudioSettings : TabsContent
|
||||
{
|
||||
[SerializeField] Toggle splashScreenToggle;
|
||||
public TMP_Dropdown resolutionsDropdown;
|
||||
public GameObject customSetter;
|
||||
public TMP_InputField widthInputField, heightInputField;
|
||||
@ -96,8 +97,14 @@ namespace HeavenStudio.Editor
|
||||
PersistentDataManager.gameSettings.masterVolume = volSlider.value;
|
||||
}
|
||||
|
||||
public void OnSplashChanged()
|
||||
{
|
||||
PersistentDataManager.gameSettings.showSplash = splashScreenToggle.isOn;
|
||||
}
|
||||
|
||||
public override void OnOpenTab()
|
||||
{
|
||||
splashScreenToggle.isOn = PersistentDataManager.gameSettings.showSplash;
|
||||
resolutionsDropdown.value = GlobalGameManager.ScreenSizeIndex;
|
||||
|
||||
widthInputField.text = GlobalGameManager.CustomScreenWidth.ToString();
|
@ -1,4 +1,4 @@
|
||||
namespace HeavenStudio
|
||||
namespace HeavenStudio.Util
|
||||
{
|
||||
public class GameEvent
|
||||
{
|
@ -56,6 +56,28 @@ namespace HeavenStudio.Util
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Pauses all currently playing sounds.
|
||||
/// </summary>
|
||||
public static void PauseOneShots()
|
||||
{
|
||||
if (oneShotAudioSource != null)
|
||||
{
|
||||
oneShotAudioSource.Pause();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unpauses all currently playing sounds.
|
||||
/// </summary>
|
||||
public static void UnpauseOneShots()
|
||||
{
|
||||
if (oneShotAudioSource != null)
|
||||
{
|
||||
oneShotAudioSource.UnPause();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the length of an audio clip
|
||||
/// </summary>
|
||||
|
@ -43,7 +43,7 @@ namespace HeavenStudio.Util
|
||||
|
||||
if (beat == -1 && !scheduled)
|
||||
{
|
||||
audioSource.PlayScheduled(AudioSettings.dspTime);
|
||||
audioSource.Play();
|
||||
playInstant = true;
|
||||
played = true;
|
||||
startTime = cnd.songPositionAsDouble;
|
||||
@ -65,7 +65,7 @@ namespace HeavenStudio.Util
|
||||
{
|
||||
if (scheduled)
|
||||
{
|
||||
if (AudioSettings.dspTime > scheduledTime)
|
||||
if (scheduledPitch != 0 && AudioSettings.dspTime > scheduledTime)
|
||||
{
|
||||
StartCoroutine(NotRelyOnBeatSound());
|
||||
played = true;
|
||||
@ -73,7 +73,7 @@ namespace HeavenStudio.Util
|
||||
}
|
||||
else if (!playInstant)
|
||||
{
|
||||
if (AudioSettings.dspTime > startTime)
|
||||
if (scheduledPitch != 0 && AudioSettings.dspTime > startTime)
|
||||
{
|
||||
played = true;
|
||||
StartCoroutine(NotRelyOnBeatSound());
|
||||
@ -82,9 +82,21 @@ namespace HeavenStudio.Util
|
||||
{
|
||||
if (!played && scheduledPitch != cnd.SongPitch)
|
||||
{
|
||||
scheduledPitch = cnd.SongPitch;
|
||||
startTime = (AudioSettings.dspTime + (cnd.GetSongPosFromBeat(beat) - cnd.songPositionAsDouble)/(double)scheduledPitch);
|
||||
audioSource.SetScheduledStartTime(startTime);
|
||||
if (cnd.SongPitch == 0)
|
||||
{
|
||||
scheduledPitch = cnd.SongPitch;
|
||||
audioSource.Pause();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (scheduledPitch == 0)
|
||||
{
|
||||
audioSource.UnPause();
|
||||
}
|
||||
scheduledPitch = cnd.SongPitch;
|
||||
startTime = (AudioSettings.dspTime + (cnd.GetSongPosFromBeat(beat) - cnd.songPositionAsDouble)/(double)scheduledPitch);
|
||||
audioSource.SetScheduledStartTime(startTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user