Search Unity

Setting GameObject via script yeilds unwanted results

Discussion in 'Editor & General Support' started by bh03ig, Mar 24, 2018.

  1. bh03ig

    bh03ig

    Joined:
    Jan 31, 2018
    Posts:
    13
    Hi,

    I have 2 scripts; a GameManager.cs script and a Board.cs script.

    I have code to set a large group of gameobjects in the Board.cs script. The GameManager script would access the Board.cs script and use its public method to set the objects. However, this doesn't seem to work.

    So I tried moving the code entirely to the GameManager script. I realized from this script, it works perfectly. Obviously this isn't how I want to structure my script. I want the code to be in the Board.cs script, but I just can't get it to function correctly.

    I hope someone can tell me why one works but not the other. The code is exactly the same, and I don't get any errors.

    Here are my scripts:
    PasteBin versions can be found here: Game_Manager.cs & Board.cs

    Game_Manager.cs
    Code (CSharp):
    1. public class Game_Manager : MonoBehaviour
    2. {
    3.     public GameObject Board_Grouped_Clubs_Bottom; public Transform[] Clubs_Bottom = new Transform[14];
    4.     public GameObject Board_Grouped_Clubs_Top; public Transform[] Clubs_Top = new Transform[14];
    5.     public GameObject Board_Grouped_Spades_Left; public Transform[] Spades_Left = new Transform[14];
    6.     public GameObject Board_Grouped_Spades_Right; public Transform[] Spades_Right = new Transform[14];
    7.     public GameObject Board_Grouped_Diamonds_Left; public Transform[] Diamonds_Left = new Transform[14];
    8.     public GameObject Board_Grouped_Diamonds_Right; public Transform[] Diamonds_Right = new Transform[14];
    9.     public GameObject Board_Grouped_Hearts_Bottom; public Transform[] Hearts_Bottom = new Transform[14];
    10.     public GameObject Board_Grouped_Hearts_Top; public Transform[] Hearts_Top = new Transform[14];
    11.  
    12. void Start()
    13.     {
    14.         // Get the Group ObjectS and each Groups children Objects
    15.         createAssignBoardSlots();
    16.     }
    17.  
    18. private void createAssignBoardSlots()
    19.     {
    20.         // Get the Groups of each card type Group Object
    21.         Board_Grouped_Clubs_Bottom = GameObject.FindGameObjectWithTag("ClubsBottom");
    22.         Board_Grouped_Clubs_Top = GameObject.FindGameObjectWithTag("ClubsTop");
    23.         Board_Grouped_Spades_Left = GameObject.FindGameObjectWithTag("SpadesLeft");
    24.         Board_Grouped_Spades_Right = GameObject.FindGameObjectWithTag("SpadesRight");
    25.         Board_Grouped_Diamonds_Left = GameObject.FindGameObjectWithTag("DiamondsLeft");
    26.         Board_Grouped_Diamonds_Right = GameObject.FindGameObjectWithTag("DiamondsRight");
    27.         Board_Grouped_Hearts_Bottom = GameObject.FindGameObjectWithTag("HeartsBottom");
    28.         Board_Grouped_Hearts_Top = GameObject.FindGameObjectWithTag("HeartsTop");
    29.  
    30.         // In these groups, find each child and assign it to its array
    31.         Clubs_Bottom = Board_Grouped_Clubs_Bottom.GetComponentsInChildren<Transform>();
    32.         Clubs_Top = Board_Grouped_Clubs_Top.GetComponentsInChildren<Transform>();
    33.         Spades_Left = Board_Grouped_Spades_Left.GetComponentsInChildren<Transform>();
    34.         Spades_Right = Board_Grouped_Spades_Right.GetComponentsInChildren<Transform>();
    35.         Diamonds_Left = Board_Grouped_Diamonds_Left.GetComponentsInChildren<Transform>();
    36.         Diamonds_Right = Board_Grouped_Diamonds_Right.GetComponentsInChildren<Transform>();
    37.         Hearts_Bottom = Board_Grouped_Hearts_Bottom.GetComponentsInChildren<Transform>();
    38.         Hearts_Top = Board_Grouped_Hearts_Top.GetComponentsInChildren<Transform>();
    39.     }
    40. }

    Board.cs
    (Board.Script.set_BoardSlotGameObjects(); is used to set the GameObjects)
    Code (CSharp):
    1.  
    2. public class Board : MonoBehaviour {
    3.  
    4.     public static Board Script;
    5.  
    6.     #region BOARD CARD SLOTS
    7.     // The arrays of Board Objects used to set Active/Inactive on card Selection
    8.     // We hold 2 arrays for each GameObject type:
    9.     // 1 for the Group of children objects, another for the Children in each group
    10.     public GameObject Board_Grouped_Clubs_Bottom;      public Transform[] Clubs_Bottom = new Transform[14];
    11.     public GameObject Board_Grouped_Clubs_Top;         public Transform[] Clubs_Top = new Transform[14];
    12.     public GameObject Board_Grouped_Spades_Left;       public Transform[] Spades_Left = new Transform[14];
    13.     public GameObject Board_Grouped_Spades_Right;      public Transform[] Spades_Right = new Transform[14];
    14.     public GameObject Board_Grouped_Diamonds_Left;     public Transform[] Diamonds_Left = new Transform[14];
    15.     public GameObject Board_Grouped_Diamonds_Right;    public Transform[] Diamonds_Right = new Transform[14];
    16.     public GameObject Board_Grouped_Hearts_Bottom;     public Transform[] Hearts_Bottom = new Transform[14];
    17.     public GameObject Board_Grouped_Hearts_Top;        public Transform[] Hearts_Top = new Transform[14];
    18.     #endregion
    19.  
    20.     void Awake()
    21.     {
    22.         Script = this;
    23.     }
    24.  
    25. public void set_BoardSlotGameObjects()
    26.     {
    27.         // Get the Groups of each card type Group Object
    28.         Board_Grouped_Clubs_Bottom = GameObject.FindGameObjectWithTag("ClubsBottom");
    29.         Board_Grouped_Clubs_Top = GameObject.FindGameObjectWithTag("ClubsTop");
    30.         Board_Grouped_Spades_Left = GameObject.FindGameObjectWithTag("SpadesLeft");
    31.         Board_Grouped_Spades_Right = GameObject.FindGameObjectWithTag("SpadesRight");
    32.         Board_Grouped_Diamonds_Left = GameObject.FindGameObjectWithTag("DiamondsLeft");
    33.         Board_Grouped_Diamonds_Right = GameObject.FindGameObjectWithTag("DiamondsRight");
    34.         Board_Grouped_Hearts_Bottom = GameObject.FindGameObjectWithTag("HeartsBottom");
    35.         Board_Grouped_Hearts_Top = GameObject.FindGameObjectWithTag("HeartsTop");
    36.  
    37.         // In these groups, find each child and assign it to its array
    38.         Clubs_Bottom = Board_Grouped_Clubs_Bottom.GetComponentsInChildren<Transform>();
    39.         Clubs_Top = Board_Grouped_Clubs_Top.GetComponentsInChildren<Transform>();
    40.         Spades_Left = Board_Grouped_Spades_Left.GetComponentsInChildren<Transform>();
    41.         Spades_Right = Board_Grouped_Spades_Right.GetComponentsInChildren<Transform>();
    42.         Diamonds_Left = Board_Grouped_Diamonds_Left.GetComponentsInChildren<Transform>();
    43.         Diamonds_Right = Board_Grouped_Diamonds_Right.GetComponentsInChildren<Transform>();
    44.         Hearts_Bottom = Board_Grouped_Hearts_Bottom.GetComponentsInChildren<Transform>();
    45.         Hearts_Top = Board_Grouped_Hearts_Top.GetComponentsInChildren<Transform>();
    46.     }
    47. }
    48.  
     
    Last edited: Mar 24, 2018
  2. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    I'd recommend that you try to avoid GameObject.Find and create the references directly.

    Also, when posting code on the forums, it's best to use the proper code tags: https://forum.unity.com/threads/using-code-tags-properly.143875/

    Did you have any errors when you tried to call the script from the other?

    Did you call the method in Awake/Start when trying?

    It definitely can work.. so there must be an issue; in case you weren't sure.:)
     
  3. bh03ig

    bh03ig

    Joined:
    Jan 31, 2018
    Posts:
    13
    I can't drag every gameobject into the Inspector slots as I have 96 of them, so I don't think there are any other options :D

    No I have no errors but i noticed this:
    Setting the script instance in void Start() gives me a Object Reference error. However, if I move the Script = this; code to void Awake(), instead of void Start(), indexes are filled.
    So its something to do with time but it still makes no sense. I thought Awake() ensure all gameobjects were loaded before they can be manipulated?
     
    Last edited: Mar 24, 2018
  4. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Both scripts will run Awake before Start(), but the execution order of which is first is not known. You can edit this with script execution order, but for your case there is no need. Doing the assignment in Awake makes more sense. It's good practice to initialize references on the game object in Awake and outside references in Start.

    You could certainly drag the ones for which you're using 'Find'.. only 8 of those. :)

    With Awake and Start() sorted out, can you call the method from 1 script on the other properly?
     
  5. bh03ig

    bh03ig

    Joined:
    Jan 31, 2018
    Posts:
    13
    I fixed the issue. Since I knew it was something to do with time and script loading, I created a coroutine and a method to be called. When 1 second has passed, I use Board.Script.set_BoardSlotGameObjects(); to set the objects and set a bool to true. In Update() Start() I then evaluate the bool to make sure the scripts have loaded before doing anything with them. I set this bool false when the process if complete so it doesn't occur every frame :).

    It works so far!

    Still don't know why this was an issue though.

    Code (CSharp):
    1.  
    2. void Awake()
    3.     {
    4.         StartCoroutine(Wait());
    5.     }
    6.  
    7.     IEnumerator Wait()
    8.     {
    9.         yield return new WaitUntil(() => Time.time > 1);
    10.         Board.Script.set_BoardSlotGameObjects();
    11.         ScriptReady = true;
    12.     }
    13.  
    14.     void Update()
    15.     {
    16.         if (ScriptReady)
    17.         {
    18.             // Get the Group ObjectS and each Groups children Objects
    19.             //createAssignBoardSlots();
    20.  
    21.             // Initially, all oard slot sprites are Empty (neither Active/Inactive)
    22.             SpriteManager.Script.nullify_BoardSprites();
    23.             //setBoardSlotsSpriteDefault();
    24.  
    25.             // Set the Players turn. Initially, it is player 1's turn
    26.             Players.Script.setPlayerTurnState(TurnStates.Player_1_Turn);
    27.             //setPlayerFSM(TurnStates.Player_1_Turn);
    28.  
    29.             // Get the UI Gameobjects (Timer, ConvoyDisplay, PlayerTurn, Left/Right Advertisements)
    30.             UI.Script.setUIObjects();
    31.             //setUIObjects();
    32.  
    33.             UI.Script.setLocationBools(false, true);
    34.             //IsPastDownMax = false; IsPastUpMax = true;
    35.  
    36.             // Set the initial location of Advertisements
    37.             UI.Script.setAdvertisementLocations("Initial");
    38.             //setAdvertisementLocations("Initial");
    39.  
    40.             // Generate 4 completely random numbers between 0 and 4, ensuring they are all different
    41.             GenerateRN();
    42.  
    43.             // Assign the Card Deck GameObjects
    44.             setCardDeckGameObjects();
    45.  
    46.             // Assign the Player Card Objects
    47.             setPlayerCardGameObjects();
    48.  
    49.             // Assign the Players Hand using Deck Cards
    50.             setPlayerHands();
    51.  
    52.             ScriptReady = false;
    53.         }
    54.  
    55.         // Quit Game if Finished
    56.         if (GameFinished)
    57.         {
    58.             Application.Quit();
    59.         }
    60.  
    61.         UI.Script.update_SessionTime();
    62.  
    63.         UI.Script.Update_Convoys_And_PlayerTurn();
    64.         //Update_Convoys_And_PlayerTurn();
    65.  
    66.         checkMouseClick();
    67.  
    68.         UI.Script.MoveAdvertisements();
    69.         //MoveAdvertisements();
    70.  
    71.         getKeyPressed();
    72.         checkFinished();
    73.     }
    74.  
     
    Last edited: Mar 24, 2018