Search Unity

SIMPLE: one Variable in multiple scripts in six easy steps!

Discussion in 'Community Learning & Teaching' started by AAcat, May 11, 2015.

Thread Status:
Not open for further replies.
  1. AAcat

    AAcat

    Joined:
    Apr 11, 2015
    Posts:
    19
    (note: we are using Java Script (JS) for this) So you wanna know how to get that 1 variable on that 1 script to move on another script? Well there was never a straight on answer that could be easily found until now. first off you must create your script and variable:
    STEP 1:
    (create script: test1)
    TYPE: var Potato = 2; //this is the variable that will be changed in the other script
    STEP 2:
    (create script: test2) // we are just creating a separate script that will use Potato
    STEP 3:
    (in script test1)
    TYPE: var script: test2; //this connect the two scripts
    STEP 4:
    (In script test2 under function Update)
    TYPE: GetComponent(test1).Potato = 4;
    STEP 5:
    (in script test1 under funtion Update)
    TYPE: if (Potato == 4)
    Debug.Log("it works");
    STEP 6:
    attach the two scripts to any object and run the game. under debug it should say "it works". if you need any help please leave a comment/question below.
    HERE IS HOW THE CODE SHOULD LOOK LIKE:
    Untitlefdsafdasfdsad.png ddddddddddddddddd.png
     

    Attached Files:

    • test1.js
      File size:
      118 bytes
      Views:
      812
    • test2.js
      File size:
      80 bytes
      Views:
      779
    Last edited: May 14, 2015
  2. SubZeroGaming

    SubZeroGaming

    Joined:
    Mar 4, 2013
    Posts:
    1,008
    ...

    You tried, and that's what counts.
     
  3. AAcat

    AAcat

    Joined:
    Apr 11, 2015
    Posts:
    19
    All my friends ask me how to make this work, so I created this thread so I don't have to explain it to them.
     
  4. Samuel411

    Samuel411

    Joined:
    Dec 20, 2012
    Posts:
    646
    Potato != 4
    A+ For effort though
     
  5. AAcat

    AAcat

    Joined:
    Apr 11, 2015
    Posts:
    19
    No we are looking for "is equal" not "not equal".
     
  6. Adam-Buckner

    Adam-Buckner

    Joined:
    Jun 27, 2007
    Posts:
    5,664
    No trolling guys. (Seriously)

    And, yes, this code does work.

    It's not great code, but it does work.

    Test1
    Code (JavaScript):
    1. #pragma strict
    2.  
    3. var script : Test2;
    4. var potato = 2;
    5.  
    6. function Update () {
    7.     if (potato == 4)
    8.         Debug.Log ("It works!");
    9. }
    Test2
    Code (JavaScript):
    1. #pragma strict
    2.  
    3. function Update () {
    4.     GetComponent (Test1).potato = 4;
    5. }
    Now, a couple of notes:

    First, it's general practice to use PascalCase for Functions and ScriptNames, and camelCase for variableNames. PascalCase is where the first letter is Capitalized. camelCase is where the first letter is lowerCase. In general, it's good to stay close withing the "best practice" zone so other people can easily read your code!

    I've adjusted this in the code I've posted.

    Next, a "hidden" step: To make this code work, both scripts MUST be on the same GameObject. This is how the GetComponent() works.What a GetComponent does is find a component on another GameObject. In a case like this, with no other GameObject specified, it will look on this GameObject. So, this code works because, and only if, both components are on the same GameObject. Test2 is looking, every frame, for a Component on this GameObject called Test1 and then trying to find the variable potato and then trying to set its value to 4. One particular downside to this code is the reference between these scripts is being done in Update, which means the same reference is looked up every frame. This is not efficient and can lead to slowdowns in your game.

    In this case var script : Test2 is redundant, and does nothing. When you make a public variable like this, you can make a reference to another script, but you must find a way to set that reference. In Unity, the most common way of doing this is to drag the GameObject with the Component attached into the property field created by the public variable in the inspector. This will mean you can bypass the GetComponent step, which also grabs a reference by code, as you've created this reference in the inspector. As I said, in this case, you are not using this reference to Test2, so you don't need it. It's doing nothing and the reference is NULL.

    For more information on this subject, you can look for my session on Communicating between Scripts and GameObjects.

    To make this code work efficiently, you should try something like this:

    Test1
    Code (JavaScript):
    1. #pragma strict
    2.  
    3. public var potato : int = 2;
    4. private var changed : boolean = false;
    5.  
    6. function Update () {
    7.     if (!changed) {
    8.         if (potato == 4) {
    9.             changed = true;
    10.             Debug.Log ("It works!");
    11.         }
    12.     }
    13. }
    Test2
    Code (CSharp):
    1. #pragma strict
    2.  
    3. private var otherScript : Test1;
    4. private var changed : boolean = false;
    5.  
    6. function Start () {
    7.     otherScript = GetComponent (Test1);
    8. }
    9.  
    10. function Update () {
    11.     if (!changed) {
    12.         changed = true;
    13.         otherScript.potato = 4;
    14.     }
    15. }
    What this code is doing is:

    In Test1, we set up our int value. This is the value we will change. It's public, so we can change it in the inspector. If it doesn't need to be changed in the inspector, make it private. Then we create a boolean flag, so we don't spam the console. With this logic, we will only get one message in our console. In Update we check every frame to see if we have changed our value to 4. If we have, then we flip our flag, so we will stop testing, and then print to the console only once.

    In Test2, we set up our variable to hold the reference to our other script, but it's NULL at this stage. It's private, so we can't set this in the inspector. We also set up another changed flag, so we don't try to change this value every frame. We will set the reference to otherScript in the Start function, so we only have to find this reference once. This is more efficient that finding this reference every frame. If we made otherScript public, and we dragged the reference, we could remove the entire Start function. In Update, we check to see if we've change this value or not, and if we've not changed the value on Test1, then we use our reference to the otherScript, look for the variable potato and change its value to 4.

    Does this make sense?
     
    Dantus and AAcat like this.
  7. Ironmax

    Ironmax

    Joined:
    May 12, 2015
    Posts:
    890
    better to use singleton

    otherScript.instance.Potato = 4

    dont complicate things :)

    The getComponent function is very usefull but in use like Adams just explained.
     
    AAcat likes this.
  8. jhocking

    jhocking

    Joined:
    Nov 21, 2009
    Posts:
    814
    Whether singletons are better is definitely debatable. First off, as the name implies, you can only have one instance of the singleton; what if you need multiple instances of it? If you are trying to manipulate values on the enemies in your game, you don't want every single enemy to be a separate singleton class.

    Second, if you use singletons then your code is tightly coupled to that specific class, which means you can't replace it with a different class later (eg. replacing some sort of device manager for different platforms). This issue is more controversial so I won't get into the whole argument, but this is why I avoid singletons myself.
     
    Last edited: May 14, 2015
  9. SubZeroGaming

    SubZeroGaming

    Joined:
    Mar 4, 2013
    Posts:
    1,008
    I hope you're joking...

    This thread makes me sad :(

    Adam, great job for being a good sport and explaining everything to AACat. I should have done the same, but the troll in me took over.

    Also, I'm not sure Adam explained it, but it's bad practice to call GetComponent in Update, you should cache the variable. Check out my youtube tutorial on GetComponent in my Misc. playlist for a better understanding of GetComponent and how scripts communicate within Unity3D.

    Also, I have a video on Singletons, I highly suggest IronMax watches it so he can stop recommending everyone use static variables.

    Best,

    Jon
     
  10. AAcat

    AAcat

    Joined:
    Apr 11, 2015
    Posts:
    19
    correction... its AAcat not AACat :3
     
  11. Ironmax

    Ironmax

    Joined:
    May 12, 2015
    Posts:
    890
    There is no problem with using static variables if you know you only need 1 of it (the whole idea of singleton). Good for management classes, good performance and no overheads.. Maybe you where using it wrong? If you do a performance test correctly, you see that singleton can perform better than GetComponent. GetComponent can also trigger GC.. (bad for you.)

    Static variables are allocated on the heap

    I recommond people to use it, because its good for performance and you get no overhead issue.
     
    Last edited: May 14, 2015
  12. Ironmax

    Ironmax

    Joined:
    May 12, 2015
    Posts:
    890
    Yes you can only have 1 instance of the it, but you can have many instances of objects depending on it, without any problem. Example, have a pool manager in singleton, that handles instantiation of other gameobjects and there ID,
    then use GetCompent to interact with does objects. If your gameobjects are going to interact with some skills or
    each other then use collision.hit.GetCompent <ScriptName>().Health etc..
     
  13. Ironmax

    Ironmax

    Joined:
    May 12, 2015
    Posts:
    890
    There is a big flaw in this statement, since GetCompent only give you a peak of the content in that object, caching the variables or content only give you a state at the point where you cache it. means you can lose important data. Not only that, but this also give you a hell of a overhead spike. Only use GetCompent at the point where you need to access another objects.
     
    Last edited: May 14, 2015
  14. jhocking

    jhocking

    Joined:
    Nov 21, 2009
    Posts:
    814
    That's not true. It's a reference to the actual object, not just a snapshot of the object.
     
  15. Ironmax

    Ironmax

    Joined:
    May 12, 2015
    Posts:
    890
    Code (C#):
    1.  
    2. GameObject  LastGameObject;
    3. int TargetHealth ;
    4.  
    5. void Awake()
    6. {
    7.       LastGameObject = PoolManager.First(GO) as GameObject;
    8.      TargetHealth = LastGameObjec.GetComponent.<Stats>().Health;
    9. }
    Now if that GO change, your TargetHealth will not be valid even if your reference the GO. You need to reference the object again..
     
    Last edited: May 14, 2015
  16. SubZeroGaming

    SubZeroGaming

    Joined:
    Mar 4, 2013
    Posts:
    1,008
    Why the hell would you assign your component like that? Who does that?

    Listen, this threads gonna make me shoot myself so I'm un-following it. You're talking to two published authors on programming. Stop telling people to use Static variables, end of story.
     
  17. Ironmax

    Ironmax

    Joined:
    May 12, 2015
    Posts:
    890
    Really? you never store values from other objects? wow i hope you don't teach other that limitation.

    I don't care if you follow it or not. your the one coming with claims without backing up your arguments.

    What is the point accessing Compents if your not getting values? Where talking about Potato values here.

    Yes I highly recommend Singleton code pattern when you need it for that situation. This is just one of many design patterns. Maybe you as a publisher should read this page? http://en.wikipedia.org/wiki/Software_design_pattern

    Also kindly dont tell me what to do..thank you..
     
    Last edited: May 14, 2015
  18. renaissanceCoder1

    renaissanceCoder1

    Joined:
    Apr 8, 2015
    Posts:
    127
    If you want to know how to get two scripts communicating effectively, we did a tutorial on GetComponent and SendMessage - and we talk about the advantages and pitfalls of both.

    Check it out here if you are interested: Script Communication
     
  19. Adam-Buckner

    Adam-Buckner

    Joined:
    Jun 27, 2007
    Posts:
    5,664
    This thread no longer has any relevance to the original posters intent.

    To the OP: If you wish to continue your learning and discussion, please post again. I appreciate whenever someone is both trying to help and to learn

    To Ironmax: It can be unwise to be impolite to people experienced in their field of expertise. This won't help anyone learn and may keep people from helping you. None of us know everything, and listening to advice is both sensible and wise - even if we don't take it on-board. If there is a difference of opinion, then polite discussion can be had on the subject.

    As such, I am closing this thread.
     
    robertoyurims and AAcat like this.
Thread Status:
Not open for further replies.