+2
Answered

Null variable values causing invalid operation exception

odyssey96 2 years ago updated by pixelman 10 months ago 11

I have defined a object variable named 'Toggle Group' set type to Game Object and left value to none.  When I perform the following:


an InvalidOperationException is generated at the object equals unit - missing target object.  When I stop playback, inspecting the object variable, the type is (null) i.e. not a gameobject anymore.  I see this thread

https://support.ludiq.io/forums/5-bolt/topics/870-object-variable-type-set-to-null-when-exiting-play-mode/

So I know why this is happening - but this then seems to me that object variables MUST have a value set i.e. I wanted to be able to specify a game object reference on some object variables, and if a reference is set then do some logic, if not do some other logic.  So even in the worst case scenario, I'd see some prefab instances with their game object variable as not even defined (instead of seeing, oh I'm expecting a variable of type gameobject) but Bolt seems to validate so you wouldn't be able to perform this null comparison at all?  Easy to workaround, but just wanted to make sure this is the case?


Bolt Version:
Unity Version:
Platform(s):
Scripting Backend:
.NET Version (API Compatibility Level):
+1

I'm not sure why == null generates an error, but in the meantime, take a look at "Null Check" and "Null Coalesce" units.  The former rolls a null check and branch in one, the other takes a fallback value if the input is null.

+1
Answered

That's normal; you're basically trying to write this code: null.Equals(null). Your choices:

  • The other static object equals method that doesn't work with a target
  • The equals unit (look for the pink math symbol)
  • The null check unit (recommended, because it handles Unity nulls better)
+1

Ah crap - this is my bad.  I didn't realise when looking at the graph (long day) this was the Object.Equals method I was using, I just typed equals and was meant to type equal '.e to get the 'bolt unit' ==.  So sorry guys for wasting time :( >facepalm< 

i saw in one book for Unity  -   that  using reference equals is better for perfomance then null check 
but in bolt u cant  recreate this code /  check will be false if you delete obj with FlowMashine

but if you set it to none by hand  it will work

ReferenceEquals.zip

its not big issue for me  becouse they say it is few nanoseconds of perfomans boost and is more like a overkill to do this.

+1

I don't know which book you read this in, but it's actually a very bad idea to do that in Unity! Because Unity object references are wrappers around native pointers, they overload the equality operator to return true to a null comparison when their native pointer is no longer valid. ReferenceEqual won't catch this case, so for example, your object won't be null after having been destroyed!

ty for answer , i will be carefull with books and use null check)

book is this one 

https://www.amazon.fr/Unity-2017-Game-Optimization-performance/dp/1788392361

that is full chapter how he describe his decision

+1

It might be faster, but it is exceedingly dangerous to do in Unity, because when you do == null in Unity, you're actually checking for more than whether the reference is null.  You're also checking whether the Unity has destroyed the object.  

While the author is correct about the memory layout, they are incorrect that the ReferenceEquals is "functionally equivalent".  In normal C#, they are equivalent for most reference types, but == and .Equals can be overridden to change the default behavior, whereas ReferenceEquals cannot.  

Variables don't become null once Unity destroys an object. Internally the C# object still exists until it is no longer referenced, then it is garbage collected.  Unity's overrides the Equals (implicitly called by ==)  to check for both null and destruction for you so that you don't have to worry about this nuance.

You can get Unity's own analysis of this here:
https://blogs.unity3d.com/2014/05/16/custom-operator-should-we-keep-it/

This optimization won't be performing this check, and is a pure check for null, which will only catch uninitialized variables and those explicitly set to null. 

Also, unless you're in extreme optimization settings, this sort of tweak is not usually worth the headache, as "double performance" of an extremely, extremely small operation is completely negligible compared to the other tasks that are performed by the program.  The author is trying to convey this at the end of the last referenced paragraph.  If you're doing this in a tight loop a thousand times a frame, it might be worth it, but 30 times a second isn't going to be noticeable.  In general, you'll get far more results from optimizing the algorithms and hierarchy than from optimizing single statements.

Reality.Stop()  ty for answer,link and interesting information)

P.s  I tried to check nulls with AOt remove  or  List remove item . it work properly even if it says  can be null at first and then not/   it   loop over list   and remove all nulls even after deleted objects

is it like checking equals and its still better to use null check ?

after tests its not good cos its dont  wait for the end of checking all list . flow will continue and it can be mistakes . standart Forloop  with null check is more predictable

+1

Hi Nikita!

Unfortunately this is a known issue we can't do anything about. Bolt's warnings are excessively aggressive with Nulls. You can disable them entirely if you have too many false positives like these, see: https://ludiq.io/bolt/manual/flow/debugging#null-references

I have issue with "Null". I realize that it has been 5 months since the above discussion. Any luck the issue been fixed? Or perhaps if someone have the solution to fix my problem as attached image.