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 Kallen330 · Mar 11, 2014 at 01:30 AM · randomenemycomponentclassaddcomponent

Best way to find appropriate script for random enemy?

Okay, so I'm making a card game-- and the way that it's set up, currently, is that when I want to create a card, the call goes to the card manager with an id-- this id being the specific card in question. The card is fetched (the data, I should say) and the prefab is created. This is nice because I can just supply a random id and it will give me a random card. The problem I've run into is (theoretically) initializing these cards as enemies.

When the object is created, sometimes I'll know which card I'm calling (and therefore, which specific class it should be-- ie. Arcanist, Fire Mage, etc) and sometimes I won't. I've had to settle with the less-than-ideal situation of using GetComponent("scriptname") to add the appropriate script behavior, but I don't like the idea of GetComponent having to do a string search, as I feel like this call could get costly (I also don't like the idea of having a million unique scripts per unique enemy, but I don't see a way around that). Is there a more efficient, or more OOP to do this? Should I even attach a component?

The idea behind attaching a component with the specific class script was so that I could have a parent class, EnemyAI, run virtual methods like OnHit(), or PostTurnEffect() and then override child methods could be called instead (so that each enemy exhibits specific behavior) but I'm starting to question whether that's the best way to go about it.

Any ideas? Surely this has been done before?

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 highpockets · Mar 11, 2014 at 02:00 AM 0
Share

What about using a Random.Range of integers and having each number in the range represent a class...??

avatar image Kallen330 · Mar 11, 2014 at 03:18 AM 0
Share

Is it possible to make a list of classes?

avatar image ShadoX · Mar 11, 2014 at 09:01 AM 0
Share

Why not just create a card pool and get cards from that randomly ? http://en.wikipedia.org/wiki/Object_pool_pattern

avatar image highpockets · Mar 12, 2014 at 02:27 AM 0
Share

That's a great idea, keep all of your cards in a pool and use random.range to get them. Store each of the cards in an array of GOs.

1 Reply

· Add your reply
  • Sort: 
avatar image
0

Answer by TonyLi · Mar 11, 2014 at 03:41 PM

It sounds like components are a good idea for what you're doing, so I'd stick with them.

If you don't know the component ahead of time, you're always going to need some kind of lookup. String lookups are fragile though; typos and the like can easily break them.

Consider using a C# interface, something like:

 public interface IEnemyAI {
     void OnHit();
     void PostTurnEffect(); ...
 }

And make each component an implementation of this interface:

 public class Arcanist : MonoBehaviour, IEnemyAI {
     public void OnHit() {...}
     public void PostTurnEffect() {...}
 }

If you want to inherit reusable code, you can always use inheritance, too:

 public abstract class BasicEnemy : MonoBehaviour, IEnemyAI {
     public virtual void OnHit() {...}
     public virtual void PostTurnEffect() {...}
 }
 
 public class FireMage : BasicEnemy {
     public override void OnHit() {
         base.OnHit();
         ExplodeInFlames();
     }
 }

When you get a prefab instance, you can store a reference to the interface:

 GameObject enemyObject = CardManager.GetCard(i);
 IEnemyAI enemyAI = enemyObject.GetComponent(typeof(IEnemyAI)) as IEnemyAI;
 ...
 enemyAI.OnHit(); // Enemy was just hit.


You can still put them in a pool like @ShadoX suggests. It sounds like your card manager already basically does this. Once you pull them out of a pool, you can use the method above to access the component.

Comment
Add comment · Show 2 · 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 Kallen330 · Mar 11, 2014 at 04:38 PM 0
Share

This sounds great, thank you!! $$anonymous$$y only last question now is adding the component to the object in the first place. Any elegant way of doing this that doesn't involve searching with a string?

avatar image TonyLi · Mar 12, 2014 at 01:06 AM 0
Share

You create prefabs at design time and instantiate them at runtime. If you're creating a prefab, I figured you'd manually assign the appropriate script(s). If you use composition (combining lots of small scripts to build up the final behavior) and make scripts configurable, you won't need as many scripts. By configurable, I mean for example you could have a Fire script that spawns a projectile prefab. You can use the same script for an archer (arrow), fire mage (fireball), or any other ranged unit.

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

23 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

Related Questions

problem extracting transform from an array 1 Answer

How do I animate my enemy randomly with time? 1 Answer

AddComponent for RawImage not functioning as expected 0 Answers

Database-like arrays 1 Answer

Instantiation from class 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