Search Unity

c# script communication efficiency question

Discussion in 'Scripting' started by Endgame, Jun 7, 2012.

  1. Endgame

    Endgame

    Joined:
    Dec 9, 2011
    Posts:
    61
    In my scene I have 1 GO 'game map' with a script attached called MapRuler, on my player GO i have a turret script, and I know of 2 ways of updating a kill counter int inside of the MapRuler from within the player turret script, I was hoping someone could explain the better method or if this even matters, keeping in mind ill have 10+ player scripts which could be adjusting it aiming for iPhone.

    first I can straight adjust the counter by calling MapRuler.kills++;

    the other method I store a reference to MapRuler with mapRuler = GameMap.GetComponent<MapRuler>();
    and then call mapRuler.killCounter(); in which is public void killCounter() { kills++;}

    I
     
  2. KelsoMRK

    KelsoMRK

    Joined:
    Jul 18, 2010
    Posts:
    5,539
    There is always some overhead with a method call but it's negligible. The real question comes down to design. Does anything else need to be done when a turret kills something? If so, then a method is better so all the functionality can be encapsulated. Is the kills member static? If so, is there only ever one instance of MapRuler? If so, is there any reason the entire class can't be static?
     
  3. KyleStaves

    KyleStaves

    Joined:
    Nov 4, 2009
    Posts:
    821
    As Kelso said, it really boils down to design. If there is only ever one MapRuler I go one of two routes.

    A: If it has to be a component, Singleton pattern
    B: If it does not have to be a component, fully static class

    As far as method call vs property, it's also really a question of design - the reality is that a property can do everything a method can do, it just is more ambiguous in terms of how it should be used (sometimes that's a good thing, sometimes that's a bad thing).

    For example:

    Code (csharp):
    1.  
    2. public static class MapRuler {
    3.     static TextField _killsText;
    4.    
    5.     static int _kills;
    6.     public static int Kills {
    7.         get { return _kills; }
    8.         set {
    9.             _kills = value;
    10.             _killsText.text = _kills.ToString();
    11.         }
    12.     }
    13.    
    14.     public static void ScoreKill(){
    15.         _kills++;
    16.         _killsText.text = _kills.ToString();
    17.     }
    18. }
    19.  
    In your case, it's a question of whether or not you want everyone to know how to use the kills variable - or only MapRule. I'd imagine you really only want MapRuler to be able to do things like reset the variable, remove kills. In this case I would encapsulate the functionality and go the method route. However, I'd probably do it like this:

    Code (csharp):
    1.  
    2. public static class MapRuler {
    3.     static TextField _killsText;
    4.    
    5.     static int _kills;
    6.     static int Kills {
    7.         get { return _kills; }
    8.         set {
    9.             _kills = value;
    10.             _killsText.text = _kills.ToString();
    11.         }
    12.     }
    13.    
    14.     public static void ScoreKill(){
    15.         Kills++;
    16.     }
    17. }
    18.  
    That way the behavior of scoring a kill is still encapsulated and handled only by MapRuler, but I don't need to manually update the text field in every location that I adjust the Kills value. I'd only ever adjust it through the (private) property. If MapRuler has to be a MonoBehavior - I would implement it as a singleton...

    Code (csharp):
    1.  
    2. public class MapRuler : MonoBehavior {
    3.     static MapRuler _instance;
    4.     public static MapRuler Instance {
    5.         get {
    6.             if (_instance == null){
    7.                 GameObject go = GameObject.FindWithTag("MapRuler"); // Find an existing MapRuler in the scene
    8.                 if (go == null){
    9.                     go = new GameObject("MapRuler"); // If there isn't one, let's make one! Note - this is only going to work if it's a simple script with no inspector setup
    10.                                                      // If you need inspector setup, instantiate a prefab here instead of just making a new GameObject
    11.                     go.tag = "MapRuler";
    12.                 }
    13.                
    14.                 _instance = go.GetComponent<MapRuler>(); // If you want to use a tag to find it - otherwise find it however you'd like
    15.             }
    16.            
    17.             return _instance;
    18.         }
    19.     }
    20.    
    21.     int _kills;
    22.     int Kills {
    23.         get { return _kills; }
    24.         set {
    25.             _kills = value;
    26.             _killsText.text = _kills.ToString();
    27.         }
    28.     }
    29.    
    30.     public void ScoreKill(){
    31.         Kills++;
    32.     }
    33. }
    34.  
     
  4. Endgame

    Endgame

    Joined:
    Dec 9, 2011
    Posts:
    61
    thanks a lot guys, I appreciate the explanation, and I think that I will go the method call route.