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

Better way of passing variables between scripts

Discussion in 'Getting Started' started by Alexsutton, Jul 18, 2019.

  1. Alexsutton

    Alexsutton

    Joined:
    May 27, 2016
    Posts:
    4
    Hi all, apologies if this is a bit of a noob question, I'm just getting started learning how to use Unity with zero experience in programming so I'm teaching everything myself.

    I'm working on a game where the player controls a 'catcher' to catch balls falling through a board. Each ball can have special properties that are triggered when those balls are caught which are stored on the ball GameObject itself. My current system for passing this information around feels messy but I can't think of a more streamlined way of doing it, I was hoping for some advice if anyone could offer it!

    Each ball has a script attached called BallBehaviour. BallBehaviour contains a string variable specialType.

    Every time a ball is spawned, this code is used on one of my main game logic scripts (I've omitted the non-relevant parts of the code):

    Code (CSharp):
    1. spawnedBall = SpawnBall();
    2. DecideSpecial(spawnedBall);
    3.  
    4. private void DecideSpecial(GameObject ball)
    5.     {
    6.         spawnedBallBehaviour = ball.GetComponent<BallBehaviour>();
    7.         //Makes special ball when time delay has reached zero
    8.         if (rateUpTimer <= 0)
    9.         {
    10.             spawnedBallBehaviour.specialType = "BallRateUp";
    11.             spawnedBallBehaviour.ChangeColor(rateUpColor);
    12.             //Resets special ball delay timer
    13.             rateUpTimer = RandomTimerValue(rateUpSpawnFrequency, 2f);
    14.         }
    15.     }
    Then, if the ball is caught my Catcher script runs the following:

    Code (CSharp):
    1. public void OnTriggerEnter2D(Collider2D col)
    2.     {
    3.         //Sends caught message to collider i.e. ball
    4.         col.SendMessage("OnCatch");
    5.         caughtBehaviour = col.GetComponent<BallBehaviour>();
    6.         caughtType = caughtBehaviour.specialType;
    7.         //Sends caught message to game mode with caughtType string
    8.         sharedValues.currentGameMode.SendMessage("BallCaught", caughtType);
    9.     }
    Then, the Game Mode script runs that method:

    Code (CSharp):
    1. public void BallCaught(string type)
    2.     {
    3.         switch (type)
    4.         {
    5.             case "BallRateUp":
    6.                 DropRateUp();
    7.                 break;
    8.             default:
    9.                 break;
    10.         }
    11.        
    12.         sharedValues.currentScore = sharedValues.currentScore + pointsPerBall;
    13.         sharedValues.currentTotalBallsCaught++;
    14.     }
    To me, it feels like there's a lot of GetComponent being used to find the relevant scripts and information during runtime and there must be a more efficient way of doing what the above achieves but I don't know what it is. I've got no knowledge of how events/delegates work in C# but they seem like they might be something I need to look into? Equally I'm not sure whether I'd be able to make a custom class/struct to hold the ball variables but then I still don't know how to pass that information around any simpler than with the same path as the above code.

    Thanks for any advice anyone can offer!
     
  2. Joe-Censored

    Joe-Censored

    Joined:
    Mar 26, 2013
    Posts:
    11,847
    Looks pretty typical to me, though I'd check if caughtBehaviour is null before using it when you eventually add other GameObjects with colliders to your game. GetComponent isn't that slow really. Cache the results rather than repeating calls to GetComponent when possible, but I doubt your OnTrigger is getting called at a high enough rate for GetComponent to appear very high in the profiler.

    What you want to avoid is calling GetComponent several times a frame, such as in Update, especially when you could have just cached a previous result.
     
  3. Alexsutton

    Alexsutton

    Joined:
    May 27, 2016
    Posts:
    4
    Thanks for your advice! When you say to cache the results, what exactly do you mean with regards to this example specifically? As in store the returned component in a variable somewhere in the script that called GetComponent so that it can just refer to that rather than immediately forget about it and have to re-call GetComponent?

    In my game specifically I can't think of a way to make it more efficient as when a ball gets caught and the above code executes, the only other thing that happens is the ball GameObject is destroyed.