文章目录
- 单脚步声
- 多脚步声,跳跃落地音效
- 播放不同材质的多脚步声
- 完结
单脚步声
public AudioClip walkingSound;
public AudioClip runningSound;//移动音效
public void MoveSound()
{// 如果在地面上并且移动长度大于0.9if (isGround && moveDirection.sqrMagnitude > 0.9f){audioSource.clip = isRun ? runningSound : walkingSound;if (!audioSource.isPlaying) audioSource.Play();}else{if (audioSource.isPlaying) audioSource.Pause();}
}
多脚步声,跳跃落地音效
[SerializeField] private float m_StepInterval; // 脚步声间隔[SerializeField] private AudioClip[] m_FootstepSounds; // 脚步声音效数组
[SerializeField] private AudioClip m_JumpSound; // 跳跃声音效
[SerializeField] private AudioClip m_LandSound; // 落地声音效private void Update()
{if (!m_Jump){m_Jump = Input.GetButtonDown("Jump"); // 检测跳跃输入}ProgressStepCycle(speed); // 更新步行声音//判断角色是否落地,这个判断非常巧妙,假设角色起跳,m_PreviouslyGrounded和m_CharacterController.isGrounded肯定都是false,//执行到下一步时角色到达地上,m_CharacterController.isGrounded变为true,因为m_PreviouslyGrounded还未执行,所以还是false,及此时角色刚落地if (!m_PreviouslyGrounded && m_CharacterController.isGrounded){PlayLandingSound(); // 播放落地声音}if (m_CharacterController.isGrounded){if (m_Jump){PlayJumpSound(); // 播放跳跃声音}}m_PreviouslyGrounded = m_CharacterController.isGrounded;
}
private void PlayLandingSound()
{m_AudioSource.clip = m_LandSound; // 设置落地声音m_AudioSource.Play();//播放落地声音后延迟0.5s再播放脚步声m_NextStep = m_StepCycle + .5f;
}private void PlayJumpSound()
{m_AudioSource.clip = m_JumpSound; // 设置跳跃声音m_AudioSource.Play();
}private void ProgressStepCycle(float speed)
{//判断角色是否在移动。if (m_CharacterController.velocity.sqrMagnitude > 0 && (m_Input.x != 0 || m_Input.y != 0)){//如果角色在移动,根据角色当前的速度和行走/奔跑状态来更新步行声音循环计数器 m_StepCycle 的值。m_StepCycle += (m_CharacterController.velocity.magnitude + (speed * (m_IsWalking ? 1f : m_RunstepLenghten))) * Time.fixedDeltaTime;}//然后,检查是否到达了下一个播放脚步声音的时间点。如果没有到达,就直接返回if (!(m_StepCycle > m_NextStep)){return;}//如果到达了下一个播放脚步声音的时间点,就更新 m_NextStep 的值m_NextStep = m_StepCycle + m_StepInterval;PlayFootStepAudio(); // 播放脚步声音
}private void PlayFootStepAudio()
{if (!m_CharacterController.isGrounded){return;}int n = UnityEngine.Random.Range(1, m_FootstepSounds.Length);m_AudioSource.clip = m_FootstepSounds[n]; // 随机选择一个脚步声音m_AudioSource.PlayOneShot(m_AudioSource.clip);//播放过的脚步声放置第一位,避免连续播放相同的脚步声m_FootstepSounds[n] = m_FootstepSounds[0];m_FootstepSounds[0] = m_AudioSource.clip;
}
播放不同材质的多脚步声
using System.Collections.Generic;
using UnityEngine;public class FootStepSound : MonoBehaviour
{public RaycastHit hit; // 射线检测结果public GameObject RayGo; // 射线起点对象public AudioClip[] clipsMetal, clipsTree, clipsGrass, clipsDirt, clipsWater; // 不同类型表面的声音剪辑数组public float dist = 2; // 射线的长度private string tagProv; // 上一次射线检测到的地面标签private int go = 0; // 控制播放声音的变量,0表示重新播放,1表示继续播放public AudioSource AS; // 声音源组件public float PitchWalk, PitchRun; // 行走和奔跑时的音调// 创建一个列表用于存储之前选择过的音效索引private List<int> playedIndexes = new List<int>();void Update(){float horizontal = Input.GetAxisRaw("Horizontal");float vertical = Input.GetAxisRaw("Vertical");if (Input.GetKey(KeyCode.LeftShift) && Input.GetKey(KeyCode.W))AS.pitch = PitchRun; // 如果同时按下左Shift和W键,则设置为奔跑音调elseAS.pitch = PitchWalk; // 否则设置为行走音调if (horizontal != 0 || vertical != 0){if (Physics.Raycast(RayGo.transform.position, Vector3.down, out hit, dist)) // 向下发射射线检测地面{if (hit.collider){if (hit.collider.tag != tagProv) go = 0;tagProv = hit.collider.tag;switch (hit.collider.tag) // 根据地面的标签选择对应的声音类型{case "Metal":PlayRandomSound(clipsMetal); // 播放金属声音break;case "Tree":PlayRandomSound(clipsTree); // 播放树木声音break;case "Grass":PlayRandomSound(clipsGrass); // 播放草地声音break;case "Dirt":PlayRandomSound(clipsDirt); // 播放土地声音break;case "Water":PlayRandomSound(clipsWater); // 播放水声音break;default:StopSound(); // 停止播放声音break;}}}}else{StopSound(); // 停止播放声音}}// 从给定的声音剪辑数组中随机播放一个声音void PlayRandomSound(AudioClip[] clips){if (go == 0) // 如果需要重新设置音频剪辑{AS.clip = null;go = 1;}if (!AS.isPlaying) // 如果当前没有正在播放的声音{// AS.clip = clips[Random.Range(0, clips.Length)]; // 随机选择一个声音剪辑int randomIndex = GetUniqueRandomIndex(clips.Length); // 获取一个未播放过的随机索引AS.clip = clips[randomIndex]; // 根据索引选择一个声音剪辑AS.Play(); // 播放声音}}// 获取一个未播放过的随机索引int GetUniqueRandomIndex(int arrayLength){int randomIndex;do{randomIndex = Random.Range(0, arrayLength); // 生成一个随机索引} while (playedIndexes.Contains(randomIndex)); // 循环判断该索引是否已经播放过playedIndexes.Add(randomIndex); // 将新的索引添加到已播放列表中if (playedIndexes.Count >= arrayLength){playedIndexes.Clear(); // 如果已播放列表包含所有索引,则清空列表,重新开始播放}return randomIndex;}// 停止播放声音并重置go变量void StopSound(){AS.clip = null; // 清空音频剪辑AS.Stop(); // 停止播放声音go = 0; // 重置go变量}
}
解释:
go 的这个逻辑保证了只有在需要重新设置音频剪辑时才会执行,避免了声音的混叠和中断。如果去除这个逻辑,可能会导致声音播放不正常。
AS.pitch是用来控制音频的音调(pitch)的属性。音调指的是声音的高低,可以用数字表示,其中1.0表示原始音调,小于1.0表示降低音调,大于1.0表示提高音调。
通过改变音调,可以实现音频的加速或减速播放。较高的音调会使音频听起来更快,而较低的音调则会使音频听起来更慢。
大致参数配置
完结
赠人玫瑰,手有余香!如果文章内容对你有所帮助,请不要吝啬你的点赞评论和关注
,以便我第一时间收到反馈,你的每一次支持
都是我不断创作的最大动力。当然如果你发现了文章中存在错误
或者有更好的解决方法
,也欢迎评论私信告诉我哦!
好了,我是向宇
,https://xiangyu.blog.csdn.net
一位在小公司默默奋斗的开发者,出于兴趣爱好,最近开始自学unity,闲暇之余,边学习边记录分享,站在巨人的肩膀上,通过学习前辈们的经验总是会给我很多帮助和启发!php是工作,unity是生活!如果你遇到任何问题,也欢迎你评论私信找我, 虽然有些问题我也不一定会,但是我会查阅各方资料,争取给出最好的建议,希望可以帮助更多想学编程的人,共勉~