- Home /
Play sound on collision, how do I avoid having the sound play every frame when a player character pushes the object into a corner?
I'm using the following code to play sound on collision:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Crate : MonoBehaviour {
Rigidbody rb;
AudioSource audioSource;
float timer;
void Start() {
rb = GetComponent<Rigidbody>();
audioSource = GetComponent<AudioSource>();
}
void OnCollisionEnter(Collision col) {
ImpactSound(col);
}
void OnCollisionStay(Collision col) {
ImpactSound(col);
}
void ImpactSound(Collision col) {
float volume = (col.impulse / Time.fixedDeltaTime).magnitude / 2000f;
volume = Mathf.Min(1f, volume);
if (volume > 0.05f && timer <= Time.time) {
audioSource.PlayOneShot(audioSource.clip, volume);
timer = Time.time + 0.2f;
}
}
}
Without the timer, when I push the Crate into a wall, I end up with the sound playing every frame, which sounds broken, of course.
I don't know how to distinguish between collisions that are based on actual motion and those based on the ones being caused by the crate being squeezed between the player and wall.
How can I avoid this without the timer?
Answer by ElijahShadbolt · Nov 28, 2016 at 12:35 AM
In the OnCollisionStay method, the call to ImpactSound happens for (almost) every frame that any collider is touching this collider. I would remove it from OnCollisionStay, so that it only happens in OnCollisionEnter, when the other collider first touches the crate.
reason i do it in OnColliderStay is that i want sounds when the crate falls over or rolls on the other collider without losing contact.
You could have a separate rolling sound for that, where you start it in OnCollisionEnter and have it continue playing on loop until OnCollisionExit.
Your answer
Follow this Question
Related Questions
How to get sound to play on barrel Explosion 1 Answer
Dice roll collision sound 1 Answer
Making a sound using collisions 1 Answer
Collide sound 2 Answers
Sound play on collision 3 Answers