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
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

List<T>, variable initialization inspector

Discussion in 'Scripting' started by arioch82, Aug 25, 2011.

  1. arioch82

    arioch82

    Joined:
    Dec 3, 2009
    Posts:
    253
    I am having a weird issue here...

    given this test code

    Code (csharp):
    1.  
    2. [System.Serializable]
    3. public class TestClass{
    4.     public int test_int = 50;
    5.  
    6.    public TestClass(){
    7.     Debug.LogError("constructor");
    8.     test_int = 50;
    9.    Debug.LogError("constructor_end = " + test_int);
    10.   }
    11. }
    12.  
    13. public class TestComponent: MonoBehaviour
    14. {  
    15.     public TestClass test_item;
    16.     public List<TestClass> test_item_list;
    17.  
    18.  
    I've no problem with the "test_item" member, is correctly displayed and its "test_int" has a value of 50 (with or without the constructor).

    the "test_item_list" is empty and as soon as i change the size i get the constructor logs displayed in the console with the correct "test_int" value (50) but the value of "test_int" of the element displayed in the inspector is magically "0" !

    is like the engine/inspector/whatever is doing the initialization using the default values that i've set (with or without the constructor) and after creating the element is doing a memset to 0 of all it's content!
    Any List<T> will always set to 0 any parameter (int, float, enum) contained in the class!

    where's the trick?
    is it an inspector/unity bug?
     
    Last edited: Aug 26, 2011
  2. raybarrera

    raybarrera

    Joined:
    Nov 20, 2010
    Posts:
    207
    Not sure if this is the problem, but as far as I know, Unity doesn't like constructors. Maybe use the Start or Awake function instead?
     
  3. tertle

    tertle

    Joined:
    Jan 25, 2011
    Posts:
    3,635
    Constructors work fine in unity, they just can't be called on classes inheriting from monobehaviour and as his TestClass isn't inheriting from monobehaviour it has no Start/Awake function.
     
  4. arioch82

    arioch82

    Joined:
    Dec 3, 2009
    Posts:
    253
    I've added that constructor only as a test (although there's no problem with it), anyway also without it you would expect to see the test_int set to 50 in the inspector but that happens only if you declare a variable of type "TestClass", if you define an array (TestClass[] test_array) or a list (List<TestClass> test_list) everytime you add an element all its members are set to 0...
     
  5. arioch82

    arioch82

    Joined:
    Dec 3, 2009
    Posts:
    253
    also, let's say that you have an element in your array/List and it's member are set to certain values, if you add new elements to the array/list their value will always be a copy of the last element defined!

    for instance in the previous code if you add an element to the list and set the "test_int" value to "20" and then change the size of the list from 1 to 10 to add new elements, all the elements "from 2 to 10" will have the "test_int" value set to "20" as well!

    how can I make it so that it follows the default values that I want?
     
  6. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,601
    1. Make it extend UnityEngine.ScriptableObject so the editor correctly serializes it. thats the class intend for editor used "serialized data containers" basically. If you use an own class with serializable, make a custom editor for the monobehaviour that uses it instead of using the auto reflection.

    2. One problem of making stuff serializable instead of having them scriptableobject is that they behave quite a bit different especially in the editor. they behave more like the original C99 structs (name mapped memory blocks) that get cloned upon growth of array / list, and the entry can never be null again in the editor due to serializable which tells the editor that there is something writable it must write so it will write and read it as if there were something in. this impacts the auto serialization with the inbuilt inspector
     
  7. arioch82

    arioch82

    Joined:
    Dec 3, 2009
    Posts:
    253
    Hi dreamora and thanks first of all.

    I've tried to create it as a ScriptableObject but it shows up in the inspector as a reference to a script instead of a "class/struct" with attributes like the one you get with the serialize attribute; do I have to write a custom inspector for it? I hope there's an easier/faster solution...

    the ScriptableObject doc page doesn't really tellls much about them

    EDIT

    reading more about ScriptableObject on the web it looks like I have to create an instance in the editor using an editor script, and this instance will live as a separate asset in the project, not really what i want to do... i really need a simple struct to show up in the inspector with the default values i provide, any other way i could achieve it? or if you can tell me more about scriptableobject it would be great.

    thanks
     
    Last edited: Aug 30, 2011
  8. arioch82

    arioch82

    Joined:
    Dec 3, 2009
    Posts:
    253
  9. chechoggomez

    chechoggomez

    Unity Technologies

    Joined:
    Feb 25, 2013
    Posts:
    91
    PJRM, Threeyes and Kiwasi like this.
  10. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    OnValidate may also be of use.
     
  11. Gnatty

    Gnatty

    Joined:
    May 17, 2012
    Posts:
    77
    Necro-post!
     
  12. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    Lol, didn't even see that!