- Home /
How to reference a class in another script properly?
Lets say I have a script on my main camera that I use to store important classes:
public class ImportantStuff : MonoBehavior {
public class foo {}
public class bar {}
}
I want to use this in another script on a different object like this:
using ImportantStuff;
public class otherThing : MonoBehavior {
foo.randomMethod();
bar.randomMethod();
}
Instead, I'm being forced to do this:
public class otherThing : MonoBehavior {
ImportantStuff.foo.randomMethod();
ImportantStuff.bar.randomMethod();
}
Does anyone know if this is possible? Writing out the class name each time I need to use it seems too inefficient to be the correct way of referencing other classes, especially when ImportantStuff will have to be used a huge number of times over all my other scripts. Even if this is not possible, is there any way of shortening the statement so I can do something like what python does (psuedo code because I forget python syntax):
const is = using(ImportantStuff);
public class otherThing : MonoBehavior {
is.foo.method();
is.bar.method();
}
Thanks for any help!
Why not use a namespace ins$$anonymous$$d of nesting classes?
I need to be able to hold properties on this class (more specifically I have a set of dictionaries to hold stats of all my characters).
I'm going to agree with UnityCoach - you're doing some weird stuff here. If you absolutely have to or want to do this, you can make a call to find the gameobject your desired class is attached to (using GameObject.Find()/FindGameObjectWithTag()). After that, you reference it with objectWith$$anonymous$$yClass.GetComponent().
If the classes are all attached to scripts that you are working on in the same scene and none of them are Instantiated at runtime, you can always just directly reference the class you'd like to with a public variable. $$anonymous$$ake this variable of type (YourClassName) and simply drag the object your class is attached to into the field on the object that's trying to reference it.
Answer by Bunny83 · May 05, 2017 at 01:15 AM
While it's possible to create a local alias name for a type like @Mikael-H showed in his comment, your actual setup seems to be just wrong. Why do you define nested classes inside your "ImportantStuff" class? The only point to have nested classes (or any nested type definition for that matter) is because that class / type is exclusivly used by or strongly bound to the outer class.
You should never use a class as some sort of "folder" for other classes. That's what namespaces are good for. Also your example of:
ImportantStuff.foo.randomMethod();
would only apply to static methods. "ImportantStuff.foo" is a type and not an instance. So you could create an instance like this:
ImportantStuff.foo instance = new ImportantStuff.foo();
Nested types are defined in the static scope of the outer class. You always have to use the outer class name in combination with the nested classname to refer to the nested class. Nested classes / types could even be private so they can only be used inside the outer class.
Your two classes ("foo" and "bar") are currently empty classes so it's impossible to see or guess what's the point / purpose of those classes. You may want to declare them inside a namespace instead:
namespace ImportantStuff
{
public class Foo
{
public static void SomeHelperMethod()
{
// [ ... ]
}
}
}
The full class name in this case is still "ImportantStuff.Foo". However namespaces can be simplified with using:
using ImportantStuff;
public class someOtherClass : MonoBehaviour
{
void Start()
{
Foo.SomeHelperMethod();
}
}
Note that i changed the classname from "foo" to "Foo" as classnames always start with a capital letter
ps: if a class only contains static members, you should declare the class as static as well. This will prevent any user from creating an instance of the class and also prevents you from accidentally declaring any instance methods or instance fields.
public static class Bar
{
// [ ... ]
}
Answer by Mikael-H · May 04, 2017 at 05:42 PM
Yes, it is possible:
using is = ImportantStuff;
public class otherThing : MonoBehavior {
is.foo.method();
is.bar.method();
}
Answer by SoulRider · May 05, 2017 at 12:13 AM
As your object is a MonoBehaviour it requires a reference to an instance of the object. There are a few different ways to do this, I will list a couple.
In the OtherThing class create a public ImportantStuff and in the editor, drag the gameobject with the ImportantStuff script on it, into the inspector variable. In code this would look like this:
public class OtherThing : MonoBehavior {
public ImportantStuff is;
is.foo.randomMethod();
is.bar.randomMethod();
}
Alternatively, if it needs to be accessed by many objects, you can create a global instance of ImportantStuff:
public class ImportantStuff : Monobehaviour {
private static ImportantStuff is;
public static ImportantStuff Instance()
{
if (!is)
{
is = FindObjectOfType(typeof(ImportantStuff)) as ImportantStuff;
}
return is;
}
public class foo {}
public class bar {}
}
public class OtherThing : MonoBehavior {
private ImportantStuff is;
void Start(){
is = ImportantStuff.Instance()
}
is.foo.randomMethod();
is.bar.randomMethod();
}
As I said there are other methods for doing this, but generally these are good starting points. Searching for the object using FindObjectOfType is another often cited, but expensive alternative.
I hope this helps somewhat.
This is all wrong on multiple levels -.-
First of all nested classes belong to the static scope of the outer class and not the instance scope. So you can not access a nested type definition through an instance reference. You have to use the type name of the outer class, just has pointed out in the question where he said:
Ins$$anonymous$$d, I'm being forced to do this:
A singleton reference should never be cached elsewhere. The pattern requires a single globally accessable point and it should be used everywhere you want to access the singleton. Depending on the implementation and usecase a singleton instance could be destroyed and it would get recreated / reloaded by the accessor methods / property.
Answer by HelloTom · May 08, 2017 at 02:20 PM
public GameObject mainCamera; on the script that you want.
and then pass in the main camera in the inspector then just go
mainCamera.GetComponent().Classname;
Answer by FM-Productions · May 05, 2017 at 12:36 PM
Hi,
Edit: to shortly answer your question to your main problem: A possiblity would be, in any other MonoBehaviour script, you could store the camera gameObject. Get it in the "Start()" or "Awake()" function. For example with:
GameObject camera = GameObject.Find("Main Camera");
Find() takes the name of your camera object in your scene to find it.
then you could access a script attached to your MainCamera like so, let's asume ImportantStuff is the class name of the script attached to your main camera:
ImportantStuff cameraStuff = camera.GetComponent<ImportantStuff>();
Now to my remarks to your question:
In my opinion, the code you wrote is very strange."randomMethod()" would also have to be a static public method, since you call it directly from a class, not an instance. Secondly, be sure to differentiate class names with namespaces. The previous answer already explained how class names can be shortened for use.
Maybe you want to do something like this? If not, ignore the following section. Sorry, but I cannot exactly get what you are trying to do with your code.
namespace ImportantStuff
{
public class TestClass
{
public static SomeClass foo;
public static SomeClass bar;
}
}
This, however, does not spare you from using TestClass.foo for accessing foo. If you are fine with static variables that belong to the class rather then an instance of a class, you could do this.
SomeClass could look like this:
namespace ImportantStuff
{
public class SomeClass
{
public SomeClass(){} //constructor
public void randomMethod(){}
}
}
Above are examples with plain classes that do not inherit from "MonoBehaviour", but it should demonstrate the concept. In a class deriving from MonoBehaviour you would not need a constructor. (You also do not necessarily need one in a plain class, since there is one generated by default if you explicitly type it).
Your answer

Follow this Question
Related Questions
My "deathEffect" doesn't disappears after use, can you help me? 2 Answers
How do you change a variable in another gameobjects script 2 Answers
problem with arcade racer timer system 0 Answers
HoloLens: detect Airtap regardless of Raycast hit 0 Answers
Using GetPixels to break down an image, and only getting the last part. 1 Answer