Search Unity

How to: find game object with tag in hierarchy and toggle mesh renderer

Discussion in 'Scripting' started by xkingjohnx, Jan 19, 2021.

  1. xkingjohnx

    xkingjohnx

    Joined:
    Feb 22, 2016
    Posts:
    67
    Hi guys,

    I hope someone could help me a bit..
    I am trying to find runtime instatiated prefabs (clones) of a Game Object with a specific tag and than using the Toggle to turn off (and back on) the mesh renderer for these objects..

    I thought to make a empty game object and than add a script to that and than mapping the Script on the UI Toggle (On Value Changed Boolean and setting the GameObject to SetActive... but I have been only able to deactivate the object with this:


    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class Testing: MonoBehaviour
    5. {
    6.     GameObject[] MyTagObject;
    7.  
    8.     void Start()
    9.     {
    10.         Ceiling = GameObject.FindGameObjectsWithTag("MyTag");
    11.  
    12.         foreach (GameObject r in MyTagObject)
    13.         {
    14.             r.GetComponent<MeshRenderer>().enabled = false;
    15.             r.GetComponent<Collider>().enabled = false;
    16.         }

    I would very much appreciate if anyone would know how to toggle the mesh renderer back on with the toggle..

    any ideas?
     
  2. csofranz

    csofranz

    Joined:
    Apr 29, 2017
    Posts:
    1,556
    Why don't you show us the code that you have to enable the mesh renderer so we can see what is going wrong, i.e. what is not working?

    Also, I notice that you are iterating MyTagObject, but are collecting into a variable called 'Ceiling'.
     
  3. xkingjohnx

    xkingjohnx

    Joined:
    Feb 22, 2016
    Posts:
    67
    Hi thanks for your fast reply!

    yes, good point.. I have changed the code afterwards...
    anway I tried a new script, but it still doesn´t work..

    Could you please take a look at this:

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.UI;
    3.  
    4. public class ToggleObjects : MonoBehaviour
    5. {
    6.     Toggle m_Toggle;
    7.     public Text m_Text;
    8.     GameObject[] Ceiling;
    9.  
    10.     void Start()
    11.     {
    12.         //Fetch the Toggle GameObject
    13.         m_Toggle = GetComponent<Toggle>();
    14.         //Add listener for when the state of the Toggle changes, to take action
    15.         m_Toggle.onValueChanged.AddListener(delegate {
    16.             ToggleValueChanged(m_Toggle);
    17.         });
    18.  
    19.      
    20.         {
    21.             m_Text.text = "First Value : " + m_Toggle.isOn;
    22.             Ceiling = GameObject.FindGameObjectsWithTag("Ceiling");
    23.             foreach (GameObject r in Ceiling)
    24.             {
    25.                 r.GetComponent<MeshRenderer>().enabled = false;
    26.                 r.GetComponent<Collider>().enabled = false;
    27.             }
    28.         }
    29.     }
    30.  
    31.    
    32.     void ToggleValueChanged(Toggle change)
    33.     {
    34.         {
    35.             m_Text.text = "New Value : " + m_Toggle.isOn;
    36.             Ceiling = GameObject.FindGameObjectsWithTag("Ceiling");
    37.             foreach (GameObject r in Ceiling)
    38.             {
    39.                 r.GetComponent<MeshRenderer>().enabled = true;
    40.                 r.GetComponent<Collider>().enabled = true;
    41.             }
    42.         }
    43.     }
    44. }
    any idea how to fix that?

    many thanks for your support so far!
     
  4. csofranz

    csofranz

    Joined:
    Apr 29, 2017
    Posts:
    1,556
    Can you be more specific what doesn't work where and when, i.e. what you expected to see, why you expected that, and what you got instead? I see no invocation to ToggleValueChanged

    A tip: instead of collecting the objects each time, why don't you collect them into your global 'Ceioling' once at start, and then simply iterate over Ceiling? perhaps write a small 'setEnable' method like this:

    Code (CSharp):
    1. public void setEnable(bool setTo) {
    2.     foreach (GameObject r in Ceiling)  {
    3.          r.GetComponent<MeshRenderer>().enabled = setTo;
    4.          r.GetComponent<Collider>().enabled = setTo;
    5.     }
    6. }
    and replace the two foreach loops in Start() and ToggleValueChanged() with an invocation to setEnable()

    Edit: I belatedly see the invocation via delegate. Can you verify it invokes?
     
  5. xkingjohnx

    xkingjohnx

    Joined:
    Feb 22, 2016
    Posts:
    67

    Hi,
    what I am trying to achieve is simply find runtime instatiated prefabs in the hierarchy with the tag "ceiling" and than using a UI toggle to turn off and on the mesh renderer ..

    maybe you have an even better solution to achieve that?
     
  6. csofranz

    csofranz

    Joined:
    Apr 29, 2017
    Posts:
    1,556
    What is not working, and how do you know it is not working?
     
  7. xkingjohnx

    xkingjohnx

    Joined:
    Feb 22, 2016
    Posts:
    67
    it´s not activating the mesh back on
     
  8. xkingjohnx

    xkingjohnx

    Joined:
    Feb 22, 2016
    Posts:
    67
    once the toggle is clicked, the mesh turns off, but it should be visible again, when the toggle is clicked again..
     
  9. csofranz

    csofranz

    Joined:
    Apr 29, 2017
    Posts:
    1,556
    Does the Ceiling array hold the game objects that you expected it to hold, and does your ToggleValueChanged method get invoked, and does your log list the correct values?
     
  10. csofranz

    csofranz

    Joined:
    Apr 29, 2017
    Posts:
    1,556
    Add some logging to get better info
    Code (CSharp):
    1. public void setEnable(bool setTo) {
    2.     foreach (GameObject r in Ceiling)  {
    3.          r.GetComponent<MeshRenderer>().enabled = setTo;
    4.          r.GetComponent<Collider>().enabled = setTo;
    5.          Debug.Log("Trying to set " + r.name + "'s mesh and collider to " + setTo);
    6.     }
    7. }
     
  11. csofranz

    csofranz

    Joined:
    Apr 29, 2017
    Posts:
    1,556
    Then check the log against what you expect to be set / reset
     
  12. xkingjohnx

    xkingjohnx

    Joined:
    Feb 22, 2016
    Posts:
    67
    Hm I added the logging, but I have no debug msg in the console..

    what has worked was this Script:

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. public class Testing: MonoBehaviour
    4. {
    5.     GameObject[] Ceiling;
    6.     void Start()
    7.     {
    8.         Ceiling= GameObject.FindGameObjectsWithTag("Ceiling");
    9.         foreach (GameObject r in Ceiling)
    10.         {
    11.             r.GetComponent<MeshRenderer>().enabled = false;
    12.             r.GetComponent<Collider>().enabled = false;
    13.         }
    14.     }
    15. }
    I have attached it to a game object and then mapped it to the Togle and set to active..
    But ofcourse it turns the mesh renderer only to not visible, as soon as the toggle is clicked, but I would need an additional function to show the MeshRenderer from a Clone Game Object in the hierarchy (once the toggle is clicked again)

    any idea how to achieve that?
     
  13. csofranz

    csofranz

    Joined:
    Apr 29, 2017
    Posts:
    1,556
    Doesn't this work?

    Code (CSharp):
    1. public void setEnable(bool setTo) {
    2.     foreach (GameObject r in Ceiling)  {
    3.          r.GetComponent<MeshRenderer>().enabled = setTo;
    4.          r.GetComponent<Collider>().enabled = setTo;
    5.          Debug.Log("Trying to set " + r.name + "'s mesh and collider to " + setTo);
    6.     }
    7. }
    Or do you have issues with getting invoked?