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. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

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

Discussion in 'Scripting' started by PhoenixRising1, Oct 14, 2015.

  1. PhoenixRising1

    PhoenixRising1

    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:
    8,380
    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 PhoenixRising1 like this.
  3. PhoenixRising1

    PhoenixRising1

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

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,380
    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.
     
    PhoenixRising1 likes this.
  5. PhoenixRising1

    PhoenixRising1

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

    PhoenixRising1

    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:
    8,380
    make the field 'playerTransform' public, and drag the playerTransform onto it.
     
    PhoenixRising1 likes this.
  8. PhoenixRising1

    PhoenixRising1

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

    Zaladur

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

    PhoenixRising1

    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:
    8,380
    nope, just public properties (or private with SerializeField), attach the script to a gameobject, and you'll see the property in the inspector.
     
  12. PhoenixRising1

    PhoenixRising1

    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,616
    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:
    8,380
    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. PhoenixRising1

    PhoenixRising1

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

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,380
    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.
     
    PhoenixRising1 likes this.
  17. PhoenixRising1

    PhoenixRising1

    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. PhoenixRising1

    PhoenixRising1

    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