我的问题很简单,但是我很难找到答案。简要说明一下,我有一个根据麦克风输入沿Y轴移动的精灵。事先,我提示用户记录其最低和最高音符,计算这两个音符的频率,并将其用作将子画面在Y轴上定位的参考。
比方说,最低音符为100 Hz,最高音符为400 Hz。因此,如果播放器发出100 Hz的音调,则精灵应向下移动到Y轴的底部。要移回中心(Y位置0),播放器必须发出250 Hz的音调(介于100和400之间的中点)。
因此我们知道,对于该演奏者,250 Hz等于Y位置0。但是我需要知道最低音符(底部边缘)和最高音符(顶部边缘)的Y位置等效项。当我手动将精灵移动到顶部边缘并在检查器中查看Y值时,显然是4.58。但是我不确定硬编码4.58是否可以在不同屏幕尺寸的设备上很好地缩放。
此处的屏幕截图:https://i.ibb.co/pjrkSNV/Capture.png
理想情况下,我希望有一种称为FrequencyToY(浮动频率)的方法,该方法将频率值转换为轴上的相应Y值。我将最低和最高频率值保存在PlayerPrefs中。关于精灵运动的重要说明,我不要重力。每当玩家发出声音时,小鸟就应该平稳地移动到相应的Y位置,否则应留在原处。
这是我当前附加到我的精灵上的脚本:
public class Player : MonoBehaviour
{
public AudioSource audioPlayer;
public AudioMixer masterMixer;
private float[] _spectrum;
private float _fSample;
private Transform playerTransform;
void Start()
{
playerTransform = transform;
//Code for microphone loop
masterMixer.SetFloat("masterVolume", -80f);
_spectrum = new float[AudioAnalyzer.QSamples];
_fSample = AudioSettings.outputSampleRate;
audioPlayer.clip = Microphone.Start("", true, 10, 44100);
audioPlayer.loop = true;
while(!(Microphone.GetPosition("") > 0)) { }
audioPlayer.Play();
}
void Update()
{
//Calculate frequency of currently detected tones
audioPlayer.GetSpectrumData(_spectrum, 0, FFTWindow.BlackmanHarris);
float pitchVal = AudioAnalyzer.calculateFrequency(ref _spectrum, _fSample);
if(pitchVal != 0)
{
if (pitchVal < PlayerPrefs.GetFloat("lowestFrequency"))
pitchVal = PlayerPrefs.GetFloat("lowestFrequency");
else if (pitchVal < PlayerPrefs.GetFloat("highestFrequency"))
pitchVal = PlayerPrefs.GetFloat("highestFrequency");
//This is how I'd like to call the function
//But if someone could change this and make the sprite actually
//"move" to that point instead of just popping there it would be awesome!
transform.position = new Vector2(0, FrequencyToY(pitchVal));
}
}
//Converts frequency to position on Y-axis
public float FrequencyToY(float frequency)
{
float x = 0;
return x;
}
}
答案 0 :(得分:0)
您需要定义要使用的Y坐标的范围(例如0-> 100),然后相对于它们的比例尺缩放给出的音高(因此在其比例尺0-100上的百分比)然后将该%用作Y上的一个点。
因此,如果他们给您一个音符,恰好在音阶的中间(50%),并且您在游戏中的Y坐标范围为0-10,则您希望将其设置为5。