單腳步聲
public AudioClip walkingSound;
public AudioClip runningSound;
//移動(dòng)音效
public void MoveSound()
{
// 如果在地面上并且移動(dòng)長(zhǎng)度大于0.9
if (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; // 腳步聲音效數(shù)組
[SerializeField] private AudioClip m_JumpSound; // 跳躍聲音效
[SerializeField] private AudioClip m_LandSound; // 落地聲音效
private void Update()
{
if (!m_Jump)
{
m_Jump = Input.GetButtonDown("Jump"); // 檢測(cè)跳躍輸入
}
ProgressStepCycle(speed); // 更新步行聲音
//判斷角色是否落地,這個(gè)判斷非常巧妙,假設(shè)角色起跳,m_PreviouslyGrounded和m_CharacterController.isGrounded肯定都是false,
//執(zhí)行到下一步時(shí)角色到達(dá)地上,m_CharacterController.isGrounded變?yōu)閠rue,因?yàn)閙_PreviouslyGrounded還未執(zhí)行,所以還是false,及此時(shí)角色剛落地
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; // 設(shè)置落地聲音
m_AudioSource.Play();
//播放落地聲音后延遲0.5s再播放腳步聲
m_NextStep = m_StepCycle + .5f;
}
private void PlayJumpSound()
{
m_AudioSource.clip = m_JumpSound; // 設(shè)置跳躍聲音
m_AudioSource.Play();
}
private void ProgressStepCycle(float speed)
{
//判斷角色是否在移動(dòng)。
if (m_CharacterController.velocity.sqrMagnitude > 0 && (m_Input.x != 0 || m_Input.y != 0))
{
//如果角色在移動(dòng),根據(jù)角色當(dāng)前的速度和行走/奔跑狀態(tài)來(lái)更新步行聲音循環(huán)計(jì)數(shù)器 m_StepCycle 的值。
m_StepCycle += (m_CharacterController.velocity.magnitude + (speed * (m_IsWalking ? 1f : m_RunstepLenghten))) * Time.fixedDeltaTime;
}
//然后,檢查是否到達(dá)了下一個(gè)播放腳步聲音的時(shí)間點(diǎn)。如果沒(méi)有到達(dá),就直接返回
if (!(m_StepCycle > m_NextStep))
{
return;
}
//如果到達(dá)了下一個(gè)播放腳步聲音的時(shí)間點(diǎn),就更新 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]; // 隨機(jī)選擇一個(gè)腳步聲音
m_AudioSource.PlayOneShot(m_AudioSource.clip);
//播放過(guò)的腳步聲放置第一位,避免連續(xù)播放相同的腳步聲
m_FootstepSounds[n] = m_FootstepSounds[0];
m_FootstepSounds[0] = m_AudioSource.clip;
}
播放不同材質(zhì)的多腳步聲
獲取人物移動(dòng)狀態(tài)
public class PlayerState : Singleton<PlayerState>
{
[Header("判斷人物狀態(tài)")]
public bool isMove;//是否在移動(dòng)
public bool isWalking;//是否正在行走
public bool isRuning; //是否正在奔跑
public bool isCrouching; //是否正在下蹲
private void Update()
{
isMove = MovementScript.Instance.isGround && MovementScript.Instance.moveDirection.sqrMagnitude > 0;
isRuning = MovementScript.Instance.isRun && isMove;
isCrouching = MovementScript.Instance.isCrouching;
isWalking = !isRuning && !isCrouching && isMove;
}
}
腳步聲控制
using System.Collections.Generic;
using UnityEngine;
//腳步聲
public class FootStepSound : MonoBehaviour
{
public RaycastHit hit; // 射線檢測(cè)結(jié)果
public GameObject RayGo; // 射線起點(diǎn)對(duì)象
public AudioClip[] clipsMetal, clipsTree, clipsGrass, clipsDirt, clipsWater; // 不同類(lèi)型表面的聲音剪輯數(shù)組
public float dist = 2; // 射線的長(zhǎng)度
private string tagProv; // 上一次射線檢測(cè)到的地面標(biāo)簽
private int go = 0; // 控制播放聲音的變量,0表示重新播放,1表示繼續(xù)播放
public AudioSource AS; // 聲音源組件
//該屬性控制音頻的播放速度,1.0 表示正常速度,小于 1.0 表示慢速播放,大于 1.0 表示快速播放。
public float PitchRun, PitchWalk, PitchCrouch;
// 創(chuàng)建一個(gè)列表用于存儲(chǔ)之前選擇過(guò)的音效索引
private List<int> playedIndexes = new List<int>();
void Update()
{
if (PlayerState.Instance.isRuning)
AS.pitch = PitchRun; //則設(shè)置為奔跑音調(diào)
else if(PlayerState.Instance.isWalking){
AS.pitch = PitchWalk;
}else{
AS.pitch = PitchCrouch;
}
if (PlayerState.Instance.isMove)
{
if (Physics.Raycast(RayGo.transform.position, Vector3.down, out hit, dist)) // 向下發(fā)射射線檢測(cè)地面
{
if (hit.collider)
{
if (hit.collider.tag != tagProv) go = 0;
tagProv = hit.collider.tag;
switch (hit.collider.tag) // 根據(jù)地面的標(biāo)簽選擇對(duì)應(yīng)的聲音類(lèi)型
{
case "Metal":
PlayRandomSound(clipsMetal); // 播放金屬聲音
break;
case "Tree":
PlayRandomSound(clipsTree); // 播放樹(shù)木聲音
break;
case "Grass":
PlayRandomSound(clipsGrass); // 播放草地聲音
break;
case "Dirt":
PlayRandomSound(clipsDirt); // 播放土地聲音
break;
case "Water":
PlayRandomSound(clipsWater); // 播放水聲音
break;
default:
StopSound(); // 停止播放聲音
break;
}
}
}
}
else
{
StopSound(); // 停止播放聲音
}
}
// 從給定的聲音剪輯數(shù)組中隨機(jī)播放一個(gè)聲音
void PlayRandomSound(AudioClip[] clips)
{
if (AS.isPlaying)
{
// AS.Stop();
}
if (go == 0) // 如果需要重新設(shè)置音頻剪輯
{
AS.clip = null;
go = 1;
}
if (!AS.isPlaying) // 如果當(dāng)前沒(méi)有正在播放的聲音
{
// AS.clip = clips[Random.Range(0, clips.Length)]; // 隨機(jī)選擇一個(gè)聲音剪輯
int randomIndex = GetUniqueRandomIndex(clips.Length); // 獲取一個(gè)未播放過(guò)的隨機(jī)索引
AS.clip = clips[randomIndex]; // 根據(jù)索引選擇一個(gè)聲音剪輯
AS.Play(); // 播放聲音
}
}
// 獲取一個(gè)未播放過(guò)的隨機(jī)索引
int GetUniqueRandomIndex(int arrayLength)
{
int randomIndex;
do
{
randomIndex = Random.Range(0, arrayLength); // 生成一個(gè)隨機(jī)索引
} while (playedIndexes.Contains(randomIndex)); // 循環(huán)判斷該索引是否已經(jīng)播放過(guò)
playedIndexes.Add(randomIndex); // 將新的索引添加到已播放列表中
if (playedIndexes.Count >= arrayLength)
{
playedIndexes.Clear(); // 如果已播放列表包含所有索引,則清空列表,重新開(kāi)始播放
}
return randomIndex;
}
// 停止播放聲音并重置go變量
void StopSound()
{
AS.Stop(); // 停止播放聲音
go = 0; // 重置go變量
}
}
解釋?zhuān)?br> go 的這個(gè)邏輯保證了只有在需要重新設(shè)置音頻剪輯時(shí)才會(huì)執(zhí)行,避免了聲音的混疊和中斷。如果去除這個(gè)邏輯,可能會(huì)導(dǎo)致聲音播放不正常。
AS.pitch是用來(lái)控制音頻的音調(diào)(pitch)的屬性。該屬性控制音頻的播放速度,1.0 表示正常速度,小于 1.0 表示慢速播放,大于 1.0 表示快速播放。
通過(guò)改變音調(diào),可以實(shí)現(xiàn)音頻的加速或減速播放。較高的音調(diào)會(huì)使音頻聽(tīng)起來(lái)更快,而較低的音調(diào)則會(huì)使音頻聽(tīng)起來(lái)更慢。
大致參數(shù)配置
完結(jié)
贈(zèng)人玫瑰,手有余香!如果文章內(nèi)容對(duì)你有所幫助,請(qǐng)不要吝嗇你的點(diǎn)贊評(píng)論和關(guān)注
,以便我第一時(shí)間收到反饋,你的每一次支持
都是我不斷創(chuàng)作的最大動(dòng)力。當(dāng)然如果你發(fā)現(xiàn)了文章中存在錯(cuò)誤
或者有更好的解決方法
,也歡迎評(píng)論私信告訴我哦!
好了,我是向宇
,https://xiangyu.blog.csdn.net
一位在小公司默默奮斗的開(kāi)發(fā)者,出于興趣愛(ài)好,最近開(kāi)始自學(xué)unity,閑暇之余,邊學(xué)習(xí)邊記錄分享,站在巨人的肩膀上,通過(guò)學(xué)習(xí)前輩們的經(jīng)驗(yàn)總是會(huì)給我很多幫助和啟發(fā)!php是工作,unity是生活!如果你遇到任何問(wèn)題,也歡迎你評(píng)論私信找我, 雖然有些問(wèn)題我也不一定會(huì),但是我會(huì)查閱各方資料,爭(zhēng)取給出最好的建議,希望可以幫助更多想學(xué)編程的人,共勉~文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-814732.html
文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-814732.html
到了這里,關(guān)于【Unity小技巧】3D人物移動(dòng)腳步和跳躍下落音效控制的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!