LazyLoadReference

Hello, today i was browsing trough unity s source code and i found LazyLoadReference, now i have a 2 questions:
1: Will this get backported??
2: Does this work at runtime?
Btw the way i do this in older unitys is like:

public class NoRefObject
    {
        private string _json;
        [SerializeField]
        private Object o;

        private int instanceId;

        public int ObjectInstanceId => instanceId;

        public NoRefObject(Object o)
        {
            if (o == null)
            {
                throw new ArgumentNullException("No ref object");
            }

            this.o = o;
            instanceId = o.GetInstanceID();
            _json = JsonUtility.ToJson(this);
            this.o = null;
        }
        /// <summary>
        /// Deserializes the internal json and returns the AssetReference
        /// </summary>
        public Object GetInstance()
        {
            JsonUtility.FromJsonOverwrite(_json, this);
            Object ret = o;
            o = null;
            return ret;
        }
    }

but this eats memory :(, i really hope this gets into older versions of unity

Not to 2018.4, unless they break their rules:

https://unity3d.com/unity/qa/lts-releases

If runtime refers to a build/player, then it seems the LazyLoadReference does stay intact, but will actually not be loaded lazily:

https://docs.unity3d.com/2019.3/Documentation/ScriptReference/LazyLoadReference_1.html

“loaded when the player is loaded” sound vague to me though. Is it done at player startup? Do they refer to assets Resources? They probably don’t resolve all LazyLoadReference’s that exist in all scenes when the player is loaded, if these scenes are not loaded yet.

Yes when i was asking about runtime i was refering to builds lazy loading, would be a pitty if this would not work :frowning:

Wait!
Unity can serialize generic classes now?
Please tell me it does…

No, sadly it does not suport generic serialization.

You can look at the docs here, and the source here. The big comment block up top seems to indicate that this is made for speeding up editor work, by allowing you to open a scene without every single thing referenced in that scene being immediately loaded.

1 Like

I wonder why they didn’t implement it as an attribute in this case. This would then allow us to just decorate a field with said attribute and everything else in user code stays the same. It would then be trivial to even change existing code to use the attribute.

Right now, with this LazyLoad struct, not being able to work with the reference directly because of this one level of indirection, only for an editor side improvement, seems odd to me. Not a fan of adding indirection.

Isn’t this useful for runtime, too? Maybe I am misunderstanding.

Consider a simple example where a scriptable object ‘defines’ a character in a game like CrossyRoads. It contains the name of the character (String), an Icon for the character (Texture2D) and its in game prefab (GameObject). You could reference the Icon and the Prefab using LazyLoadReference, and it would mean the texture and the gameobject (and the meshes, SFX, textures, etc references by that gameobject) aren’t loaded into memory when you reference the scriptable object that defines your character.

That would mean you’d want to make sure it doesn’t ‘automagically’ load the referenced assets unless you specifically request it (hence the need for one level of indirection?) :slight_smile:

That would be useful, but as the docs say:

- In a standalone player, all assets are loaded when the player is loaded, or when asset bundles are loaded.

If you need something like this for runtime, you’d go with Addressables, which provide async loading of assets.

According to the documentation, it seems it’s not loading lazily in a player:
https://docs.unity3d.com/2019.3/Documentation/ScriptReference/LazyLoadReference_1.html

Interesting, then yeah I agree with Peter, the indirection it introduces just for the sake of an editor specific improvement is a little gross.

Correct, LazyLoadReference<> is relevant only for editor work, in standalone mode its behavior is the same as if it was not present. Why it’s not editor only is just to ease it’s use (not having to if def stuff)

Why not an attribute? because the usage is not that straight forward. to get the object you need to explicetly request the object from the LazyLoadReference<> field, an attribute would not have allowed that.

check out the doc’s example: Unity - Scripting API: LazyLoadReference<T0>

Will there every be any lazy loading references for runtime?

Would be so very useful for memory management I cant even begin to explain how much I could use that right now.

That’s covered by Addressables, isn’t it?

Sorry to say, but at the moment, no work is planned to extend this to the runtime.
If we see a high demand for this feature, then it might be considered.

oh, and one last thing I forgot to mention: feature will not be back ported.

Correct.

Does addressables actually let you lazy load? I thought it was just a better way at managing loading and references to assets?
Althought I havent looked into it that much I will admit!

One of the biggest complaints is that it doesn’t have a synchronous load option. So yes, it very much lets you :wink:

1 Like

Hi,
Does this API work in the Unity2021 LTS versions of mobile Runtime players?

Hi! A bit late but it looks like it works on Android.