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

Vector3 null reference

Discussion in '2D' started by DrDress, Mar 14, 2020.

  1. DrDress

    DrDress

    Joined:
    Sep 11, 2019
    Posts:
    30
    This is actually a more generel c# question. But some classes can't be set to null like the Vector3 in Unity. But you can still check to see if the refernce is a null reference like this:

    Code (CSharp):
    1. Vector3 test;
    2.  
    3. if(!test)
    4. {
    5.    test = new Vector3(1,2,3);
    6. }
    7. else
    8. {
    9. // Whatever...
    10. }
    I used to think that this meant that an an un instatiated refernce was just a null refence by default, but then why can't you do the following to all classes. Why aren't all classes nullable?

    Code (CSharp):
    1. test = null;
    2.  
    3. if(!test)
    4. {
    5.    // Whatever...
    6. }
     
  2. Lo-renzo

    Lo-renzo

    Joined:
    Apr 8, 2018
    Posts:
    1,323
    The answer is that Vector3 is a struct. Structs are not reference types. C# makes a distinction between "reference types" and "value types." Explanation. In short, reference types are nullable - their "address" in memory can be blank. When you declare a Vector3, you populate it with some value always.

    Code (CSharp):
    1.     Vector3 test;
    2.  
    3.     if(!test)
    4.     {
    5.        test = new Vector3(1,2,3);
    6.     }
    7.     else
    8.     {
    9.     // Whatever...
    10.     }
    11.  
    This code is actually not valid. Your IDE (e.g. Visual Studio) should report to you that you cannot write it this way (red squiggly under the "Vector3 test" declaration).

    The following, however, is valid:
    Code (CSharp):
    1.     Vector3 test = default(Vector3);
    2.  
    3.     if(test != default(Vector3))
    4.     {
    5.        test = new Vector3(1,2,3);
    6.     }
    7.     else
    8.     {
    9.     // Whatever...
    10.     }
    11.  
    The above works because we're giving the struct its default value ( 0, 0, 0 ). Then specifically checking for that value. We're not checking if it's null, because structs don't null, we check the specific value.

    By the way, it's very unconventional c# to be able to go:
    Code (CSharp):
    1. if(someUnityType)
    2. {
    3. // something
    4. }
    You've probably seen this somewhere because Unity has overloaded an operator. Idiomatic C# does not allow you to do that with normal classes. It's a Unity-type specific thing (and it is a pretty weird thing in c# generally). Idiomatic C# would look like this:
    Code (CSharp):
    1. if(myCSharpReferenceInstance != null)
    2. {
    3. // something
    4. }
    As an aside, it is possible to declare a special nullable struct, but to not confuse things you should consider that a more advanced topic that should be ignored in 99.9% of cases.
     
  3. DrDress

    DrDress

    Joined:
    Sep 11, 2019
    Posts:
    30
    Thank for a great answer. I'm surprised to learn that Vectors are struc since they have various methods. I actually have a sort of similar question:

    Can you use == to check if two classes or GameObjects are the same. Something like this:

    Code (CSharp):
    1.  
    2. ClassType[] classArray = GetFromSomewhere();
    3. ClassType test = GetFromSomewhereElse();
    4.  
    5. for(int i = 0 ; i < classArray.Length ; i++)
    6. {
    7.    if(test == classArray[i]) // This is the line I'm unsure about
    8.   {
    9.      // Do stuff
    10.   }
    11. }
     
  4. Lo-renzo

    Lo-renzo

    Joined:
    Apr 8, 2018
    Posts:
    1,323
    Yes, by default == for reference types does reference-comparison: "are the two addresses the same?" However, you should know that "==" is what's called an operator. Some classes may define custom overrides for the behavior of "==" / "!=" and even "+" / "-". Overall, it's rare for classes and more common for structs. That's how you can add and compare two vector3s. For Vector3, Unity has defined that the "==" means "check if all three floats are the same." More info.