• 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
Question by SrBilyon · Nov 16, 2012 at 08:00 AM · inheritancemonobehaviourclassesaddcomponentsubclass

Using AddComponent to add a Sub Class using a String

I'm trying to temporarily add a component that is a sub class in order to load certain variables.

 var equipTex = GetEquipment("Gloves");

Gloves inherits from a type "Equipment".

 public string GetEquipment(string equipmentName)
     {
         var equipName = (Equipment)gameObject.AddComponent(equipmentName);
         Debug.Log(equipName);
 }

When I try the code above, I will get this:

Can't add component because class 'Gloves' doesn't exist! UnityEngine.GameObject:AddComponent(String)

However, if I were to assign "equipmentName" to Equipment, it will not give me that error.

I'm beginning to believe that subclasses cannot be used by storing their name as a string, and calling them by that string, but classes that inherit from Monobehaviour can.

Is their something that I'm not getting? Or will I have to try another method?

Comment

People who like this

0 Show 6
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 FakeBerenger · Nov 16, 2012 at 08:35 AM 0
Share

This should work, but Unity can't find the Gloves class apparently . Are both classes implemented in C# ?

avatar image SrBilyon · Nov 16, 2012 at 08:37 AM 0
Share

Yep. That's why I'm getting a major headache. The class "Gloves" is written in the same script as "Equipment" <-- The only one deriving from monobehavior. Is that a problem, because I really don't want to write a script for each equipment...

avatar image fafase · Nov 16, 2012 at 08:57 AM 0
Share

Where is the GetEquipment function stored?

avatar image SrBilyon · Nov 16, 2012 at 08:59 AM 0
Share

In a separate script from where the Equipment classes are: EquipmentManager();

avatar image FakeBerenger · Nov 16, 2012 at 09:15 AM 0
Share

What do you mean "in the same script as 'Equipment' ? It's declared inside Equipement ? Or does it inherit from it, in another file / scope ?

Show more comments

4 Replies

  • Sort: 
avatar image
Best Answer

Answer by fafase · Nov 16, 2012 at 09:35 AM

OK here I got it working with a generic type:

 void GetEquipment() where T : class, new(){
     gameObject.AddComponent(typeof(T));
 }

and you call like this:

     GetEquipment<Gloves>();

It works for me, so there is no reason it should not work for you. :)

Edit: Let's take an example. One file:

 using UnityEngine;
 using System.Collections;
 
 public class Equipment : MonoBehaviour {
 
     public Vector3 velocity;    
     public Transform _transform;    
     protected int health;
 
     public virtual void Start(){
         velocity = new Vector3(Random.Range(0.5f,1.5f),0,0);
         _transform = GetComponent<Transform>();
     }
     public virtual void Update(){
          //Some Update
     }
 }
 
 public class Gloves : Equipment {
     public int variable;
     public override void Start () {
         base.Start();
         variable =10;
     }
     
     public override void Update () {
         base.Update ();
     }
 }

Ok so we have in the same file two classes Equipment and Gloves that inherits from Equipment

Just for the example here is a third independent class:

 using UnityEngine;
 using System.Collections;
 
 public class NPC : Enemy {
     public int varToShowInTheInpsector;
     public override void Start(){
         base.Start ();
         varToShowInTheInpsector = 100;
     }
 
     public override void Update(){
                //Some stuff happening here
     }
 }

Now we have an object with another script that is not any of those above:

 using UnityEngine;
 using System.Collections;

 public class MyClass : MainClass {

     public override void Start () {
         base.Start ();
      }
 
     public override void Update () {
        //Many stuff here
       if(Input.GetKeyDown(KeyCode.A)) 
          GetEquipment<Gloves>();
       else if(Input.GetKeyDown(KeyCode.B)) 
          GetEquipment<NPC>();
       else if(Input.GetKeyDown(KeyCode.C)) 
          GetEquipment<Equipment>();
     }
     void GetEquipment() where T : class, new(){
         gameObject.AddComponent(typeof(T));
     }
 }

Try that on and you will see new script popping up on your inspector. I added some public variable so that you can see that the appropriate class is created. You see how easy it gets to add any custom component?

Comment
SrBilyon
FakeBerenger
Seth-Bergman
sean244

People who like this

4 Show 4 · 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 SrBilyon · Nov 16, 2012 at 09:42 AM 0
Share

Ah, this is a little new to me (Generic types). Is it possible to use this in such a way that I can call it like: GetEquipment () <--- equipmentName, considering each equipment will have it's own type? (with a base class of Equipment?)

avatar image fafase · Nov 16, 2012 at 09:44 AM 1
Share

I will extend my answer with a larger example. Give me a few minutes, I 'll be back

avatar image SrBilyon · Nov 16, 2012 at 09:45 AM 0
Share

Nice, Thanks :)

avatar image SrBilyon · Nov 16, 2012 at 10:23 AM 0
Share

