Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 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 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
Add comment · 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: Equipment$$anonymous$$anager();

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

· Add your reply
  • Sort: 
avatar image
4
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
Add comment · 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 $$anonymous$$utes, 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
-1

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
Add comment · 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
0

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
Add comment · 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 $$anonymous$$onobehaviour can.

avatar image
0

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

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

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

can't place inherited class of an abstract class in editor? 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