mirror of
https://github.com/RHeavenStudio/HeavenStudio.git
synced 2025-06-12 08:37:37 +02:00
Game Overlays (#280)
* add accuracy display * temp BG for show * separate overlays prefab make proper shader for star effects * aim shakiness display * implement testing skill star * fully functional skill star * separate section display from editor * fully separate chart section display from timeline * add section to overlays * fix nullreference issues * start game layout settings * add game settings script * fix nonfunctioning scoring * invert y position logic on timing bar * add perfect challenge functionality * fix section not showing up in editor add perfect challenge option * add timing display minimal mode * Update PerfectAndPractice.png * show gismo for minigame bounds in editor * add ability to disable overlays in editor * prepare medals add new timing display graphic * hide screen preview * per-axis camera control added per request * section medals basic functionality * add medal get animations * fix bug with perfect icons * visual enhancements * adjust look of timing display minmode address audio ducking issues(?) * prepare overlay lyt editor add viewport pan, rotate, scale adjust audio setting * add layout editor UI elements * dynamic overlay creation * fix default single timing disp * set up overlay settings controls * start UI events * runtime uuid for component reference * layout editor affects overlay elements * show overlay element previews while editing * advanced audio settings * fix bug in drop-down creation * fallback defaults for the new stuff * fix textbox & overlay visibility bugs
This commit is contained in:
@ -94,9 +94,8 @@ namespace HeavenStudio.Editor
|
||||
|
||||
public void Init()
|
||||
{
|
||||
GameCamera.instance.camera.targetTexture = ScreenRenderTexture;
|
||||
GameManager.instance.StaticCamera.targetTexture = ScreenRenderTexture;
|
||||
GameManager.instance.CursorCam.targetTexture = ScreenRenderTexture;
|
||||
GameManager.instance.OverlayCamera.targetTexture = ScreenRenderTexture;
|
||||
GameLetterbox = GameManager.instance.GameLetterbox;
|
||||
Screen.texture = ScreenRenderTexture;
|
||||
|
||||
@ -501,9 +500,8 @@ namespace HeavenStudio.Editor
|
||||
|
||||
MainCanvas.enabled = false;
|
||||
EditorCamera.enabled = false;
|
||||
GameCamera.instance.camera.targetTexture = null;
|
||||
GameManager.instance.StaticCamera.targetTexture = null;
|
||||
GameManager.instance.CursorCam.enabled = false;
|
||||
GameManager.instance.OverlayCamera.targetTexture = null;
|
||||
fullscreen = true;
|
||||
|
||||
}
|
||||
@ -514,9 +512,8 @@ namespace HeavenStudio.Editor
|
||||
|
||||
MainCanvas.enabled = true;
|
||||
EditorCamera.enabled = true;
|
||||
GameCamera.instance.camera.targetTexture = ScreenRenderTexture;
|
||||
GameManager.instance.StaticCamera.targetTexture = ScreenRenderTexture;
|
||||
GameManager.instance.CursorCam.enabled = true && isCursorEnabled;
|
||||
GameManager.instance.OverlayCamera.targetTexture = ScreenRenderTexture;
|
||||
fullscreen = false;
|
||||
|
||||
GameCamera.instance.camera.rect = new Rect(0, 0, 1, 1);
|
||||
|
@ -1,3 +1,4 @@
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
@ -16,6 +17,8 @@ namespace HeavenStudio.Editor
|
||||
|
||||
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>();
|
||||
@ -53,16 +56,30 @@ namespace HeavenStudio.Editor
|
||||
|
||||
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()
|
||||
@ -88,6 +105,13 @@ namespace HeavenStudio.Editor
|
||||
|
||||
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()
|
||||
|
273
Assets/Scripts/LevelEditor/SettingsDialog/Tabs/GameSettings.cs
Normal file
273
Assets/Scripts/LevelEditor/SettingsDialog/Tabs/GameSettings.cs
Normal file
@ -0,0 +1,273 @@
|
||||
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;
|
||||
[SerializeField] Toggle editorOverlaysToggle;
|
||||
[SerializeField] Toggle perfectChallengeToggle;
|
||||
[SerializeField] Toggle sectionMedalsToggle;
|
||||
[SerializeField] Toggle timingDispMinModeToggle;
|
||||
|
||||
[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";
|
||||
|
||||
// Start is called before the first frame update
|
||||
void Start()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// Update is called once per frame
|
||||
void Update()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
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 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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
public override void OnCloseTab()
|
||||
{
|
||||
foreach (var e in lytElements)
|
||||
{
|
||||
e.DisablePreview();
|
||||
}
|
||||
lytElements.Clear();
|
||||
InPreview = 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()
|
||||
{
|
||||
var element = lytElements[currentElementIdx];
|
||||
element.enable = ElementToggle.isOn;
|
||||
element.PositionElement();
|
||||
}
|
||||
|
||||
public void OnXPosInputChanged()
|
||||
{
|
||||
var element = lytElements[currentElementIdx];
|
||||
XPosSlider.value = float.Parse(XPosInput.text);
|
||||
element.position.x = XPosSlider.value;
|
||||
element.PositionElement();
|
||||
}
|
||||
|
||||
public void OnXPosSliderChanged()
|
||||
{
|
||||
var element = lytElements[currentElementIdx];
|
||||
XPosInput.text = XPosSlider.value.ToString(fFormat);
|
||||
element.position.x = XPosSlider.value;
|
||||
element.PositionElement();
|
||||
}
|
||||
|
||||
public void OnYPosInputChanged()
|
||||
{
|
||||
var element = lytElements[currentElementIdx];
|
||||
YPosSlider.value = float.Parse(YPosInput.text);
|
||||
element.position.y = YPosSlider.value;
|
||||
element.PositionElement();
|
||||
}
|
||||
|
||||
public void OnYPosSliderChanged()
|
||||
{
|
||||
var element = lytElements[currentElementIdx];
|
||||
YPosInput.text = YPosSlider.value.ToString(fFormat);
|
||||
element.position.y = YPosSlider.value;
|
||||
element.PositionElement();
|
||||
}
|
||||
|
||||
public void OnRotationInputChanged()
|
||||
{
|
||||
var element = lytElements[currentElementIdx];
|
||||
RotationSlider.value = float.Parse(RotationInput.text);
|
||||
element.rotation = RotationSlider.value;
|
||||
element.PositionElement();
|
||||
}
|
||||
|
||||
public void OnRotationSliderChanged()
|
||||
{
|
||||
var element = lytElements[currentElementIdx];
|
||||
RotationInput.text = RotationSlider.value.ToString(fFormat);
|
||||
element.rotation = RotationSlider.value;
|
||||
element.PositionElement();
|
||||
}
|
||||
|
||||
public void OnScaleInputChanged()
|
||||
{
|
||||
var element = lytElements[currentElementIdx];
|
||||
ScaleSlider.value = float.Parse(ScaleInput.text);
|
||||
element.scale = ScaleSlider.value;
|
||||
element.PositionElement();
|
||||
}
|
||||
|
||||
public void OnScaleSliderChanged()
|
||||
{
|
||||
var element = lytElements[currentElementIdx];
|
||||
ScaleInput.text = ScaleSlider.value.ToString(fFormat);
|
||||
element.scale = ScaleSlider.value;
|
||||
element.PositionElement();
|
||||
}
|
||||
|
||||
public void OnTimingDispTypeDropdownChanged()
|
||||
{
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 32bac8197392a514388a446353759930
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -1,6 +1,7 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
using HeavenStudio;
|
||||
using HeavenStudio.Editor;
|
||||
@ -11,6 +12,7 @@ public class SectionDialog : Dialog
|
||||
{
|
||||
SectionTimelineObj sectionObj;
|
||||
[SerializeField] TMP_InputField sectionName;
|
||||
[SerializeField] Toggle challengeEnable;
|
||||
|
||||
public void SwitchSectionDialog()
|
||||
{
|
||||
@ -29,6 +31,7 @@ public class SectionDialog : Dialog
|
||||
{
|
||||
this.sectionObj = sectionObj;
|
||||
sectionName.text = sectionObj.chartSection.sectionName;
|
||||
challengeEnable.isOn = sectionObj.chartSection.startPerfect;
|
||||
}
|
||||
|
||||
public void DeleteSection()
|
||||
@ -48,4 +51,10 @@ public class SectionDialog : Dialog
|
||||
sectionObj.chartSection.sectionName = name;
|
||||
sectionObj.UpdateLabel();
|
||||
}
|
||||
|
||||
public void SetSectionChallenge()
|
||||
{
|
||||
if (sectionObj == null) return;
|
||||
sectionObj.chartSection.startPerfect = challengeEnable.isOn;
|
||||
}
|
||||
}
|
||||
|
@ -132,10 +132,6 @@ namespace HeavenStudio.Editor.Track
|
||||
[SerializeField] private RectTransform TimelineEventObjRef;
|
||||
[SerializeField] private RectTransform LayersRect;
|
||||
|
||||
[SerializeField] private GameObject TimelineSectionDisplay;
|
||||
[SerializeField] private TMP_Text TimelineSectionText;
|
||||
[SerializeField] private Slider TimelineSectionProgress;
|
||||
|
||||
[Header("Timeline Inputs")]
|
||||
public TMP_InputField FirstBeatOffset;
|
||||
public TMP_InputField StartingTempoSpecialAll;
|
||||
@ -307,7 +303,6 @@ namespace HeavenStudio.Editor.Track
|
||||
timelineState.SetState(CurrentTimelineState.State.Selection);
|
||||
|
||||
AutoBtnUpdate();
|
||||
GameManager.instance.onSectionChange += OnSectionChange;
|
||||
}
|
||||
|
||||
public void FitToSong()
|
||||
@ -387,7 +382,6 @@ namespace HeavenStudio.Editor.Track
|
||||
SongBeat.text = $"Beat {string.Format("{0:0.000}", Conductor.instance.songPositionInBeats)}";
|
||||
SongPos.text = FormatTime(Conductor.instance.songPosition);
|
||||
}
|
||||
TimelineSectionProgress.value = GameManager.instance.sectionProgress;
|
||||
|
||||
SliderControl();
|
||||
|
||||
@ -993,21 +987,6 @@ namespace HeavenStudio.Editor.Track
|
||||
UpdateStartingVolText();
|
||||
}
|
||||
|
||||
public void OnSectionChange(DynamicBeatmap.ChartSection section)
|
||||
{
|
||||
if (section == null)
|
||||
{
|
||||
TimelineSectionDisplay.SetActive(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!TimelineSectionDisplay.activeSelf)
|
||||
TimelineSectionDisplay.SetActive(true);
|
||||
TimelineSectionText.text = section.sectionName;
|
||||
TimelineSectionProgress.value = GameManager.instance.sectionProgress;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Commands
|
||||
|
Reference in New Issue
Block a user