#57 - Character footstep sound based on terrain texture
Date: 2019-04-20 12:00 - c#
Simple class for Unity that gets the texture behind the character's position and plays the appropriate footstep sound.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class FootstepAudio : MonoBehaviour {
public AudioSource footstepSource;
public void PlayFootstep() {
AudioClip clip = SoundManager.Instance.defaultFootstep;
RaycastHit hitInfo;
if (Physics.Raycast(transform.position, Physics.gravity, out hitInfo, 0.4f)) {
Terrain terrain = hitInfo.transform.GetComponent<Terrain>();
if (terrain != null) {
int textureIndex = terrain.GetMainTextureIndex(transform.position);
SoundManager soundManager = SoundManager.Instance;
if (textureIndex < soundManager.textureFootsteps.Count) {
clip = soundManager.textureFootsteps[textureIndex];
}
}
}
footstepSource.clip = clip;
footstepSource.volume = 0.7f;
footstepSource.pitch = Random.Range(0.9f, 1.2f);
footstepSource.Play();
}
void FootR() {
PlayFootstep();
}
void FootL() {
PlayFootstep();
}
}
// Extension class to extend Terrain
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
static public class MethodExtensionForTerrain {
static public float[] GetTextureMix(this Terrain terrain, Vector3 worldPosition) {
Vector3 terrainPosition = terrain.transform.position;
Vector3 terrainSize = terrain.terrainData.size;
float mapX = ((worldPosition.x - terrainPosition.x) / terrainSize.x) * terrain.terrainData.alphamapWidth;
float mapZ = ((worldPosition.z - terrainPosition.z) / terrainSize.z) * terrain.terrainData.alphamapHeight;
float[,,] splatmapData = terrain.terrainData.GetAlphamaps((int) mapX, (int) mapZ, 1, 1);
float[] cellMix = new float[splatmapData.GetUpperBound(2) + 1];
for (int i = 0; i < cellMix.Length; i++) {
cellMix[i] = splatmapData[0, 0, i];
}
return cellMix;
}
static public int GetMainTextureIndex(this Terrain terrain, Vector3 worldPosition) {
float[] mix = terrain.GetTextureMix(worldPosition);
float maxMix = 0.0f;
int maxIndex = 0;
for (int i = 0; i < mix.Length; i++) {
if (mix[i] > maxMix) {
maxIndex = i;
maxMix = mix[i];
}
}
return maxIndex;
}
}
// This is the singleton that contains the actual sounds... you can add the list to the other class if you wish
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SoundManager : Singleton<SoundManager> {
public AudioClip defaultFootstep;
public List<AudioClip> textureFootsteps;
}