Ah, I get this a lot more now! Thanks a ton!

avatar image

Answer by Seth-Bergman · Nov 16, 2012 at 09:16 AM

Your problem is, this is half C#, half JavaScript!!! Otherwise though, what you are trying to do will work perfectly, if you just get the SYNTAX right:

case JavaScript:

 function GetEquipment(equipmentName : String)
     {
        var equipName = (Equipment)gameObject.AddComponent(equipmentName);
        Debug.Log(equipName);
        return equipName.ToString();  //????
 }

...

 var equipTex = GetEquipment("Gloves");


in JAVASCRIPT, the class and subclass are declared this way:

[http://answers.unity3d.com/questions/7614/does-unity-support-inheritance-and-subclassing.html][1]

case C#:

 public string GetEquipment(string equipmentName)
     {
        Equipment equipName = (Equipment)gameObject.AddComponent(equipmentName);
        Debug.Log(equipName);
        return (string)equipName;   // ???
 }

....

 string equipTex = GetEquipment("Gloves");

the classes here are declared this way:

 public class Equipment : MonoBehaviour
 {

...etc

 public class Gloves : Equipment
 {

...etc [1]: http://answers.unity3d.com/questions/7614/does-unity-support-inheritance-and-subclassing.html

Comment
sean244

People who like this

-1 Show 5 · 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 fafase · Nov 16, 2012 at 09:19 AM 4
Share

If you refer to var being UnityScript, var is also a c# keyword http://msdn.microsoft.com/en-us/library/bb383973.aspx

avatar image FakeBerenger · Nov 16, 2012 at 09:20 AM 2
Share

Well, actually, you can declare a variable as 'var' in C# too. So his code is correct in C#.

avatar image SrBilyon · Nov 16, 2012 at 09:20 AM 0
Share

I was about to note that. I tried the same thing as above, but strangely, I'm getting the same error.

avatar image Seth-Bergman · Nov 16, 2012 at 09:33 AM 0
Share

OOps, my mistake... thought you were declaring the classes wrong, didn't know about that with var too.. :)

at any rate

the reason your script isn't working, incedentally, is that you need to save each class in a SEPARATE script

the name of the file is the reference to the contained class

avatar image fafase · Nov 16, 2012 at 09:39 AM 0
Share

I got it working with both classes in the same file. This is just a matter of making the function generic and telling the compiler you want the type to be a class and have the new constraint.

Fact is there might be some less scary ways but they would be longer to write and debug :).

avatar image

Answer by FakeBerenger · Nov 16, 2012 at 09:26 AM

I tested it, and your problem is that Gloves is in the same file as Equipment. Create a Gloves.cs. It would have worked with AddComponent( typeof(Gloves) ) though.

Comment

People who like this

0 Show 4 · 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 SrBilyon · Nov 16, 2012 at 09:31 AM 0
Share

I had a feeling that was the reason. I was trying to be lazy and call the equipment by name, though, the problem with the second part of your solution, combined with my "lazy idea" is that i wouldn't be able to use (typeof(equipmentName)), since the contents of "equipmentName" would be the type.

I'm mainly using the string technique so that I won't have to write 20+ .CS files for like, 5 lines of code in each .CS.

avatar image FakeBerenger · Nov 16, 2012 at 09:33 AM 1
Share

Lazy ideas have a tendancy to backfire :p

avatar image SrBilyon · Nov 16, 2012 at 09:35 AM 0
Share

Yeah, they have a tendency of wasting a lot of time when they don't work :D

avatar image Seth-Bergman · Nov 16, 2012 at 10:37 AM 1
Share

So, ultimately though, your original suspicion was correct, it seems:

using the STRING version rather than the generic was the problem.. :

(as originally stated ) ...subclasses cannot be used by storing their name as a string, and calling them by that string, but classes that inherit from Monobehaviour can.

avatar image

Answer by SrBilyon · Nov 16, 2012 at 09:33 AM

For the moment, to get it in a working condition, I started writing functions for each Equipment, and I'm using

 SendMessage(equipmentName); 

to call the function with the appropriate name of the Equipment I want. That function will load the values I need, and presto. Now that I think about it, writing a class for each equipment would have been a little overboard, since I only need the classes to hold variables XD

What are you guy's opinion on this?

Comment

People who like this

0 Show 0 · 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

Unity Answers is in Read-Only mode

Unity Answers content will be migrated to a new Community platform and we are aiming to launch a public beta by June 9. Please note, Unity Answers is now in read-only so we can prepare for the final data migration.

For more information and updates, please read our full announcement thread in the Unity Forum.

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

Issues Inheriting classes and monoBehaviour 1 Answer

How to store data in script and attach it later? 0 Answers

Will using a Monobehaviour script versus a non-Monobehaviour script use less memory? 2 Answers

Making a static class derive from MonoBehaviour in C# 3 Answers

Defining and inheriting from a Javascript Class 0 Answers


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