【问题标题】:Scene loads differently when loaded from another scene than selecting that scene first, in the editor (Unity, c#)从另一个场景加载场景时,场景加载与在编辑器中首先选择该场景不同(Unity,c#)
【发布时间】:2016-04-08 12:06:48
【问题描述】:

确实是一个很简单的问题,但是在搜索了互联网后,我很难找到答案。

问题

场景没有完全加载,有些部分工作,有些不工作,从另一个场景(通过 Application.LoadLevel() ),而直接打开场景然后播放它工作正常。

我的尝试

  • 等待一段时间,看看它是否只需要时间来加载(1 分钟以上),而它自己加载时需要 10 秒。
  • 构建它并查看问题是否重复出现,让我确定是否是由于编辑器造成的,例如切换场景并且灯光变暗时。然而,问题重演。
  • 将我的 Unity 升级到版本 5.3.4f1,然后使用 SceneManager.LoadScene() 而不是 Application.LoadLevel()。没有明显的变化。

我认为可能导致它的原因

  • 阅读了很多网页,我了解到 Unity 的场景加载和场景系统可能很烦人

感谢您阅读本文,我希望这是一个简单的问题,但对于一个非常缺乏经验的 Unity 用户 (ME) 来说,它是相当令人困惑的。如果需要任何确切的详细信息,我会添加它们,但对我来说它们是不必要的(也需要付出很多努力)。

更多细节(如果需要)

显示直接加载的场景和从另一个场景加载的视频 (HERE)

带有有趣调试结果的脚本 -

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++;
        }

    }
}

控制台消息

直接加载场景时

SceneDirect

但有趣的是,当它从另一个场景加载时,它没有任何“2HEY”或“3HEY”的调试。

【问题讨论】:

    标签: c# unity3d load scene


    【解决方案1】:

    Time.frameCount 正在从游戏开始计算帧数。所以如果你从另一个场景加载场景Time.frameCount肯定会大于0。

    此外,调试您的游戏而不是使用日志来查看正在发生的事情会更快。只需在 MonoDevelop 中点击 Play 并(对于 Unity 4.3 及更低版本)选择 Unity Debugger,在需要停止并检查变量值的位置放置断点,然后在 Unity 中点击 Play

    祝你好运

    【讨论】:

    • 非常感谢,我现在知道为什么会出现我的问题,我使用 if(Time.frameCount == 1) 来确保我可以从其他脚本和该脚本从启动函数访问数据。我想我仍然可以通过从 start 函数获取 frameCount 然后在我的 update 函数中说什么时候加一来获得相同的期望结果。
    • 有趣的是,这个答案花了我不到半小时的时间来解决堆栈溢出问题,但在统一答案后花了 19 个小时,同时通过我进一步尝试解决问题来更新我的问题。
    • 是的,起初我从 Unity Answers 开始,但那里的愚蠢问题让我很生气。与 Unity Answers 相比,雇主更看重一个人的 stackoverflow 评级,所以是的,嗨
    • @g_l 如果你希望你的 if(Time.frameCount) 块只在关卡开始时发生一次,更新不是最好的地方。这样的事情怎么样? void Start() { //Initialize stuff here StartCoroutine(AfterOneFrame()); } IEnumerator AfterOneFrame() { yield return null; Debug.Log("2HEY"); }
    • @罗伯特。因此,如果我放弃所有代码 IEnumerator AfterOneFrame () { yield return null; HERE }(使用 start 函数)它会在 start 函数后一帧工作,并且比在 update 函数中使用 if 语句更有效?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-30
    • 1970-01-01
    • 2015-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多