Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Create dynamic vars

Discussion in 'Scripting' started by Eidern, Mar 23, 2015.

  1. Eidern

    Eidern

    Joined:
    Mar 29, 2014
    Posts:
    94
    Hello,
    i'd like to know how to create reference for objects by using dynamic variables.
    I explain myself a bit with an example

    I got 3 references for different Classes
    Code (CSharp):
    1.  
    2. P1Controller p1controller;
    3. P2Controller p2controller;
    4. EnemyController enemyController;
    5.  
    they all got a x var in each class

    later inside a loop i'd like to have something like
    Code (CSharp):
    1.  
    2. ..
    3. var varToFind = "p1"+Controller.x;  //where 'p1' can be 'p2' or 'enemy'
    4. ..
    5.  
    6.  
    is there a way to do this?
     
  2. Fajlworks

    Fajlworks

    Joined:
    Sep 8, 2014
    Posts:
    344
    Personally I think it is a bad approach having P1Controller, P2Controller, EnemyController as separate classes. I'm pretty sure both your P1Controller and P2Controller classes reuse same code. But, for this case I would think you would need a Dictionary<string, MonoBehaviour>

    Something like this:
    Code (CSharp):
    1. using System.Collections.Generic;
    2.  
    3. public Dictionary<string, MonoBehaviour> list = new Dictionary<string, MonoBehaviour>();
    4.  
    5. list.Add("p1", p1controller);
    6. list.Add("p2", p2controller);
    7. list.Add("e1", enemyController);
    Accessing them becomes as easy as:
    Code (CSharp):
    1. P1Controller = list["p1"] as P1Controller;
    However, I urge you to reconsider your design. Having different classes for different players means double work and lots of copy pasting. Also, I would advise you to think about your variables, if you plan to have more than 1 of the same object, put them into a list. Sure you won't have more than let's say 4 players, but in case you would consider adding extra 12 to create 16 player multiplayer you won't have to refactor your code. Also having a List<EnemyController> is much better than having enemy1Controller, enemy2Controller, etc.
     
    Eidern likes this.
  3. Glockenbeat

    Glockenbeat

    Joined:
    Apr 24, 2012
    Posts:
    669
    Make a new base class, "BaseController" or so, where you put your shared code. Inherit from that base class.
     
    Eidern likes this.
  4. Eidern

    Eidern

    Joined:
    Mar 29, 2014
    Posts:
    94
    Ok thanks
    You're both right : I have first to re-think my game mechanics with classes,
    and i'll see then if I'll need dictionary or if inheritance alone will help me enough.
    Thanks again :)
     
  5. Eidern

    Eidern

    Joined:
    Mar 29, 2014
    Posts:
    94
    Well As I'm rewriting everything (not that much, though)
    I'm seeing that i'm falling again in the same scheme of view and I'll stuck soon with the same problems of scopes even with inheritance.

    So i'd like a little help with the organisation of my components
    Actually I have :
    -Base controller,
    which see the player/ennemy vars and contains the actions (player/ennemy cannot act of their own, they need an item displayed on screen to act, when you click on the item, it calls the correspondant action on the gameController that will see the player/enemy stats and change them depending of the action, launch the animation for each player/enemy concerned)
    -EnemyXController,
    containing the stats of ennemys
    -playerXController,
    containing the stats of players

    Should I have a:
    -Basecontroller where both my player/ennemy will inherit, but I guess it's the same that above

    -or should I mix up between Basecontroller/itemController/and character controllers? but in this case I don't really get how to make them work together..
     
  6. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,179
    You've hit the divide between polymorphic scripting and component-based scripting. From what I've seen, there's a lot of very diehard component adherents in the community, and Unity is kinda built to support that kind of scripting, but both methods still have merits, and mixing them is often smart.

    In essence, what you're trying to do is polymorphism. The idea is to put base behaviour in one (usually abstract) base class, and then inherit from that to make more specialized scripts for each thing in the game.

    In that case, you have a BaseController (I think 'EntityController' is better) that defines stuff like movement, health, etc. Then you inherit from that to create the PlayerController, which calls the movement methods from the BaseController based on input, and a EnemyController that uses AI to call those methods.

    The component idea is different. In that case, you have very small scripts that each take care of one little thing each. So you have one movement script, one health script, one AI script, one Input script, and so on.

    Then you create your player by throwing the health script, the input script and the movement script onto one object. The input script finds the movement script and sends it commands, while the AI does the same. Any weapons looks for health scripts, and applies damage to that script instead of the player or enemies directly.

    The big downside to components is that your scripts will be talking back and forth a lot. Your movement script have to check the health script in some way - as you probably don't want dead stuff to move. Still, it's probably a bit easier to wrap your head around doing components instead of polymorphism if you don't come from a programming background.
     
    Eidern likes this.
  7. Eidern

    Eidern

    Joined:
    Mar 29, 2014
    Posts:
    94
    Thanks,
    It's kinda confusing at first because there are so many different approaches of unity.
    So I was stick to the learning tuts and so, and became to write everything with components talking to each others with the help of a mainGame controller component.

    But now I'm a little stuck with that kind of approach because of my main problem.
    I'm trying now to make a mix between components and communication between "handmade" classes..not that easy at first :/
     
  8. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    Simply implement an interface that exposes x
     
  9. novashot

    novashot

    Joined:
    Dec 12, 2009
    Posts:
    373
    "The big downside to components is that your scripts will be talking back and forth a lot. Your movement script have to check the health script in some way - as you probably don't want dead stuff to move. "

    Don't think I'd ever have movement check my health script at all... Fire off a death event when whatever dies... Heck even a send message to self in event of death is ok to make sure all components know it has died (I know most people will slam Send Message... but if not abused it works fine)

    Code (CSharp):
    1. //health.cs
    2.  
    3. void TakeDamage(int amount){
    4.      health -= amount;
    5.  
    6.      if(health <= 0){
    7.           Die();
    8.      }
    9. }
    10.  
    11. void Die(){
    12.      // do some death stuff here
    13.      //one time call on death to hit all components on this object these components require to have the "YouDied" function to listen of course
    14.      gameObject.BroadcastMessage("YouDied", SendMessageOptions.DontRequireReciver);
    15. }
    16.  
    17.  
    18. // player input / movement.cs
    19. private bool dead = false;
    20.  
    21. void YouDied(){
    22.      dead=true;
    23. }
    24.  
    25.  
    26. void Update(){
    27.      if(!dead){
    28.           // handle input
    29.      }
    30. }
    again... not ideal, but better than checking other scripts before handling input or anything
     
  10. passerbycmc

    passerbycmc

    Joined:
    Feb 12, 2015
    Posts:
    1,738
    novashot that is way better done using a event or interface
     
  11. novashot

    novashot

    Joined:
    Dec 12, 2009
    Posts:
    373
    Event or interface is better overall... but I didn't have a basic sample to show for that. This is easier and better than constantly checking.
     
  12. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    Wait, why the instead? Polymorphism is one of the fundamental tools of OOP, and you should be making heavy use of it in any component based architecture.

    Also note that close coupling between a set of related classes is not always a bad thing. I normally build a bunch of abstract base components, that are tightly coupled. Then the derived classes can make use of the coupling, without being dependent on a specific class. You can also do this with interfaces, but it can require more work as Unity does not serialise interfaces out of the box.
     
  13. Fajlworks

    Fajlworks

    Joined:
    Sep 8, 2014
    Posts:
    344