• 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 SinisterRainbow · Oct 24, 2013 at 06:46 AM · componenttypeconversion

Forcing a type conversion from an abstract class C#

I have a class of objects in an object pool that are all derived from an abstract class, but this is failing:

 //SUProjectile : Base abstract class
 //BeamProjectile : derived from SUProjectile

 SUProjectile SU_P; 
 GameObject goProjectile = TheObjectPool.GetNextObject("Heretic Juice");
 System.Type st = GetProjectileType("Heretic Juice");
 SU_P = (st) goProjectile.GetComponent(typeof(st)); //<-- fail, can't use "st" in this way apparently.. 

This is, of course just part of the problem.

I have an objectpool, it stores many types of projectiles all derived from the base abstract class of SUProjectile. There may be hundreds of projectile types eventually, so I'd like to do this at runtime..

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 Tarlius · Oct 24, 2013 at 06:55 AM 0
Share

Without trying to run it through a compiler, is it not that you already have the typeof in st? typeof st would just be System.Type, no?

avatar image Tarlius · Oct 24, 2013 at 06:57 AM 1
Share

Although would it not be easier to use the generic version of GetComponent with the base type? I think this sort of structure suggests you don't really need the "correct" type, just the instance? Unless the next few lines are a switch(st) or something, which it probably a symptom of a bigger problem...

 SU_P = goProjectile.GetComponent< SUProjectile > () ;
avatar image dood2 · Oct 24, 2013 at 07:03 AM 0
Share

I think you want to do GetType at the end

 SU_P = (st) goProjectile.GetComponent(typeof(st)).GetType();
avatar image SinisterRainbow · Oct 24, 2013 at 08:47 AM 0
Share

I tried this but it wasn't working.. apparently due to another uncaught bug.. But this works. thanks. if you put it as an answer i can accept and close the q.

3 Replies

· Add your reply
  • Sort: 
avatar image
1
Best Answer

Answer by Tarlius · Oct 24, 2013 at 08:51 AM

I think it would be easier to simply use the generic version of GetComponent with the base type:

 SU_P = goProjectile.GetComponent< SUProjectile > ();
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
1

Answer by fafase · Oct 24, 2013 at 09:24 AM

You do not need the GameObject in the middle.

Simply:

 SUProjectile SU_P; 
 SU_P = TheObjectPool.GetNextObject("Heretic Juice");

if all objects inherits from SUProjectile, they are all of this type so they can directly be stored into an object of type SUProjectile.

Then if you are trying to access a method from the SUProjectile you can call it, if you need to access something from a sub class you can try:

 if(SU_P is SubClass){
     SubClass sub = (SubClass)SU_P;
     sub.SubMethod();
 }
Comment
Add comment · Show 6 · 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 SinisterRainbow · Oct 24, 2013 at 12:04 PM 0
Share

I appreciate the response. GetNextObject returns a GameObject ref, as I am never sure which child-SUProjectile the object pool may be storing. Also, I'm trying to avoid having to do checks if it is a subclass.. as I will be adding many types over time, I'd rather only make changes in one place....

avatar image fafase · Oct 24, 2013 at 12:55 PM 0
Share

If your object pool is filled with object derivating from the same base class there is little reason why it should return a GameObject. Just by returning the appropriate type, you would make it easier. That is the whole point about C#, typesafe.

avatar image Tarlius · Oct 24, 2013 at 01:17 PM 0
Share

Not to mention slightly faster ;) I considered mentioning it myself, but thought it wasn't really related to the question.

avatar image SinisterRainbow · Oct 24, 2013 at 09:37 PM 0
Share

it's is for anything that needs pooling...

avatar image Azrapse · Oct 25, 2013 at 05:03 AM 1
Share

You can have a pool of game objects even when you only store references to one of their components. For example, you could have a pool of SUProjectile. Every one of them would include the whole game object, and you wouldn't need to be using the slow GetComponent every time.

