HeavenStudio/Assets/Scripts/Games/Global/Textbox.cs
minenice55 b1fab52ad9
Integration of Jukebox Library (#451) (#457)
* add Jukebox library

todo:
- saving / loading of new format
- inferrence of unknown data like past versions
- move the temporary float casts to proper use of double
- make sound related functions take double for timing
- inform people that the Jukebox sound player was renamed to SoundByte lol

* make sound, input scheduling, and super curve use double precision

* successfully load charts

* editor works again

v1 riqs can be saved and loaded

* first tempo and volume markers are unmovable

fix loading of charts' easing values

* use gsync / freesync

* update Jukebox refs to SoundByte

* game events use double part 1

Air Rally - Glee Club converted

* don't load song if chart load fails

* finish conversion of all minigames

* remove editor waveform toggle

* timeline now respects added song offset length

clear cache files on app close
prepped notes for dsp sync

* update timeline length when offset changed

* update to latest Jukebox

* make error panel object in global game manager

* improve conductor music scheduling

* added error message box

fix first game events sometimes not playing
2023-06-10 19:17:06 +00:00

294 lines
11 KiB
C#

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
using HeavenStudio.TextboxUtilities;
using Jukebox;
using Jukebox.Legacy;
namespace HeavenStudio.Games.Global
{
public class Textbox : MonoBehaviour
{
public enum TextboxAnchor {
TopLeft,
TopMiddle,
TopRight,
Left,
Middle,
Right,
BottomLeft,
BottomMiddle,
BottomRight
}
public enum ClosedCaptionsAnchor {
Top,
Bottom,
}
private List<RiqEntity> textboxEvents = new List<RiqEntity>();
private List<RiqEntity> openCaptionsEvents = new List<RiqEntity>();
private List<RiqEntity> idolEvents = new List<RiqEntity>();
private List<RiqEntity> closedCaptionsEvents = new List<RiqEntity>();
public static Textbox instance { get; private set; }
[Header("Objects")]
public GameObject TextboxEnabler;
public TextboxObject TextboxObject;
public GameObject OpenCaptionsEnabler;
public TMP_Text OpenCaptionsLabel;
public RectTransform OpenCaptionsLabelRect;
public GameObject IdolEnabler;
public Animator IdolAnimator;
public TMP_Text IdolSongLabel;
public TMP_Text IdolArtistLabel;
public GameObject ClosedCaptionsEnabler;
public TMP_Text ClosedCaptionsLabel;
public RectTransform ClosedCaptionsLabelRect;
public RectTransform ClosedCaptionsBgRect;
float XAnchor = 1.5f;
float YAnchor = 1.75f;
Vector2 textboxSize = new Vector2(3f, 0.75f);
bool idolShown = false;
public void Awake()
{
instance = this;
}
public void Start()
{
GameManager.instance.onBeatChanged += OnBeatChanged;
TextboxEnabler.SetActive(false);
OpenCaptionsEnabler.SetActive(false);
ClosedCaptionsEnabler.SetActive(false);
UpdateTextboxDisplay();
UpdateOpenCaptionsDisplay();
UpdateClosedCaptionsDisplay();
}
public void Update()
{
UpdateTextboxDisplay();
UpdateOpenCaptionsDisplay();
UpdateIdolDisplay();
UpdateClosedCaptionsDisplay();
}
public void OnBeatChanged(double beat)
{
TextboxEnabler.SetActive(false);
OpenCaptionsEnabler.SetActive(false);
ClosedCaptionsEnabler.SetActive(false);
textboxEvents = EventCaller.GetAllInGameManagerList("vfx", new string[] { "display textbox" });
openCaptionsEvents = EventCaller.GetAllInGameManagerList("vfx", new string[] { "display open captions" });
idolEvents = EventCaller.GetAllInGameManagerList("vfx", new string[] { "display song artist" });
closedCaptionsEvents = EventCaller.GetAllInGameManagerList("vfx", new string[] { "display closed captions" });
UpdateTextboxDisplay();
UpdateOpenCaptionsDisplay();
UpdateClosedCaptionsDisplay();
UpdateIdolDisplay();
if (!idolShown)
{
IdolAnimator.Play("NoPose", -1, 0);
IdolAnimator.speed = 1;
}
}
private void UpdateTextboxDisplay()
{
foreach (var e in textboxEvents)
{
float prog = Conductor.instance.GetPositionFromBeat(e.beat, e.length);
if (prog >= 0f && prog <= 1f)
{
TextboxEnabler.SetActive(true);
TextboxObject.SetText(e["text1"]);
TextboxObject.Resize(e["valA"], e["valB"]);
// ouch
switch (e["type"])
{
case (int) TextboxAnchor.TopLeft:
TextboxEnabler.transform.localPosition = new Vector3(-XAnchor, YAnchor);
break;
case (int) TextboxAnchor.TopMiddle:
TextboxEnabler.transform.localPosition = new Vector3(0, YAnchor);
break;
case (int) TextboxAnchor.TopRight:
TextboxEnabler.transform.localPosition = new Vector3(XAnchor, YAnchor);
break;
case (int) TextboxAnchor.Left:
TextboxEnabler.transform.localPosition = new Vector3(-XAnchor, 0);
break;
case (int) TextboxAnchor.Middle:
TextboxEnabler.transform.localPosition = new Vector3(0, 0);
break;
case (int) TextboxAnchor.Right:
TextboxEnabler.transform.localPosition = new Vector3(XAnchor, 0);
break;
case (int) TextboxAnchor.BottomLeft:
TextboxEnabler.transform.localPosition = new Vector3(-XAnchor, -YAnchor);
break;
case (int) TextboxAnchor.BottomMiddle:
TextboxEnabler.transform.localPosition = new Vector3(0, -YAnchor);
break;
case (int) TextboxAnchor.BottomRight:
TextboxEnabler.transform.localPosition = new Vector3(XAnchor, -YAnchor);
break;
default:
TextboxEnabler.transform.localPosition = new Vector3(0, 0);
break;
}
return;
}
if (prog > 1f || prog < 0f)
{
TextboxEnabler.transform.localPosition = new Vector3(0, 0);
TextboxEnabler.SetActive(false);
}
}
}
private void UpdateOpenCaptionsDisplay()
{
foreach (var e in openCaptionsEvents)
{
float prog = Conductor.instance.GetPositionFromBeat(e.beat, e.length);
if (prog >= 0f && prog <= 1f)
{
OpenCaptionsEnabler.SetActive(true);
OpenCaptionsLabel.text = e["text1"];
OpenCaptionsLabelRect.sizeDelta = new Vector2(18f * e["valA"], 2.5f * e["valB"]);
// ouch
switch (e["type"])
{
case (int) TextboxAnchor.TopLeft:
OpenCaptionsEnabler.transform.localPosition = new Vector3(-XAnchor, YAnchor);
break;
case (int) TextboxAnchor.TopMiddle:
OpenCaptionsEnabler.transform.localPosition = new Vector3(0, YAnchor);
break;
case (int) TextboxAnchor.TopRight:
OpenCaptionsEnabler.transform.localPosition = new Vector3(XAnchor, YAnchor);
break;
case (int) TextboxAnchor.Left:
OpenCaptionsEnabler.transform.localPosition = new Vector3(-XAnchor, 0);
break;
case (int) TextboxAnchor.Middle:
OpenCaptionsEnabler.transform.localPosition = new Vector3(0, 0);
break;
case (int) TextboxAnchor.Right:
OpenCaptionsEnabler.transform.localPosition = new Vector3(XAnchor, 0);
break;
case (int) TextboxAnchor.BottomLeft:
OpenCaptionsEnabler.transform.localPosition = new Vector3(-XAnchor, -YAnchor);
break;
case (int) TextboxAnchor.BottomMiddle:
OpenCaptionsEnabler.transform.localPosition = new Vector3(0, -YAnchor);
break;
case (int) TextboxAnchor.BottomRight:
OpenCaptionsEnabler.transform.localPosition = new Vector3(XAnchor, -YAnchor);
break;
default:
OpenCaptionsEnabler.transform.localPosition = new Vector3(0, 0);
break;
}
return;
}
if (prog > 1f || prog < 0f)
{
OpenCaptionsEnabler.transform.localPosition = new Vector3(0, 0);
OpenCaptionsEnabler.SetActive(false);
}
}
}
private void UpdateIdolDisplay()
{
var cond = Conductor.instance;
foreach (var e in idolEvents)
{
float prog = cond.GetPositionFromBeat(e.beat, e.length);
if (prog >= 0f && prog <= 1f)
{
float inp = cond.GetPositionFromBeat(e.beat, 1);
IdolSongLabel.text = e["text1"];
IdolArtistLabel.text = e["text2"];
IdolAnimator.Play("IdolShow", -1, Mathf.Min(inp, 1));
IdolAnimator.speed = 0;
idolShown = true;
return;
}
else if (idolShown)
{
if (prog < 1f)
{
IdolAnimator.Play("NoPose", -1, 0);
IdolAnimator.speed = 1;
idolShown = false;
}
else
{
IdolAnimator.Play("IdolHide", -1, 0);
IdolAnimator.speed = (1f / cond.pitchedSecPerBeat) * 0.5f;
idolShown = false;
}
}
}
}
private void UpdateClosedCaptionsDisplay()
{
foreach (var e in closedCaptionsEvents)
{
float prog = Conductor.instance.GetPositionFromBeat(e.beat, e.length);
if (prog >= 0f && prog <= 1f)
{
ClosedCaptionsEnabler.SetActive(true);
ClosedCaptionsLabel.text = e["text1"];
ClosedCaptionsLabelRect.sizeDelta = new Vector2(9f, e["valA"]);
ClosedCaptionsBgRect.sizeDelta = new Vector2(9f, e["valA"]);
switch (e["type"])
{
case (int) ClosedCaptionsAnchor.Bottom:
ClosedCaptionsEnabler.transform.localPosition = new Vector3(0, -2.5f + e["valA"]/2);
break;
default:
ClosedCaptionsEnabler.transform.localPosition = new Vector3(0, 2.5f - e["valA"]/2);
break;
}
return;
}
if (prog > 1f || prog < 0f)
{
ClosedCaptionsEnabler.SetActive(false);
}
}
}
}
}