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!

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
{
    // [ ... ]
}

Yes, it is possible:

using is = ImportantStuff;
public class otherThing : MonoBehavior {
     is.foo.method();
     is.bar.method();
 }

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.

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;

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).