Search Unity

Cannot Control Player Characters after LoadScene or LoadSceneAsync

Discussion in 'Scripting' started by calmoji, May 20, 2019.

  1. calmoji

    calmoji

    Joined:
    Apr 23, 2014
    Posts:
    2
    Premise
    As a personal educational project I’m recreating the Windows 3.1 game BangBang in the unity engine. Basic layout for BangBang is two cannons on either side of the screen facing one another separated by some terrain; each cannon represents a playable character. The object of the game is to destroy your opponent’s cannon.



    https://archive.org/details/win3_BANGBANG

    Problem
    I’m running into issues when using additive scene loading, or when loading from one scene to another; the control of my player characters (the cannons) is not working. Instead the controls seem to default to the loaded scene’s camera, or perhaps some other entity of which I’m not aware. When loading either of my game-play scenes manually (loading the scene from the editor and selecting the “play” button, the cannons control fine.

    Game-play Scene Loaded from another Scene
    https://i.imgur.com/gKxEP8a.gifv

    Game-play Scene loaded directly from Editor
    https://i.imgur.com/lOnScgq.gifv


    Question
    Why do the controls seem to default to the camera, rather than my player characters after loading a scene? (additive or normal)

    Setup
    Currently my setups is using 3 scenes. A manager scene for handling the game state and loading/unloading of scenes, and two game-play scenes.

    ‘manager’ – Contains an empty game object with a script StateManager.cs attached the purpose of which is handle the loading and unloading of scenes.



    State Manager has three parameters:
    • Level One Scene – Indicates the scene to load for level 1
    • Level Two Scene – Indicates the scene to load for level 2.
    • Is Playing? – A manual trigger for the Boolean value that tracks whether or not the level is currently in play (a level is not in play when one of the player cannons has been destroyed).
    ‘Level 1’ – First playable level of the game. – Contains two cannons (player objects) and an obstacle. Control for the cannons is handled by a scripts (cannonRotate.cs, FireBarrel.cs) attached to the barrel mesh of the object.



    Cannon Rotate takes three parameters:
    • Rotate Speed – Speed at which the barrel can be rotated.
    • Rotation Max – Maximum angle relative to starting position to which the barrel can be rotated.
    • Rotation Min - Minimum angle relative to starting position to which the barrel can be rotated.

    Player 1’s cannon has the following controls:
    • W – Rotate barrel up
    • A – Rotate Barrel down
    • Space – Fire

    Player 2’s cannon has the following controls:
    • Up Arrow – Rotate barrel up
    • Down Arrow – Rotate barrel down
    • 0 (Numpad) - Fire

    ‘Level 2’ – Second playable level of the game. – Same as Level 1 but the obstacle is different.

    I’ve uploaded my scripts to a public github for reference
    https://github.com/moicodes/public
     
  2. palex-nx

    palex-nx

    Joined:
    Jul 23, 2018
    Posts:
    1,046
    Have you tried swithing the Editor to 'Game' tab?
     
  3. xVergilx

    xVergilx

    Joined:
    Dec 22, 2014
    Posts:
    1,875
    You've probably got errors in the console. Because of the errors the editor is paused.
    That way your scene tab is selected by default. Unpause it and you'll probably proceed to the game tab.

    Disable "Error Pause" if you do not want editor to be paused automatically. Or better yet, fix your errors.
    errorpause.PNG
     
  4. calmoji

    calmoji

    Joined:
    Apr 23, 2014
    Posts:
    2
    It's FIXED :D
    @palex-nx , @xVergilx I cannot thank you enough!
    With your help I was able to figure out and fix the problem :)

    So how was the mystery solved?
    I started by taking @palex-nx 's suggestion: I loaded up my manager scene, pressed play, and swapped to the game tab; alas no luck. Fortunately knowing about the game tab will be incredibly helpful in the future :)

    So I next tried @xVergilx 's recommendation (which in hindsight seems obvious, I can't believe I didn't check the console), and found several errors. I've never been so happy to see errors!
    What were those errors? They were as following:
    With some errors and line numbers in hand I opened up VisualStudio to check out my StateManger script. Around line 16 I had the following:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEditor;
    4. using UnityEngine;
    5. using UnityEngine.SceneManagement;
    6.  
    7. [System.Serializable]
    8. public class StateManager : MonoBehaviour
    9. {
    10.     public string levelOneScene;
    11.     public string levelTwoScene;
    12.  
    13.     public bool isPlaying = true;
    14.    
    15.     private Scene currentScene;
    16.     private Scene stateManagerScene = SceneManager.GetActiveScene()
    17.  
    18.     // Start is called before the first frame update
    19.     void Start()
    20.     {
    21.         DontDestroyOnLoad(gameObject);
    22.         currentScene = SceneManager.GetActiveScene();
    23.     }
    24. ...
    Key thing to note is I'm calling SceneManger.GetActiveScene() as part of a variable instantiation that happens at construct time, which apparently is illegal in the proud nation of Unity. To appease the almighty errors I moved the instantiation of the stateManagerScene variable into the Start() method. Now I have the following code:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEditor;
    4. using UnityEngine;
    5. using UnityEngine.SceneManagement;
    6.  
    7. [System.Serializable]
    8. public class StateManager : MonoBehaviour
    9. {
    10.     public string levelOneScene;
    11.     public string levelTwoScene;
    12.  
    13.     public bool isPlaying = true;
    14.  
    15.     private Scene currentScene;
    16.     private Scene stateManagerScene;
    17.  
    18.     // Start is called before the first frame update
    19.     void Start()
    20.     {
    21.         DontDestroyOnLoad(gameObject);
    22.         stateManagerScene = SceneManager.GetActiveScene();
    23.         currentScene = SceneManager.GetActiveScene();
    24.     }
    25. ...
    After making these changes I once again opened up my manager scene, hit the play button aaaaand...SUCCESS!

    You ROCK!
    I've been banging my head on this issue for weeks, and within one day of posting on the forums ya'll have helped me get over this roadblock. I really appreciate your help :)