Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 14 Next capture
2021 2022 2023
2 captures
12 Jun 22 - 14 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by ThatGuy_Jay · Apr 07, 2017 at 02:45 PM · scripting problemclass library

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!

Comment
Add comment · Show 4
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image UnityCoach · Apr 07, 2017 at 03:37 PM 1
Share

Why not use a namespace ins$$anonymous$$d of nesting classes?

avatar image ThatGuy_Jay · Apr 08, 2017 at 03:11 AM 0
Share

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

avatar image Zymu · Apr 08, 2017 at 08:07 AM 1
Share

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.

avatar image Sergio7888 · May 04, 2017 at 04:15 PM 0
Share

You cant call method outside a method body.

5 Replies

· Add your reply
  • Sort: 
avatar image
7

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
 {
     // [ ... ]
 }
Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image FinnTess · Oct 09, 2019 at 11:34 PM 0
Share

That really help me :) Thx !

avatar image
1

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();
  }


Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
0

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.

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Bunny83 · May 05, 2017 at 12:58 AM 0
Share

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.

avatar image
0

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;

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
0

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

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

12 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Is there a reason why Unity would be able to read one variable in a script and not another? 1 Answer

After exporting my project from my PC to my laptop the physics of my game work differently. 1 Answer

Left side panel in monodevelop 1 Answer

Script problem 1 Answer

How to prevent an object from instantiating inside another object? 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges