Having some problems with referencing a script inside a scriptable object

So im making a developer console (cheat console) and the command are basically scriptable objects, and one of the commands is for gravity, now i created a script for the gravity and it works fine, but im trying to reference that script for the scriptable object to use (to make a command change the amount of gravity, for testing purposes) but i try using public Player player: (Player is the script that i need to accuse) and when i do this, it gives me a NullReferenceException which i then go into the command (a scriptable object asset, used by making it be bale to be created in the assetmenu) and i see i need to drag in the gameobject that contains the Player script, and i drag it, and it does not work, i click the symbol and it shows nothing, for some reason, i cant reference a script (through the gameobject) or anything. Below is my code for multiple scripts, please help, if you need anything just tell me.

IConsoleCommand (used for testing):

namespace DapperDino.UDCT.Utilities.DeveloperConsole.Commands
{
    public interface IConsoleCommand
    {
        string CommandWord { get; }
        bool Process(string[] args);
    }
}

ConsoleCommand;

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace DapperDino.UDCT.Utilities.DeveloperConsole.Commands
{
    public abstract class ConsoleCommand : ScriptableObject, IConsoleCommand
    {
        [SerializeField] private string commandWord = string.Empty;

        public string CommandWord => commandWord;

        public abstract bool Process(string[] args);
    }
}

GravityCommand:

using UnityEngine;

namespace DapperDino.UDCT.Utilities.DeveloperConsole.Commands
{
    [CreateAssetMenu(fileName = "New Gravity Command", menuName = "Utilities/DeveloperConsole/Commands/Gravity Command")]
    public class GravityCommand : ConsoleCommand
    {
        public Player player;
        public void Awake()
        {
            // Have tried this - does not work ---player = FindObjectOfType<Player>();
        }
        public override bool Process(string[] args)
        {

            if (args.Length != 1) { return false; }

            if (!float.TryParse(args[0], out float value))
            {
                return false;
            }
            //Physics.gravity = new Vector3(Physics.gravity.x, value, Physics.gravity.z);
            player.gravity = value;
            Debug.Log("RUnning");
            return true;
        }
    }
}

pictures of me not being able to place the script in the slot (1st person player contains the Player script):



plz help

You can’t do that. ScriptableObjects aren’t part of the scene. They are assets on the disk. What you could do is to self-register your game objects. Which means you reference the ScriptableObject in your game object and then when they wake, you can update the reference in the ScriptableObject to your script. But since you already reference the ScriptableObject from your MonoBehaviour, it’s kind of moot at that point.

To expand on this a little, your scriptable object will lose all reference to objects in the scene upon entering or exiting play mode. Sometimes it will look like something is still referenced in the inspector for the scriptable object but that link is broken, if you are going to use this setup you will need to inject that reference like Lurking-Ninja said.

On a different note, I use scriptable objects for a large number of systems and will often have them work as data repositories for runtime stuff but you need to understand that they operate in a very different manner than monobehaviours. First off ScriptableObject.Awake != Monobehavior.Awake and the same is true for all the other Unity Message functions. Spend some time looking through the method’s documentation here. If you place debug statements like they have and observe the timing of them you will see what I mean.

It is my practice to always have an Initialize function and a Deinitialize function that I call from somewhere outside the ScriptableObject in order to have explicit control over the timing of those calls.

i found an easier way of doing it, instead of using scriptable objects, im just straight coding it in. thanks though :slight_smile: