Files
2026-03-04 10:03:45 +08:00

141 lines
4.0 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
namespace Artngame.SKYMASTER
{
[RequireComponent(typeof(CharacterController), typeof(AudioSource))]
public class FootstepSoundPlayerSM : MonoBehaviour
{
[Serializable]
private class TextureSound
{
public Texture Albedo;
public AudioClip[] Clips;
}
[SerializeField]
private LayerMask FloorLayer;
[SerializeField]
private TextureSound[] TextureSounds;
[SerializeField]
private bool BlendTerrainSounds;
private CharacterController Controller;
private AudioSource AudioSource;
private void Awake()
{
Controller = GetComponent<CharacterController>();
AudioSource = GetComponent<AudioSource>();
}
private void Start()
{
StartCoroutine(CheckGround());
}
private IEnumerator CheckGround()
{
while (true)
{
if (Controller.isGrounded && Controller.velocity != Vector3.zero && Physics.Raycast(base.transform.position - new Vector3(0f, 0.5f * Controller.height + 0.5f * Controller.radius, 0f), Vector3.down, out var hitInfo, 1f, FloorLayer))
{
Renderer component2;
if (hitInfo.collider.TryGetComponent<Terrain>(out var component))
{
yield return StartCoroutine(PlayFootstepSoundFromTerrain(component, hitInfo.point));
}
else if (hitInfo.collider.TryGetComponent<Renderer>(out component2))
{
yield return StartCoroutine(PlayFootstepSoundFromRenderer(component2));
}
}
yield return null;
}
}
private IEnumerator PlayFootstepSoundFromTerrain(Terrain Terrain, Vector3 HitPoint)
{
Vector3 vector = HitPoint - Terrain.transform.position;
Vector3 vector2 = new Vector3(vector.x / Terrain.terrainData.size.x, 0f, vector.z / Terrain.terrainData.size.z);
int x = Mathf.FloorToInt(vector2.x * (float)Terrain.terrainData.alphamapWidth);
int y = Mathf.FloorToInt(vector2.z * (float)Terrain.terrainData.alphamapHeight);
float[,,] alphamaps = Terrain.terrainData.GetAlphamaps(x, y, 1, 1);
if (!BlendTerrainSounds)
{
int num = 0;
for (int i = 1; i < alphamaps.Length; i++)
{
if (alphamaps[0, 0, i] > alphamaps[0, 0, num])
{
num = i;
}
}
TextureSound[] textureSounds = TextureSounds;
foreach (TextureSound textureSound in textureSounds)
{
if (textureSound.Albedo == Terrain.terrainData.terrainLayers[num].diffuseTexture)
{
AudioClip clipFromTextureSound = GetClipFromTextureSound(textureSound);
AudioSource.PlayOneShot(clipFromTextureSound);
yield return new WaitForSeconds(clipFromTextureSound.length);
break;
}
}
yield break;
}
List<AudioClip> list = new List<AudioClip>();
int num2 = 0;
for (int k = 0; k < alphamaps.Length; k++)
{
if (!(alphamaps[0, 0, k] > 0f))
{
continue;
}
TextureSound[] textureSounds = TextureSounds;
foreach (TextureSound textureSound2 in textureSounds)
{
if (textureSound2.Albedo == Terrain.terrainData.terrainLayers[k].diffuseTexture)
{
AudioClip clipFromTextureSound2 = GetClipFromTextureSound(textureSound2);
AudioSource.PlayOneShot(clipFromTextureSound2, alphamaps[0, 0, k]);
list.Add(clipFromTextureSound2);
num2++;
break;
}
}
}
float seconds = list.Max((AudioClip clip) => clip.length);
yield return new WaitForSeconds(seconds);
}
private IEnumerator PlayFootstepSoundFromRenderer(Renderer Renderer)
{
TextureSound[] textureSounds = TextureSounds;
foreach (TextureSound textureSound in textureSounds)
{
if (textureSound.Albedo == Renderer.material.GetTexture("_MainTex"))
{
AudioClip clipFromTextureSound = GetClipFromTextureSound(textureSound);
AudioSource.PlayOneShot(clipFromTextureSound);
yield return new WaitForSeconds(clipFromTextureSound.length);
break;
}
}
}
private AudioClip GetClipFromTextureSound(TextureSound TextureSound)
{
int num = UnityEngine.Random.Range(0, TextureSound.Clips.Length);
return TextureSound.Clips[num];
}
}
}