Search Unity

  1. If you have experience with import & exporting custom (.unitypackage) packages, please help complete a survey (open until May 15, 2024).
    Dismiss Notice
  2. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice

new Vector3 ?

Discussion in 'Scripting' started by larswik, Oct 8, 2015.

  1. larswik

    larswik

    Joined:
    Dec 20, 2012
    Posts:
    312
    I have been learning the C# syntax and the 'new' is throwing me off. A Vector3 is a struct, not an object. But coming from Objective C, new would be the same thing as instantiating an object thats allocating memory for it. Why would you need to use new for a Vector3 struct?

    To me it sounds like I would then also need to say

    Code (CSharp):
    1. public new float value = 5.0;
     
  2. Timelog

    Timelog

    Joined:
    Nov 22, 2014
    Posts:
    528
    A Vector3 is a struct, not a class. Both are objects, but a struct is a value type, and a class a reference type. https://msdn.microsoft.com/en-us/library/ms173109.aspx

    Also, your example is wrong, it would be more like this:
    Code (CSharp):
    1. public float fl = new float();
    Which funny enough is perfectly valid, but unneeded as it gets handled by the backing code automatically.
     
    Last edited: Oct 8, 2015
    JoeStrout likes this.
  3. larswik

    larswik

    Joined:
    Dec 20, 2012
    Posts:
    312
    Thanks, I am reading up on it.
     
  4. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,557
    I see you mention 'objective-c' and the use of the 'new' keyword in that language. Those coming from C++ might also be thrown by the C# use of the 'new' keyword. The 'new' keyword is only used when you're dealing with a pointer.

    In C# being a class/struct is all that controls this. You don't need to define pointers. All classes are always referenced, and structs are always treated as values (unless you explicitly 'ref' or 'out' them as parameters... or use pointers when scoped in an 'unsafe' block of code).

    This means that 'new' really doesn't serve any purpose anymore in regards to actual memory allocation. It's just implied code. For all intents and purposes... we could throw it out.

    BUT

    How about naming? C++ and objective-c are plagued with weird naming systems to get around all the weird name collisions that can occur. This results in communal standards to naming stuff, but those standards can be very localized, and there's really no controlling it... you screw up some naming mechanic, and as long as there are no collisions, the compiler doesn't care. The name of that class, and that field, are just gibberish lines of characters to the compiler.

    Of course over the years the various C/C++/objective-C standards have come up with systems to try and remedy this. But these too were often bandaids, and weren't always included in every compiler. And even so, developers usually just stuck to habit.

    Where as with .Net/C#, Microsoft had 100% control, they get to create standards that stick. And they get to them before the community molests them.

    So lets consider the situation of a class with a property that has the same name as another class that exists:

    Code (csharp):
    1.  
    2.     public struct Data
    3.     {
    4.  
    5.         public int Id;
    6.         public int Value;
    7.  
    8.         public Data(int id, int val)
    9.         {
    10.             Id = id;
    11.             Value = val;
    12.         }
    13.  
    14.     }
    15.  
    16.     public struct Foo
    17.     {
    18.  
    19.         public Data Data;
    20.      
    21.         public void SetData(int id, int val)
    22.         {
    23.             Data = new Data(id, val);
    24.         }
    25.  
    26.     }
    27.  
    This is legit code. It works. It can determine what the difference between the various uses of 'Data'. Because the act of setting Data to a new Data uses the 'new' keyword. It syntactically can work out.

    Where as in C++:

    Code (csharp):
    1.  
    2. struct Data
    3. {
    4.     int Id;
    5.     int Value;
    6.  
    7.     Data() {};
    8.     Data(int id, int val)
    9.     {
    10.         Id = id;
    11.         Value = val;
    12.     }
    13. };
    14.  
    15. struct Foo
    16. {
    17.     Data Data;
    18.  
    19.     void SetData(int id, int val)
    20.     {
    21.         Data = Data(id, val);
    22.     }
    23. };
    24.  
    This fails, the compiler doesn't know the difference between the various uses of 'Data' in the code.

    Another situation might be where you happen to have a method with the same name. Now it's even MORE shaped like the constructor. C# just basically decided that 'new' is used to denote the use of the constructor function for a type.

    One might argue that the field 'Data Data' is a bad name. But why? What should I call it? Should I change the struct name to be 'DataInfo' and the field can remain 'Data'?




    In the end... it's just the way C# do.
     
  5. Tiki

    Tiki

    Joined:
    Mar 3, 2013
    Posts:
    299
    Pretty much anything that holds multiple variables (that includes Vector3, as it holds 3 different floats), will require a new inclusion when initiating.

    so Vector3 newVector = new Vector3(); is necessary unless you plan on filling newVector with an existing initiated and filled Vector3, including a public (user-filled) Vector3, before actually using it.

    On the other hand, float, int, string, etc, as they are singular, do not require a new tag. Hope this clears up a few things.
     
    MurphyMurph_21 likes this.
  6. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    This.

    The language devs decided that new keyword had to be used to call a constructor.
     
    Tiki likes this.
  7. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    How about this? ;)

    Code (CSharp):
    1. public class Empty {}
     
  8. Tiki

    Tiki

    Joined:
    Mar 3, 2013
    Posts:
    299
    Har, har, sir. Hardy har har :p
     
    Kiwasi likes this.
  9. larswik

    larswik

    Joined:
    Dec 20, 2012
    Posts:
    312
    I see what you are saying. In the code I am working with to turn an AI to point at the player I see new Vector3 along side of Vector3 without the new statement. In this situations its just passing the pointer to the already instantiated Class memory location

    Thanks again for the clear example code folks! Lars == Happy
     
  10. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,776
    One minor clarification on that last bit. When the component is first created, a public member will be null if there's no default value set in the class. Whenever an inspector view for an object stumbles across a public member that it knows how to serialize (which will 99% of the time be almost immediately, because people usually have the inspector view of an object open when they add a new member and it compiles), if that member is 'null', it will make a new one. TBH I'm not entirely sure what it uses to populate the values of this new one, although I do know it's not the default constructor, so it's probably not using the "new" keyword anywhere in there. (As an aside, the "not using a default constructor" thing is SERIOUSLY annoying when you're dealing with custom serialized classes that need particular values in order to not be nonsensical.)
     
  11. MurphyMurph_21

    MurphyMurph_21

    Joined:
    Jul 3, 2020
    Posts:
    73
    Thanks man you made it so clear and simple... much appreciated God bless!!!!