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:
minenice55
2023-05-07 16:33:15 -04:00
committed by GitHub
parent 6c0fcca922
commit caf7d9465f
183 changed files with 17863 additions and 2247 deletions

View File

@ -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)

View File

@ -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);
}
}

View File

@ -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);
}

View File

@ -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

View File

@ -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;
}

View 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();
}
}
}

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 35da130f5b96d034885c14ed6ac9a2cf
guid: 013f3797143f4e241a6959ce253780f7
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@ -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);
}
}
}

View File

@ -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);
}
}
}

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 907f7d1eb5d90af408aa531ea366e63e
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,45 @@
using System;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
using HeavenStudio.Editor;
namespace HeavenStudio.Common
{
public class SettingsDialog : Dialog
{
[SerializeField] private TMP_Text BuildDateDisplay;
[SerializeField] private TabsManager tabsManager;
[SerializeField] private TabsManager.TabsEntry[] tabs;
private void Start() {}
public void SwitchSettingsDialog()
{
if(dialog.activeSelf) {
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();
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;
}
}
private void Update() {}
}
}

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: c00b45746e9b68744b76eb77268a0c61
guid: d82cc04699de2e54483ca0e0468d9ed2
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: f40824f5d4f2d0545ab42811c01c4470
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,257 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
using HeavenStudio;
using HeavenStudio.Util;
using HeavenStudio.InputSystem;
using static JSL;
namespace HeavenStudio.Editor
{
public class ControllerSettings : TabsContent
{
[SerializeField] private TMP_Text numConnectedLabel;
[SerializeField] private TMP_Text currentControllerLabel;
[SerializeField] private TMP_Dropdown controllersDropdown;
[SerializeField] private GameObject pairSearchItem;
[SerializeField] private GameObject autoSearchLabel;
[SerializeField] private GameObject pairSearchLabel;
[SerializeField] private TMP_Text pairingLabel;
[SerializeField] private List<GameObject> controllerIcons;
[SerializeField] private Material controllerMat;
private bool isAutoSearching = false;
private bool isPairSearching = false;
private bool pairSelectLR = false; //true = left, false = right
private void Start() {
numConnectedLabel.text = "Connected: " + PlayerInput.GetNumControllersConnected();
currentControllerLabel.text = "Current Controller: " + PlayerInput.GetInputController(1).GetDeviceName();
PopulateControllersDropdown();
ShowControllerIcon(PlayerInput.GetInputController(1));
controllersDropdown.onValueChanged.AddListener(delegate
{
InputController lastController = PlayerInput.GetInputController(1);
InputController newController = PlayerInput.GetInputControllers()[controllersDropdown.value];
AssignController(newController, lastController);
});
}
private void Update() {
if (isAutoSearching) {
var controllers = PlayerInput.GetInputControllers();
foreach (var controller in controllers) {
if (controller.GetLastButtonDown() > 0 || controller.GetLastKeyDown() > 0) {
InputController lastController = PlayerInput.GetInputController(1);
isAutoSearching = false;
autoSearchLabel.SetActive(false);
AssignController(controller, lastController);
controllersDropdown.value = PlayerInput.GetInputControllerId(1);
}
}
}
else if (isPairSearching) {
var controllers = PlayerInput.GetInputControllers();
InputController.InputFeatures lrFlag = pairSelectLR ? InputController.InputFeatures.Extra_SplitControllerLeft : InputController.InputFeatures.Extra_SplitControllerRight;
foreach (var controller in controllers) {
if (controller == PlayerInput.GetInputController(1)) continue;
InputController.InputFeatures features = controller.GetFeatures();
if (!features.HasFlag(lrFlag)) continue;
if (controller.GetLastButtonDown() > 0 || controller.GetLastKeyDown() > 0) {
InputJoyshock con = (InputJoyshock) PlayerInput.GetInputController(1);
con.AssignOtherHalf((InputJoyshock) controller);
isPairSearching = false;
pairSearchLabel.SetActive(false);
currentControllerLabel.text = "Current Controller: " + controller.GetDeviceName();
pairingLabel.text = "Joy-Con Pair Selected\nPairing Successful!";
ShowControllerIcon(controller);
StartCoroutine(SelectionVibrate(con));
StartCoroutine(SelectionVibrate((InputJoyshock) controller));
}
}
}
}
void AssignController(InputController newController, InputController lastController)
{
lastController.SetPlayer(-1);
newController.SetPlayer(1);
if (typeof(InputJoyshock) == lastController.GetType()) {
InputJoyshock con = (InputJoyshock) lastController;
con.UnAssignOtherHalf();
}
if (typeof(InputJoyshock) == newController.GetType()) {
InputJoyshock con = (InputJoyshock) newController;
StartCoroutine(SelectionVibrate(con));
con.UnAssignOtherHalf();
}
currentControllerLabel.text = "Current Controller: " + newController.GetDeviceName();
ShowControllerIcon(newController);
InputController.InputFeatures features = newController.GetFeatures();
if (features.HasFlag(InputController.InputFeatures.Extra_SplitControllerLeft)) {
pairingLabel.text = "Joy-Con (L) Selected\nPress A to pair with Joy-Con (R)";
pairSelectLR = !features.HasFlag(InputController.InputFeatures.Extra_SplitControllerLeft);
pairSearchItem.SetActive(true);
StartPairSearch();
}
else if (features.HasFlag(InputController.InputFeatures.Extra_SplitControllerRight)) {
pairingLabel.text = "Joy-Con (R) Selected\nPress A to pair with Joy-Con (L)";
pairSelectLR = !features.HasFlag(InputController.InputFeatures.Extra_SplitControllerLeft);
pairSearchItem.SetActive(true);
StartPairSearch();
}
else {
CancelPairSearch();
pairSearchItem.SetActive(false);
}
}
public void StartAutoSearch() {
if (!isPairSearching)
{
autoSearchLabel.SetActive(true);
isAutoSearching = true;
}
}
public void StartPairSearch() {
if (!isAutoSearching) {
pairSearchLabel.SetActive(true);
isPairSearching = true;
}
}
public void CancelPairSearch() {
if (isPairSearching) {
pairSearchLabel.SetActive(false);
isPairSearching = false;
pairingLabel.text = "Joy-Con Selected\nPairing was cancelled.";
}
}
public void SearchAndConnectControllers()
{
int connected = PlayerInput.InitInputControllers();
numConnectedLabel.text = "Connected: " + connected;
currentControllerLabel.text = "Current Controller: " + PlayerInput.GetInputController(1).GetDeviceName();
PopulateControllersDropdown();
}
public void PopulateControllersDropdown()
{
List<TMP_Dropdown.OptionData> dropDownData = new List<TMP_Dropdown.OptionData>();
var vals = PlayerInput.GetInputControllers();
for (int i = 0; i < vals.Count; i++)
{
TMP_Dropdown.OptionData optionData = new TMP_Dropdown.OptionData();
optionData.text = vals[i].GetDeviceName();
dropDownData.Add(optionData);
}
controllersDropdown.ClearOptions();
controllersDropdown.AddOptions(dropDownData);
controllersDropdown.value = 0;
}
public void ShowControllerIcon(InputController controller)
{
string name = controller.GetDeviceName();
foreach (var icon in controllerIcons)
{
if (icon.name == name)
{
icon.SetActive(true);
}
else
{
icon.SetActive(false);
}
}
//setup material
Color colour;
switch (name)
{
case "Keyboard":
controllerMat.SetColor("_BodyColor", ColorUtility.TryParseHtmlString("#F4F4F4", out colour) ? colour : Color.white);
break;
case "Joy-Con (L)":
case "Joy-Con (R)":
InputJoyshock joy = (InputJoyshock) controller;
controllerMat.SetColor("_BodyColor", joy.GetBodyColor());
controllerMat.SetColor("_BtnColor", joy.GetButtonColor());
controllerMat.SetColor("_LGripColor", ColorUtility.TryParseHtmlString("#2F353A", out colour) ? colour : Color.white);
controllerMat.SetColor("_RGripColor", ColorUtility.TryParseHtmlString("#2F353A", out colour) ? colour : Color.white);
break;
case "Joy-Con Pair":
joy = (InputJoyshock) controller;
int joySide = JslGetControllerSplitType(joy.GetHandle());
controllerMat.SetColor("_BodyColor", joySide == SplitRight ? joy.GetButtonColor() : joy.GetOtherHalf().GetButtonColor());
controllerMat.SetColor("_BtnColor", joySide == SplitLeft ? joy.GetButtonColor() : joy.GetOtherHalf().GetButtonColor());
controllerMat.SetColor("_LGripColor", joy.GetLeftGripColor());
controllerMat.SetColor("_RGripColor", joy.GetRightGripColor());
break;
case "Pro Controller":
joy = (InputJoyshock) controller;
controllerMat.SetColor("_BodyColor", joy.GetBodyColor());
controllerMat.SetColor("_BtnColor", joy.GetButtonColor());
controllerMat.SetColor("_LGripColor", joy.GetLeftGripColor());
controllerMat.SetColor("_RGripColor", joy.GetRightGripColor());
break;
case "DualShock 4":
joy = (InputJoyshock) controller;
controllerMat.SetColor("_BodyColor", ColorUtility.TryParseHtmlString("#E1E2E4", out colour) ? colour : Color.white);
controllerMat.SetColor("_BtnColor", ColorUtility.TryParseHtmlString("#414246", out colour) ? colour : Color.white);
controllerMat.SetColor("_LGripColor", joy.GetLightbarColour());
controllerMat.SetColor("_RGripColor", joy.GetLightbarColour());
break;
case "DualSense":
joy = (InputJoyshock) controller;
controllerMat.SetColor("_BodyColor", ColorUtility.TryParseHtmlString("#DEE0EB", out colour) ? colour : Color.white);
controllerMat.SetColor("_BtnColor", ColorUtility.TryParseHtmlString("#272D39", out colour) ? colour : Color.white);
controllerMat.SetColor("_LGripColor", joy.GetLightbarColour());
controllerMat.SetColor("_RGripColor", joy.GetLightbarColour());
break;
default:
controllerMat.SetColor("_BodyColor", Color.white);
controllerMat.SetColor("_BtnColor", Color.white);
controllerMat.SetColor("_LGripColor", Color.white);
controllerMat.SetColor("_RGripColor", Color.white);
break;
}
}
IEnumerator SelectionVibrate(InputJoyshock controller)
{
JslSetRumbleFrequency(controller.GetHandle(), 0.4f, 0.4f, 80f, 160f);
yield return new WaitForSeconds(0.15f);
JslSetRumbleFrequency(controller.GetHandle(), 0f, 0f, 0f, 0f);
yield return new WaitForSeconds(0.05f);
JslSetRumbleFrequency(controller.GetHandle(), 0.5f, 0.5f, 160f, 320f);
yield return new WaitForSeconds(0.25f);
JslSetRumbleFrequency(controller.GetHandle(), 0f, 0f, 0f, 0f);
}
public override void OnOpenTab()
{
}
public override void OnCloseTab()
{
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 10d59ed8edc40a448a61794f93c74ccd
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,79 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using HeavenStudio.Editor.Track;
using HeavenStudio.Util;
using HeavenStudio.StudioDance;
using TMPro;
namespace HeavenStudio.Editor
{
public class CreditsLegalSettings : TabsContent
{
private static int SecretCounter = 0;
private static bool SecretActive = false;
[SerializeField] private TextAsset creditsText;
[SerializeField] private TMP_Text creditsDisplay;
[SerializeField] private GameObject secretObject;
private void Start()
{
SecretCounter = 0;
secretObject.SetActive(false);
}
public void OnClickCountUp()
{
SecretCounter++;
Debug.Log("SecretCounter: " + SecretCounter);
if (SecretCounter == 10)
{
secretObject.SetActive(true);
}
}
public void OnClickSecret()
{
if (SecretActive) return;
SecretActive = true;
Jukebox.PlayOneShot("applause");
Debug.Log("Activating Studio Dance...");
if (Editor.instance == null)
{
}
else
{
Editor.instance.StudioDanceManager.OpenDanceWindow();
}
}
public void MakeSecretInactive()
{
SecretCounter = 0;
secretObject.SetActive(false);
SecretActive = false;
if (Editor.instance == null)
{
}
else
{
Editor.instance.StudioDanceManager.CloseDanceWindow();
}
}
public override void OnOpenTab()
{
creditsDisplay.text = creditsText.text;
}
public override void OnCloseTab()
{
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 406705ab8ec428e439d9138fd4984a9e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,128 @@
using System.Linq;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
using HeavenStudio.Common;
namespace HeavenStudio.Editor
{
public class DispAudioSettings : TabsContent
{
[SerializeField] Toggle splashScreenToggle;
public TMP_Dropdown resolutionsDropdown;
public GameObject customSetter;
public TMP_InputField widthInputField, heightInputField;
public Slider volSlider;
public TMP_InputField volLabel;
public TMP_Dropdown dspSizeDropdown;
public TMP_Dropdown sampleRateDropdown;
private void Start() {
List<TMP_Dropdown.OptionData> dropDownData = new List<TMP_Dropdown.OptionData>();
var vals = GlobalGameManager.DEFAULT_SCREEN_SIZES_STRING;
for (int i = 0; i < vals.Length; i++)
{
TMP_Dropdown.OptionData optionData = new TMP_Dropdown.OptionData();
optionData.text = vals[i];
dropDownData.Add(optionData);
}
resolutionsDropdown.AddOptions(dropDownData);
resolutionsDropdown.onValueChanged.AddListener(delegate
{
GlobalGameManager.ScreenSizeIndex = resolutionsDropdown.value;
customSetter.SetActive(resolutionsDropdown.value == GlobalGameManager.DEFAULT_SCREEN_SIZES_STRING.Length - 1);
});
widthInputField.onEndEdit.AddListener(delegate
{
GlobalGameManager.CustomScreenWidth = System.Math.Max(int.Parse(widthInputField.text), 64);
widthInputField.text = GlobalGameManager.CustomScreenWidth.ToString();
});
heightInputField.onEndEdit.AddListener(delegate
{
GlobalGameManager.CustomScreenHeight = System.Math.Max(int.Parse(heightInputField.text), 64);
heightInputField.text = GlobalGameManager.CustomScreenHeight.ToString();
});
resolutionsDropdown.value = GlobalGameManager.ScreenSizeIndex;
widthInputField.text = GlobalGameManager.CustomScreenWidth.ToString();
heightInputField.text = GlobalGameManager.CustomScreenHeight.ToString();
volSlider.value = GlobalGameManager.MasterVolume;
volLabel.text = System.Math.Round(volSlider.value * 100, 2).ToString();
dspSizeDropdown.onValueChanged.AddListener(delegate
{
GlobalGameManager.currentDspSize = GlobalGameManager.DSP_BUFFER_SIZES[dspSizeDropdown.value];
GlobalGameManager.ChangeAudioSettings(GlobalGameManager.currentDspSize, GlobalGameManager.currentSampleRate);
});
sampleRateDropdown.onValueChanged.AddListener(delegate
{
GlobalGameManager.currentSampleRate = GlobalGameManager.SAMPLE_RATES[sampleRateDropdown.value];
GlobalGameManager.ChangeAudioSettings(GlobalGameManager.currentDspSize, GlobalGameManager.currentSampleRate);
});
}
public void WindowFullScreen()
{
GlobalGameManager.WindowFullScreen();
GlobalGameManager.ResetGameRenderTexture();
}
public void WindowConfirmSize()
{
GlobalGameManager.ChangeScreenSize();
GlobalGameManager.ResetGameRenderTexture();
}
public void OnVolSliderChanged()
{
GlobalGameManager.ChangeMasterVolume(volSlider.value);
volLabel.text = System.Math.Round(volSlider.value * 100, 2).ToString();
PersistentDataManager.gameSettings.masterVolume = volSlider.value;
}
public void OnVolLabelChanged()
{
volSlider.value = (float)System.Math.Round(System.Convert.ToSingle(volLabel.text) / 100f, 2);
GlobalGameManager.ChangeMasterVolume(volSlider.value);
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();
heightInputField.text = GlobalGameManager.CustomScreenHeight.ToString();
volSlider.value = GlobalGameManager.MasterVolume;
volLabel.text = System.Math.Round(volSlider.value * 100, 2).ToString();
dspSizeDropdown.ClearOptions();
sampleRateDropdown.ClearOptions();
dspSizeDropdown.AddOptions(GlobalGameManager.DSP_BUFFER_SIZES.Select(x => x.ToString()).ToList());
sampleRateDropdown.AddOptions(GlobalGameManager.SAMPLE_RATES.Select(x => x.ToString()).ToList());
dspSizeDropdown.value = GlobalGameManager.DSP_BUFFER_SIZES.ToList().IndexOf(GlobalGameManager.currentDspSize);
sampleRateDropdown.value = GlobalGameManager.SAMPLE_RATES.ToList().IndexOf(GlobalGameManager.currentSampleRate);
}
public override void OnCloseTab()
{
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 752cb90567101a545ab1e2aeae732a9f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,45 @@
using UnityEngine;
using UnityEngine.UI;
using TMPro;
using HeavenStudio.Common;
namespace HeavenStudio.Editor
{
public class EditorSettings : TabsContent
{
public Toggle cursorCheckbox;
public Toggle discordRPCCheckbox;
private void Start() {
cursorCheckbox.isOn = PersistentDataManager.gameSettings.editorCursorEnable;
discordRPCCheckbox.isOn = PersistentDataManager.gameSettings.discordRPCEnable;
}
public void OnCursorCheckboxChanged()
{
Editor.instance.isCursorEnabled = cursorCheckbox.isOn;
PersistentDataManager.gameSettings.editorCursorEnable = cursorCheckbox.isOn;
if (Editor.instance != null && !Editor.instance.fullscreen)
{
GameManager.instance.CursorCam.enabled = Editor.instance.isCursorEnabled;
}
}
public void OnRPCCheckboxChanged()
{
PersistentDataManager.gameSettings.discordRPCEnable = discordRPCCheckbox.isOn;
Editor.instance.isDiscordEnabled = discordRPCCheckbox.isOn;
}
public override void OnOpenTab()
{
cursorCheckbox.isOn = PersistentDataManager.gameSettings.editorCursorEnable;
discordRPCCheckbox.isOn = PersistentDataManager.gameSettings.discordRPCEnable;
}
public override void OnCloseTab()
{
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 4dcd15958462e4e488a04ef094e7ffcb
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,322 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
using HeavenStudio.Common;
namespace HeavenStudio.Editor
{
public class GameSettings : TabsContent
{
public static bool InPreview;
static Color ambiColour;
static bool needUpdateAmbi;
[SerializeField] Toggle editorOverlaysToggle;
[SerializeField] Toggle perfectChallengeToggle;
[SerializeField] Toggle sectionMedalsToggle;
[SerializeField] Toggle timingDispMinModeToggle;
[SerializeField] Toggle letterboxBgEnable;
[SerializeField] Toggle letterboxFxEnable;
[SerializeField] Image LytEditBg;
[SerializeField] Image LytEditBgAmbi;
[SerializeField] GameObject LytEditBgAmbiGO;
[Header("Layout Settings - Header")]
[SerializeField] TMP_Text ElementNameText;
[Header("Layout Settings - General")]
[SerializeField] Toggle ElementToggle;
[SerializeField] TMP_InputField XPosInput;
[SerializeField] TMP_InputField YPosInput;
[SerializeField] Slider XPosSlider;
[SerializeField] Slider YPosSlider;
[SerializeField] TMP_InputField RotationInput;
[SerializeField] Slider RotationSlider;
[SerializeField] TMP_InputField ScaleInput;
[SerializeField] Slider ScaleSlider;
[Header("Layout Settings - Timing Display")]
[SerializeField] GameObject TimingDispTypeContainer;
[SerializeField] TMP_Dropdown TimingDispTypeDropdown;
List<OverlaysManager.OverlayOption> lytElements = new List<OverlaysManager.OverlayOption>();
static int currentElementIdx = 0;
const string fFormat = "0.000";
bool initLyt = false;
public static void UpdatePreviewAmbient(Color col)
{
ambiColour = col;
needUpdateAmbi = true;
}
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
if (InPreview && needUpdateAmbi)
{
LytEditBgAmbi.color = ambiColour;
needUpdateAmbi = false;
}
}
void CreateDefaultLayout()
{
PersistentDataManager.gameSettings.timingDisplayComponents = new List<OverlaysManager.TimingDisplayComponent>()
{
OverlaysManager.TimingDisplayComponent.CreateDefaultDual()
};
PersistentDataManager.gameSettings.skillStarComponents = new List<OverlaysManager.SkillStarComponent>()
{
OverlaysManager.SkillStarComponent.CreateDefault()
};
PersistentDataManager.gameSettings.sectionComponents = new List<OverlaysManager.SectionComponent>()
{
OverlaysManager.SectionComponent.CreateDefault()
};
PersistentDataManager.SaveSettings();
}
public void OnEditorOverlaysToggleChanged()
{
PersistentDataManager.gameSettings.overlaysInEditor = editorOverlaysToggle.isOn;
}
public void OnPerfectChallengeToggleChanged()
{
PersistentDataManager.gameSettings.perfectChallengeType = perfectChallengeToggle.isOn ? PersistentDataManager.PerfectChallengeType.On : PersistentDataManager.PerfectChallengeType.Off;
}
public void OnSectionMedalsToggleChanged()
{
PersistentDataManager.gameSettings.isMedalOn = sectionMedalsToggle.isOn;
}
public void OnTimingDispMinModeToggleChanged()
{
PersistentDataManager.gameSettings.timingDisplayMinMode = timingDispMinModeToggle.isOn;
}
public void OnLetterboxBgToggleChanged()
{
PersistentDataManager.gameSettings.letterboxBgEnable = letterboxBgEnable.isOn;
StaticCamera.instance.ToggleLetterboxBg(PersistentDataManager.gameSettings.letterboxBgEnable);
LytEditBg.color = PersistentDataManager.gameSettings.letterboxBgEnable ? Color.white : Color.black;
}
public void OnLetterboxFxToggleChanged()
{
PersistentDataManager.gameSettings.letterboxFxEnable = letterboxFxEnable.isOn;
StaticCamera.instance.ToggleLetterboxGlow(PersistentDataManager.gameSettings.letterboxFxEnable);
LytEditBgAmbiGO.SetActive(PersistentDataManager.gameSettings.letterboxFxEnable);
}
public override void OnOpenTab()
{
TimingDispTypeDropdown.ClearOptions();
TimingDispTypeDropdown.AddOptions(Enum.GetNames(typeof(OverlaysManager.TimingDisplayComponent.TimingDisplayType)).ToList());
editorOverlaysToggle.isOn = PersistentDataManager.gameSettings.overlaysInEditor;
perfectChallengeToggle.isOn = PersistentDataManager.gameSettings.perfectChallengeType != PersistentDataManager.PerfectChallengeType.Off;
sectionMedalsToggle.isOn = PersistentDataManager.gameSettings.isMedalOn;
timingDispMinModeToggle.isOn = PersistentDataManager.gameSettings.timingDisplayMinMode;
letterboxBgEnable.isOn = PersistentDataManager.gameSettings.letterboxBgEnable;
letterboxFxEnable.isOn = PersistentDataManager.gameSettings.letterboxFxEnable;
if (PersistentDataManager.gameSettings.timingDisplayComponents.Count == 0 &&
PersistentDataManager.gameSettings.skillStarComponents.Count == 0 &&
PersistentDataManager.gameSettings.sectionComponents.Count == 0)
{
CreateDefaultLayout();
}
lytElements = new List<OverlaysManager.OverlayOption>();
foreach (var c in PersistentDataManager.gameSettings.timingDisplayComponents) { lytElements.Add(c); c.EnablePreview();}
foreach (var c in PersistentDataManager.gameSettings.skillStarComponents) { lytElements.Add(c); c.EnablePreview();}
foreach (var c in PersistentDataManager.gameSettings.sectionComponents) { lytElements.Add(c); c.EnablePreview();}
UpdateLayoutSettings();
InPreview = true;
initLyt = true;
}
public override void OnCloseTab()
{
foreach (var e in lytElements)
{
e.DisablePreview();
}
lytElements.Clear();
InPreview = false;
initLyt = false;
}
void UpdateLayoutSettings()
{
var element = lytElements[currentElementIdx];
element.EnablePreview();
ElementToggle.isOn = element.enable;
XPosInput.text = element.position.x.ToString(fFormat);
YPosInput.text = element.position.y.ToString(fFormat);
XPosSlider.value = element.position.x;
YPosSlider.value = element.position.y;
RotationInput.text = element.rotation.ToString(fFormat);
RotationSlider.value = element.rotation;
ScaleInput.text = element.scale.ToString(fFormat);
ScaleSlider.value = element.scale;
if (element is OverlaysManager.TimingDisplayComponent)
{
TimingDispTypeContainer.SetActive(true);
TimingDispTypeDropdown.value = (int)(element as OverlaysManager.TimingDisplayComponent).tdType;
ElementNameText.text = "Timing Display";
}
else
{
TimingDispTypeContainer.SetActive(false);
}
if (element is OverlaysManager.SkillStarComponent)
{
ElementNameText.text = "Skill Star";
}
if (element is OverlaysManager.SectionComponent)
{
ElementNameText.text = "Section Progress";
}
}
public void OnNextElementButtonClicked()
{
currentElementIdx = (currentElementIdx + 1) % lytElements.Count;
UpdateLayoutSettings();
}
public void OnPrevElementButtonClicked()
{
currentElementIdx = (currentElementIdx - 1 + lytElements.Count) % lytElements.Count;
UpdateLayoutSettings();
}
public void OnElementToggled()
{
if (!initLyt) return;
var element = lytElements[currentElementIdx];
element.enable = ElementToggle.isOn;
element.PositionElement();
}
public void OnXPosInputChanged()
{
if (!initLyt) return;
var element = lytElements[currentElementIdx];
XPosSlider.value = float.Parse(XPosInput.text);
element.position.x = XPosSlider.value;
element.PositionElement();
}
public void OnXPosSliderChanged()
{
if (!initLyt) return;
var element = lytElements[currentElementIdx];
XPosInput.text = XPosSlider.value.ToString(fFormat);
element.position.x = XPosSlider.value;
element.PositionElement();
}
public void OnYPosInputChanged()
{
if (!initLyt) return;
var element = lytElements[currentElementIdx];
YPosSlider.value = float.Parse(YPosInput.text);
element.position.y = YPosSlider.value;
element.PositionElement();
}
public void OnYPosSliderChanged()
{
if (!initLyt) return;
var element = lytElements[currentElementIdx];
YPosInput.text = YPosSlider.value.ToString(fFormat);
element.position.y = YPosSlider.value;
element.PositionElement();
}
public void OnRotationInputChanged()
{
if (!initLyt) return;
var element = lytElements[currentElementIdx];
RotationSlider.value = float.Parse(RotationInput.text);
element.rotation = RotationSlider.value;
element.PositionElement();
}
public void OnRotationSliderChanged()
{
if (!initLyt) return;
var element = lytElements[currentElementIdx];
RotationInput.text = RotationSlider.value.ToString(fFormat);
element.rotation = RotationSlider.value;
element.PositionElement();
}
public void OnScaleInputChanged()
{
if (!initLyt) return;
var element = lytElements[currentElementIdx];
ScaleSlider.value = float.Parse(ScaleInput.text);
element.scale = ScaleSlider.value;
element.PositionElement();
}
public void OnScaleSliderChanged()
{
if (!initLyt) return;
var element = lytElements[currentElementIdx];
ScaleInput.text = ScaleSlider.value.ToString(fFormat);
element.scale = ScaleSlider.value;
element.PositionElement();
}
public void OnTimingDispTypeDropdownChanged()
{
if (!initLyt) return;
var element = lytElements[currentElementIdx] as OverlaysManager.TimingDisplayComponent;
if (element == null) return;
element.tdType = (OverlaysManager.TimingDisplayComponent.TimingDisplayType)TimingDispTypeDropdown.value;
bool elHide = element.enable;
switch (element.tdType)
{
case OverlaysManager.TimingDisplayComponent.TimingDisplayType.Dual:
element.position = new Vector2(-0.84f, 0);
element.rotation = 0f;
break;
default:
element.position = new Vector2(0, -0.8f);
element.rotation = 90f;
break;
}
element.scale = 1f;
element.enable = elHide;
element.PositionElement();
UpdateLayoutSettings();
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 32bac8197392a514388a446353759930
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: