Jump to content
Unity Insider Forum
Luis

Frage zur Bedingung eines if-Statements

Recommended Posts

Hii, ich habe eine Frage zu diesem Code:

 GridElement g = mouseHit.transform.GetComponent<GridElement>();  (mouseHit ist das Objekt, was die Komponente eventuell beinhaltet)

            if (!g) { ... }

GridElement ist eine Klasse, die von MonoBehaviour erbt, die ganz normal über die Create-Funktion in der Project-View angelegt wurde. 

Anschließend wird in der Update-Methode einer weiteren Klasse eine Variable g vom GridElement-Typ angelegt, die mit einer GridElement-Instanz der GridElement-Klasse gefüllt werden soll. 

Es kann sein, dass es die gesuchte Komponente nicht gibt, deswegen ist eine if-Abfrage nötig. 

Jedenfalls wundere ich mich, wieso man im if-Statement als Bedingung if(g) oder if(!g) angeben kann, da g ja vom Typen Grid-Element ist und kein boolean, aber mir wird kein Fehler angezeigt und der Code funktioniert auch. 

Habe überlegt, ob das so etwas wie if(g != NULL) heißen könnte, aber ich weiß nicht genau was NULL bedeutet, deswegen hat mir das auch nicht weitergeholfen. 

Vielen Dank schonmal im Voraus! 

 

Share this post


Link to post
Share on other sites

Hallo Luis, 

das NULL bedeutet so in etwa : Da ist nichts . Gibt ein NULL zurück .....returned null. 

Wenn du deine If (!g) hinterher abfragst, dann wirft Unity Dir möglicherweise eine NULL Reception zurück, wenn wie du sagst das Gameobject nicht die Klasse GridElement enthält.

Du kannst das vorher abfragen:  

