Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Raycast trigger multiple components at the same time

Discussion in 'Scripting' started by GladGoblinGames, Aug 20, 2016.

  1. GladGoblinGames

    GladGoblinGames

    Joined:
    Dec 14, 2011
    Posts:
    118
    Hi all,

    Ran into another problem today. So, to start with, I had a huge custom editor script, cluttered, looked messy, not easy to understand. So I went to try a different approach. I have an enum which basically states what type of horror event this object is. Door rotation, audio play, etc. On my object, I have two scripts of the same type (horrortrigger) with one being set to Audio in the enum, and the other set to door rotation. Problem is, only one of them triggers and the other is totally ignored.

    Code (CSharp):
    1.             if(hit.transform.gameObject.GetComponent<HorrorTrigger>() == true)
    2.             {
    3.                 if (hit.transform.gameObject.GetComponent<HorrorTrigger>().b_activated == false)
    4.                 {
    5.                     if(hit.transform.gameObject.GetComponent<HorrorTrigger>().m_horrorType == HorrorTrigger.horrorTypes.Audio)
    6.                     {
    7.                         hit.transform.gameObject.GetComponent<HorrorTrigger>().CallAudioHorrorEvent();
    8.                         hit.transform.gameObject.GetComponent<HorrorTrigger>().b_activated = true;
    9.                     }
    10.  
    11.                     if (hit.transform.gameObject.GetComponent<HorrorTrigger>().m_horrorType == HorrorTrigger.horrorTypes.DoorOpen)
    12.                     {
    13.                         StartCoroutine(hit.transform.gameObject.GetComponent<HorrorTrigger>().CreekOpenDoor());
    14.                         hit.transform.gameObject.GetComponent<HorrorTrigger>().b_activated = true;
    15.                     }
    16.                 }
    17.  
    18.             } else
    19.             {
    20.                 return;
    21.             }
    This piece of code is inside the Raycast check, to determine if the object being looked at has a HorrorTrigger component.

    So, essentially, how do i get two components of the same type to run but before different actions? Is there a way? Or should I carry on trying to write a really long editor? :)

    P.S. The b_activated boolean variable is to stop functions from running constantly (because the calls are being made inside of the update function)
     
  2. LeftyRighty

    LeftyRighty

    Joined:
    Nov 2, 2012
    Posts:
    5,148
    instead of using
    Code (csharp):
    1.  
    2. hit.transform.gameObject.GetComponent<HorrorTrigger>()
    3.  
    everytime, store a reference in a variable
    Code (csharp):
    1.  
    2. HorrorTrigger ht = hit.transform.gameObject.GetComponent<HorrorTrigger>();
    3.  
    then use the reference
    Code (csharp):
    1.  
    2. if(ht.b_activated == false) { //...
    3.  
     
  3. GladGoblinGames

    GladGoblinGames

    Joined:
    Dec 14, 2011
    Posts:
    118
    Hey, thanks for the reply but still no joy. Only one of the horror triggers is still being called :(

    I've posted an image to further explain what I need :)

     
  4. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    You can use your existing system by changing GetComponent to GetCompoments and then iterating through all the returned components.

    Or you can use ExecuteEvents, which does the same thing for you. ;)
     
  5. GladGoblinGames

    GladGoblinGames

    Joined:
    Dec 14, 2011
    Posts:
    118
    Oh, I've never heard of ExecuteEvents before. Will take a look into it :) thanks for the help! I'll let you know how it goes :D
     
  6. GladGoblinGames

    GladGoblinGames

    Joined:
    Dec 14, 2011
    Posts:
    118
    Code (CSharp):
    1.  
    2.             if(hit.transform.gameObject.GetComponent<HorrorTrigger>() == true)
    3.             {
    4.  
    5.                 HorrorTrigger[] ht = hit.transform.gameObject.GetComponents<HorrorTrigger>();
    6.  
    7.                 for(int i = 0; i < ht.Length; i++)
    8.                 {
    9.                     if (ht[i].b_activated == false)
    10.                     {
    11.                         if (ht[i].m_horrorType == HorrorTrigger.horrorTypes.Audio)
    12.                         {
    13.                             ht[i].CallAutioHorrorEvent();
    14.                             ht[i].b_activated = true;
    15.                         }
    16.  
    17.                         if (ht[i].m_horrorType == HorrorTrigger.horrorTypes.DoorOpen)
    18.                         {
    19.                             StartCoroutine(ht[i].CreekOpenDoor());
    20.                             ht[i].b_activated = true;
    21.                         }
    22.                     }
    23.                 }
    24.  
    25.  
    26.  
    27.             } else
    28.             {
    29.                 return;
    30.             }
    ... I can't believe it was that simple...well, now I know! thanks :D
     
  7. GladGoblinGames

    GladGoblinGames

    Joined:
    Dec 14, 2011
    Posts:
    118
    It was going so well...till the audio clips decided to stop running correctly....

    Basically, one clip after the other should play. But, they do not. You know what's strange? If i attach two horror event scripts to my door, and make them both of type 'Audio' I get no problems at all. Yet, when one horror trigger is 'Audio' and the other 'Door open' it messes up. Please ignore the comments, I've not got round to changing them xD My code is posted below...these are the functions I am calling. Again, if one object has two horror scripts and BOTH are set to type 'Audio' no problems. Yet, one object, two horror scripts, one of type Audio and the other Door Open, the Audio horror type works fine but the Door Open refuses to play at all. The if statement in 'CreakOpenDoor' does return true. So unity says its playing...but its not.

    Code (CSharp):
    1.     /*
    2.      *
    3.      * Summary: OnTriggerEnter is called to determine if the player has entered a Box Collider that is setup within the scene.
    4.      * This handles some of, if not the majority of the 'Jump Scare' events. Once the player has entered the OnTriggerEnter()
    5.      * it is imperitive that is destroyed afterwards to prevent the same event happening twice.
    6.      *
    7.      * Parameters: Collider other - The object that the horror trigger collides with to perform a certain action
    8.      *
    9.      * */
    10.     public IEnumerator CallAudioHorrorEvent()
    11.     {
    12.         yield return new WaitForSeconds(m_playMusicDelay);
    13.         // If this horror event requires a loop, Invoke the method.
    14.         if (m_requireAudioLoop) {
    15.                
    16.                // Call an invoke repeating, and only repeat when the clip has finished playing
    17.                InvokeRepeating("RequiredLoop", 0, m_audioClip.length);
    18.                Debug.Log("Message from HorrorTrigger on Gameobject " + this.gameObject.name + ": Repeating audio called");
    19.                        
    20.             } else {
    21.  
    22.                 // However, if we do not need a looped audio clip, simply play the audio once
    23.                 audioSource.PlayOneShot(m_audioClip);
    24.                 // Call the method to destroy the audio clip after it has finished playing
    25.                 StartCoroutine(DestroyAudioClip(m_audioClip.length));
    26.         }
    27.     }
    28.  
    29.     public IEnumerator CreekOpenDoor()
    30.     {
    31.  
    32.         yield return new WaitForSeconds(m_doorOpenDelay);
    33.         Debug.Log("Calling CreakDoor Open");
    34.         beginDoorRotation = true;
    35.         audioSource.clip = m_doorCreakAudio;
    36.        audioSource.Play();
    37.         if(audioSource.isPlaying && audioSource.clip.name == m_doorCreakAudio.name)
    38.         {
    39.             Debug.Break();
    40.         }
    41.         Debug.Log(m_doorCreakAudio.loadState);
    42.     }