Created
December 6, 2023 06:23
-
-
Save beardordie/4dc6f949299a917ce845a30edcfddce3 to your computer and use it in GitHub Desktop.
Using audiosamples/volume of AudioSource to simply animate a Jaw Transform. As seen here: https://youtu.be/5P_mWSFA4ow
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[SerializeField] private AudioSource _linkedAudioSource = null; | |
[SerializeField] private float _minRmsValue = 0.0001f; // minimum to consider "talking" | |
[SerializeField] private Renderer _rendererToCheckVisibility = null; | |
[SerializeField] private float _jawTalkSpeed = 0.12f; | |
private JawStates _jawState = JawStates.Default; | |
private float[] _samples = new float[512]; // For spectrum data | |
private float _rmsValue; // Root mean square, representing audio level | |
public enum JawStates | |
{ | |
Default, | |
Talking | |
} | |
void GetAudioData() | |
{ | |
_linkedAudioSource.GetSpectrumData(_samples, 0, FFTWindow.BlackmanHarris); | |
} | |
void CalculateRMS() | |
{ | |
float sum = 0; | |
for (int i = 0; i < _samples.Length; i++) | |
{ | |
sum += _samples[i] * _samples[i]; | |
} | |
decimal decimalValue = Math.Round((decimal)Mathf.Sqrt(sum / _samples.Length), 4); | |
_rmsValue = (float)decimalValue; | |
} | |
void Update() | |
{ | |
bool RmsIsLoudEnough() | |
{ | |
GetAudioData(); | |
CalculateRMS(); | |
return rmsValue >= minRmsValue; | |
} | |
if (Time.frameCount % 10 == 0) // only check once every 10 frames | |
{ | |
// this if condition is complex because we don't want to calculate things when not necessary. the most expensive calculation is last in the condition | |
if (_linkedAudioSource.clip != null && _linkedAudioSource.isPlaying && _rendererToCheckVisibility.isVisible && RmsIsLoudEnough()) | |
{ | |
if (_jawState != JawStates.Talking) | |
JawTalking(); | |
} | |
else | |
{ | |
if (_jawState != JawStates.Default) | |
JawShut(); | |
} | |
} | |
} | |
void JawTalking() | |
{ | |
jawState = JawStates.Talking; | |
// Insert your "jaw is now talking" animation/tweening logic here. I did a simple pingponging tween of the LocalRotation of the jaw transform. | |
} | |
void JawShut() | |
{ | |
jawState = JawStates.Default; | |
// Insert your "jaw shuts" animation/tween logic here. I did a simple one-time quick tween of the LocalRotation of the jaw transform to shut and stay shut. | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment