Reputation: 51
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
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 GameoObject
s are not restricted to MB.
Upvotes: 0
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
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
Reputation: 15941
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