Also, if you plan to add other subtypes that inherit from SUProjectile, it will keep on working.

If what you want is to have the One Pool that pools objects of many different types, maybe you could design something different.

What about a class like

 class TheOnePool
 {
 
 protected Dictionary<Type, ArrayList> megaPool;
 
 public T GetNext<T>()
 {
     var type = typeof(T);
     if(megaPool.Contains$$anonymous$$ey(type))
     {
         var thisTypePool = megaPool[type];
         var nextObject = thisTypePool[thisTypePool.Count-1] as T;
         // Deal here with the case that this type pool is empty and needs to spawn new blank objects
         thisTypePool.RemoveAt(thisTypePool.Count-1);
         return nextObject;
     }
 }
 
 public TheOnePool(params Type[] types)
 {
     // Initialize the pools for every time to the starting desired size
     megaPool = new Dictionary<Type, ArrayList>();
     foreach(Type type in types)
     {
         megaPool.Add(type, new ArrayList());
         // Add here some blank pooled objects of this type to this pool if you want 
     }
 
 }
 
 }

And you could initialize it like this.

 new TheOnePool(typeof(SUProjectile), typeof(Enemy), typeof(TreeScenery), typeof(Rock));

And you would get next pooled object like this.

 var nextObject = theOnePool.GetNext<SUProjectile>();
Show more comments
avatar image
0

Answer by Azrapse · Oct 24, 2013 at 10:52 AM

In line 6 you get the Type in st. An object of type Type is an object with information about a type in C#.

In line 7 you do weird stuff.

First you call the method GetComponent passing as parameter not st, but typeof(st). What typeof() does is returning a Type object with information about the type of the parameter. In this case the parameter of typeof(st) is st, that is of type Type. So the typeof() call is returning a Type object with information about class Type (Yes, you have made there a superconfusing tonguetwister in C#. :D )

Then you try to cast the returning value into (st), but st isn't a type, but an object of type Type, that is, an object with information about a type. So the compiler doesn't let you. You cannot cast to an object, only to a type.

What the last line should look like is

 SU_P = (SUProjectile) goProjectile.GetComponent(st);
Comment
Add comment · Show 3 · 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 SinisterRainbow · Oct 24, 2013 at 12:12 PM 0
Share

Line 7 is actually the long form of

 `someGameObject.GetComponent<someComponent>()..`

I tried all variations, using typeof(st), etc, but nothing worked. SU_P = (SUProjectile)tmpGO.GetComponent( st ); also doesn't compile... But appreciate trying.

avatar image Tarlius · Oct 24, 2013 at 12:26 PM 0
Share

I was able to compile it without any problem. But its a weird case ;)

Code I used:

 $$anonymous$$onoBehaviour mb; 
 GameObject go = null;
 System.Type st = typeof($$anonymous$$onoBehaviour);
 mb = ($$anonymous$$onoBehaviour) go.GetComponent(st);
avatar image Azrapse · Oct 24, 2013 at 12:30 PM 0
Share

I cannot really see why it wouldn't compile. If SU_P is of SUProjectile type, and st is of Type type, all type requirements are met. The compiler error must be elsewhere.

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.

Welcome to Unity Answers

If you’re new to Unity Answers, please check our User Guide to help you navigate through our website and refer to our FAQ for more information.

Before posting, make sure to check out our Knowledge Base for commonly asked Unity questions.

Check our Moderator Guidelines if you’re a new moderator and want to work together in an effort to improve Unity Answers and support our users.

Follow this Question

Answers Answers and Comments

17 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 avatar image avatar image avatar image avatar image avatar image

Related Questions

Easy? Convert System.Type to UnityEngine.Component 3 Answers

What's the difference between GetComponent and GetComponent(StringName)? 1 Answer

Getting all component types (even those not on the scene) 1 Answer

Reference to Scene Object Component in Prefab Editor, 'Type Mismatch'? 1 Answer

Declare Component type in GetComponent 2 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