Search Unity

Best way to access common variables(point, blood, star, life...)

Discussion in 'Scripting' started by lamxung55, Sep 22, 2014.

  1. lamxung55

    lamxung55

    Joined:
    Aug 1, 2014
    Posts:
    10
    Hi all,

    I'm newbie in Unity so maybe this question is a bit stupid.

    In unity I found 2 ways to control common variables:

    1. I set all common variables into MyGameObject, when I need to access them I will call MyGameObject.getInstance().getter...

    2. I set all common variables into MyGameObject, when I need to access them I will call GameObject.find<"MyGameObject">, then I can access its variable
    Which is the best way to access common variable in unity ( bloods, life, points...)

    Thank you for teaching me.
     
  2. SubZeroGaming

    SubZeroGaming

    Joined:
    Mar 4, 2013
    Posts:
    1,008
    Check out GetComponent. I have a video tutorial on it in my Interactive thread. (Link in sig)
     
    lamxung55 likes this.
  3. lamxung55

    lamxung55

    Joined:
    Aug 1, 2014
    Posts:
    10
    Thank you, but I said that I also know there are 2 ways to do that, but I wonder which is better( GetComponent or GetInstance( singleton, static)
     
  4. SubZeroGaming

    SubZeroGaming

    Joined:
    Mar 4, 2013
    Posts:
    1,008
    Singletons should only be used for Manager type classes. Things that have only 1 instance should be a Singleton.
    For everything else, use GetComponent.
     
    lamxung55 likes this.
  5. lamxung55

    lamxung55

    Joined:
    Aug 1, 2014
    Posts:
    10
    I still see any differences. Please show me more details.

    In my eyes now, two ways has a same result but please tell me which is the better way and show me some example cases?

    I'm a developer but in Unity I'm newbie, please forgive me.
    Thank you
     
  6. jhocking

    jhocking

    Joined:
    Nov 21, 2009
    Posts:
    814
    Frankly I'm not a huge fan of either approach, but using GameObject.Find() is definitely worse. I mean, I'm assuming you mean calling that command every time; calling Find() just once can have it's uses (that's why the command exists after all) but calling it every time is inefficient. At most, you'd want to call it once in Start() to get a reference to the object, and then use that reference whenever using the object later on.

    Using a Singleton is closer to what you want, although this gets at a programming preference of mine (that is increasingly becoming a consensus position in the industry). Singletons create problems for code design (too tightly coupled) so in the code I write (eg. the examples in my book) I use an approach where shared objects are accessed through a Service Locator, rather than the shared objects being Singletons.

    However, I'm making assumptions about what exactly you're trying to do, because you didn't explain much in your original question. For example, what is MyGameObject anyway? You should probably explain better in order to get better/more relevant answers.
     
    lamxung55 likes this.
  7. lamxung55

    lamxung55

    Joined:
    Aug 1, 2014
    Posts:
    10
    Thank you jhocking,
    In fact you can see what I want in the topic's title: GameObject is a class which contain all common variables, it can be accessed everytime, everywhere. Example:
    public class MyGameObject : MonoBehaviour
    {
    private int point;
    private int blood;
    private int currentLevel;
    private bool isAlive;
    ....
    GETTER and SETTER...
    }
    Then in other scripts you can update or query points, blood... into/from above class.
    With a traditional programing language, I think Singleton is the best choice for me but I'm not sure in unity stuff.
     
  8. GarBenjamin

    GarBenjamin

    Joined:
    Dec 26, 2013
    Posts:
    7,441
    I use singletons a lot. Personally, I think sometimes people go to extremes to decouple the systems and end up just making everything more complex than is necessary. Singletons are a very easy way of decoupling. For instance, I have a GameState singleton that makes it incredibly simple for all objects to know the current state. One of the properties is isCurrentlyPaused. All any object needs to do at the very start of its Update is examine oGameState.isCurrentlyPaused and if true return. Sure there is a dependency on the GameState class. But who cares? That is what the classes are for to be used. Lol And this way the related stuff is all wrapped up in one place. The GameSate class can be completely replaced.
     
    lamxung55 and StarManta like this.
  9. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,775
    There ARE happy middle grounds between singletons and GameObject.Find. For example, there are situations (this may be one of them) where 90% of the time there will only be one of a thing, but occasionally (say, during multiplayer?), there will be more. In this case you can have a 'PlayerStats.mainPlayer' static member that always points to the player, as well as a 'PlayerStats.all" member that returns an array of all the PlayerStats objects in the scene (which should be maintained by adding and removing from a private static List<PlayerStats>, in OnEnable and OnDisable).
     
    lamxung55 likes this.
  10. lamxung55

    lamxung55

    Joined:
    Aug 1, 2014
    Posts:
    10
    Thank you all,
    I puzzled after read your advices... :(
    Now, before I have more experiences, I choose Singleton
     
  11. Glader

    Glader

    Joined:
    Aug 19, 2013
    Posts:
    456
    Singletons are not the reason for a perceived decoupling. The decoupling is a result of moving logic that conceptually represents a state and its management into a class that's sole purpose is to do so. The very fact you make it a singleton in fact reduces the benefits of the decoupling. Now, everywhere in your code when you need a state you couple yourself not only with the state manager but also with the conceptual idea that it'll be statically accessible. You've arguably coupled your code in a worse way. You may be able to replace the internal workings of the so called GameState class but you can never change its state of global accessibility, anytime you'd like to switch to a more derived or more specific manager you have to go to the 20 places in code that reference this one and switch it and etc.

    However, this is a fault of the Unity workflow. If Unity would allow us to utilize the constructor and provide and interface for registering out dependencies in some sort of Dictionary of IoC containers then maybe Unity clientside code wouldn't be so polluted with singletons, service locating, non-compile time checked GameObject.Finds and GetComponents and etc. You trade in the rigidity and simplicity of the singleton anti-pattern for a more flexible and reusable components. In this way you can build a base library for your game to carry over as a dll from project to project. Using a singleton and trying to do so would be a nightmare.
     
  12. GarBenjamin

    GarBenjamin

    Joined:
    Dec 26, 2013
    Posts:
    7,441
    I've not had any issues with them. My ObjectPooler is a singleton. AudioManager is a singleton. GameState is a singleton. I copy them into each new Unity project and they are ready to be used. Sure there are dependencies on these singletons but that is hardly the worst possible way of doing it. It is the nature of programming to rely on other classes and of course that causes dependencies. I just look for the way that works with the least amount of issues and go with it. I prefer using singletons over IoC and DI and such that tends to just add another layer of complexity to the code. Sometimes it is beneficial but often it is just some extra work for little benefit. A lot of it comes down to personal preferences. Some people are fanatics about using singletons. Others despise them. Some are fanatics about DI and use it as much as possible. Others see it as just making more work that was not necessary. As long as you're getting the game done in a timely manner you're using the right approach. That is my view. ;)
     
  13. Glader

    Glader

    Joined:
    Aug 19, 2013
    Posts:
    456
    The singletons are the only thing you'll be copying into your new project because all your other components and code is worthless without access to some global access point you've coupled them with. Anytime you want to reuse a component you wrote you have to copy the n many singletons you've coupled it with.