Search Unity

Resolved Passing a static int between scripts and GO's

Discussion in 'Scripting' started by QuickiSticki, May 9, 2021.

  1. QuickiSticki

    QuickiSticki

    Joined:
    Nov 18, 2020
    Posts:
    26
    Okay, so I am trying to pass a static int from one script to another and then to another. The first script is on one GO in scene 1. The two other scripts are on a new GO in scene 2. I am checking the value transfer using a Debug code. The transfer from script 1/GO 1/Scene 1 to script 2/GO 2/scene 2 works just fine. I get the value I am expecting. However, the transfer from script 2/GO 2/scene 2 to script 3/GO 2/scene 2 is not working. I always get a value of 0, which is the default for an unassigned int value. Attached are the clips from my code that deal with this transfer.

    Script 1/GO 1/scene 1
    1.PNG

    script 2/GO 2/scene 2. This one works.
    2.PNG

    script 3/GO2/scene 2. This one does not work.
    3.PNG

    Again, after the full transfer, the Debug on the Character_Assign_Script is giving a value of 0. The Debug on the CharacterAssignedInt script is giving the correct value, pulled from the first script under CharacterConfirm().

    Thank you for any help you can offer!
     
  2. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,909
    One thing I see is you are doing these assignments in Start() for script 2 and script 3. There is no guaranteed order for the Start() function being run on different GameObjects in your scene. It is possible and likely for "script 3"'s Start function to run before that of Script 2 - such that you are copying the value from script 2 before it gets assigned from script 1 in Script 2's start function.

    I'm also noting what I would consider a major design flaw in everything you're doing here. You have at least 3 copies of the same data. Every single one of your scripts has its own independent int "selection" variable. Assigning the value of one int variable to that of another does not link or tie those variables together in any way. It simply copies the current snapshot value of that variable. So it is possible and very likely for these values to not be in sync with either without a lot of diligence on your part.

    In general you should have a single source of truth for this value, and call back to that single source of truth whenever you need to know the current value of that variable.
     
    QuickiSticki likes this.
  3. QuickiSticki

    QuickiSticki

    Joined:
    Nov 18, 2020
    Posts:
    26
    Ah! For reference, at the start of my game, the player selects a character model they want to use from an array. That selected model is then assigned an int value, which I am passing on from that scene to the next scene, where the player will actually play the game. The second script, CharacterAssignedInt, is supposed to be the "source of truth" for this int during scene 2. It is given by the script in the first scene and then is unchanged for the duration of the game. The 3rd script should be reading this source of truth int, which I am then using for both isLocalPlayer and !isLocalPlayer functions in multiplayer.

    In the end, script 1 should assign the int value to script 2/scene 2, where it will remain unchanged. Script 3 should then read that value so I can assign the correct models for each character in the game. I cannot jump directly from script 1 to script 3, due to scene 1 being local only and scene 2 being multiplayer. I need to be able to read the int value given from scene 1 for all players in scene 2, but I need the source to be in scene 2 as well.

    You do make a wonderful point about the Start() order. I was unaware that there was no particular "order" for them to be read, but it makes total sense. I had just never thought about it.
     
    Last edited: May 10, 2021
  4. MartinMa_

    MartinMa_

    Joined:
    Jan 3, 2021
    Posts:
    455
    Just set variable anywhhere in any your scene/go and then only access it CharacterAssignetInt._selection.

    Also it is good to set it private because then you can see who want to acces it and you can easily find what changing this variable.
    Code (CSharp):
    1. public static int _selection {get;set;}
    In your case can be hard to find what is changing your variable since it is public

    https://codeasy.net/lesson/properties
     

    Attached Files:

    • sn.png
      sn.png
      File size:
      154.6 KB
      Views:
      278
  5. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    4,001
    Well, if you turn your field into a property it's actually easy to see where and when your variable got set and even where and when it got read. You can simply replace the original public field with a public property and use a private backing field. That way you can simply add Debug.Log statements in both the getter and the setter of the property. So you can easily see when each is executed. So assuming the field looks like this:

    Code (CSharp):
    1. public static int _selection;
    2.  
    you can simply replace it with:

    Code (CSharp):
    1.  
    2. private static int m_selection;
    3. public static int _selection
    4. {
    5.     get {
    6.         Debug.Log("_selection is read. Current value is " + m_selection);
    7.         return m_selection;
    8.     }
    9.     set {
    10.         Debug.Log("_selection is being set to "+value+". Old value was " + m_selection);
    11.         m_selection = value;
    12.     }
    13. }
    14.  
    Of course you want to remove those debug.log statements once you solved your issue.
     
  6. MartinMa_

    MartinMa_

    Joined:
    Jan 3, 2021
    Posts:
    455

    This is same but shorter, check that link there are all cases

    Code (CSharp):
    1.     public static int _selection {get;set;}
    2.  
     
  7. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    4,001
    You missed my point ^^. The Point was to add Debug.Log statements inside the getter and setter in order to figure out who is reading / writing to that variable. An auto-property is pretty useless on its own. It only makes sense if you have to implement an interface and don't need any special functionality.
     
  8. MartinMa_

    MartinMa_

    Joined:
    Jan 3, 2021
    Posts:
    455
    I still missing your point , you can see who is reading or setting your variable in refference you no need Debug.Log