Search Unity

Unity 5 removed implicit component accessor properties... except that it also didn't? O_o

Discussion in 'Scripting' started by invicticide, Mar 26, 2015.

  1. invicticide

    invicticide

    Joined:
    Nov 15, 2009
    Posts:
    109
    So we all know that Unity 5 changes this:

    Camera camera = gameObject.camera;
    to this:

    Camera camera = gameObject.GetComponent<Camera>();
    Which is fine! Except that I just discovered that those properties are still defined even though we're apparently not supposed to use them any more. I used "camera" in the example but the same goes for "audio", "renderer", "rigidbody", etc. Which means I can't reclaim those as variable names without triggering a "X hides inherited member Component.X" script warning.

    Is it just me, or does this seem a bit silly? o_O
     
  2. makeshiftwings

    makeshiftwings

    Joined:
    May 28, 2011
    Posts:
    3,350
    They're "deprecated", which is engineer-speak for "stop using this because we're going to totally delete them soon but we're giving you some time to change over first".
     
    Kiwasi likes this.
  3. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    This. If you attempt to actually use them they won't function. You get an error message and a prompt to run the API updater.

    Its standard practice to leave deprecated members there for a while with warnings and errors. Its a much nicer transition then just waking up one day and finding the entire API has been pulled out from under you and everything is broken.
     
  4. Deleted User

    Deleted User

    Guest

    as the warning message says, use the new keyword if you want to use these names
    Code (csharp):
    1. private new Camera camera;
     
    Kiwasi likes this.
  5. Brainswitch

    Brainswitch

    Joined:
    Apr 24, 2013
    Posts:
    270
    Make sure you put those 'new' in there - otherwise Unity might accidentally "upgrade" your variable.
     
  6. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    You also need to be aware of what hiding actually does. Its slightly weird from an OOP point of view. If you call MonoBehaviour.rigidbody you will get the old property. If you call MyComponent.rigidbody you will get the new property. Hiding is opposite to how overriding works.
     
  7. blizzy

    blizzy

    Joined:
    Apr 27, 2014
    Posts:
    775
    It is also standard practice to keep deprecated members functioning like before, and not break existing code by changing their behavior.
     
  8. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    Yeah. Unfortunately in this case it wouldn't have achieved the objectives of the deprecation. The deprecated members will be editor only. They won't actually exist in a compiled build.
     
  9. invicticide

    invicticide

    Joined:
    Nov 15, 2009
    Posts:
    109
    So just to clarify this, let's say I define a class like this:

    Code (CSharp):
    1. public class Foo : MonoBehaviour {
    2.     new public Renderer renderer;
    3. }
    And then I store and access two different references to it in another class, like this:

    Code (CSharp):
    1. public class Bar : MonoBehaviour {
    2.     public MonoBehaviour m_monoBehaviour;
    3.     public Foo m_foo;
    4.  
    5.     void Test() {
    6.         Renderer a = m_monoBehaviour.renderer;
    7.         Renderer b = m_foo.renderer;
    8.     }
    9. }
    You're saying that in Test(), the attempt to assign a will throw an error, while b will get assigned Foo.renderer. Do I have that right?
     
  10. makeshiftwings

    makeshiftwings

    Joined:
    May 28, 2011
    Posts:
    3,350
    Yes, but more than that, it will throw an error if you do this:
    Code (csharp):
    1. ((MonoBehaviour) m_Foo).renderer;
    or this:
    Code (csharp):
    1. public void SomeOtherFunction(MonoBehaviour stuff) { Renderer a = stuff.renderer; }
    2.  
    3. //somewhere else...
    4. SomeOtherFunction(m_Foo);
     
    Kiwasi likes this.