解决问题:
- 3D角色动画需要很精确的在某个动作点时播放特定音效
- 3D角色在自定义的地形模型上行走时,根据地面材质的不同(如草地,石头,泥土等等),脚所发出的
音效也会随着替换
问题一思路:
1.对于第一个问题,利用动画事件,在关键动作处触发该事件去实现音效的播放
2.在脚本中去调用走和跑不同的Function函数(走:step 跑:steprun)
这里有个新问题:走和跑是混合树动画(下面解决它)
由于角色的动画是用了混合树,根据控制在走和跑之间切换的动作状态,在调用step和steprun两个函数时,需要对混合树的参数值movespeed进行判断,关键代码如下:
public void StepRun()
{
if (ani.GetFloat("Movespeed") >= 0.6)
{
moveSound.pitch = 1.5f;
moveSound.volume = 0.5f;
moveSound.Play();
}
}
public void Step()
{
if (ani.GetFloat("Movespeed") > 0.1 && ani.GetFloat("Movespeed") < 0.6)
{
moveSound.pitch = 0.8f;
moveSound.volume = 0.3f;
moveSound.Play();
}
}
问题二思路:
(注:地面非unity内置terrain,而是一个自定义的gameObect,IDMask也是自定义的)
关键代码:
texture= (Texture2D)material.GetTexture("_Mask");
2.根据主角的位置信息去对贴图进行采样,用采样的RGB通道值来作为判定条件识别是播放什么材质
的音效。
关键点在于地形的有个角一定是世界坐标原点,那么我们可以把地形的UV和地形的尺寸大小一一对应起来形成映射,角色在世界空间坐标系下位置代表对地形上某个点的采样,从而得到该位置的color值。
unity官方文档API链接------------ Texture2D.GetPixel
关键代码如下:
void Update()
{
x = -transform.position.x / 100*texture.width;
y = -transform.position.z / 100*texture.height;
color = texture.GetPixel((int)x, (int)y);
Debug.Log(color.r);
得到了color的RGB值后面就容易了,根据这个值来做限定,去调用不同情况下的音效文件,最好的方法是外面只添加一个Audio Source组件,AudioClip以数组的形式添加,示例代码如下:
public class FootSteps : MonoBehaviour
{
[SerializeField]
private AudioClip[] stoneClips;
[SerializeField]
private AudioClip[] mudClips;
[SerializeField]
private AudioClip[] grassClips;
private AudioSource audioSource;
private void Awake()
{
audioSource = GetComponent<AudioSource>();
}
private void Step()
{
AudioClip clip = stoneClips[1];
audioSource.PlayOneShot(clip);
PS:如果是用的unity自带的Terrain地形制作,想要制作脚步在不同地形材质上的不同音效方法可以参考这个YouTube视频教程,内附代码: