Search Unity

Why does unity not initialize public properties in AddComponent?

Discussion in 'Scripting' started by boolean01, Sep 16, 2016.

  1. boolean01

    boolean01

    Joined:
    Nov 16, 2013
    Posts:
    92
    This is a minor thing, but still managed to confuse me for a good hour.

    I noticed that if I create a component which has a public property like List<int>, on Awake Unity seems to initialize the property for me. Handy I guess since it prevents nulls.

    However, if I create the script through "AddComponent", I noticed the list won't be initialized and left as null.

    Is there a reason behind the scenes why Unity initializes one and not the other?

    Cheers.
     
  2. KelsoMRK

    KelsoMRK

    Joined:
    Jul 18, 2010
    Posts:
    5,539
    So the Inspector can work properly.
     
  3. Vedrit

    Vedrit

    Joined:
    Feb 8, 2013
    Posts:
    514
    But don't the Start and Awake functions run when the component gets added? Shouldn't that be initializing the properties?
     
  4. KelsoMRK

    KelsoMRK

    Joined:
    Jul 18, 2010
    Posts:
    5,539
    Assuming you do it in Awake, yes. If you do both then you'll wipe your Inspector assignments when entering play mode.
     
  5. boolean01

    boolean01

    Joined:
    Nov 16, 2013
    Posts:
    92
    I wonder then - what's the difference between the inspector property when it has a component added through the editor (drag and drop) and a component added through AddComponent? If it's for the inspector to work, shouldn't it act the same for both? At the end of the day its the same script on the same object with the same public property.
     
  6. kru

    kru

    Joined:
    Jan 19, 2013
    Posts:
    452
    This is a subtle but deep distinction. When a component shows up in the inspector, Unity has done an internal initialization. Unity serialized the values that are exposed on that object. Part of the Unity Inspector treatment of an object is to create default values for lists and other collections that Unity knows how to serialize. This treatment only occurs in the editor.

    When you use AddComponent at runtime, the editor doesn't have a chance to initalize the object in the same way. So components added with AddComponent aren't deserialized from backing data, which means that no default collections are created.

    If you want the convenience of knowing that your class's public Lists aren't null, you can use a field initializer to give it a default (empty) list.
     
  7. boolean01

    boolean01

    Joined:
    Nov 16, 2013
    Posts:
    92
    That's cool! I always wonder how you guys figure this stuff out, ha.

    Thanks Kru, great info.