• 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 Setzer22 · Jun 18, 2012 at 01:28 PM · rtsimplementation

Implementation question: Classes instantiating prefabs, or multiple prefabs with classes?

Hello everyone.

This is more like a discussion on which would do better in terms of implementation rather than an actual question, but here it goes:

In my game (something like an RTS, to make things a little bit clearer), I want each unit in game to be an instance of the class named Unit, which contains things such as an inventory, and all the stats for that single unit, I'm working on that so I can store everything I need to make units work independently and be able to take simple orders by themselves (like move there, or, get that thing into your inventory).

Anyway, so I've come into two different ways of doing this and I don't know which would do better:

First I had thought of creating a prefab named Unit, with my Unit script attached on it, so that script would give my unit each property it needs (a 3d model, an HP value and so on...) But then I thought that if I wanted to do that through code, i could approach this in a different way which I think should work as well.

Let's say I create the unit class, and instead of attaching it to a gameObject in the scene, I create instances of that class through code. And then, those instances are able to Instantiate an animated 3d model in scene and are able to control it, so I have many instances of that class in memory controlling a 3d model in the actual game but not being "inside" that gameObject.

What's the best way to implement what I want? I don't fully understand how unity works at that level, so I'm not able to decide which one would do better, I see both ways to be viable and I also can find some pros and cons, for example:

If I use the first method, I can easily access each unit's Unit class, let's say, with a rayCast where the mouse is clicking.

However, if I used the second method, I find it easier to save all my Unit instances into an array, not having to save the whole prefab multiple times, but a bunch of numeric values which I store in the class. Also, having an array with all the units in game seems easier with this second method.

Taking into account the way in which unity works, I find the first way to be more logical, however I don't want to start coding in one way and then find out that the other one had some serious advantages.

Thank you very much

Comment
demented_hedgehog

People who like this

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

1 Reply

· Add your reply
  • Sort: 
avatar image
Best Answer

Answer by Berenger · Jun 18, 2012 at 10:24 PM

You must understand that the script you create that can be attached to game objects inherit from MonoBehaviour. That allow them to receive messages like Update, Start etc. However, you cannot instantiate them like any object with a new keyword. You need to either drag them in the editor on the gameObject, or to use AddComponent.

This being said, I suggest you create a class called UnitPool (or whatever) that contains all the instances of units, all inactive at first. This class must be able to provide an instance of a unit (activating it) or recycle one that is dead (inactive). That way, you don't need to use Instantiate, which is quite expensive, and you can keep track of all the active instance.

This may be usefull.


First, the hierarchy so everything is well sorted in the hierarchy view. You don't HAVE to do it, but it's cleaner. So, create a GameObject named UnitPool, reset transform, add the script UnitPool.cs/js to it (I'll get to that later). Then create other empty go with relevant names for those Units (Troopers, Tanks, etc), make them children of UnitPool, reset transform. Finally, drag you're unit(s) prefab on the scene, make it child of the corresponding go and duplicate them 20 (or more). Select them all and uncheck the active checkbox.

The script now. Declare as many arrays as you have types of units. Assign them the duplicates in the inspector. Create an enum with the name of your units, like enum UnitType{ Trooper, Tank }. Then, create a function that returns a gameObject depending on the type :

 // PS : It would be smart to create a class that does the array access, counter and wrapping.
 public GameObject GetUnit( UnitType type )
 {
     GameObject unit = null;
     switch( type )
     {
         case UnitType.Trooper : unit = trooperArray[ trooperCounter ];
                                 trooperCounter++;
                                 // Wrap the counter when we reach the end
                                 trooperCounter = trooperCounter >= trooperArray ? 0 : trooperCounter;
                                 break;
         case UnitType.Tank : unit = tankArray[ tankCounter ];
                                 tankCounter++;
                                 // Wrap the counter when we reach the end
                                 tankCounter = tankCounter >= tankArray ? 0 : tankCounter;
                                 break;
     }
     // Re-active it
     unit.SetActiveRecursively(true);
 
     // An init function is probably needed here, to restore health for instance
     return unit; 
 }

Finally, a recycle function. The point is to make the unit disappear when it's dead without destroying it. Basically, you just use SetActiveRecursively(true);. You might have to reset the parent if you changed it.

 public void Recycle( GameObject unit )
 {
     unit.SetActiveRecursively(false);
     unit.transform.localPosition = Vector3.zero;
     unit.transform.localRotation = Quaternion.identity;
 }

As you may understand, you need at to have enough pre-instantiated units for any possibilities in your game. The best is probably to limit the number the player can create.

Comment
Setzer22

People who like this

1 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 Setzer22 · Jun 19, 2012 at 08:22 AM 0
Share

Well, I understand the concept, but I'm not sure on how to implement this. So what you're telling me is:

  • I should create a class (UnitPool) which contains instances of all of my units in game. But what do you mean by inactive, made them disabled?

  • Also, how can I avoid using the instantiate method with this? If I have all my instances in a singleton class, and want to get one into game, rather than activating it, shouldn't I copy it into the game? Or were you talking about this class holding ALL of the units let's say there are 20 soldiers in screen, all of them the same (just like in most RTS games), then the UnitPool must have 20 instances of the soldier?

I know this is asking a lot... I'd be very gratefull if you were able to answer me

avatar image Berenger · Jun 19, 2012 at 02:53 PM 0
Share

No worries. I added an example of how I would do it.

avatar image Setzer22 · Jun 19, 2012 at 03:18 PM 0
Share

Well, taking into account the kind of game I want to create, this seems to be what I'm looking for. Unlike normal RTS games, i'm planning to decide all the units in a battle before the battle starts, so this avoids me a lot of unnecesary memory cost. Each unit involved in battle must have been determined before, and doing that through the scene view rather than coding seems like the best way to do it.

So, thank you very much, that was really helpful ^^ I'll keep on working

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

4 People are following this question.

avatar image avatar image avatar image avatar image

Related Questions

Multiplayer RTS Script 2 Answers

How to check hit on tank 1 Answer

How do I implement Kongregate's API? 0 Answers

Attaching an RTS scrolling script to a camera (Noob Question) 3 Answers

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