Search Unity

I'm sure it's simple and I am just missing something.

Discussion in 'Scripting' started by Seaworth, Aug 23, 2019.

  1. Seaworth

    Seaworth

    Joined:
    Aug 15, 2019
    Posts:
    19
    I have:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.SceneManagement;
    5. using UnityEngine.UI;
    6.  
    7. public class S0Calling1 : MonoBehaviour
    8. {
    9.     // Start is called before the first frame update
    10.     public Button testButton;
    11.     void Start()
    12.     {
    13.        
    14.     }
    15.  
    16.     // Update is called once per frame
    17.     void Update()
    18.     {
    19.        
    20.     }
    21.  
    22.     public void S0ButtonClicked()
    23.     {
    24.         Debug.Log("pssss");
    25.         testButton.GetComponentInChildren<Text>().text = "Push"; // Was "Start"
    26.         DontDestroyOnLoad(testButton);
    27.         SceneManager.LoadScene(1);
    28.     }
    29. }
    30.  
    At this point, I go through to scene 1 and then have this:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.SceneManagement;
    5. using UnityEngine.UI;
    6.  
    7. public class S1Calling0 : MonoBehaviour
    8. {
    9.     public Canvas qCanvas;
    10.  
    11.     // Start is called before the first frame update
    12.     void Start()
    13.     {
    14.         qCanvas.gameObject.SetActive(false);  
    15.     }
    16.  
    17.     // Update is called once per frame
    18.     void Update()
    19.     {
    20.        
    21.     }
    22.  
    23.     private void OnDestroy()
    24.     {
    25.         Debug.Log("Destroyer");
    26.     }
    27.     public void S1ButtonClicked()
    28.     {
    29.         Debug.Log("Aleph");
    30.         SceneManager.LoadScene(0);
    31.     }
    32. }
    33.  
    Now I return to scene 0 as expected but the text for the scene 0 button remains unaltered. What am I missing to keep it as "push"?
     
  2. hpjohn

    hpjohn

    Joined:
    Aug 14, 2012
    Posts:
    2,190
    Although you dontDestroyOnLoad the button, when you do reload the scene, is the old button with other text being re-loaded and shown ontop?
     
  3. Seaworth

    Seaworth

    Joined:
    Aug 15, 2019
    Posts:
    19
    It is being shown with the original text. I used dontdestroyonload in the first script before calling scene 2
     
  4. Laperen

    Laperen

    Joined:
    Feb 1, 2016
    Posts:
    1,065
    You probably should move your DontDestroyOnLoadLine to awake or start instead. That in itself wont solve your problem since having something not destroyed on load means you want a particular instance of the object to exist, so when you go back to scene 0, youll have to destroy the newly created duplicate from scene 0 being loaded in.

    What are you trying to achieve with this scene changing? Is it like entering and exiting a room in the context of the game? whats wrong with having a button in scene 1 in the same position to do the return to scene 0?
     
    Seaworth likes this.
  5. Seaworth

    Seaworth

    Joined:
    Aug 15, 2019
    Posts:
    19
    Essentially this is just a mock up of the problem. What I am looking to do is have a player make a menu choice(choice button) for a puzzle type (choice scene), get taken to a new scene(puzzle scene N) where they attempt to solve the puzzle, after which they are taken back to choice scene and the appropriate choice button should now be inactive with either a tick or across, but most importantly not interactable.

    So as I see it:
    1) They make a choice
    2) The button settings are altered and they are taken to the puzzle scene
    3) They come back to the choice scene where the button now appears to reflect it is no longer a choice.
     
  6. Brathnann

    Brathnann

    Joined:
    Aug 12, 2014
    Posts:
    7,188
    If all your buttons are under a parent object, what I would do is just maintain a static list of which child to turn off. Say I have

    parent
    --button0
    --button1
    --button2
    etc...more buttons

    And the user clicks on the first button. My static list on of ints then gets the number 0 added to it. When I return to the choice scene, I then loop through that list and simply turn off each child based on the index. So the first button is now off/not interactable. Then I choose button2, and I add 2 to my list. Loop through on return, and button0 and 2 are disabled.
     
    Seaworth likes this.
  7. Yoreki

    Yoreki

    Joined:
    Apr 10, 2019
    Posts:
    2,605
    I just wanted to say that your thread title is pretty useless. I mean, when you itend to buy a book, you look through the titles to see if something interrests you. Then you read the abstract / summary to find out if you wanna buy it. In forums it's the same way. We use titles to see if we can potentially help with a problem, then read the first post to get a closer look. Sorry for not having anything useful to say ontopic, but i wasnt even sure what the topic was when i got here ;)
     
    Seaworth likes this.
  8. Laperen

    Laperen

    Joined:
    Feb 1, 2016
    Posts:
    1,065
    Ah i see. you want a change of state to persist between scenes. In hindsight you mentioned that quite a few times.

    I assume button pressing occurs on canvas, and you are attaching the public functions to canvas buttons. The moment UnityEvents are used in the inspector, your scene setup should be made known, since it's not obvious what is called by what.

    case and point, the script supposedly being marked by DontDestroyOnLoad. Where is this script attached to? What's calling S0ButtonClicked? If the script isn't attached to the button, the button remains but the script will be destroyed on load, and the button's UnityEvent will nolonger call the function in the destroyed script.

    In order to keep the things you want persistent between scene changes, you either have to make the things marked as DontDestroyOnLoad self contained, or make sure every necessary object interacting with each other is marked as DontDestoryOnLoad.

    You also have to manage duplicates which doesn't seem to be present at all. It makes me feel your original way of using DontDestroyOnLoad wasn't successful. Check for a duplicate button after moving DontDestroyOnLoad to Awake or Start.

    If there is a duplicate, all that means is the duplicate needs to be destroyed when it is loaded. Even assuming that fixes it and nothing breaks, I can't imagine this way of working to scale well. What happens when you have another 2 scenes which function this way aswell? Are you going to make some of the objects between those 2 new scenes marked as DontDestoryOnLoad again? What if you have 10 of these situations? The number of objects that remain loaded in the scene will just keep increasing with each new scene loaded in. They may all remain on the screen aswell unless you manually destroy them, which is going to be tedious.

    Not to say DontDestroyOnLoad is bad, its just not practical to use it for this situation. Much easier will be what @Brathnann recommended. The general idea is to keep the state of objects separate from the scene, and check the state on Start/Awake to see what should be displayed. There are so many ways to do this but static variables is a good place to start.
     
    Seaworth likes this.
  9. Seaworth

    Seaworth

    Joined:
    Aug 15, 2019
    Posts:
    19
    Thanks to everyone for their feedback and help. Based on the comments, I have solved this in the following way. Created static variables in a game initialization script to hold the button status. Setup the choice scene to modify the buttons as reflected in the global variables when the scene was Start()ed. Then created button click functions to modify the statics. After that each time it goes back to the choice scene then the buttons appear as per condition reflected in the statics. Works a treat. I just need to make it more efficient, but the first goal of something working has been achieved. Efficiency comes later. Thanks all.