The script has a method that reloads the canvas. In Canvas-e itself, there is a Button object to which the reload method is programmatically attached.

using UnityEngine; using UnityEngine.UI; public class Trashscript : MonoBehaviour { public GameObject Temp; private GameObject Active; int Counter; void Start() { Menu(); } void Menu() { Counter++; if (Active != null) Destroy(Active); Active = Instantiate(Temp); GameObject.Find("Text").GetComponent<Text>().text = Counter.ToString(); GameObject.Find("Btn").GetComponent<Button>().onClick.AddListener(Menu); } } 

When loading in the "Text" object appears "1". After clicking on the "Btn" Canvas restarts, but without the text in the "Text", and "Btn" does not work on it (when pressed, nothing else happens.

Already the 3rd day I can not understand what the problem is.

  • In general, it should work ..... but ...... does it give any errors? - Alexey Shimansky
  • That's the joke, that there are no mistakes ... - Tomas

1 answer 1

Try putting the button into a separate variable. Initialize it at startup. And there to add a listener.

And when the object is destroyed, do not forget the listener to remove RemoveListener

 using UnityEngine; using System.Collections; using UnityEngine.UI; public class Trashscript : MonoBehaviour { public GameObject Temp; private GameObject Active; int Counter; private Button myselfButton; void Start() { myselfButton = GameObject.Find("Btn").GetComponent<Button>(); myselfButton.onClick.AddListener(Menu); Menu(); } void Menu() { Counter++; if (Active != null) Destroy(Active); Active = Instantiate(Temp); GameObject.Find("Text").GetComponent<Text>().text = Counter.ToString(); } void Destroy() { myselfButton.onClick.RemoveListener(Menu); } } 

UPD

If initially there are no Canvas on the scene and if the GameObject Temp is just the same as the canvas prefab is instantiated and instantiated into Active , then the error is trivial: instead of searching on the GameObject.Find(.... scene GameObject.Find(.... just apply the actions to the instantiated an object that lies in a variable, i.e.

 Active.GetComponentInChildren..... 

In general, the code will be as follows:

 public GameObject Temp; private GameObject Active; int Counter; void Start() { Menu(); } void Menu() { Counter++; if (Active != null) { Destroy(Active); Active = null; } Active = Instantiate(Temp); Active.GetComponentInChildren<Text>().text = Counter.ToString(); Active.GetComponentInChildren<Button>().onClick.AddListener(this.Menu); } 

By the way, I also added Active = null; because with Destroy(Active); the object will be destroyed from the scene, but it will still remain in the Active field.

Comment!

If the generated canvas has a lot of buttons, and not one, then there is another option:

If the layout of the buttons does not change, you can use GetChild (index) to get a specific item. Something like

 Active.transform.GetChild(1).GetComponent<Button>().onClick.AddListener(Menu); 

either specify specific names for these specific buttons and simply find via the Find directly the Active object. I.e:

 Active.transform.Find("MyButtonName").GetComponent<Button>().onClick.AddListene‌​r(Menu); 
  • Initially, I have no Canvas on stage, I tried to move the first 2 lines from Start after Instantiate, but the result remains the same. - Tomas
  • Then you should show all the code. that is, what creates the canvas, where, if there is work there and how much. Plus, is there something else in this class and a more detailed description .... for some things taken out of context will not give anything - Alexey Shimansky
  • There is not a single script on the canvas, all that is friends with the code is this script. And the script hangs on an empty GameObject. In addition, there is a camera and an EventHandler in the scene. - Tomas
  • You don’t say something ......... If initially there are no Canvas on the stage, as you say, if you are in GameObject Temp; instantiated just the canvas , then your GameObject.Find("Text") type construction should no longer work in principle ..... because the GameObject.Find("Canvas(Clone)/Text") and GameObject.Find("/Canvas(Clone)/Btn") should be searched for at least GameObject.Find("/Canvas(Clone)/Btn") ..... and if this is really a canvas, then of course you destroy it if (Active == null) Destroy(Active); and then re-created .... already with plain text .................... what is the main idea of ​​what you are doing? - Alexey Shimanskyj
  • Thanks for the thought of the search, perhaps the reason for it, although the replacement ("Text") with (Active.name + "/ Text") did not give the desired result. The thought of my actions is changing the language using the button in the main menu. In the menu script, the text is generated from a separate class, when the button is pressed, the class reboots, but the canvas reboots, as you said "with empty text" ... - Tomas