因此,汽车发动机声音(数组)的数量是可变的。我想让声音从一个到另一个平滑地流动,具体取决于引擎 RPM(从 0 到 1 的数字,其中 0 = 0 RPM,1 = 例如 7000),就像 FMOD 程序那样。
我已经写好了脚本的基础,但是我在转换的计算上停滞不前。我希望有人能给我神奇的公式......
我附上了图片和我的代码以便更好地理解。
public class Car_Audio : MonoBehaviour
{
private CarController carController;
[SerializeField] private AudioClip[] engineRPMSoundClips;
[SerializeField, Range(0.35f, 0.75f)] private float minEngineVolume = 0.65f;
[SerializeField, Range(0.75f, 1)] private float maxEngineVolume = 1;
[HideInInspector] public List<AudioSource> engineRPMSoundSources;
private float acceleration;
private float verticalInput;
private float currRPM;
private float maxRPM;
private int currGear;
private bool isGearShifting;
private bool isBraking;
private void Start()
{
carController = FindObjectOfType<CarController>();
maxRPM = carController.maxRPM;
for (int i = 0; i < engineRPMSoundClips.Length; i++)
{
AudioSource tempSource = EngineAudioSourceSetUp(engineRPMSoundClips[i]);
engineRPMSoundSources.Add(tempSource);
}
}
private void FixedUpdate()
{
verticalInput = carController.verticalInput;
currRPM = carController.currRPM;
currGear = carController.currGear;
isGearShifting = carController.isGearShifting;
isBraking = carController.isBraking;
if (verticalInput != 0 && !isGearShifting && !isBraking) acceleration = Mathf.Abs(Mathf.Clamp(verticalInput, minEngineVolume, maxEngineVolume));
else acceleration = Mathf.Lerp(acceleration, minEngineVolume / 2, 0.1f);
float currEngineRPMPosition = Mathf.Clamp(currRPM / maxRPM, 0, 1);
foreach (AudioSource audSrc in engineRPMSoundSources)
{
audSrc.volume = ...
}
}
private AudioSource EngineAudioSourceSetUp(AudioClip clip)
{
AudioSource source = gameObject.AddComponent<AudioSource>();
source.clip = clip;
source.volume = 0;
source.spatialBlend = 1;
source.loop = true;
source.dopplerLevel = 0;
source.time = Random.Range(0f, clip.length);
source.minDistance = 50;
source.maxDistance = 250;
source.Play();
return source;
}
}
在我看来,这就像一个计算带有偏移量的百分比的问题。我发现处理这个问题最简单的方法就是说:
var t = (value - min) / (max - min);
t值是百分比。然而它是松开的,所以你必须事后处理。
如果您存储了每个剪辑的最小和最大 RPM 值,您可以根据给定的 RPM 轻松计算出剪辑的当前 t 值。
这个类看起来是这样的:
private class RPMClip
{
public float min, max;
public AudioClip clip;
public RPMClip(AudioClip clip, float min, float max)
{
this.clip = clip;
this.min = min;
this.max = max;
}
public float GetValue(float rpm)
{
if (max == min) return 0;
var t = (rpm - min) / (max - min);
return Mathf.Clamp01(t);
}
}
使用 GetValue 方法,您可以为其提供当前 RPM,它会根据其最小值和最大值为您提供 0 到 1 之间的值。
例如,如果您给它最小值 50,最大值 150,那么
GetValue(100)
将为您提供 0.5
然后您可以将此值应用于定义其应具有多少体积的曲线。