Jump to content
Unity Insider Forum

Canvas schließt nicht mehr


Recommended Posts

Ich fühle mich gerade wieder zurück an den Anfang meiner Programmierfähigkeiten zurück geworfen und weiß nicht mehr woran es liegen könnte. Aber UIs sind echt nicht meine Stärke...

Ich habe hier ein Canvas, was über zwei verschiedene Buttons abgeschaltet werden können soll. Es gibt einen einfach "Zurück" button, der das letzte geöffnete Menü schließen soll. Funktioniert auch so, wie es sol.
Dann habe ich in meinem Spiel die möglichkeit Gebäude auf Bauplätze zu bauen und Gebäude auszuwählen... egal

Eins dieser Gebäude soll (unter anderem) das Menü ebenfalls schließen und ruft im zuge dessen DIE SELBE METHODE auf. Also die Back() Methode. In diesem Fall geht es nicht.

Die Back Methode schließt kein Variables Canvas oder ähnliches. Es ist immer das selbe Canvas was diese schließt (Weil ich keine Menütiefe mit 5018 untermenüs habe)

Damit ich weiß, dass auch beide Funktionieren habe ich mir ein Debu.Log rein gesetzt. Beide rufen auch die Methode auf. Nur über die eine Seite wird das Canvas nicht geschlossen.

Der Unterschied (und der wird eben diesen machen denke ich mal) liegt in den Buttons. Der richtige "Zurück" Button ist ein Button von Unity, den ich an seinen Platz gesetzt und mit funktion versehen habe. Der andere ruft eine Funktion des Gebäudes auf welche (wie gesagt, unter anderem) das Menü schließen soll. Dieses Gebäude ist eine von mir erstellte Klasse, die nicht von MonoBehavior erbt aber zugriff auf meinen MenuManager bekommt und dort die Methode aufrufen soll. Was er auch tut (Debug.Log wird wie gewünscht angezeigt) aber das Menü wird nicht geschlossen...

Ich weiß nicht ob das alles so verständlich war... ansonsten gerne nochmal nachfragen :D Danke euch.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Was heisst denn bei dir schließen? Das Canvas disablen?
Wenn du ein debug.log bekommst, dann ist ja in dieser einen Sache alles in Ordnung. Also muss von einer anderen Seite aus noch etwas anstehen, was das Schließen unterbindet, oder aber sofort nach dem schließen wieder öffnet. Kannst du das Öffnen ausschließen?

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ja mit schließen meinte ich Disablen. Öffnen kann ich ausschließen, weil beide auf die selbe Methode zugreifen und die Methode keine weitere Methode o.ä. aufruft. Jeder Button hat auch nur eine einzige Aktion. 

image.png.8d7ff6e410b134c4fb86fbbf8c3f0dcd.png

Da ich dachte es könnte mal wieder der Falsche befehl sein, den ich genommen habe, habe ich beide also enabled = false und SetActive(false) sowohl einzeln als auch zusammen verwendet.

Es gibt nur einen Verweis oben weil eine andere Methode auf diese Zugreift. Das andere ist der Button mit Zuweisung aus dem Inspektor. Der wird oben ja nicht angezeigt.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ich habe mal weiter probiert:

image.png.e75fcf3b4d470e2fcb3638717e182da0.png

Auch hier ist es das selbe Ergebnis.

CloseAll() - schließt alle geöffneten Menüs und wirft mich zurück ins Spiel
OpenPlanet(clickedPlanet) - öffnet den angeklickten Planeten und öffnet das entsprechende Menü.

über den Knopf in Unity geht es, über das Menü des Gebäudes geht es nicht. In beiden fällen wird aber Debug.Log ausgegeben.

Das hier ist übrigens die Methode des Gebäudes:

image.png.92877b6b55c3a6b8ca5b7459dfeac0b1.png

Es gibt drei Buttons die jeweil 0, 1 oder 2 übergeben. Der Button den ich klicke übergibt 1.

kontinent ist eine eigene Klasse ohne vererbung, jeder Planet hat bis zu 6 davon. Planet ist eine Klasse und erbt von Monobehaviour und mm ist der MenuManager in dem die Methode ChangeToTransportMenu() drin ist.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hmmm....

