Improve note parameters (#798)

* Add note parameter

* Increase max semitones

* Add previewing sounds for notes

* Add note preview toggle setting

* Fix Launch Party starting note

* Fix preview sound pooling + add BTS preview sound

* Add previewing note when slider handle is clicked
This commit is contained in:
EpicGamer2469
2024-03-21 20:37:41 -05:00
committed by minenice55
parent 194b4b6e04
commit 35b1120d01
25 changed files with 1987 additions and 99 deletions

View File

@ -19,6 +19,7 @@ namespace HeavenStudio.Editor
[Header("Property Prefabs")]
[SerializeField] private GameObject IntegerP;
[SerializeField] private GameObject FloatP;
[SerializeField] private GameObject NoteP;
[SerializeField] private GameObject ButtonP;
[SerializeField] private GameObject BooleanP;
[SerializeField] private GameObject DropdownP;
@ -44,6 +45,7 @@ namespace HeavenStudio.Editor
PropertyPrefabs = new() {
{ typeof(Integer), IntegerP },
{ typeof(Float), FloatP },
{ typeof(Note), NoteP },
{ typeof(Dropdown), DropdownP },
{ typeof(Button), ButtonP },
{ typeof(Color), ColorP },

View File

@ -0,0 +1,127 @@
using System;
using System.Collections;
using System.Collections.Generic;
using HeavenStudio;
using HeavenStudio.Common;
using HeavenStudio.Editor;
using HeavenStudio.Util;
using TMPro;
using UnityEngine;
public class NotePropertyPrefab : NumberPropertyPrefab
{
public TMP_Text noteLabel;
private Sound previewAudioSource;
private EntityTypes.Note note;
private int offsetFromC;
public override void SetProperties(string propertyName, object type, string caption)
{
base.SetProperties(propertyName, type, caption);
note = (EntityTypes.Note)type;
slider.minValue = note.min;
slider.maxValue = note.max;
slider.wholeNumbers = true;
offsetFromC = 3 - note.sampleNote;
slider.value = Convert.ToSingle(parameterManager.entity[propertyName]) - offsetFromC;
_defaultValue = slider.value;
inputField.text = slider.value.ToString();
noteLabel.text = GetNoteText(note, (int)slider.value + offsetFromC);
slider.onValueChanged.AddListener(
_ =>
{
int trueSemitones = (int)slider.value + offsetFromC;
inputField.text = slider.value.ToString();
parameterManager.entity[propertyName] = trueSemitones;
if (slider.value != _defaultValue)
{
this.caption.text = _captionText + "*";
}
else
{
this.caption.text = _captionText;
}
noteLabel.text = GetNoteText(note, trueSemitones);
PlayPreview(note, trueSemitones);
}
);
inputField.onSelect.AddListener(
_ =>
Editor.instance.editingInputField = true
);
inputField.onEndEdit.AddListener(
_ =>
{
int trueSemitones = (int)slider.value + offsetFromC;
slider.value = Convert.ToSingle(inputField.text);
parameterManager.entity[propertyName] = trueSemitones;
Editor.instance.editingInputField = false;
if (slider.value != _defaultValue)
{
this.caption.text = _captionText + "*";
}
else
{
this.caption.text = _captionText;
}
noteLabel.text = GetNoteText(note, trueSemitones);
PlayPreview(note, trueSemitones);
}
);
}
public void OnSelectSliderHandle()
{
PlayPreview(note, (int)slider.value + offsetFromC);
}
private void PlayPreview(EntityTypes.Note note, int currentSemitones)
{
if (note.sampleName.Equals("") || !PersistentDataManager.gameSettings.previewNoteSounds) return;
if (previewAudioSource != null)
{
previewAudioSource.Stop(true);
previewAudioSource = null;
}
float pitch = SoundByte.GetPitchFromSemiTones(currentSemitones, true);
previewAudioSource = SoundByte.PlayOneShotGame(note.sampleName, pitch: pitch, volume: 0.75f, forcePlay: true, ignoreConductorPause: true);
}
private static readonly string[] notes = { "A", "A#", "B", "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#" };
private static string GetNoteText(EntityTypes.Note note, int currentSemitones)
{
int noteIndex = (note.sampleNote + currentSemitones) % 12;
if (noteIndex < 0)
{
noteIndex += 12;
}
int octaveOffset = (note.sampleNote + currentSemitones) / 12;
int octave = note.sampleOctave + octaveOffset;
if ((note.sampleNote + currentSemitones) % 12 < 0)
{
octave--;
}
return notes[noteIndex] + octave;
}
}

View File

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

View File

@ -14,8 +14,8 @@ namespace HeavenStudio.Editor
[Space(10)]
public Slider slider;
public TMP_InputField inputField;
private float _defaultValue;
protected float _defaultValue;
public override void SetProperties(string propertyName, object type, string caption)
{
@ -70,7 +70,7 @@ namespace HeavenStudio.Editor
}
);
break;
case EntityTypes.Float fl:
slider.minValue = fl.min;
slider.maxValue = fl.max;
@ -119,6 +119,8 @@ namespace HeavenStudio.Editor
);
break;
case EntityTypes.Note: break;
default:
throw new ArgumentOutOfRangeException(
nameof(type), type, "I don't know how to make a property of this type!"
@ -135,7 +137,7 @@ namespace HeavenStudio.Editor
{
switch (type)
{
case EntityTypes.Integer integer:
case EntityTypes.Integer or EntityTypes.Note:
slider.onValueChanged.AddListener(_ => UpdateCollapse((int)slider.value));
inputField.onEndEdit.AddListener(_ => UpdateCollapse((int)slider.value));
@ -143,19 +145,41 @@ namespace HeavenStudio.Editor
break;
case EntityTypes.Float fl:
case EntityTypes.Float:
slider.onValueChanged.AddListener(newVal => UpdateCollapse((float)Math.Round(newVal, 4)));
inputField.onEndEdit.AddListener(_ => UpdateCollapse(slider.value));
UpdateCollapse((float)Math.Round(slider.value, 4));
break;
default:
throw new ArgumentOutOfRangeException(
nameof(type), type, "I don't know how to make a property of this type!"
);
}
}
private static readonly string[] notes = {
"A", "A#", "B", "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#"
};
private static string GetNoteText(EntityTypes.Note note, int newSemitones)
{
int noteIndex = (note.sampleNote + newSemitones) % 12;
if (noteIndex < 0) {
noteIndex += 12;
}
int octaveOffset = (note.sampleNote + newSemitones) / 12;
int octave = note.sampleOctave + octaveOffset;
if ((note.sampleNote + newSemitones) % 12 < 0)
{
octave--;
}
return notes[noteIndex] + octave;
}
private void Update()
{