How to communicate from MonoBehaviour to ScriptableObject and Viceversa?

I’m having some trouble to connect the final dots in this matter. I get most of what is going on in the examples provided in this article:

https://unity3d.com/how-to/architect-with-scriptable-objects

So I created a scriptable object with a couple of variables. But how can I read the variables from my objects in the scene?

The only way I was able to accomplish this was by instantiating the scriptable in a singleton. But I would like to get rid of the singleton system altogether by implementing an event system.

However I stumble upon the same issue: how to access the Scriptable from so many objects in the scene. Because if I need to instantiate the scriptable, then a singleton will be required again.

I know I’m missing something rather simple here, but trust me I’m not being purposely obtuse. I’m sort of craving for someone to break this down for me step by step.

Thanks in advance!

You need a reference to the ScriptableObject.

The easiest way to do this is to have a serialized attribute in your MonoBehaviour:

[SerializeField]
private MySO mySO ; // Drag & drop the scriptableObject in the inspector

Then, in the script of the ScriptableObject, you define the needed functions

public UnityEngine.Events.UnityEvent MyEvent ;

public void DoSomething( MyMonoBehaviour myMonoBehaviour )
{
    myMonoBehaviour.enabled = !myMonoBehaviour.enabled ; // for instance
    MyEvent.Invoke() ;
}

And, back in your MonoBehaviour:

private void Start()
{
    mySO.MyEvent.AddListener( () => Debug.Log( "Event invoked by the scriptableObject" ) ) ;
}

private void Update()
{
    if( Input.GetKeyDown( KeyCode.Space ) )
        mySO.DoSomething( this ) ;
}