Also wenn er da bei beiden Fällen dein "Hier" rauswirft, er also in beiden Fällen in die Methode ChangeToTransportMenu rein springt, dann muss es auch gehen.
Es sei denn, die CloseAll() Methode macht nicht das was sie soll.
Du sprichst von allen geöffneten Menüs. Woher weiß er denn welches Menü offen ist? Ist da vielleicht der Fehler?

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Er kennt lediglich diese 4 Canvasas (🤔 Singular:Canvas Plural: Canvasas, Kann was mehr... ? :D) Und die soll er allessammt schließen. (noch ein bischen mehr steckt dahinter aber das würde jetzt den Rahmen sprengen)

image.png.e838d711f1293dfd7e403e212b6988dc.png

 

Der Button macht das ja auch. Nur nicht das Gebäude mit dieser einen Methode.

image.png.4e663909b41a6297b2c92e7d3364e82c.png 

Jetzt habe ich die Methode mal erweitert um zu überprüfen, was er macht. Es wird tatsächtlich alles ausgeführt bis auf das Canvas zu schließen. Also dieser Testtext den ich eingebunden habe, der wird auch aktualisiert.

Der Button macht auch alles auch das Canvas schließen.

Ist es einer Methode den wichtig von wo her sie aufgerufen wird oder kann ihr das nicht egal sein?

Link zu diesem Kommentar
Auf anderen Seiten teilen

Neuer Tag neues Glück... ich habe jetzt nochmal alles in dem Bereich neu gemacht, also auch das Canvas gelöscht und ein neues Gesetzt. Es hat EINMAL geklappt... beim zweiten Mal nicht mehr.

Jetzt habe ich nochmal ein neues Canvas erstellt und herausgezogen aus dem Menu also so, dass es kein untermenü des Hauptmenüs mehr ist... Selbes Problem.

Dann habe ich jetzt nochmal den Code dahingehend geändert, dass alles Geschlossen wird also meine CloseAll() Methode, die jedes untermenü und auch das Hauptmenü schließt. Jetzt komme ich hier an eine Lächerlichkeit, dass es schon fast nicht mehr zu überbieten ist: Alles wird geschlossen. Nur dieses eine Canvas wird nicht geschlossen. Der Button geht weiterhin. Nur über das Gebäude geht es nicht. Ich weiß echt nicht mehr was ich machen soll.

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Doll! :D

Also nach dem, was du da schreibst, bleibt eigentlich echt nur die Möglichkeit, dass das Canvas zwar geschlossen wird, aber trotz allem danach sofort wieder geöffnet wird.
Bist du dir sicher, dass es nur einen Ort gibt, von dem aus das Canvas wieder geöffnet wird? Wird das nur über einen Button gemacht oder ist da eine Variable mit im Spiel?
Wenn du das Canvas GameObject deaktivierst/aktivierst, dann gib ihm doch mal ein kleines Script, mit OnEnable und OnDisable Funktionen.
In beiden Funktionen führst du ein Debug.Log aus. Mit unterschiedlichen Texten und vielleicht der Time.time, um zu sehen, wann etwas passiert ist.
 

Ach so. Du hast scheinbar Schwierigkeiten damit, wann etwas enalbled und wann etwas activated wird.
Kurze Erklärung dazu:
Enabled werden nur Komponenten, die an einem Gameobject dran hängen. Also die Dinger, die ein Häkchen Im Inspector haben. Scripte, Audiosources, Collider, Meshrenderer usw.

Manche Komponenten kannst du nicht Enablen/Disablen. Das sind z.B. Transform, Material und Rigidbody.

Aktivated werden komplette GameObjects !

Wenn du ein Canvas erzeugst, dann baut Unity dir ein GameObject mit mehreren Canvas-Components zusammen.
Du kannst jetzt die Canvas Hauptkomponente disablen, und lässt alle anderen Komponenten, wie den CanvasScaler und den GraphicRaycaster an, oder du deaktivierst das ganze GameObject mit all seinen Komponenten da drin.

Das bleibt dir überlassen. Es ist aber eben ein Unterschied, ob man nur eine Komponente disabled und den Rest laufen lässt, oder ob man das ganze GameObject deaktiviert.

