mirror of
https://github.com/RHeavenStudio/HeavenStudio.git
synced 2025-06-12 11:17:39 +02:00
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:

committed by
minenice55

parent
194b4b6e04
commit
35b1120d01
@ -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 },
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3d8108e287994e145a3ca0b3d19e40c8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -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()
|
||||
{
|
||||
|
Reference in New Issue
Block a user