Search Unity

Is it ok to create a static class for easy access to scripts initialized often from...

Discussion in 'Scripting' started by ephemeral-life, Oct 14, 2015.

  1. ephemeral-life

    ephemeral-life

    Joined:
    Sep 12, 2015
    Posts:
    488
    other objects? Is this better from a perspective of performance compared to having do a GameObject.Find()? Thanks.
     
  2. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    6,775
    As long as you understand the limitations that come with the structure you define in said static class.

    You're basically describing a very loose version of the Singleton pattern. Google about that for the various debates about how that pattern is often abused and leads to bugs and spaghetti code.
     
    Kiwasi and ephemeral-life like this.
  3. ephemeral-life

    ephemeral-life

    Joined:
    Sep 12, 2015
    Posts:
    488
    Ok, I won't use it unless necessary then, thanks :).
     
  4. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    6,775
    Do note, GameObject.Find() is also a slow beast of a bad design.

    You should really be setting up references via properties on your script.
     
    ephemeral-life likes this.
  5. ephemeral-life

    ephemeral-life

    Joined:
    Sep 12, 2015
    Posts:
    488
    Ok, I'll look into that. Thanks again.
     
  6. ephemeral-life

    ephemeral-life

    Joined:
    Sep 12, 2015
    Posts:
    488
    I had to do the following to be able to use the transform as a property:

    private Transform playerTransform = GameObject.Find("Player").transform;

    Is there any better way to do it?
     
    Last edited: Oct 14, 2015
  7. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    6,775
    make the field 'playerTransform' public, and drag the playerTransform onto it.
     
    ephemeral-life likes this.
  8. ephemeral-life

    ephemeral-life

    Joined:
    Sep 12, 2015
    Posts:
    488
    You're of great help.
     
    Last edited: Oct 14, 2015
  9. Zaladur

    Zaladur

    Joined:
    Oct 20, 2012
    Posts:
    391
    Keeping it private and using the [SerializeField] attribute allows this as well.
     
    Kiwasi likes this.
  10. ephemeral-life

    ephemeral-life

    Joined:
    Sep 12, 2015
    Posts:
    488
    I'm not sure how to make this work when creating properties in a class inheriting from MonoBehaviour. Do I have to make the class static?
     
  11. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    6,775
    nope, just public properties (or private with SerializeField), attach the script to a gameobject, and you'll see the property in the inspector.
     
  12. ephemeral-life

    ephemeral-life

    Joined:
    Sep 12, 2015
    Posts:
    488
    I'll copy paste my code so I can try to explain it better:

    Code (CSharp):
    1. public class PlayerInputs : MonoBehaviour
    2. {
    3.    ...
    4.     public CapsuleCollider playerCapsuleCollider;
    5.    ...
    6.  
    7.     public CapsuleCollider PlayerCapsuleCollider
    8.     {
    9.         get
    10.         {
    11.             return playerCapsuleCollider;
    12.         }
    13.     }
    14.  
    15. void Awake(){
    16.     playerCapsuleCollider = GetComponent<CapsuleCollider>();
    17. }
    18.  
    19.  
    how do I access that property? I tried:

    Code (CSharp):
    1. private PlayerInputs myPlayerInputs;
    2. private CapsuleCollider playerCollider;
    3. ...
    4.  
    5. Start(){
    6.         myPlayerInputs = new PlayerInputs();
    7.         playerCollider = myPlayerInputs.PlayerCapsuleCollider;
    8. ...
    9. }
    This returns null. I also tried: myPlayerInputs = gameObject.AddComponent<PlayerInputs>();
     
    Last edited: Oct 15, 2015
  13. JamesLeeNZ

    JamesLeeNZ

    Joined:
    Nov 15, 2011
    Posts:
    5,618
    I never feel the drag approach is the correct one. But then I did get a corrupt scene that one time, so yeah. Easiest approach for learning though.
     
  14. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    6,775
    You don't create 'new' MonoBehaviours.

    They're components, that you drag and drop onto GameObjects.

    Unity uses a component design pattern... watch this:
    https://unity3d.com/learn/tutorials/modules/beginner/editor/game-objects-and-components
     
  15. ephemeral-life

    ephemeral-life

    Joined:
    Sep 12, 2015
    Posts:
    488
  16. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    6,775
    you can create a base class that inherits from MonoBehaviour, and then inherit from that, if you have some design pattern that requires it.

    And if there are any classes that already exist outside of the unity framework, you composite them into a MonoBehaviour.
     
    ephemeral-life likes this.
  17. ephemeral-life

    ephemeral-life

    Joined:
    Sep 12, 2015
    Posts:
    488
    Thank you, this will solve a lot of my headaches.

    So I created a class :

    public class PlayerPropertiesMonoAdd : MonoBehaviour
    {

    }

    and let PlayerInputs inherit from it, but that didn't solve the problem:

    public class PlayerInputs : PlayerPropertiesMonoAdd
    {
    ...
    }

    I'm probably missing something :/.
     
    Last edited: Oct 15, 2015
  18. ephemeral-life

    ephemeral-life

    Joined:
    Sep 12, 2015
    Posts:
    488
    For now I'm doing it in a very ugly way, I really don't like using 2 'Find'. Any further help is greatly appreciated.

    Code (CSharp):
    1.  
    2. public class PlayerPropertiesMonoAdd
    3. {
    4.     private Transform playerTransform = GameObject.Find("Player").transform;
    5.     private CapsuleCollider playerCollider = GameObject.Find("Player").GetComponent<CapsuleCollider>();
    6.  
    7.  
    8.     public Transform PlayerTransform
    9.     {
    10.         get
    11.         {
    12.             return playerTransform;
    13.         }
    14.     }
    15.  
    16.  
    17.     public CapsuleCollider PlayerCollider
    18.     {
    19.         get
    20.         {
    21.             return playerCollider;
    22.         }
    23.     }
    24. }
    25.  



    Code (CSharp):
    1.         myPlayerInputs = new PlayerPropertiesMonoAdd();
    2.         targetTransform = myPlayerInputs.PlayerTransform;
    3.         playerCollider = myPlayerInputs.PlayerCollider;
     
    Last edited: Oct 15, 2015