Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 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
2
Question by PseudoDev · Jun 19, 2017 at 04:43 PM · childclassnewinstancesparameter

Creating new instances of a child class within a function's for loop after it's passed as a parameter of the parent class type

(Edit: Do not post when you're tired and stupid, and you're changing names of classes without updating posts with the same new information, like me) I have a RoadsideObject parent class that contains fields (settings) that all derived classes should share. I have a derived class named TreeLeft. TreeLeft's constructor will randomize the settings derived from RoadsideObject when new instances of TreeLeft are created. I have a function to add RoadsideObjects to a road named AddRoadsideObjects(RoadsideObject ro) which I pass TreeLeft to. AddRoadsideObjects(TreeLeft) has a for loop that needs to create new instances of TreeLeft and add them to an array (I've left that code out, because it's irrelevant). Is it possible to do this or am I thinking about this entirely wrong? Pointing me in the right direction, possibly to a tutorial that doesn't read like some kind of AGI wrote the thing without concern for the idiots (me) that can't understand its lingo would be appreciated. I keep coming across things like "generics" and "reflection", which I suspect is closer to some answer, but I'm still not really understanding how any of that could apply to what I need. Thanks.

 public class RoadsideObject{
     public float xOffset;
     public float yOffset;
     public float xScale;
     public float yScale;
 }

 public class TreeLeft : RoadsideObject{
     public TreeLeft(){
         xOffset = Random.Range(-7, 7)
         yOffset = Random.Range(-7, -5);
         xScale = Random.Range(2, 4);
         yScale = Random.Range(2, 4);
     }
 }

 //ANOTHER MONOBEHAVIOUR SCRIPT
 void Start(){
     AddRoadsideObjects(TreeLeft){
    }
 }

 private void AddRoadsideObjects(RoadsideObject ro){
   for(int i = 0; i < count; i++){
       //CREATE NEW INSTANCES OF RO AND PUT THAT SILLINESS ON THE ROAD.
    }
 }



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 TreyH · Jun 19, 2017 at 05:17 PM 1
Share

The most naive way to do this seems to be just making an enum for the kind of Roadside Object you want to make:

 public enum RoadsideObjectType
 {
     Tree = 1,
     Barrel = 2,
     Box = 3,
     // ...
 }

Then have that function return whatever type that enum specifies by giving the base type back:

 private RoadsideObject AddRO(RoadsideObjectType objectType)
 {
     switch( objectType)
     {
         case RoadsideObjectType.Tree:
             return new ROTreeLeft();
 
         case RoadsideObjectType.Box:
             return new ROBox();
 
         //...
     }
 }
avatar image PseudoDev TreyH · Jun 19, 2017 at 05:34 PM 1
Share

@TreyH Looks doable, but I think bunny83's answer may be more of what I need. I haven't used enumerations before, but it looks easy enough. Thanks. I'll come back after refactoring and give upvotes or however this works.

avatar image NoseKills · Jun 19, 2017 at 05:29 PM 1
Share

Is this a normal c# class that just happens to have a method called Start() or is this a monobehaviour? $$anonymous$$onoBehaviours can't have. Constructors :/

To give a "good answer" we'd probably need to know still a bit more about the whole system. Or maybe I'm jist lacking in imagination :)

Is the AddRO() there for adding RO's to ther RO's or why do you need a method like that to exist on a RO?

Why does it take an RO as a parameter? Does it need to copy some field values from it or is it just for letting the method know which type of object to create (in that case the parameter's type should probably be System.Type)

Should the method always produce an object of the child type on which the method was called?

avatar image PseudoDev NoseKills · Jun 19, 2017 at 05:50 PM 0
Share

@Nose$$anonymous$$ills Sorry for the confusion. I've fixed the post and code and with new comments. Again, I think bunny's answer is what I really need.

1 Reply

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

Answer by Bunny83 · Jun 19, 2017 at 05:25 PM

Uhm, your code doesn't have a class named ROTree but only a class called RSOTreeLeft. If that's the class you want to create an instance of, just do

 AddRO( new RSOTreeLeft() );

This will create an instance of your "RSOTreeLeft" class and pass the new instance to the AddRO method.

If you want to just pass a type argument to the method, you can't do that with a normal parameter but with a generic type parameter. Though in order for the method to be able to create a new instance of the type argument passed you need to add some constraints. First we require the type to be derived from RoadsideObject and we require the type to have a parameterless constructor:

 private void AddRO<T>() where T : RoadsideObject, new()
 {
     RoadsideObject inst = new T();
     // ...
 }

This method can be used like this:

 AddRO<RSOTreeLeft>();


edit
There's another way using reflection and a System.Type reference. You can do:

 void AddRO(System.Type aType)
 {
     if (aType == null)
         throw new System.ArgumentNullException("aType");
     if (typeof(RoadsideObject).IsAssignableFrom(aType))  // dynamic type check
         throw new System.ArgumentException("aType is not derived from RoadsideObject", "aType");
     RoadsideObject inst = (RoadsideObject)System.Activator.CreateInstance(aType);
     // ...
 }

To use this version you would need to pass the type like this;

 AddRO( typeof(RSOTreeLeft) );

Note that in this case there's no way to restrict the type at compiletime as reflection operates at runtime. So you have to make sure the System.Type reference you pass is actually derived from "RoadsideObject" and has a parameterless constructor that the Activator can use.

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 PseudoDev · Jun 19, 2017 at 05:32 PM 0
Share

Updated to fix my dyslexic mistakes, thanks. I'll give both your answers a try and come back with the results (marking of answers) after refactoring.

avatar image PseudoDev · Jun 19, 2017 at 06:25 PM 0
Share

@Bunny83 Thank you so much for being awesome in the community. I always find your answers really helpful, that is, if I understand what the hell you're talking about, which I did this time.

 private void AddRoadsideObjects<T>(int start, int num, int interval) where T : RoadsideObject, new(){
     for(int i = start; i < num * interval; i += interval){
         RoadsideObject ro = new T();
         Stuff[i].ros.Add(ro);
     }
 }

 void Start(){
     AddRoadsideObjects<TreeLeft>(0, 100, 1);
 }

avatar image Fattie · Jun 20, 2017 at 10:00 PM 0
Share

wave! :)

Is there not a way to send "P$$anonymous$$s" on answers.unity3d ?!

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

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

GUI set max amount of characters for Label 1 Answer

Make a simple tree 1 Answer

Delegates and class constructors 1 Answer

Edit each Parameter Class on Function 1 Answer

All Arrayinstances get changed -1 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