Search Unity

Exposing Properties in the Inspector

Discussion in '2017.1 Beta' started by GuardianArchangelJohn, May 17, 2017.

  1. GuardianArchangelJohn

    GuardianArchangelJohn

    Joined:
    May 3, 2014
    Posts:
    54
    I was hoping that finally moving to .NET 4.6 would give Unity the ability to see .NET Properties in the Inspector window, but it looks like that's not the case, it's still only letting me show public fields. What's the best way to get it working in the new Unity beta?
     
  2. zyzyx

    zyzyx

    Joined:
    Jul 9, 2012
    Posts:
    222
    Properties usually have private backing fields. You could do something like this:

    Code (CSharp):
    1. [SerializeField]
    2. private int myVar;
    3. public int MyProperty
    4. {
    5.      get { return myVar; }
    6.      set { myVar = value; }
    7.  }
     
    kotoezh and richardkettlewell like this.
  3. GuardianArchangelJohn

    GuardianArchangelJohn

    Joined:
    May 3, 2014
    Posts:
    54
    Thanks, I was trying that with a type of decimal and needed to change it to float for it to come up in the Inspector. That brings the question though why is decimal not supported in the Inspector and is it possible to allow it to be editable in the Inspector? I use decimal types a lot when I need to process very large numbers that float or double can't handle.
     
    Last edited: May 17, 2017
  4. richardkettlewell

    richardkettlewell

    Unity Technologies

    Joined:
    Sep 9, 2015
    Posts:
    1,373
    Looks like it got requested here quite some years ago: https://feedback.unity3d.com/suggestions/scripting-decimal-type

    Maybe vote on the idea to help get it prioritised :)
     
  5. iivo_k

    iivo_k

    Joined:
    Jan 28, 2013
    Posts:
    312
  6. liortal

    liortal

    Joined:
    Oct 17, 2012
    Posts:
    3,361
    What do properties have to do with the scripting upgrade? it's 2 completely different things.
     
  7. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    3,979
    Just to mention it- actual properties being exposed in the editor (not their backing value) for editing is likely a really bad idea. Why? Because a property is actually a function, which can have side effects, such as changing another serialized value on an entirely different object. This means the serialization for things like Undo would be broken, as the editor would have no easy way to know what was changed when a property value is changed.
     
    MGGDev and mh114 like this.
  8. GuardianArchangelJohn

    GuardianArchangelJohn

    Joined:
    May 3, 2014
    Posts:
    54
    Could the code not pick that up through reflection? Let's think about that for a minute. I use a setter on a property, which hits multiple backing fields at one time because I want to simplify performing some complex function. If those backing fields are all serialized, shouldn't those backing fields be triggering events in the undo history part of the editor engine? If not, I'd have to ask why, as in if it were for performance reasons.
     
  9. GuardianArchangelJohn

    GuardianArchangelJohn

    Joined:
    May 3, 2014
    Posts:
    54
    Just a question not an assumption, I wondered if having been an old framework for so long they had just never gotten around to including properties until they did one massive undertaking of getting up to 4.6
    I haven't tested this out yet but it looks like exactly what I'm looking for, thank you for sending the link.

    I agree with the commenter on the asset that this should be a part of the Unity core. It would save some time and frustration for developers who have learned .NET in the business world many years prior to using Unity3D (I started using C# back in 2003) and have had it beaten into our heads (rather egregiously at times) by colleagues to use properties for their many benefits.

    (Off-topic: Personally I'd like to see more engagement in the development community with Unity3D outside of the gaming arena, primarily in the data visualization arena. I think anything that helps developers write better structured code will help towards that end.)
     
  10. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    3,979
    No, for that, you'd need to serialize the entire scene with every undo, or scan every object in the scene and see if any of the data had changed, basically a giant diff. Either of these options would slow the editor to a crawl. For instance, since arbitrary code can be run in a property set/get, you could easily change every object in unity, files on disk, etc.
     
  11. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    3,979

    Personally, I think properties are mostly not useful. The main reason people tell you to use properties is "in case you need to change things later". So, instead of:

    Code (CSharp):
    1. public float foo;
    you quickly end up with

    Code (CSharp):
    1. private float _foo;
    2. public float foo
    3. {
    4.    get { return _foo; }
    5.    set { _foo = value; }
    6. }
    Yay, a whole bunch of extra lines, with an easy way to create an infinite loop by mistake, just in case in the future you want to do something when someone sets/gets foo. You've also added some function call overhead, slowing things down. You can no longer pass foo to a function by reference or as an out parameter, because it's now a property. You've gained nothing, and lost much.

    Now, lets say that time comes, and you want to refactor foo to do something on a set or get. Now the gains will really pay off! To the caller, foo looks the same as a variable access. It's not a GetValue() function, so unless everyone in the world follows the same naming/casing conventions, you have no idea if what your accessing is a property or a field. So you add some messaging to foo, so it now fires off an event when it's set, which someone else is triggering a sound with. Meanwhile, a caller has something like this somewhere:

    Code (CSharp):
    1. float[] vals = GetValues();
    2. for (int i = 0; i < vals.Count; ++i)
    3. {
    4.    myObj.foo += vals[i];
    5. }
    Oh god, now it's sending that event hundreds of times, and playing that sound 100's of times, when we really only want it to happen once. Had the caller realized that they were secretly calling a function, they might have said "Hey, SetFoo() might do some work, so maybe we should add it up and then set it..". Instead, it looked just like a field, acted like a field, and is now a performance nightmare. Worse, if the sound system is smart enough to only play that sound once, it might mask the fact that we are running that code hundreds of times instead of it becoming blatantly obvious.

    IMO, fancy syntax sugar which masks functions so that they look like fields is a bad idea. If something is going to do actual work, it should be a function call. If something isn't going to do actual work, then there is really no good reason to make it look like a field but actually be a function. There's nothing but extra complexity, extra cost, and pain down that road.
     
    patternshift, MGGDev and hippocoder like this.
unityunity