Search Unity

  1. Unity Asset Manager is now available in public beta. Try it out now and join the conversation here in the forums.
    Dismiss Notice

Unity 5 Beta Insights

Discussion in 'Unity 5 Pre-order Beta' started by ImpossibleRobert, May 11, 2014.

  1. ImpossibleRobert

    ImpossibleRobert

    Joined:
    Oct 10, 2013
    Posts:
    531
    User10101 likes this.
  2. Nanity

    Nanity

    Joined:
    Jul 6, 2012
    Posts:
    148
    I'm loving it! Thanks for sharing.
     
  3. zenGarden

    zenGarden

    Joined:
    Mar 30, 2013
    Posts:
    4,538
    Thanks for the optimisation tips.
    For Unity 5 i think they have it working already, they shown global illumination working on mobile already, i think it won't take too long to make it enought complete and stable for a public release.
     
  4. shaderop

    shaderop

    Joined:
    Nov 24, 2010
    Posts:
    942
    That article has a strong linkbait-y vibe to it. The only real bit of information in there is the author's claim that convenient access properties like rigidbody and collider will be removed. Not deprecated as has been the case in the past, but outright removed, with some sort of VB6 to VB.NET conversion wizard poly-filling over it.

    I suppose it's possible, but seems improbable to me. Even if it's true, then it's more "insider information" than "insight."
     
  5. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,620
    I actually like that idea. And I did notice that there's no convenience "animator" field on MonoBehaviour.

    To be honest I've never liked those convenience fields (aside from gameObject and transform, given their relationship with the script), in so far as I've never understood the need for a bunch of variables pointing to things that usually don't exist. If you're going to use them you need to check that they're there anyway, so that may as well be a GetComponent<...> into a field you define yourself.
     
  6. Rodolfo-Rubens

    Rodolfo-Rubens

    Joined:
    Nov 17, 2012
    Posts:
    1,197
    According to Aras, this is not a big deal, just a syntax change.
     
  7. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    It's more or less random whether the "shortcut" properties exist for any of the built-in components. Removing them (except for Transform, which always exists) makes things more consistent and less confusing, as I can attest to after answering many questions about this over the years. The article isn't particularly accurate anyway, as noted by Aras in his comment.

    --Eric
     
  8. lilymontoute

    lilymontoute

    Joined:
    Feb 8, 2011
    Posts:
    1,181
    Yep, it also clears up name collisions quite a bit, so you can just name some renderer component "renderer" without worrying about that name already being used by Unity.
     
  9. VIC20

    VIC20

    Joined:
    Jan 19, 2008
    Posts:
    2,689
    ? Why do they keep the transform shortcut?

    To be honest, the information is pretty hidden in the manual. If I remember correctly you even have to click on some "show" button to see it. It should be on top of the manual but instead this bad style is propagated everywhere in the examples of the manual.
     
  10. shaderop

    shaderop

    Joined:
    Nov 24, 2010
    Posts:
    942
    Because you can't have a GameObject without a transform. It's always there and is guaranteed not to be null.
     
  11. jonas-echterhoff

    jonas-echterhoff

    Unity Technologies

    Joined:
    Aug 18, 2005
    Posts:
    1,666
    I can confirm this change it is going to happen. The reason is not only consistency of API (but that is a big one, currently it is very random whether a component type has an custom getter or not), but also enabling better modularization of code. Ie, by having these accessors, we have hard coded dependencies from MonoBehaviour (which defines these accessors) to other subsystems like Physics (.collider), which is ugly and makes code less stripable (think build sizes).
     
  12. Per

    Per

    Joined:
    Jun 25, 2009
    Posts:
    460
    Hmm, I understand why UT would do this. The change is more explicit and simplifies things considerably. However it does have two negative side effects.

    Firstly you get much more verbose code to do the same thing. Counter to the above arguments this makes it more prone to error and harder to maintain. It also doesn't force anyone into better coding habits just because it's convenient to hope so.

    Clearly there's strain showing between the existing object system of Unity and a flat non OOP front end now. Both should have changed rather than just one, at least GetComponent should be extended to replace the use of fluent interfaces in C# so you could just go

    component = object.GetComponent<FirstComponent, SubComponent, SubSubComponent>();

    Secondly it's far less beginner/user friendly, it's less "discoverable". Niceties like autocomplete cease to be workable. That's a real shame as for most human beings (i.e. people who don't prefer VI or EMACS, so the kinds of folk that would use Unity in the first place) visual autocomplete operates both to speed up typing and as a contextual help/search to see what's related or available for an object without resorting to the full documentation.

    Of course the Unity API is already fundamentally broken in that regards however I tend to err on the side of fixing things is probably preferable to ditching them, especially when it comes to useful things like core concepts of OOP (not everyone wants to go back to pure C nor views it as the ideal).

    As a developer I see the worth of the change. But as a user I worry that small changes like this do mount up and over time make it harder to justify the proposition that Unity is the user friendly option. Once that's gone I'm not sure exactly what the unity "value add." is.
     
  13. Deleted User

    Deleted User

    Guest

    C# as a language is much more friendly to beginners as a whole, especially considering C style shader languages. There comes a time when you have to cut the fat or the engine will remain excessively bloated, hard to support and inferior. Even OpenGL had to start deprecating to move forwards, if it improves the overall engine then a slight increase in verbosity can be forgiven.
     
  14. Devil_Inside

    Devil_Inside

    Joined:
    Nov 19, 2012
    Posts:
    1,119
    A welcome change in my opinion. I like when things are consistent.
     
  15. Aiursrage2k

    Aiursrage2k

    Joined:
    Nov 1, 2009
    Posts:
    4,835
    Not really a big deal but i guess you would to update all the code from the asset store to make it work with unity5. Could be a pain in the ass.
     
  16. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,620
    There's absolutely nothing to stop creation (or even inclusion as a standard asset) of something that addresses the issues you've raised, and it could quite possibly do so in a superior manner. If I had been tasked with solving the issues as a designer I very much doubt that my recommendation would have been "add references to MonoBehaviour". In fact, I'd have avoided that for precisely the reasons the Unity guys here have cited.

    As for core concepts of OOP, doesn't this change improve that? Encapsulation immediately springs to mind.
     
  17. Doddler

    Doddler

    Joined:
    Jul 12, 2011
    Posts:
    269
    I'm not really understanding his problem, you can just do it this way can't you?

    Code (csharp):
    1. GetComponent<Renderer>().GetComponent<Collider>().GetComponent<Rigidbody>().angularDrag = 0.2f;
    I mean this is a little longer, but it's not 4 lines of code long. That's what's going on behind the scenes anyways right?
     
  18. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,620
    I suspect that the 4 lines is coming from also assigning the thing to a locally cached variable (which many users recommend doing anyway) and/or checking that it actually exists (which I think is a good idea to do anyway).
     
  19. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Not that you'd ever chain GetComponent in the first place, or rather you shouldn't because there's no reason to. You can't have components of components, so it's just wasted work--all components are in a flat structure attached to a GameObject. Instead of doing gameObject.renderer.collider.rigidbody, you'd just do gameObject.rigidbody.

    --Eric
     
  20. ShilohGames

    ShilohGames

    Joined:
    Mar 24, 2014
    Posts:
    3,023
    Doddler: You do not want to call GetComponent in the Update routine, since that would cause a performance hit in every frame. Use GetComponent in the Awake routine to get a reference to an object and store it in a variable, and then use that variable in the Update routine.
     
  21. Doddler

    Doddler

    Joined:
    Jul 12, 2011
    Posts:
    269
    I was thinking that too... but I just went with a shorter version of his example, which chained the GetComponents for who knows what reason.

    Does using gameObject.renderer or gameObject.rigidbody now cause the same hit as GetComponent?
     
  22. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,620
    I don't know, because it actually makes zero practical difference to me.

    The way I do things means that if I reference something per-frame I have a local reference anyway.
     
  23. niosop2

    niosop2

    Joined:
    Jul 23, 2009
    Posts:
    1,059
    Yes, it's just syntactic sugar that compiles to a GetComponent call. Same runtime overhead, just shorter to type. I'm in agreement with either removing the calls so it's very evident what's happening, or making the .transform and friends cache the result on first use. Since you can't remove a component anyways, caching should be fairly safe. Although I'm sure someone will think of a situation where caching the component would cause problems.
     
  24. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,620
    Am I missing something?
     
  25. User340

    User340

    Joined:
    Feb 28, 2007
    Posts:
    3,001
    There are so many weirdnesses in this .rigidbody vs GetComponent<Rigidbody>() debate. See:

    1) Why doesn't .rigidbody automatically cache for you?
    2) Why is GetComponent() expensive? I'm sure components are a simple array behind the scenes.
    3) Why is Transform required? If you want to increase consistency then make Transform like any other component.
    4) Why is there only certain shortcut component accessors? Wheres one for TrailRenderer? (I know this has already been asked).
     
  26. arvzg

    arvzg

    Joined:
    Jun 28, 2009
    Posts:
    619
    I've often wondered about this too. Sometimes it actually makes little sense for an object to have a transform. Think of something like a GameManager, AudioManager, EventManager objects - they persist in the game without having an actual physical "being" (for lack of a better word). They're just things in the scene that exist but aren't actually in the scenes physically.
     
  27. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,620
    Transform (and GameObject) isn't "like any other component".

    Transform is required because you can't have a GameObject without a Transform. It makes sense to have that one there because the component is in fact guaranteed to be there, and one of Unity's underlying assumptions is that GameObjects have a position in space and a relationship with the scene hierarchy. There's always a 1:1 relationship, and the functionality of many other components depends explicitly on properties of the Transform.

    It's definitely true that sometimes it makes no sense for a GameObject to have a Transform. It does make sense for performance that the Transform (or something) handles both the spatial and hierarchical relationships together, though. It used to irk me, but eventually I got over it as it's a reasonable enough compromise.
     
    Last edited: May 12, 2014
  28. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,620
    Why do those things need to be attached to GameObjects, then? You can always make standard .NET classes.
     
  29. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    That's incorrect. It's cached, although not "as cached" as doing it manually. Speed goes, from slowest to fastest: GetComponent<Transform>() > GetComponent(Transform) > .transform > manually cached.

    It does.

    It's not that expensive, though it depends to some extent on the number of components attached.

    All GameObjects are located in 3D space, regardless of whether they are currently have anything that can be rendered.

    There are plenty more that don't. Someone has to decide to sit down and make a shortcut, and that doesn't always happen.

    Of course you can.

    --Eric
     
  30. jonas-echterhoff

    jonas-echterhoff

    Unity Technologies

    Joined:
    Aug 18, 2005
    Posts:
    1,666
    It is not. When you have scripts with the old syntax, Unity will ask you to automatically update your code. Just click yes, and it should work.
     
  31. jonas-echterhoff

    jonas-echterhoff

    Unity Technologies

    Joined:
    Aug 18, 2005
    Posts:
    1,666
    As others pointed out, there is never a reason to do that. Why get the Renderer, and Collider on the current GameObject, when you just want the Rigidbody? The above is equivalent to:

    Code (csharp):
    1. GetComponent<Rigidbody>().angularDrag = 0.2f;
     
  32. jonas-echterhoff

    jonas-echterhoff

    Unity Technologies

    Joined:
    Aug 18, 2005
    Posts:
    1,666
    That is not correct. The quick accessors (.rigidbody, .transform) were never internally cached in the first place. The only difference is that GetComponent<Type>() needs to map the mono type to an internal component type, which has some small additional overhead.

    Walking through the list of components to find the one you are looking for is really not that expensive. The bigger overhead probably comes from calling from scripting into native code. In most cases, the overhead of getting components is not something to worry about either way, but if you do something on a component in an inner loop or in an Update function of which you have thousands of instances, it probably does make sense to cache it (the profiler should tell you if your script code is worth optimizing).

    When we started out Unity, we only had a dozen or so different component types - it seemed reasonable to have the quick accessors. As Unity grew, we added many more components. Doing quick accessors for all of them seemed like it would unnecessarily pollute the namespace, so we did not decide to continue along this path, resulting in the inconsistent situation as it is now. With 5.0 we will fix that, by removing them all (except for .transform). Transform is special, because it is:
    -present always, so the code stripping concerns (one big reason why we did this) are not relevant here.
    -used much more then any other component, so it has a bigger practical use then the others.
     
  33. Jasper-Flick

    Jasper-Flick

    Joined:
    Jan 17, 2011
    Posts:
    959
    @jonas echterhoff: What will be the status of transform? A readonly variable in managed space - eliminating the need for caching - or still a call to native, or somewhere in between?
     
  34. SimonDarksideJ

    SimonDarksideJ

    Joined:
    Jul 3, 2012
    Posts:
    1,689
    Thanks for pointing out the article.

    Just to clarify, this changes nothing for now but it is something that exists in Unity today.

    Unity3D in it's modular layout does a lot of things under the hood and not all are understood, so the articles main aim is to educate script developers in Unity about a better way of achieving the same thing. The actual cost of using DOT notation in scripts to access components on a GameObject isn't really known.

    But in reality you should manage your references to components within your scripts and if you repeatedly use a certain component (say renderer or physics for example), it is good practice to maintain that reference in your class rather than trying to keep doing GetComponent everytime you access it. It's pretty much the same as doing GameObject.Find every frame, not a good idea.

    Just my 10 pence worth.

    Unity 5 plans aren't finalised and things may change. Let's wait for the official announcement from Unity to see their response.
    *My views are my own
     
  35. SimonDarksideJ

    SimonDarksideJ

    Joined:
    Jul 3, 2012
    Posts:
    1,689
    Interesting hadn't come across that term before. But no, I never write article to "get links".

    If you check the history of my blog, I only aim to educate or inform. (with the occasional book review if I think it's worth reading :D)
     
  36. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,620
    That really depends. Keeping a local reference is a great idea if a) you know it won't change and/or b) you're going to use it a lot. Outside of that, GetComponent<...> isn't anything to get upset over, and I'd do whatever provided cleaner code rather than whatever was "faster".

    And I'm not saying that "cleaner code" thing as a heathen who doesn't care about performance, either. That kind of optimisation is just rarely, if ever, where significant performance increases come from. Organizing large data effectively is far more important than nitpicking over how seldom used references are handled.

    Of course the other thing is making sure that things that can be seldom used are seldom used.
     
    Last edited: May 12, 2014
  37. mattbenic

    mattbenic

    Joined:
    Nov 24, 2010
    Posts:
    38
    I think it makes total sense to remove fields like this which introduce unnecessary dependency on unrelated classes for rare use (most components won't have any of these objects, never mind all of them).
    However the article linked in the first post seems to imply that the shortcut properties will still exist, but that the getters will be calling GetComponent<Type>-which would eliminate this benefit while just adding a hidden performance hit. Is this how they will work? Or will the properties be removed outright?
     
  38. SimonDarksideJ

    SimonDarksideJ

    Joined:
    Jul 3, 2012
    Posts:
    1,689
    I Agree completely, as with everything it is on a case by case basis and you should use what fits the situation.
    not saying don't use GetComponent (or even GameObject.Find), just use them sensibly.

    Fits an old saying that you should only tweak performance where performance needs tweaking. Although generally I find that it's better to architect it better from the beginning and only fall back when lots of code doesn't add anything. It is certainly a tricky thing to manage that only gets better with experience.
     
  39. SimonDarksideJ

    SimonDarksideJ

    Joined:
    Jul 3, 2012
    Posts:
    1,689
    One of the Unity devs seems to confirm that the change will happen (although subject to change :D)
    The shortcuts/properties do appear to be on their way out BUT there will be an automatic script upgrade feature to ease migration.
     
  40. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,620
    Yep, don't fix it after, design and build for it in the first place.

    That doesn't mean you should always be optimizing, it just means you should know how things work and design to work with them rather than around/through/despite them.

    I don't usually end up spending much time specifically optimizing, and when I do it's special hot-spot cases where a lot of work is being done with a relatively small piece of code.
     
    Last edited: May 12, 2014
  41. LukaKotar

    LukaKotar

    Joined:
    Sep 25, 2011
    Posts:
    394
    Honestly, I think it's a good idea. It will force people to code more efficiently. My only concern is that Unity would attempt to "fix" all existing code while upgrading the project, resulting in potentially unwanted behavior. Working around the dot notations manually (error by error) could save time and massive headaches.

    I currently cannot afford Unity 5, but just to be on the safe side, I've been trying to adapt my code for Unity 5 compatibility. I soon encountered an issue:
    Code (csharp):
    1. ... Type `UnityEngine.RaycastHit' does not contain a definition for `GetComponent' ...
    How does one access the 'Transform' component of 'RaycastHit' without using the "dot" notation?
     
  42. squared55

    squared55

    Joined:
    Aug 28, 2012
    Posts:
    1,818
    I don't like this. Unity shouldn't be forcing how I code. Not only that, but I don't want to have to fix all my scripts, end up with longer code, and still get the same result.

    People who want to code this way already can. People who don't, shouldn't have to.
     
  43. Jasper-Flick

    Jasper-Flick

    Joined:
    Jan 17, 2011
    Posts:
    959
    @LukaKotar: The "dot" notation is no official thing. The convenience properties of components will be gone in MonoBehaviour, that is all. Don't go change anything else.
     
  44. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,620
    Check the docs for RaycastHit, you do it via the collider. Also, it's not a MonoBehaviour or even a Component, so it's not what's being discussed here.

    All that's being discussed is the built-in references in MonoBehaviour for some built-in components. There's nothing wrong with dot notation itself. You wouldn't get far without it!
     
    Last edited: May 12, 2014
  45. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,620
    They aren't, and you don't have to. If you really want to do things the same way then making a wrapper for MonoBehaviour which defines and auto-fills those fields will be pretty easy. Also, you could provide access to other components that MonoBehaviour is "missing" if you were to do that.

    Plus, this isn't about "forcing how you code". It's about making things better on the back end and more consistent on the front end.

    @Unity: It could be worth bundling such a MonoBehaviour wrapper out of the box, and providing a context menu option to use it directly. Best of both worlds.
     
    landon912 likes this.
  46. LukaKotar

    LukaKotar

    Joined:
    Sep 25, 2011
    Posts:
    394
    @Jasper @angrypenguin Thanks for clearing that up, seems I misunderstood completely. I will have to re-read the blog post.
     
  47. SimonDarksideJ

    SimonDarksideJ

    Joined:
    Jul 3, 2012
    Posts:
    1,689
    Yup it would be fairly easy to write a small trunch of extension methods to replicate the DOT notation between components. Might even end up writing some of them myself and submitting them to Nick Gravelyn's excellent opensource script resource https://github.com/nickgravelyn/UnityToolbag

    But in my view, you would still only want to use this when there's no need for a reference and it's more of a one time thing.
     
  48. squared55

    squared55

    Joined:
    Aug 28, 2012
    Posts:
    1,818
    That would be great. :)


    But why does Unity care how I write my scripts, as long as it compiles? The very nature of scripting means consistency gets thrown out the window. Unless they want to make work easier for Support? Or there's some speed boost by not having "."?

    Or when you're automatically getting said reference.
     
  49. LukaKotar

    LukaKotar

    Joined:
    Sep 25, 2011
    Posts:
    394
    I imagine they want to encourage caching components inside the Start() or Awake(), which would result less work on the CPU.
     
  50. squared55

    squared55

    Joined:
    Aug 28, 2012
    Posts:
    1,818
    But that should be my problem, not Unity's.