Zaine Abaddin
Zaine Abaddin

Reputation: 51

Can i access a monobehaviour script from within a non monobehaviour script?

I'm trying to access a monobehaviour script from within a non monobehaviour script and haven't had any luck yet. These two classes need to stay as they are as changing them will break a lot of functionality so i cant create an instance and cant attach to a gameobject to drag and drop.

Any ideas?

public class myClass1 : monoBehaviour
{
  public String text = "hello";
}

public class myClass2
{
  private myClass1 monoClass = new myClass1();

  private void Start()
  {
    Debug.Log(monoClass.text);
  }
}
//THIS DOES NOT WORK

Upvotes: 0

Views: 5642

Answers (4)

Zaine Abaddin
Zaine Abaddin

Reputation: 51

I did not know you could pass them as parameters. This is good to know, however in my project this wouldn't have worked as I was calling the method from another non-MB script which did not have the the MB script referenced anywhere for me to pass it on.

What I did was create an empty GameoObject and attach the script as a component then use the class from there across the non_MB script.

3 lines of code:

GameObject obj = new GameObject();
obj.AddComponent<MyScript1>();
MyScript1 myscript1 = obj.GetComponent<MyScript1>();

Works great as GameoObjects are not restricted to MB.

Upvotes: 0

aOtf_
aOtf_

Reputation: 23

Sometimes What I did is create an interface that can receive Component object for Non-Monobehaviour class.

public interface IComponentReceiver<T> where T: Component{
    void AddComponent(T pComponent);
}

public class ExampleNonMonoBehaviour : IComponentReceiver<CharacterController>{
    private CharacterController _cc;
    public void AddComponent(CharacterController cc)
    {
     _cc = cc;
    }
}

Upvotes: 0

KYL3R
KYL3R

Reputation: 4073

As an alternative to the GetComponent approach from @Zaine I'd like to throw the singleton pattern into the pool of possible answers:

public class SomeClass : MonoBehaviour {
    private static SomeClass _instance;
    public String text = "singleton text";

    public static SomeClass Instance { get { return _instance; } }
    private void Awake()
    {
        if (_instance != null && _instance != this)
        {
            Destroy(this.gameObject);
        } else {
            _instance = this;
        }
    }
}

It only works if you have exactly one of these scripts. But from all other scripts, you can access it easily:

public class SomeOtherClass : MonoBehaviour {
     private void Start(myClass1 mc1)
     {
         Debug.Log(SomeClass.Instance.text);
     }
}

Upvotes: 1

Yes, but...

You can't call new on any script that inherits from MonoBehaviour due to requiring being attached to a game object. So you can't create references, but you can absolutely pass them around:

public class myClass1 : monoBehaviour
{
  public String text = "hello";
}

public class myClass2
{
  private void Start(myClass1 mc1)
  {
    Debug.Log(mc1.text);
  }
}

Now, myClass2#Start is going to be difficult to call in this example, but it will compile.

I do stuff like this in my projects all the time. I usually have one class that is a MonoBehaviour component that's attached to the main camera with a static instance field that I can reference from anywhere else, though most of the non-MB scripts don't deal with Unity objects most of the time (they only hold data and one of the manager classes handle updating game objects with that data by maintaining a dictionary between them).

Though sometimes the object holds its own GO reference (the result of trying different things to see what worked or wanting to avoid a dictionary lookup--regardless of if it was efficient or not).

Upvotes: 1

Related Questions