Wenn du das GameObject aktivierst/deaktivierst, musst du eine Referenz zum Objekt gebildet haben, weil es sonst, wenn deaktiviert, nicht mehr gefunden werden kann.

Ich persönlich deaktiviere das ganze Canvas GameObject, denn dann ist alles aus.

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Du hast recht... Das Canvas wird wieder an geschaltet... Jetzt muss ich nur noch heraus finden von wo...

Die Idee war gut. Ich wusste nciht, dass es Methoden für OnEnable/Disable gibt. Danke dir.

 

Achso und ja ich hatte Probleme mit dem SetActive oder enable = ... 
Im laufe des Problems habe ich dann auch irgendwann gemerkt, dass mit enabled = false nur die Komponente ausgeschaltet wird. Danke dir. :D 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ich weiß auch nicht wer das war ;)

Gut, dass nicht allzuviele an dem Projekt arbeiten und ich den schuldigen bestimmt bald finde :D

Danke dir nochmal. Vor allem einfach mal OnEnable/OnDiable zu verwenden. Wie gesagt war mir nicht bewusst, dass es die Methoden gibt. Aber wahrscheinlich gibt es so ziemlich für alles irgendwelche Methoden um so etwas abzufragen.

Ich habe mich eben auf dem Heimweg von der Arbeit gefragt ob es möglich ist, diese Methoden dazu zu verwenden eine Animation abzuspielen. Also, dass das Menü dann zugeklappt wird statt dass es einfach verschwinden o.Ä. Problem ist dann aber, wenn die Methode ausgeführt wird das Objekt schon weg ist oder gibt es da möglichkeiten?

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ne, dafür sind diese Methoden nicht gut.
OnEnable() Wird immer dann ausgeführt, wenn das Script eingeschaltet wird (Häkchen im Inspector). Also entweder wenn das Script von außen mit .enable=true eingeschaltet wird oder aber das komplette GameObject aktiviert wird und das Script am GameObject nicht deaktiviert war.

Das passiert wirklich nur beim Einschalten. Das nutzt du am Besten um dich irgendwo anzumelden und gewisse Eigenschaften einzustellen. 

Genauso ist das mit dem OnDisable(). Das wird kurz vor dem ausschalten des Scripts, oder dem deaktivieren des GameObjects gemacht. Hiermit  kann sich dann das Objekt abmelden.
Das ist aber nur einmal in einem Zyklus und bringt dir nichts um eine Animation ablaufen zu lassen, denn gleich danach ist das GO deaktiviert und somit weg.
Das OnEnable() könnte aber für eine Einfluganimation gut genutzt werden.

Wenn du aber so eine Animation ablaufen lassen willst, dann kannst du ja eine public Methode im Script des UI Eelementes erstellen, wo du von außen reinspringst, anstatt das Canvas von außen zu deaktivieren.
In der Methode wird dann ne Animation gestartet, die das Objekt verschwinden lässt.
Jetzt musst du aber trotzdem das UI Element deaktivieren. Also brauchst du was, dass nach der Animation das Canvas deaktiviert.
Entweder weisst du wie lange die Animation abläuft und du startest eine Coroutine, die genau so lange wartet und danach das Canvas deaktiviert,
oder du baust dir noch eine public Methode, in die die Animation per Event rein springt und dort dann das Canvas deaktiviert wird.

 

Hier ist mal eine Liste von allen Monobehavior-Methoden.
Diese On... Methoden sind ja Message-Methoden, die (wenn sie im Script sind) dir mitteilen, dass dieses oder jenes jetzt gerade aufgetreten ist Awake, Start und Update gehören auch dazu, denn in dem Moment, wo sie aufgerufen werden, ist etwas passiert.

https://docs.unity3d.com/ScriptReference/MonoBehaviour.html

Und hier ist der Ablauf dieser ganzen Events und deren Reihenfolge. Das ist wichtig zu wissen.

https://docs.unity3d.com/Manual/ExecutionOrder.html

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Archiviert

Dieses Thema ist jetzt archiviert und für weitere Antworten gesperrt.

×
×
  • Neu erstellen...