Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
1
Question by JohnnyFactor · Sep 10, 2018 at 06:22 PM · c#collisionaudio

Collision sounds doubling up.

I have a physics playground with a pile of poker chips and a sound plays when they collide.

The issue is, the sound is played for each gameObject so the collision sound plays twice and creates a terrible reverb-like effect. I have tried a random bool but sometimes no sound plays.

I can't think of any logic that would solve this problem.

 void OnCollisionEnter(Collision collision)
 {
     if (Time.timeSinceLevelLoad > 0.2f && gameObject.GetComponent<Rigidbody>().velocity.magnitude > 0.75f && transform.position.y < 5.0f)
     {
         bool altPlay = (Random.value > 0.5f);
         audioSource.clip = chipHit;
         audioSource.volume = (rBody.velocity.magnitude / 5) * audioSpeedModifier;
         audioSource.pitch = Random.Range (0.6f , 1.0f);
         
         if (altPlay == true)
         {
             audioSource.PlayOneShot(chipHit);
         }
     }
 }
Comment
Add comment · Show 2
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Nikola7007 · Sep 10, 2018 at 08:12 PM 0
Share

Perhaps you could have a static int representing the amount of frames since the last "collision sound" was played, and only play the sound if the static variable is above a certain threshold (say 5 frames).

Alternatively, assu$$anonymous$$g both collisions happen in the same frame, just have a static Bool indicating whether the sound was already played on that frame. The poker chip that first "notices" the collision will set the Bool to true, then play the sound. The other poker chip will avoid playing the sound, since the Bool is already true. Finally, the Bool can be reset to false on the next frame.

avatar image JohnnyFactor Nikola7007 · Sep 10, 2018 at 08:41 PM 0
Share

Thanks for the suggestions but I'm not sure it could work. Sometimes a chip will collide multiple times in the same frame, especially in the beginning when all the chips are dumped on the table. I can't filter by name or tag because each chip needs to produce a sound at some point.

1 Reply

· Add your reply
  • Sort: 
avatar image
1
Best Answer

Answer by trapazza · Sep 10, 2018 at 10:54 PM

Right from the top of my head:

  1. Remove the sound logic from the entity.

  2. Instead, write some kind of SoundManager where you'd have some method called "PlayCollisionSound(Collision a, Collision b)".

  3. When called, register all pairs of colliders and actually play a sound.

  4. Ignore collisions of already registered pairs of colliders during the current frame.

  5. Clear registered pairs at the beginning of the next frame.

Comment
Add comment · Show 4 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image JohnnyFactor · Sep 11, 2018 at 03:38 AM 0
Share

Edit: Updated. Removed dictionary and coroutine, based on trapazza Hashset code:

 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 
 public class Chip_Coll : $$anonymous$$onoBehaviour
 {
     void OnCollisionEnter(Collision collision)
     {
         if (Time.timeSinceLevelLoad > 0.2f && gameObject.GetComponent<Rigidbody>().velocity.magnitude > 0.75f && transform.position.y < 6.0f)
         {
             GameObject.Find("Sound$$anonymous$$anager").GetComponent<sound$$anonymous$$anagerScript>().PlayCollisionSound(GetComponent<Collider>(), collision.collider, GetComponent<Rigidbody>());
         }
     }
 }
 
 

..and the sound manager script.

 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 
 public class sound$$anonymous$$anagerScript : $$anonymous$$onoBehaviour
 {
     public AudioClip chipHit;
     private HashSet<Collider> _collisions = new HashSet<Collider>();
 
     public void Update()
     {
         _collisions.Clear();
     }
 
     public void PlayCollisionSound(Collider colla, Collider collb, Rigidbody rbody)
     {
         if (_collisions.Contains(colla) && _collisions.Contains(collb))
         {
             return;
         }    
 
         _collisions.Add(colla);
         _collisions.Add(collb);
 
         AudioSource audioSource = GetComponent<AudioSource>();
         audioSource.clip = chipHit;
         audioSource.volume = (rbody.velocity.magnitude / 5);
         audioSource.pitch = Random.Range (0.7f , 1.0f);
         audioSource.PlayOneShot(chipHit);
     }
 }


avatar image trapazza · Sep 11, 2018 at 12:58 PM 0
Share

I'm confused about needing a co-routine for this.

Every time OnCollisionEnter is called you're creating a coroutine that doesn't behave as such. It's called like a normal function since you're yielding on exit. Also on every call you're creating a local dictionary that will only contain a single element, so iterating through it makes no sense. I mean, you could get rid of the whole coroutine thing (no IEnumerable, no yield, no dictionary).

I'm very surprised it's working, but if it is I doubt it's because of the reason you think it is.

The idea is to keep track of all pairs of game objects that have collide during a frame. This could be a starting point. Note that I'm now using a HashSet ins$$anonymous$$d of a Dictionary.

  // untested code
  public class sound$$anonymous$$anagerScript : $$anonymous$$onoBehaviour
  {
      public AudioClip chipHit;
      private HashSet<Collider> _collisions = new HashSet<Collider>();

     public void Update()
     {
          _collisions.Clear();
     }

      public void PlayCollisionSound(Collider colla, Collider collb, Rigidbody rbody)
      {
          // have this pair of colliders already made a sound?
          if( _collisions.Exists(colla) && _collisions.Exists(collb) )
              return;

          // nop, register both colliders (one of them might have been registered already)
          _collisions.Add( colla );
          _collisions.Add( collb )

          // play a single sound
          AudioSource audioSource = GetComponent<AudioSource>();
  
          audioSource.clip = chipHit;
          audioSource.volume = (rbody.velocity.magnitude / 5);
          audioSource.pitch = Random.Range (0.7f , 1.0f);
          audioSource.PlayOneShot(chipHit);
      }
 }












avatar image JohnnyFactor trapazza · Sep 11, 2018 at 04:42 PM 0
Share

I have updated the code based on this and it seems to be working. A little more variation (like different hit sounds) and this should be good. Thanks for your help on this.

avatar image trapazza JohnnyFactor · Sep 12, 2018 at 04:07 PM 0
Share

Yes, you could add a lot of variation depending on what's colliding. Also, you'd probably want to change the condition and use '||' in place of '&&', to let a single chip to make a sound when colliding with several others.

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

572 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Distribute terrain in zones 3 Answers

Yet another Audio on Collision issue 1 Answer

Audio on Collision not working C# 0 Answers

Sound plays right at the beginning 2 Answers

Sounds triggering too fast 4 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges