UnityEngine.Object in an ScriptableObject is empty in WebGL build

Hi, I am encountering a problem in a WebGL build.

A WorkPlanController (singleton MonoBehaviour) defining in a subclass the member “data” as the reference to the struct:

public class WorkPlanController : Singleton<WorkPlanController>
{
    public class WorkPlanModule
    {
         public ModuleData data;
    }
}

I have an ScriptableObject (accessed via Singleton) containing a list of modules and every module holds a struct of data:

The ScriptableObject:

public class WorkplanData : SingletonScriptableObject<WorkplanData>
{
    public WorkPlanController.WorkPlanModule[] module = null;
}
[Serializable]
public struct ModuleData
{
    public string name;
    public string description;
    public UnityEngine.Object processFile;   <<== problem 
}

At runtime I’am accessing the data via

foreach (var module in WorkPlanController.Instance.data.module)
{
    //throw exception in WebGL because module.data.processFile == null
   string processPath = $"Processes/{module.data.processFile.name}";
}

In the Editor it works very well, file pathes and files can be read without a problem. But in the WebGL build the reference to the GameEngine.Object module.data.processFile is null.

I don’t know if relevant, but the source files put in to processFile resides in Assets/StreamingAssets/

Would be great if someone can shed some light on the problem.
Thanks

Look at your singletons. Chances are if you picked them up from some random website then they are broken and require some silly “must be in scene” or “must be loaded” step first, which suddenly imposes these massive irritations upon you like knowing their load order, enforcing a good load order, etc.

Here are the ONLY forms of a singleton I use in Unity because they have been engineered to consider Unity’s full object lifecycle. Because of this they have the important advantage that they never require dragging and dropping random stuff into random scenes, and they also work. :slight_smile:

Simple Singleton (UnitySingleton):

Some super-simple Singleton examples to take and modify:

Simple Unity3D Singleton (no predefined data):

Unity3D Singleton with a Prefab (or a ScriptableObject) used for predefined data:

These are pure-code solutions, DO NOT put anything into any scene, just access it via .Instance!

The above solutions can be modified to additively load a scene instead, BUT scenes do not load until end of frame, which means your static factory cannot return the instance that will be in the to-be-loaded scene. This is a minor limitation that is simple to work around.

If it is a GameManager, when the game is over, make a function in that singleton that Destroys itself so the next time you access it you get a fresh one, something like:

public void DestroyThyself()
{
   Destroy(gameObject);
   Instance = null;    // because destroy doesn't happen until end of frame
}

There are also lots of Youtube tutorials on the concepts involved in making a suitable GameManager, which obviously depends a lot on what your game might need.

OR just make a custom ScriptableObject that has the shared fields you want for the duration of many scenes, and drag references to that one ScriptableObject instance into everything that needs it. It scales up to a certain point.

And finally there’s always just a simple “static locator” pattern you can use on MonoBehaviour-derived classes, just to give global access to them during their lifecycle.

WARNING: this does NOT control their uniqueness.

WARNING: this does NOT control their lifecycle.

public static MyClass Instance { get; private set; }

void OnEnable()
{
  Instance = this;
}
void OnDisable()
{
  Instance = null;     // keep everybody honest when we're not around
}

Anyone can get at it via MyClass.Instance., but only while it exists.

Thank you Kurt for your super rich answer.

We make heavy use of Addressables and small scenes that will be un/loaded all the time, so we have slightly bigger Singletons with types, thread lock and unicon glitter (and maybe some bugs, to be honest) and also not like yours with the implementation of the Unity lifecycle methods.

But this time I think that these are not the problem, because other fields than the module.data.processFile are accessible like module.data.name only it itself is not. Therefore I think that the problem lies elsewhere.

Would you agree with that?
Thanks

Problem still unsolved… if anyone has any suggestion please let me know :slight_smile: