Search code examples
c#unity-game-engineloadscene

Scene loads differently when loaded from another scene than selecting that scene first, in the editor (Unity, c#)


Quite a simple problem really, but after searching the internet i am struggling to find an answer.

Problem

Scene doesn't load fully, some parts work, some don't, from another scene (through Application.LoadLevel() ), whereas opening the scene directly and then playing it works fine.

What I've tried

  • Waiting for a while to see if it is just taking time to load (1 min +), in comparison to the ten seconds when it loads on its own.
  • Built it and seen if the problem repeats itself or not, allowing me to decide if it is due to the editor, like when you switch scene and the lighting goes dark. However, the problem repeats itself.
  • Upgraded my Unity to version 5.3.4f1, then used SceneManager.LoadScene() instead of Application.LoadLevel(). No change evident at all.

What I think may causing it

  • Reading many web pages i understand that Unity's scene loading and scene system can be annoying

Thank you for reading this, I hope it is a simple problem but to a quite inexperienced Unity user (ME) it is quite perplexing. If any exact details are required i will add them on but to me they are unnecessary (and take a lot of effort too).

Further Detail (If you need it)

Video showing the scene loaded directly and from another scene (HERE)

Script with interesting debug results -

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class ObstacleController : MonoBehaviour {
    ButtonCreator ButtonCreator;
    List<GameObject> LineGameObjects;
    List<LineClass.Line> LineInfos;
    List<GameObject> Positions;
    List<GameObject> Obstacles;
    List<GameObject> PossiblePositions;
    public List<Vector3> Targets;
    List<Vector3> PossiblePos;
    List<LineClass.Line> ConnectedLines;
    GameObject Ball;
    public GameObject ball;
    public int numberOfBalls;
    public float speed;
    Vector3 noGoPoint;
    List<float> Speeds;
    public List<Vector3> PastReachedPoints;
    bool Targeted;
    public GameObject cross;
    int i99;
    // Use this for initialization
    void Start() {
        i99 = 0;
        Speeds = new List<float>();
        ConnectedLines = new List<LineClass.Line>();
        ButtonCreator = GetComponent<ButtonCreator>();
        LineGameObjects = new List<GameObject>();
        LineInfos = new List<LineClass.Line>();
        Positions = new List<GameObject>();
        PossiblePositions = new List<GameObject>();
        Obstacles = new List<GameObject>();
        Targets = new List<Vector3>();
        PossiblePos = new List<Vector3>();
        Targeted = true;
        PastReachedPoints = new List<Vector3>();
    }

    void LateUpdate()
    {
        GameObject[] gameObjects = GameObject.FindGameObjectsWithTag("cross");
        foreach (GameObject target in gameObjects)
        {
            GameObject.Destroy(target);
        }
        Instantiate(cross, noGoPoint, Quaternion.identity);
    }
    // Update is called once per frame
    void Update() {
        Debug.Log("HEY"); // LOOK HERE <- <- <- <- <- 
        if (Time.frameCount == 1)
        {
            Debug.Log("2HEY"); // LOOK HERE <- <- <- <- <- 
            // connect up lists
            LineGameObjects = ButtonCreator.LineGameObjects;
            Positions = ButtonCreator.Positions;
            LineInfos = ButtonCreator.LineInfos;
            //intialise possible positions
            PossiblePositions.Clear();
            int i = 0;
            while (i < Positions.Count)
            {
                PossiblePositions.Add(Positions[i]);
                i++;
            }
            // set number of balls
            numberOfBalls = 11;
            // create balls
            i = 0;
            while (i < numberOfBalls)
            {
                GameObject Ball = Instantiate(ball) as GameObject; // create the ball
                int i2 = Random.Range(0, PossiblePositions.Count); // randomise the index
                Ball.transform.position = PossiblePositions[i2].transform.position; // set the positions
                Ball.transform.position = new Vector3(Ball.transform.position.x, Ball.transform.position.y, -0.1f);// set the z to -1
                Obstacles.Add(Ball); // add to list
                Debug.Log("3HEY"); // LOOK HERE <- <- <- <- <- 
                i++;
            }
            PossiblePositions.Clear();
            i = 0;
            while (i < Positions.Count)
            {
                PossiblePositions.Add(Positions[i]);
                i++;
            }
            // reset possible positions

            setNoGo();
            setTarget();
        }

        bool TargetsReached = false;
        bool TargetsNotReached = false;
        int i5 = 0;
        while (i5 < Obstacles.Count)
        {
            if (Obstacles[i5].transform.position == new Vector3(Targets[i5].x, Targets[i5].y, -1))
            {
                TargetsReached = true;
            }
            else
            {
                TargetsNotReached = true;
            }
            i5++;
        }

        if (TargetsReached == true && TargetsNotReached == false)
        {
            Targeted = false;
        }
        if (Targeted == false)
        {
            SetupTarget();
        }
        if (Targeted == true)
        {
            int i3 = 0;
            while (i3 < numberOfBalls)
            {
                Vector3 current = Obstacles[i3].transform.position;
                Vector3 target = new Vector3(Targets[i3].x, Targets[i3].y, -1);
                float step = Speeds[i3] * Time.deltaTime;
                Obstacles[i3].transform.position = Vector3.MoveTowards(current, target, step);
                i3++;
            }
        }

    }
    void SetupTarget ()
    {
        if (i99 == 2)
        {
            setNoGo();
            i99 = 0;
        }
        setTarget();
        i99++;
        Targeted = true;
    }
    void setNoGo() // if targeted = false as targets have reached
    {
        Vector3 previous = noGoPoint;
        PossiblePositions.Clear();

        int i = 0;
        while (i < Positions.Count)
        {
            PossiblePositions.Add(Positions[i]);
            i++;
        }
        i = 0;
        while (i < PossiblePositions.Count)
        {
            bool isThereBlue; // will return true if at least one of the connected lines of this point is blue
            isThereBlue = false;

            // for each possible position find all the connected lines
            ConnectedLines.Clear();
            int i2 = 0;
            while (i2 < LineInfos.Count)
            {
                if (LineInfos[i2].endpos == PossiblePositions[i].transform.position || LineInfos[i2].startpos == PossiblePositions[i].transform.position)
                {
                    ConnectedLines.Add(LineInfos[i2]);
                }
                i2++;
            }

            // checks if there is a connected blue line
            i++;
            int i3 = 0;
            while (i3 < ConnectedLines.Count)
            {
                if (ConnectedLines[i3].colour == Color.blue)
                {
                    isThereBlue = true;

                }
                i3++;
            }

                // if there are no connected blue lines remove from the selection for no go zone
                if (isThereBlue == false)
                {
                    PossiblePositions.RemoveAt(i);
                    if (i != 0)
                    {
                        i--;
                    }
                }
            i++;

        }

        i = 0;
        while(i < PossiblePositions.Count)
        {
            if (PossiblePositions[i].transform.position == previous)
            {
                PossiblePositions.RemoveAt(i);
                if (i != 0)
                {
                    i--;
                }
            }
            i++;
        }
        // for each obstacle
        // when targeted = false
        // choose a target, which is not - 
        // where it is now
        // or in the no go area
        i = Random.Range(0, PossiblePositions.Count);
        noGoPoint = PossiblePositions[i].transform.position;
        }


    void setTarget()
    {
        PastReachedPoints.Clear();
        Targets.Clear();
        Speeds.Clear();
        int i3 = 0;
        while (i3 < numberOfBalls)
        {
            Vector3 point = Obstacles[i3].transform.position;
            //if (i3 == 1)
            //{
            //    Instantiate(cross, point, Quaternion.identity);
            //}
            point.z = 0;
            PossiblePos.Clear();
            // find all the possible positions to move towards
            int i = 0;
            while (i < LineInfos.Count)
            {
                if (point == LineInfos[i].startpos)
                {
                    PossiblePos.Add(LineInfos[i].endpos);
                }

                else if (point == LineInfos[i].endpos)
                {
                    PossiblePos.Add(LineInfos[i].startpos);
                }
                i++;
            }
            //i = 0;
            //while (i < PossiblePos.Count)
            //{
            //    if (i3 == 1)
            //    {
            //        Instantiate(ocross, PossiblePos[i], Quaternion.identity);
            //    }
            //    i++;
            //}
            PossiblePos.Remove(point);

            // remove any from the no go list
            i = 0;
            while (i < PossiblePos.Count)
            {
                    if (new Vector2(PossiblePos[i].x, PossiblePos[i].y) == new Vector2(noGoPoint.x, noGoPoint.y))
                    {
                        PossiblePos.RemoveAt(i);
                        if (i != 0)
                        {
                            i--;
                        } 
                    }   
                i++;
            }
            //choose the random target
            //i = 0;
            //while(i < PossiblePos.Count)
            //{
            //
            //    if (i3 == 1)
            //    {
            //        Instantiate(rmarker, PossiblePos[i], Quaternion.identity);
            //    }
            //    i++;
            //}
            PastReachedPoints.Add(point);
            Targets.Add(PossiblePos[Random.Range(0, PossiblePos.Count)]);
            float time = 0.3f;
            float distanceInBetween = Vector3.Distance(Obstacles[i3].transform.position, Targets[i3]);
            float speed = distanceInBetween / time;
            Speeds.Add(speed);
            i3++;
        }

    }
}

The Console Messages

When the scene is loaded directly

SceneDirect

But interestingly when it is loaded from another scene it does not have any debugs of "2HEY" or "3HEY".


Solution

  • Time.frameCount is counting frames from the start of the game. So if you load the scene from another scene Time.frameCount will be greater than 0 for sure.

    Also it's faster to debug your game instead of using logs to see what's going on. Just hit Play in MonoDevelop and (for Unity 4.3 and below) choose Unity Debugger, place breakpoints where you need to stop and check variable values, then hit Play in Unity.

    Good luck