今日達成したこと:
足跡をたどるために、ScriptableObjectの原理を学びました。スクリプトサウンドリソースは、ScriptableObjectを使用してアプリケーションを保存します。キャラクターが地面に触れて移動しているときに、足音を鳴らします。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(menuName = "FPS/Footstep Audio Data")]
public class FootstepAudioData : ScriptableObject
{
public List<FootstepAudio> footstepAudios = new List<FootstepAudio>();
}
[System.Serializable]
public class FootstepAudio
{
// 用于标记踩在什么表面上
public string Tag;
// 声音片段列表
public List<AudioClip> AudioClips = new List<AudioClip>();
// 声音间隔
public float walkVoiceInterval;
//public float sprintingVoiceInterval;
//public float CrouchingVoiceInterval;
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerFootstepListener : MonoBehaviour
{
public FootstepAudioData footstepAudioData;
public AudioSource footstepAudioSource;
private CharacterController characterController;
private Transform footstepTransform;
private float timePassed = 0;
private FPCharacterControllerMovement movement;
// 角色移动或者发生较大幅度位移时 播放脚步声
// 根据角色踩踏的不同材质播放不同的声音
// 具体实现方式采用Physics API
private void Start()
{
characterController = GetComponent<CharacterController>();
footstepTransform = transform;
movement = GetComponent<FPCharacterControllerMovement>();
}
private void FixedUpdate()
{
// 角色处于地面
if(characterController.isGrounded)
{
// 角色正在移动
if(characterController.velocity.normalized.sqrMagnitude > 0.1f)
{
// 设置下一次播放的时间
timePassed += Time.deltaTime;
// 播放移动声音
if(Physics.Linecast(footstepTransform.position,
footstepTransform.position + Vector3.down * characterController.height,
out RaycastHit temp_hitInfo)) //检测当前踩踏在什么地面上
{
#if UNITY_EDITOR
Debug.Log(temp_hitInfo.collider.tag);
Debug.DrawRay(footstepTransform.position,
-footstepTransform.up * characterController.height, Color.red);
#endif
// 对于所有类型的脚步声
foreach (var temp_audioElement in footstepAudioData.footstepAudios)
{
// 找到匹配的类型
if (temp_hitInfo.collider.CompareTag(temp_audioElement.Tag))
{
// 用于保存实际要用的声音播放间隔
float temp_VoiceInterval = 0;
if (movement.m_isSprinting && movement.m_isCrouched) //是否在蹲下时冲刺
{
temp_VoiceInterval = temp_audioElement.walkVoiceInterval;
}
else if(movement.m_isCrouched) //是否蹲下
{
temp_VoiceInterval = temp_audioElement.walkVoiceInterval * 2;
}
else if (movement.m_isSprinting) //是否在冲刺
{
temp_VoiceInterval = temp_audioElement.walkVoiceInterval / 2;
}
else // 那就只是在走了
{
temp_VoiceInterval = temp_audioElement.walkVoiceInterval;
}
Debug.Log(temp_VoiceInterval);
// 如果到了下一次播放时间
if (timePassed >= temp_VoiceInterval)
{
// 获取这个类型脚步声的素材总数
int temp_audioCount = temp_audioElement.AudioClips.Count;
// 随机获取一个
int temp_audioIndex = UnityEngine.Random.Range(0, temp_audioCount);
// 获取到对应的声音片段
AudioClip temp_footstepAudioClip = temp_audioElement.AudioClips[temp_audioIndex];
// 播放音效
footstepAudioSource.clip = temp_footstepAudioClip;
footstepAudioSource.Play();
timePassed = 0;
// 找到了就行了 直接跳出循环
break;
}
}
}
}
}
}
}
}
FootstepAudioDataは、効果音リソースを格納するために使用されるScriptableObjectの生成を担当し、PlayerFootstepListenerは、キャラクターが配置されている地面を判断し、対応する効果音を見つけ、効果音をランダムに取得し、効果音を再生するために使用されます。効果音には、実際に聞こえる効果をほとんど達成できない再生間隔があります。また、さまざまなモーション状態がさまざまな効果音の再生間隔に対応していることも認識しています。
効果:移動時の足音とバグ
バグと欠陥:
地上のタグが不可解に検出できない場合があります。しかし、実際には、私の光線検出は間違っています。検出の終点は、原点が下がるのではなく、キャラクターが下がる点でなければなりません。上記のコードは正しくなるように修正されています。
しゃがむときの足音はありません。光線が地面を検出できないはずです。
最大の欠点は、この効果音は本当に醜いです、それを忘れて、関数を実装する方法を学ぶだけです。
注意する価値がある:
モバイルステータスを判断する方法は?以前の動き制御スクリプトを直接引用しました。スクリプトには、教師が行ったものとは異なる、動きの状態を表すブール値があります。