Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

How to destroy other game object?

Discussion in 'Scripting' started by Hotpots, Apr 17, 2015.

  1. Hotpots

    Hotpots

    Joined:
    Apr 9, 2015
    Posts:
    143
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class CoinPickup : MonoBehaviour
    5. {
    6.     public int coinValue = 1;
    7.  
    8.     GameObject gem;
    9.     public AudioClip impact;
    10.  
    11.     void Start () {
    12.         gem = GameObject.FindGameObjectWithTag ("Gem");
    13.     }
    14.  
    15.     void OnTriggerEnter (Collider other)
    16.     {
    17.         if(other.gameObject == gem)
    18.         {
    19.             ScoreManager.score += coinValue;
    20.             GetComponent<AudioSource>().PlayOneShot(impact, 0.7F);
    21.             Destroy(gameObject);
    22.             // Play the collect sound effect.
    23.         }
    24.     }
    25. }
    This will be attached to the player, and will be used to collect collectables.

    How would I get it to destroy the object it's colliding with rather than itself?

    Destroy(gameObject);

    Destroy(other.gameObject); ?
     
  2. Hotpots

    Hotpots

    Joined:
    Apr 9, 2015
    Posts:
    143
    I have now decided to use Destroy(other.gameObject); and it destroys the gem but... only 1 gem :(
     
  3. Hotpots

    Hotpots

    Joined:
    Apr 9, 2015
    Posts:
    143
    I just tried this and it destroys as many gems as I wanted but only played the sound for 1 of them

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class CoinPickup : MonoBehaviour
    5. {
    6.     public int coinValue = 1;
    7.  
    8.     GameObject player;
    9.     public AudioClip impact;
    10.  
    11.     void Start () {
    12.         player = GameObject.FindGameObjectWithTag ("Player");
    13.     }
    14.  
    15.     void OnTriggerEnter (Collider other)
    16.     {
    17.         // If the entering collider is the player...
    18.         if(other.gameObject == player)
    19.         {
    20.             ScoreManager.score += coinValue;
    21.             GetComponent<AudioSource>().PlayOneShot(impact, 0.7F);
    22.             Destroy(gameObject, 0.5f);
    23.             // Play the collect sound effect.
    24.         }
    25.     }
    26. }
     
    Last edited: Apr 17, 2015
  4. KelsoMRK

    KelsoMRK

    Joined:
    Jul 18, 2010
    Posts:
    5,539
    You're destroying the thing that is playing the sound.
     
    jtsmith1287 likes this.
  5. Hotpots

    Hotpots

    Joined:
    Apr 9, 2015
    Posts:
    143
    Im using
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class GemPickup : MonoBehaviour
    5. {
    6.     public int coinValue = 1;
    7.  
    8.     public GameObject gem;
    9.     public AudioClip impact;
    10.  
    11.     void Start () {
    12.         gem = GameObject.FindGameObjectWithTag ("Gem");
    13.     }
    14.  
    15.     void OnTriggerEnter (Collider other)
    16.     {
    17.         // If the entering collider is the player...
    18.         if(other.gameObject == gem)
    19.         {
    20.             ScoreManager.score += coinValue;
    21.             GetComponent<AudioSource>().PlayOneShot(impact, 0.7F);
    22.             Destroy(other.gameObject);
    23.         }
    24.     }
    25. }
    It plays the sound once and destroys the object once, how do I make collectables then coz im totally stuck :(

    Attached to the player
     
  6. Hotpots

    Hotpots

    Joined:
    Apr 9, 2015
    Posts:
    143
    If I also use this code and attach the audio source elsewhere I get

    MissingComponentException: There is no 'AudioSource' attached to the "gem 2" game object, but a script is trying to access it.
    You probably need to add a AudioSource to the game object "gem 2". Or your script needs to check if the component is attached before using it.
    CoinPickup.OnTriggerEnter (UnityEngine.Collider other) (at Assets/RoboCroc Scripts/CoinPickup.cs:22)

    but of course I cannot attach it as I'm destroying it, so what's a solution?


    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class CoinPickup : MonoBehaviour
    5. {
    6.     public int coinValue = 1;
    7.  
    8.     GameObject player;
    9.     public AudioClip impact;
    10.  
    11.     void Start () {
    12.         player = GameObject.FindGameObjectWithTag ("Player");
    13.     }
    14.  
    15.     void OnTriggerEnter (Collider other)
    16.     {
    17.         // If the entering collider is the player...
    18.         if(other.gameObject == player)
    19.         {
    20.             ScoreManager.score += coinValue;
    21.             Destroy(gameObject);
    22.             GetComponent<AudioSource>().PlayOneShot(impact, 0.7F);
    23.             // Play the collect sound effect.
    24.         }
    25.     }
    26. }
     
  7. KelsoMRK

    KelsoMRK

    Joined:
    Jul 18, 2010
    Posts:
    5,539
    Put an audio source on the player and do player.GetComponent<AudioSource>()
     
  8. Hotpots

    Hotpots

    Joined:
    Apr 9, 2015
    Posts:
    143
    I've now tried using 2 scripts:

    Attached to player:

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class GemPickup : MonoBehaviour
    5. {
    6.  
    7.     GameObject gem;
    8.     public AudioClip impact;
    9.  
    10.     void Start () {
    11.     gem = GameObject.FindGameObjectWithTag ("Gem");
    12.     }
    13.  
    14.     void OnTriggerEnter (Collider other)
    15.     {
    16.         // If the entering collider is the player...
    17.         if(other.gameObject == gem)
    18.         {
    19.             GetComponent<AudioSource>().PlayOneShot(impact, 0.7F);
    20.         }
    21.     }
    22. }
    Attached to collectable:

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class CoinPickup : MonoBehaviour
    5. {
    6.     public int coinValue = 1;
    7.  
    8.     GameObject player;
    9.  
    10.     void Start () {
    11.         player = GameObject.FindGameObjectWithTag ("Player");
    12.     }
    13.  
    14.     void OnTriggerEnter (Collider other)
    15.     {
    16.         // If the entering collider is the player...
    17.         if(other.gameObject == player)
    18.         {
    19.             ScoreManager.score += coinValue;
    20.             Destroy(gameObject);
    21.             //GetComponent<AudioSource>().PlayOneShot(impact, 0.7F);
    22.             // Play the collect sound effect.
    23.         }
    24.     }
    25. }
    Audio source is on the player, destroys all the gems I want but STILL wont play sound.


    EDIT: Just seen your reply Kelso, trying it now
     
  9. KelsoMRK

    KelsoMRK

    Joined:
    Jul 18, 2010
    Posts:
    5,539
    You didn't do what I suggested. I meant to call PlayOneShot on player from CoinPickup.
     
  10. jtsmith1287

    jtsmith1287

    Joined:
    Aug 3, 2014
    Posts:
    787
    Why not just use object pooling? Don't destroy anything. Just set it as inactive and keep a list of each type (gems and coins) and when you would normally instantiate a new one you'd instead grab an inactive one from the list, put it where you want it and set it to active again. You're doing all this work to keep from deleting the object that is "hosting" the audio... so don't delete it. That's my 2 cents.
     
    xPitaChipsx likes this.
  11. Hotpots

    Hotpots

    Joined:
    Apr 9, 2015
    Posts:
    143
    I think I got it working Kelso, will fully test it soon, thank you very much! :)

    Didn't know you could specify which object you want to play the sound from :D
     
  12. KelsoMRK

    KelsoMRK

    Joined:
    Jul 18, 2010
    Posts:
    5,539
    If you're not reusing them then there's no point in pooling them and I would imagine in the case of coin collection - you're probably not reusing them.
     
  13. jtsmith1287

    jtsmith1287

    Joined:
    Aug 3, 2014
    Posts:
    787
    Most games that are similar to what this sounds like *do* reuse them. But ya if he's not reusing them then pooling is 100% pointless.
     
  14. KelsoMRK

    KelsoMRK

    Joined:
    Jul 18, 2010
    Posts:
    5,539
    I'm not sure what you're basing that on since "collectibles" could mean anything. I took it as items placed by a level designer.

    In either case - it's out of scope for this discussion and object pooling seems like an unnecessary level of complexity and wouldn't directly solve the problem being put forth (disabling would still leave a lot of potential for audio-related bugs).
     
  15. jtsmith1287

    jtsmith1287

    Joined:
    Aug 3, 2014
    Posts:
    787
    It wasn't intended to be out of scope. I didn't think there'd be an issue with playing a one shot and setting an object to inactive. All that does is disable update calls on scripts. I guess I don't know how the audio source plays (can't imagine it's with Update :p ) If the issue is that the audio source is being destroyed then pooling is a direct fix to the issue. So I really don't see how it's out of scope here. That and it's not at all complex. I could argue that dealing with destroying and instantiating objects correctly can be equally complex. Anyway, I understand what you're saying but I think that if objects are in fact being re-used pooling is going to solve this issue.
     
  16. KelsoMRK

    KelsoMRK

    Joined:
    Jul 18, 2010
    Posts:
    5,539
    Clips running via Play() will mute if you make the GameObject inactive. I wouldn't be surprised if the behavior with PlayOneShot() is consistent. So it might not solve the problem. In either case it's certainly not related to Update because audio runs in its own thread.

    That and I still don't see how just having the Player object play the sounds isn't the easier solution. It's literally as simple as adding an AudioSource to the player and prepending the GetComponent call with player.GetComponent. And then each coin thing doesn't need to have an AudioSource attached to it.

    I'll change my mind when OP comes back and says "it works but my game runs like crap because I actually have 100 coins explode out of an enemy whenever it dies". :)
     
    jtsmith1287 likes this.
  17. Hotpots

    Hotpots

    Joined:
    Apr 9, 2015
    Posts:
    143
    It works perfectly for my game Kelso, I may have breakable crates in the game that spawn multiple gems, not just yet though. So thank you very much :)
     
  18. jtsmith1287

    jtsmith1287

    Joined:
    Aug 3, 2014
    Posts:
    787
    *pokes head in* You'll want to use object pooling eventually *runs away*