• 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 devstudents · Dec 03, 2014 at 09:02 PM · classinheritanceinstancebuildingrts

efficient way to make RTS building instances

I am working on a construction system for my RTS. Each building requires different amounts of cordage, wood, stone etc. My first attempt was to make a class "structure" and then make a c$$anonymous$$ld class for each building type w$$anonymous$$ch would specify its building requirements and other stats such as $$anonymous$$t points.

The problem with t$$anonymous$$s approach is that it requires a long if statement to work. For example, I press the 'build' button and the worker finds the closest construction site and takes materials to it. In order for the worker to know what materials to bring and how much, they must access the component unique to that structure. Since every structure type has a different class, I need to create an if statement like in the following pseudo code:

 if (closestConstructionSite.name == "Wood Storage")
 {
    woodStorageScript = closestConstructionSite.transform.GetComponent<WoodStorage>(); 
 }
 else if(closestConstructionSite.name == "Stone Wall")
 {
   stoneWallScript = closestConstructionSite.transform.GetComponent<StoneWall>(); 
 }
 //etc.... for every building type that I have. 

I'm more than happy to do t$$anonymous$$s but I've got a sinking feeling that there is a better way. Any ideas?

Comment
Add comment
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

2 Replies

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

Answer by Kiwasi · Dec 06, 2014 at 12:29 AM

Some pseudo code may illustrate the point.

  public class Structure : MonoBehaviour {
      public string structureName;
      public int structureID; 
      public int structureHP; 
      public int requiredWood;
      public int requiredCordage; 
      ...
  }
 
  public class TreeHouse : Structure {
      void Start (){
          requiredWood = 30;
      }
  }
 
 
  public class Builder : MonoBehavour{
      void SomeFunction (){
          woodRemaining = constructionSite.GetComponent(typeof(Structure)).requiredWood;
      }
  }

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 devstudents · Dec 06, 2014 at 06:17 AM 0
Share

ahhh, I've never seen the typeof(x) syntax before. I'm going to try it out right away. I think that was the missing link for me. Thanks a lot skaredcreations and boredMormon for your help.

avatar image devstudents · Dec 06, 2014 at 07:05 AM 0
Share

ok... really sorry to be slow but I need to be sure. I've attached a woodStorage script to the wood storage prefab. It inherits from the structure script. My worker finds the closest construction site and needs to access the woodStorage component. I tried to do this by doing the following code:

 public void FindClosestBuilding()  
     {
         pathFindingScript.canMove= true;
         closestEmptyBuilding = hugeVector; 
         for(int i = 0; i < managerScript.emptyBuildings.Count; i++)
         {
             if(Vector3.Distance (transform.position, managerScript.emptyBuildings[i].transform.position) < Vector3.Distance(transform.position, closestEmptyBuilding))
             {
                 closestEmptyBuilding =  managerScript.emptyBuildings[i].transform.position;
                 emptyBuilding  = managerScript.emptyBuildings[i]; 
             }
         }
         if(emptyBuilding != null)
         {
             pathFindingScript.target = emptyBuilding.transform.position;
             pathFindingScript.findTarget = true;             
             interactionScript.transportingState = Interaction.TransportingStates.DepositMaterials; 
         }
     }
 
     //in the next state, this method is evertually called: 
     
     public void AddMaterialsToBuildingSite()
     {
         if(emptyBuilding.GetComponent(typeof(Structure)).requiredWood != 0)
         {
             //add wood
         }
     }


The problem is that emptyBuilding.GetComponent(typeof(Structure)).x is not accessing any values. What have I missed? Thanks again for your time.

avatar image devstudents · Dec 06, 2014 at 07:17 AM 0
Share

ah man, I'm spamming! well it seems to work when I just do GetComponent().requiredWood, but I'd like to know why the typeof thing didn't work out. This formatting looks interesting.

avatar image
2

Answer by SkaredCreations · Dec 04, 2014 at 02:08 AM

Why not adding the requirements (materials, $$anonymous$$t points etc) directly in the base building class? Since every building has requirements I see no reason to add t$$anonymous$$s in every subclass, I did t$$anonymous$$s way in the last RTS having HitPoints, RequireWood, RequireIron etc as "int" type in the BaseBuilding class. The buildings that don't require a specific resource would have the property set to 0.

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 Kiwasi · Dec 04, 2014 at 03:36 AM 1
Share

Polymorphism is the answer. One alternative to endless derived classes is to have the constructionSite own an instance of costData. Either as a reference in your script, or a a seperate component.

avatar image devstudents · Dec 05, 2014 at 05:56 AM 0
Share

Thanks for the replies! Ideally I would have just one base building class. This would make accessing the component and finding out the number of materials etc. much easier. My problem is that I do not know how to do this with one script. How would I use polymorphism to solve this problem? I've attached my base building class just so you can see what I'm up to:

 public class Structure 
 {
     public string structureName;
     public int structureID; 
     public int structureHP; 
     public int requiredWood;
     public int requiredCordage; 
     public int requiredMud;
     public int requiredStraw; 
     public int requiredStones; 
     public int currentWood;
     public int currentCordage; 
     public int currentMud;
     public int currentStraw; 
     public int currentStones;
     public int structureCurrentHP; 
     public float buildTime; //this is how long the building would take to construct if the person was a master of their craft. 
     public Vector3 structureLocation; 
 
     public bool structureBuilt; 
 
     public Structure()
     {
 
     }
 
     public Structure(float time, string name, int id, int hp, int wood, int cordage, int mud, int straw, int stones, int cwood, int ccordage, int cmud, int cstraw, int cstones, int currentHP)
     {
         buildTime = time;
         structureName = name;
         structureID = id;
         structureHP = hp;
         requiredWood = wood;
         requiredCordage = cordage;
         requiredMud = mud;
         requiredStraw = straw;
         requiredStones = stones;
         currentWood = cwood;
         currentCordage = ccordage;
         currentMud = cmud;
         currentStraw = cstraw;
         currentStones = cstones;
         structureCurrentHP = currentHP; 
     }
 
 }

   
avatar image SkaredCreations · Dec 05, 2014 at 11:46 PM 1
Share

Your issue is easily solved by setting the values of properties in the constructor of the subclasses. In my case I inherited the BaseBuilding (your Structure) from Monobehavior so I could attach the script directly to the prefab. Why you created a class instead of a component? Your StoneWall should ideally inherit from Structure and Structure should inherit from Monobehavior, this way it's very easy to access its properties from the Worker script in your first post by using GetComponent() instead of the long "if else" statement.

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

26 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

Related Questions

inheritance - instance variable problem? 4 Answers

Is Instance Of 3 Answers

C# Inheritance, base class attributes, override and null object 1 Answer

Inheritance best solution to handle *many* instances of a class with unique values? 1 Answer

C# Parent-SubClass set inherited properties help 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