if (mouseHit.transform.GetComponent<GridElement>()

{

   GridElement g = mouseHit.transform.GetComponent<GridElement>();

}

 

Du hast Recht, die Klasse ist ja gar kein Boolean. Aber in diesem Fall steht das für : Da ist was! Ein MouseHIT, eine Transform und eine Komponente mit den Namen GridElement.

  • Like 1

Share this post


Link to post
Share on other sites

Ah okay, danke! Geht das nur mit Klassen, die von MonoBehaviour erben ? Ich habe beispielsweise mal in Visual Studio dasselbe versucht:

 class Person
        {
     
        }


    class Program
    { 
         
        static void Main(string[] args)
        {
           Person p = null;

            if (p == null)
            {
                Console.WriteLine("Eine NULL-Exception ist aufgetreten!");
            }

            if(p != null)
            {
                Console.WriteLine("Alles funktioniert.");
            }
           
        }
    }

Da funktioniert es nicht und ich muss statt !p   p == null und statt p   p!=null schreiben.

Ist das "spezielle" if-Statement von vorhin also nur in Unity möglich (,wenn die Klasse von MonoBehaviour erbt)?


 

Share this post


Link to post
Share on other sites

Hallo Luis,
Das Symbol "!" ist in C# der Not-Operator.
In Verbindung mit einer Boolschen Variable kann er verwendet werden um den Inhalt der Variable zu invertieren
 

bool boo = false;
if(boo)               //wird als If(boo==true)  ausgewertet
    mach irgendwas..

if(!boo)               //wird als If((Not boo)==true)  ausgewertet
    mach was anderes...

Es ist lediglich eine verkürzte Schreibweise.

Bei Verweisen (Objecte, Class, ..) geht das nicht, da der Inhalt invertiert werden würde.
In solchen Fällen musst du den Vergleich mit dem "Gleich-Operator" ==  oder mit dem "Ungleich-Operator"  !=  ausführen.

Gruß TurTur

  • Like 1

Share this post


Link to post
Share on other sites

Okay, würde dann der Code, den ich zuerst reingeschickt hatte, so etwas wie...

if(g) = wenn es g gibt bzw. wenn g != NULL ist

und if(!g) = wenn es g nicht gibt bzw. wenn g == NULL ist

...heißen?

Weil in Unity kann man ja anscheined Verweise als Bedingung verwenden (denn der Code oben funktioniert ja) , also ist das nur etwas was in Unity funktioniert bzw. wenn (wie oben) die Klasse, die als Datentyp verwendet wurde von MonoBehaviour erbt?

Vielen Dank schonmal für die Antworten!

Viele Grüße, Luis!

Share this post


Link to post
Share on other sites

Hallo Luis,
da die Standard-Programmiersprache in Unity ist zZt. C# ist, gibt es eigentlich keinen Unterschied .
Zu deiner ersten Frage: Nein.
Du musst unterscheiden zwischen Referenztyp-Variablen und (ich sage mal) normalen Variablen (int, float, bool, ..).

Der Not-Operator "!" kehrt einfach das Bitmuster der Variable um. Bool-Variable ==  False (alle Bits auf 0) entspricht dem Wert "0",   == true (alle bits auf 1) entspricht dem Wert "-1".
Bei der Verwendung der If-Abfrage in der Kurzform

if(g)
	mach irgendwas..

wird geprüft ob der Wert von "g" irgendein Wert ungleich dem mathematischen 0 ist.
Lässt sich der Inhalt von "g" als mathematischer Wert interpretieren wird die Bedingung ausgeführt (wenn er nicht "0" ist).
Da auch ein Objektverweis letztlich ein Zahlenwert ist, kann das klappen. Allerdings würde diese Abfrage auch als "true" ausgewertet werden, wenn der Ojektverweis "g = NULL" enthält, da dieser eben nicht dem mathematischen "0" entspricht.

Aus diesem Grund wird auch ein

if(!g)
	ich existiere nicht...

ausgeführt, ob jetzt ein gültiger Objekt- Verweis vorliegt oder als NULL gekennzeichnet ist. Da nur das Bitmuster von "g" umgedreht wird, kann das Ergenis in jeden Fall als Wert ungleich "0" ausgewertet werden

In deinem vorletzten Post hast du den Code doch korrekt aufgebaut und am Ende auch die richtige Erklärung geschrieben (" ich muss statt !p   p == null und statt p   p!=null schreiben.").

Gruß TurTur

Share this post


Link to post
Share on other sites

@TurTur Tut mir leid, da jetzt so forsch daher zu kommen, aber deine gesamte Erklärung ist leider von vorne bis hinten falsch. Sie stimmt für typschwache Sprachen wie JavaScript oder PHP, aber C# funktioniert so nicht.

@Luis Wie du schon richtig erkannt hast, geht das mit Unity-Objekten, aber nicht mit normalen. Das liegt in der Tat daran, dass die wichtigsten Unity-Klassen (GameObject, Component, ScriptableObject) alle von UnityEngine.Object erben, und diese Klasse wurde so geschrieben, dass man sie implizit zu boolean casten kann. Innerhalb dieses Casts, den Unity geschrieben hat, wird dann quasi "!= null" gemacht. "Quasi", weil Unity im Vergleichsoperator bei dieser Klasse auch herumgepfuscht hat, damit bei "meinObjekt != null" "true" heraus kommt, wenn das Objekt zerstört wurde.

Das Ganze kann man selber auch nachbauen. Ich erweitere mal deinen Code von oben:

class Person
{
  public bool alive = true;
  
  public static implicit operator bool(Person p)
  {
    return p.alive;
  }
}


class Program
{ 
    static void Main(string[] args)
    {
        Person p = null;
          
        p.alive = false;
          
        if (p)
        {
            Debug.Log("Alive!");
        }
        else
        {
            Debug.Log("Dead!"); 
        }
    }
} 

 

Share this post


Link to post
Share on other sites

Sascha:
Das sich Unityobjecte zu boolean casten lassen war mir bis jetzt nicht klar (habe sie als normale Objecte verstanden). Und schon habe ich wieder was dazu gelernt🙂

Luis:
Sorry, wenn ich dich etwas verwirrt haben sollte, aber auch ich lerne noch dazu. 🙂

Gruß TurTur
 

  • Like 1

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

×
×
  • Create New...