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
  4. Dismiss Notice

Anyone here abandon Unity for another engine only to return later?

Discussion in 'General Discussion' started by Kev00, Sep 11, 2020.

  1. neginfinity

    neginfinity

    Joined:
    Jan 27, 2013
    Posts:
    13,325
    What's wrong is that it does not immediately and clearly indicates an issue and instead hides the problem under the rug - meaning into a logfile. Which creates a hidden bug, potentially.

    My point is that you shouldn't be required to do that. And having a language directive for "non-nullable" value that would result in a strong compile error would simplify code great deal.

    Basically, writing boilerplate a lot may indicate missing language feature, as repetetive tasks should be automated and done by compiler.

    That's not true. Not existing is not a fundamental property of an object in OOP.

    See C++ for an example. C++ object cannot "not exist". It is either declared or not. If it is declared, then it is there, and it exists. However, there's a separate type which is a "pointer to object", and that pointer can "point at nothing" and that would be null. However, pointer to an object, is not that object.

    C# conflates those two different concepts into one. And that creates a mess.
    ------
    That's assuming the tool has a mechanism programmer could use in the first place.

    For example, Python does not have strict compile-time type checking, no matter how you go about it.
     
    Last edited: Sep 17, 2020
    Mark_01, Deleted User and MDADigital like this.
  2. MDADigital

    MDADigital

    Joined:
    Apr 18, 2020
    Posts:
    2,198
    if you write

    Code (CSharp):
    1. if(something == null) return;
    Thats a silent fail and its very much the devs fault
     
  3. MDADigital

    MDADigital

    Joined:
    Apr 18, 2020
    Posts:
    2,198
    Nullable reference types in C# 8 fixes this. I use it at my dayjob. Though none nullable types can never be null so it can be a pain when you turn it on :p

    A simple DTO that looked like

    Code (CSharp):
    1. public class MyDTO
    2. {
    3.    public Foo Bar {get;set;}
    4. }
    Will now fail. It needs to be either decalered as nullable (which defeats the purpose) or change to

    Code (CSharp):
    1. public class MyDTO
    2. {
    3.    public MyDTO(Foo bar)
    4.    {
    5.       Bar = bar;
    6.    }
    7.  
    8.    public Foo Bar {get;set;}
    9. }
     
  4. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,516
    That's the class. The term "object" refers to instances of a class,and they do not have to exist.

    Separately to that, there are plenty of cases where I want to be able to optionally not have something. Eg: Does the object I just collided with have a Health component attached? Eg: In the Inspector, specify the target object <I>if desired</I>.

    Null isn't the only way to specify that, but the concept of being able to refer to nothing is useful.
    How does that excuse a programmer for doing a silent early exit? Sure you may have less info than you'd like, but you should still communicate what you can.

    Blaming errors on the existence of nulls (the original post of this tangent, not yours) is just passing the buck. I checked if it was null. I correctly identified it. I even did something about it! But I chose not to call attention to it, then blamed my tools...

    (Is this "spewing hatred"?)
     
  5. MDADigital

    MDADigital

    Joined:
    Apr 18, 2020
    Posts:
    2,198
    Most of the time there is a better way of doing it than checking for null. In collision case a lookup with all the possible componenets it can collide with. for example.

    ANother example is GameObject A have two main Systems attached SystemA and SystemB. But here is also a variant of GameObject A called gameobject B that does not need SystemB. If SystemA and B are totally self aware and does not rely on Gameobject A/B or SystemA you can simply remove SystemB component and the gameobject will just work without any fragile null checks
     
  6. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,516
    So don't do it. If I detect an invalid case I'm very loud about it, because I want a developer to run into it and fix it. I don't want it hidden. Error messages are your friend.

    "Graceful degradation" is a thing which gets taught at University and such and I think the point is often missed. We should make things as nice as possible for our users, but during development we should be loud. Make sure developers are unmistakably informed that there is something they need to fix.

    Also, provide useful error messages so they know what to fix, or where to look.
     
    ippdev, OCASM and Billy4184 like this.
  7. MDADigital

    MDADigital

    Joined:
    Apr 18, 2020
    Posts:
    2,198
    Code (CSharp):
    1. if(something == null) throw new ArgumentException("foo");
    Is much better since now we do not silent fail and its easier to pin point were the fault lies. But its still code smell. Since the existence of a null object is a indicator your domain has low cohesion.
     
  8. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,516
    Neither of those sound "better" to me, because they both just move the complexity around. It is, at best, quite subjective.
     
    NotaNaN likes this.
  9. MDADigital

    MDADigital

    Joined:
    Apr 18, 2020
    Posts:
    2,198
    No existence of null check is an indicator of low cohesion, its objective.

    Null means, this part of the code is redundant to execute here. Ask yourself why did it execute
     
  10. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,516
    I'll happily ship "smelly" code. I've chased textbook perfection before, and quickly found that being dogmatic about it was far more harmful than helpful.
     
  11. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,516
    I wasn't commenting on "cohesion", I was commenting on "better". And I'm done here.
     
    MadeFromPolygons likes this.
  12. MDADigital

    MDADigital

    Joined:
    Apr 18, 2020
    Posts:
    2,198
    Its fine to ship smelly code, but when we run into smell we should take a minute and see if we can refactor.
     
  13. MDADigital

    MDADigital

    Joined:
    Apr 18, 2020
    Posts:
    2,198
    We are not talking class definitions here, we are talking how objects are allocated.
    Per default the object is allocated on the stack and cannot be null, since its not a pointer.

    Objects in C++ are structs per default
     
  14. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,516
    Haha, whoops. I did indeed read that as "defined" rather than "declared".
     
  15. Ricks

    Ricks

    Joined:
    Jun 17, 2010
    Posts:
    650
    Similar experience here. Also didn't do gamedev in years, except updating a mobile game until recently (from 5.x). In doing so I definitely got annoyed of how slow and bloated Unity has become. Even the installation has become annoying with its UnityHub crap, buggy installation, and also being very invasive when you look in how many places Unity creates files for whatever purpose, and which are a nightmare to clean up after uninstall. And even the Unity website itself has become awful to navigate and understand.

    I can't say much about the sudden different render pipelines other than it confused me even more, asking myself "is this really necessary?", and wondering about their new features (like Dots) as if there aren't more important things to do first, like solving bugs or implementing some convenient, frequently used features for games.
    Talking of bugs I remember that only after 2-3 years after finishing the game I received reports that a bug has been solved, which felt kinda ridiculous then. And that's surely not an isolated case.
    Or to mention an example for frequently used features: Tweens. They are frequently used in all kinds of games, so that you'd expect it now as a part of the game engine and not 3rd party assets only. But it's still not. Instead they rather focus on alien design patterns for games... I mean... Come on!
    Or another example is being able to Save() a Vector3 in PlayerPrefs without splitting it into 3 separate PlayerPrefs values. It's perplexing that this is still not possible after all these years, and requires 3rd party extensions or workarounds such as using "Megastrings". And while they implemented some xml file method in 2019, it doesn't mean the original way of saving things should remain as primitive forever.
    I then also looked up the "community feedback/suggestions" webpage where you originally could vote for new engine features - only to find out it has been removed...what?! So the community has no voice anymore and a couple of companies dictate the way Unity goes? Wtf has happened?

    Anyway... so what's the alternative?

    Unreal Engine 4? Not really. This monster is even bigger to chew.

    Godot? Uhm... not yet. It lacks some real quality of life features, such as a Playmode in the editor or a Terrain-Editor (only exist as rough 3rd party plugins), has a clunky UI, etc. For now it's imo only usable for tinkering around, but not to get games *done*. This might change in version 4.0 or later, but that's still some way to go. (P.S.: though I was surprised to see they have Tweens integrated into the engine).


    All that being said, I didn't find an alternative to Unity. In the end Unity still seems to be the best tool to get games done. But I don't like what it has become and where it goes.
     
    Last edited: Sep 17, 2020
    LogicFlow, IgnisIncendio, Ony and 4 others like this.
  16. neginfinity

    neginfinity

    Joined:
    Jan 27, 2013
    Posts:
    13,325
    I spoke specifically about instance and not its class. "object" == "instance", "class" == "object's type"

    That's why pointers are a thing.

    While the concept is useful, it doesn't make much sense to add it to every single thing by default.

    Silent early exit is not related to existence of type system.

    In my opinion, that's a valid criticism of the language.

    Language needs to offer tools to make programmer's life easier.
    For example, in Python you can (try to) return non-existing variable which will result in a runtime problem, and can create a heisenbug. In C++ and C# this issue will be caught at compile time, and this particular heisenbug will not occur.
    Code (csharp):
    1.  
    2. import random
    3. def boom():
    4.     if (random.randint(0,10000) < 10):
    5.         return nope #nope is undefined. Will crash at runtim
    6. boom()
    7.  
    The cool thing about this example is that you can't reliably catch it with unit testing either.

    Now, for example, consider situation where you're working with a language that does not have closures and the only form of flow control is goto. That will make things more difficult, and complaining about lack of "code blocks" would be a valid criticism.

    Same thing goes for nullable values.

    A nullable object has an invalid state where it is unusable, but said state is permitted by the language. And that state is built into everything. Null state of an object is a possible fault point, and every subroutine that deals with a nullable object need to account of possibility of null happening. And that is something you can forget to do.

    Rather than trying to account for an invalid state, it would be better to make it so the invalid state cannot occur. Removing null completely is one way to do it. That's how C++ works with pointers, by the way. If the object has to be there, you pass it by value or reference (reference cannot be null, it is always valid). If the object is optional, you pass it by pointer. A pointer can be null.

    ------

    Either way this should be probably moved into separate discussion, not that I have anything else to say on the topic anyway. My opinion is that language and frameworks should offer a way to eliminate all possible fault points at compile time, instead of moving handling of failures to runtime.
     
  17. MDADigital

    MDADigital

    Joined:
    Apr 18, 2020
    Posts:
    2,198
  18. MadeFromPolygons

    MadeFromPolygons

    Joined:
    Oct 5, 2013
    Posts:
    3,878
    Maybe its time to get back on track and talk about what the OP posted about, and move the talk regarding languages capabilities and coding practices to their own thread :)

    Its all interesting stuff, just I think we can all agree that this much of it does not belong in this particular thread.
     
    Ony, NotaNaN, OCASM and 7 others like this.
  19. Neonlyte

    Neonlyte

    Joined:
    Oct 17, 2013
    Posts:
    505
    I see some others complaining about “bloating” in other threads, but I am not sure what they are referring to, same with this case. Could you give an example?
     
    Antony-Blackett and koirat like this.
  20. Zuntatos

    Zuntatos

    Joined:
    Nov 18, 2012
    Posts:
    612
    I abandoned unity C# to move some hot code to a rust DLL, and then moved back to the burst compiler when that became a thing. Does that count?
    Interop is way easier via burst, and it is easier to deal with CPU feature support (sse2 vs sse4 vs avx etc). Also way easier cross platform.
     
    LogicFlow and tim_jones like this.
  21. Antony-Blackett

    Antony-Blackett

    Joined:
    Feb 15, 2011
    Posts:
    1,772
    I have some examples the other way:

    Remember when you had to add a rigidbody to every collider you ever wanted to move or enable and disable, even once to avoid a massive frame stall? That was bloat.

    Remember when you had to write your own UI system because there was none? That was bloat.

    Remember when you had to write your own animation controllers because the basic animation component didn't do any logic at all? That was bloat.

    Remember when you had to write your own build processing system to inject anything at all into an iOS xCode project or if you wanted to swap scenes or assets in scenes between platforms? That was massive bloat!

    Remember when you couldn't nest prefabs and you had to build instantiation scrips to spawn all the prefabs into another object? That was bloat.

    Remember how you had to write your own shader code and often do different versions for different platforms because Android always had bugs? That was bloat.

    All these things and many many more things continue to improve. I think the main issue here is people are unwilling to learn new things. You solve a problem once and it's frustrating to have to revisit it again later, i get it... but that's progress and you're never going to get away from that.


    P.S. I just installed 2020.1.6f. Wish my luck!
     
    Last edited: Sep 17, 2020
    LogicFlow, Mark_01, protopop and 2 others like this.
  22. Antony-Blackett

    Antony-Blackett

    Joined:
    Feb 15, 2011
    Posts:
    1,772
    Prefab in-context editing is awesome!

    Screen Shot 2020-09-18 at 10.56.48 AM.png


    Remember when you didn't have any context about the prefab you were editing in relation to the parent object it was nested in? That was workflow bloat.
     
    PutridEx likes this.
  23. koirat

    koirat

    Joined:
    Jul 7, 2012
    Posts:
    2,009
    This is YAGNI I was talking about previously.
    When it comes to unity I would say we got underbloat. You need content to make bloat ;)
     
  24. Ryiah

    Ryiah

    Joined:
    Oct 11, 2012
    Posts:
    20,137
    Meanwhile in the time frame between Unity 5.0 and Unity 2018 we went from reasonably priced desktops only having four cores to having sixteen, graphics hardware easily doubling in performance and memory capacity, large solid state drives becoming affordable, etc.

    Yes, it is slower than it used to be and they could stand to better optimize it, but it's not that much slower unless you're on an older computer. Just as an example I saw a thread a few days back where someone was having to wait six minutes for the SRP templates to fully load, but that's because they were on a computer missing everything you would expect from a modern PC (eg no SSD at all). I'm seeing at most 30 seconds with a fairly average computer (~$1,000 budget).
     
    MadeFromPolygons likes this.
  25. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,516
    Half of my point is that it isn't necessarily an "invalid" state.

    Example:
    Code (csharp):
    1. void OnCollisionEnter(Collider c)
    2. {
    3.     Explodable e = c.GetComponent<Explodable>();
    4.     if (e != null)
    5.     {
    6.         e.Explode();
    7.     }
    8. }
    It is completely valid, useful and even convenient to be able to return nothing. I'm not saying it's a good model to use in all cases, or that I think C# has always made the best decisions for common game / sim development cases (it hasn't), but the mere existence of null is a positive as far as I'm concerned.

    Its overuse is a different matter. :)
     
    pcg and Martin_H like this.
  26. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,516
    PlayerPrefs was never meant to be a way of saving anything other thatn Player Preferences, and it does that perfectly acceptably. We've had a full .NET environment at our disposal since the start, which includes a full set of file IO tools.

    Something I would agree with is some generic functionality to help out with managing data being saved to / loaded from disk. But I can kind of understand why that stuff is left to us - if we're separating data from functionality and we design our data well, that's most of the work done by default.
     
    NotaNaN, Ryiah and bobisgod234 like this.
  27. Ryiah

    Ryiah

    Joined:
    Oct 11, 2012
    Posts:
    20,137
    That said you only need a basic understanding of serialization to bypass the limitations imposed by Unity.

    Code (csharp):
    1. PlayerPrefs.SetString("MyVector", JsonUtility.ToJson(myvector));
    Code (csharp):
    1. myvector = JsonUtility.FromJson<Vector3>(PlayerPrefs.GetString("MyVector"));
     
    Ony, Billy4184 and angrypenguin like this.
  28. tmcdonald

    tmcdonald

    Joined:
    Mar 20, 2016
    Posts:
    160
    I'm not trying to be argumentative, as I fully agree with your argument, but there is no reason why this can't be implemented using the TryX model, where it returns a bool indicating success and has an out variable that gives you the object on success (that object happens to be null on failure generally but I mean, can't win 'em all.)
     
    angrypenguin likes this.
  29. koirat

    koirat

    Joined:
    Jul 7, 2012
    Posts:
    2,009
    OK but.
    Anyone here abandon Unity for another engine only to return later?
     
    LogicFlow, Ony, NotaNaN and 2 others like this.
  30. AcidArrow

    AcidArrow

    Joined:
    May 20, 2010
    Posts:
    11,011
    I think the answer is mostly no.

    Some people left. They haven't returned. A bunch of people are thinking of leaving.
     
    LogicFlow, Ony and Martin_H like this.
  31. Ryiah

    Ryiah

    Joined:
    Oct 11, 2012
    Posts:
    20,137
    This. I have seen some threads by people who left and then later returned but to be honest the ones that I remember the most were people who were constantly switching between engines. One of them had a good looking pet project too but it never saw the light of day thanks to this behaviour.
     
    LogicFlow and AcidArrow like this.
  32. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,516
    And that's already a better solution to me than the others suggested before. I still wouldn't call it better than just having "null" in that specific use case, though, as it's using an additional variable and slightly increasing code complexity and cognitive load to achieve... exactly the same result.

    Edit: Plus, wouldn't that result in a whole object existing because the 'out' can't be unpopulated? That has negative side effects of its own. I'll admit that I haven't fully thought through and explored the whole "what if there was no 'null'?" thing because it just seems so academic to me.

    And others do use different tools, but don't consider it to be "abandoning" or "leaving" because they're just tools.
     
    AcidArrow likes this.
  33. neginfinity

    neginfinity

    Joined:
    Jan 27, 2013
    Posts:
    13,325
    My point is there's no good reason to have nullability as default trait of every (reference) type.

    Your example actually demonstrates my point, because the code does not check for Collider being null, and is written with assumption that Collider c will be always valid. Meaning there's already a possible fault point in just a few lines of code.

    The example coudl be better if you could tell that Component c has to be always valid. This can be done either by introducing "non-nullable" type, or doing things C++ way, where reference and object are two separate concepts.
     
  34. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,516
    For sure, and that's an assumption I do make, because I trust that the caller code from Unity won't execute if there is no Collider. I agree it's a potential fault point, but having not once run into that fault since Unity 1.6 it's not one I concern myself with at this stage.

    Plus, that's one that'll be reasonably "loud" on its own if it does happen.

    I completely agree. I'm simply arguing that the ability to represent "nothing" or "the absence of an object" is a good thing.

    While I understand why the designers went a different way, I also wish that C# could do a lot of stuff that C++ can. Const is something I really wish we had, for instance.
     
    neginfinity likes this.
  35. neginfinity

    neginfinity

    Joined:
    Jan 27, 2013
    Posts:
    13,325
    I agree with that. const, const methods and const correctness.
     
  36. Ryiah

    Ryiah

    Joined:
    Oct 11, 2012
    Posts:
    20,137
    MadeFromPolygons likes this.
  37. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,516
  38. ippdev

    ippdev

    Joined:
    Feb 7, 2010
    Posts:
    3,793
    Never once in 11 years of near daily pro use of Unity have I ever had to use throw new ArgumentException. That is something IMHO enterprise coders do. The Unity console works just dandy if you PAY ATTENTION to it, know how to use the software and not impose MS dev styes on it as yer boss did so infamously with his trigger pull system.. It looks like code smell to me. You should handle any possible exceptions with a debug.log or conditional. Pass your code off to a designer and it throws that exception then WTH is he supposed to do..scratch his head and murmur under his breath thinking he doesn't know WTF he is doing? They way I do it the designer can send me an email with the console print out and I know exactly what to do about the issue.
     
    Ony likes this.
  39. ippdev

    ippdev

    Joined:
    Feb 7, 2010
    Posts:
    3,793
    I almost left, but one of the actual coders of the desktop platform personally solved a longstanding showstopper for me and when i went into Unreal the fact that its Z axis did not point forward trashed about 5000 of my ease of use 3D objects i have created in C4D over the past 20 years. i was not going to rotate everything orthogonally and deal with that mess. So I am back here. I can write C# components nearly as fast as i can write this post. Way faster than their blueprints wiring can ever hope to get. Seems Unreal's big selling point is near real grfx. I do not need that. I need good gameplay mechanics I can execute rapidly.
     
    protopop likes this.
  40. bobisgod234

    bobisgod234

    Joined:
    Nov 15, 2016
    Posts:
    1,042
    Uncaught exceptions will end up being logged to the console anyway, so it still works that way too.



    For all of Unity's faults, I have never really found a replacement engine.

    UE4 has fiddly noodle graphs (or C++, which is kind of overkill for smallish projects).

    GameMaker has somehow managed to do the opposite of what Unity and other game engines have done and charge more upfront. GameMaker 2 is quite expensive now. It's a shame because I quite liked using GM for making 2D games.

    I tried Godot's visual scripting as a replacement for GameMaker for the purposes of teaching programming, but had some nasty experiences with it wiping scripts randomly. The builtin scripting language works better, but the whole engine still feels a bit immature at the moment.

    I am quite looking forward to giving UE5 a go though.
     
    Last edited: Sep 18, 2020
    Martin_H and angrypenguin like this.
  41. MDADigital

    MDADigital

    Joined:
    Apr 18, 2020
    Posts:
    2,198
    Code (csharp):
    1. void OnCollisionEnter(Collider c)
    2. {
    3.     if (Explodable.TryGet(c, out var explodable))
    4.     {
    5.         explodable.Explode();
    6.     }
    7. }
    Code (csharp):
    1. public static bool TryGet(Collider c, out Explodable explodable)
    2. {
    3.     if (Lookup.ContainsKey(c))
    4.     {
    5.         explodable = Lookup[c];
    6.         return true;
    7.     }
    8.     return false;
    9. }
     
    Last edited: Sep 18, 2020
  42. tmcdonald

    tmcdonald

    Joined:
    Mar 20, 2016
    Posts:
    160
    We did mention the TryGet pattern, but there is an issue with it to some extent (which your example doesn't cover and why it won't compile unless I'm missing something, which I might be): you have to assign an "out" var before leaving the scope of the method, so you're either going to assign null or default or perhaps, for every single class, you'll have a static read-only "empty" version of the class that you use to assign in this case. I think the only way to avoid a null here is to have the TryGet take an Action<Explodable> parameter and only run it if the object is found, in true functional style I guess.
     
    angrypenguin likes this.
  43. MDADigital

    MDADigital

    Joined:
    Apr 18, 2020
    Posts:
    2,198
    Thats c# 7 syntax sugar, it works in Unity 2018 and forward.

    before c# 7 you had todo

    Code (csharp):
    1. void OnCollisionEnter(Collider c)
    2. {
    3.    Explodable explodable;
    4.     if (Explodable.TryGet(c, out explodable))
    5.     {
    6.         explodable.Explode();
    7.     }
    8. }
    edit: its not the try get that is the thing though. It that we have replaced null check with a domain driven approach
     
  44. neginfinity

    neginfinity

    Joined:
    Jan 27, 2013
    Posts:
    13,325
    C++ has concept of const correctness and const methods, and those are highly desirable features (for me at least)

    Basically a class method can be marked const, which would indicate to compiler, that this method is not allowed to alter class state. At all. And any attempt to alter class from within this method in any way, will result in a hard compile error you cannot disable. As a consequence, const methods cannot call non-const methods.

    What does it mean for a programmer... correct use of const creates a huge safety net of methods, where you're one hundred percent certain that "this method does not alter this class". Which helps a great in bug prevention.

    Then there's a const reference. Where you pass an object by reference, but are not allowed to alter it in any way. Which also helps a great deal. In comparison, in C#, any function that receives a reference type as argument is allowed to wreck that reference type however it wants... which is why people use immutable objects in C#. Unfortunately, immutable objects mean increased garbage generation in a GC language.

    It seems there's work being done when it comes to const arguments, however:
    https://docs.microsoft.com/en-us/dotnet/csharp/write-safe-efficient-code
     
  45. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,516
    My issue with the TryGet example is that the point has been missed. My point with the original Explode() example was that a value representing "nothing" is often useful.

    The length that is apparently being gone to in order to avoid needing "null" - which, again, is valid here - supports that. The resulting code ends up with exactly the same result, but more work to get there, in this case to achieve some academic ideal.

    I see the value in a non-nullable variable too, of course.

    I don't think that's what @tmcdonald is talking about with the compile error. The TryGet method doesn't assign anything to the out parameter before returning false. Is that not a requirement?

    That's specifically the bit I'm keen for.
     
    Last edited: Sep 18, 2020
    ippdev and tmcdonald like this.
  46. MDADigital

    MDADigital

    Joined:
    Apr 18, 2020
    Posts:
    2,198
    ops true. Difference is though that we do not rely on null value we use the boolean. But still, you need to set it to null in the false branch of the code.

    There are better examples. For example my earlier one with componet A and B.
    If you have a member on a class that can be null and you constaly need to check it for null. Its probably a indication that property should be extracted out of there.
     
  47. tmcdonald

    tmcdonald

    Joined:
    Mar 20, 2016
    Posts:
    160
    Sorry, I didn't mean "out var" (which I use all the time), I meant returning false without setting the out variable to null (which means that the variable is still declared and null is set to it in the calling method.)

    Here is an example of what I was referring to (which is sort of a modified version of one of those "async TryToDoAThing" that I've had to do a few times:

    Code (csharp):
    1.  
    2. public static void IfComponentExists<T>(Collider c, Action<T> componentAction) where T : Monobehaviour
    3. {
    4.     if (Lookup.ContainsKey(c))
    5.     {
    6.         componentAction(Lookup[c]);
    7.     }
    8. }
    9.  
     
  48. MDADigital

    MDADigital

    Joined:
    Apr 18, 2020
    Posts:
    2,198
    Yeah see my answer above. Your solution works, but there is risk you will allocate with a lambda so be careful. :)
     
  49. tmcdonald

    tmcdonald

    Joined:
    Mar 20, 2016
    Posts:
    160
    We should be able to cache the lambda. Actually, in the realm of "Anyone here abandon Unity etc." due to the garbage collector causing woes, does anyone know if the incremental garbage collector has solved some of the issues with having to deal with optimizing micro-allocations like this one? I know, for example, there are people who hate coroutines because of "yield return new whatever" causes allocations. Did the incremental garbage collector solve some of these issues?
     
  50. MDADigital

    MDADigital

    Joined:
    Apr 18, 2020
    Posts:
    2,198
    Garbage in OnEnter can be risky to allocate in. Say 200 objects enter within a few frames. Now we have 200 allocations that need to be de-allocated