精华内容
下载资源
问答
  • 我这里想讨论的是切换场景引发的对象池中对象的问题。  首先如果你什么都不处理,那么一旦你切换场景,你会发现你对象池中所有GameObject本身或者变量全部都变成了null。你下次使用这个对象就会抛出指针异常,所以...

             要在手机上玩转u3d,一定会做的一个就是对象池,在这里我不打算讨论对象池本身,基本思路大同小异。我这里想讨论的是切换场景引发的对象池中对象的问题。

            首先如果你什么都不处理,那么一旦你切换场景,你会发现你对象池中所有GameObject本身或者变量全部都变成了null。你下次使用这个对象就会抛出指针异常,所以你肯定会去研究怎么切场景不销毁,ok,你马上就能找到DontDestroyOnLoad方法,只要声明之后,这个物体就不会被销毁。

           然后你发现有那么多对象都需要声明,会很麻烦,所以你可以新建一个物体,挂上不销毁的脚本,然后把不需要销毁的物体全部放到它里面,那么所有的物体切换场景就不会销毁了。

          然后这样做的第一个问题,就是重复加载同样的场景,你会发现这个不销毁的新建的总物体每次都多复制了一个。因为上一次的保存下来,而这一次的还在,这个也不难解决,你可以直接判断场景中是否已经有这个物体,如果有就添加,没有就不用添加了,当然你可以参考雨凇MOMO的做法:http://www.xuanyusong.com/archives/2938(他说他的做法更好。。。虽然我觉得没有他说的那么夸张)

         接下来似乎不会有什么问题,但其实如果你真的在项目中这么做,你会发现还有很大的两个问题。

         1.我们放对象的时候,经常会把对象设置成不同层,比如默认是default, 可能会有UI层,  effect层。ok,当你把不同层的东西都放在一个obj下面的时候,下次再次加载场景时,它的父亲突然就变了。莫名其妙的把这个非销毁的所有物体挂在了UI层下(这是我碰到的情况,也许可能会挂在别的层,总之就是父亲变了)。这样问题就大了,因为如果父亲不是销毁的,那么儿子标记销毁是无效的,而且改变父亲这种行为也不是我们想看到的。也许你觉得只要重新设置一下父亲就好了。。。但所有儿子的Layer也会全被改掉。。。。你得全部重新设置,蛋碎。。。所以不建议这么做。 要解决也不难,只要注意不同层都应该要有自己的一个非销毁obj,比如default有一个,UI也要有一个,这样就不会乱了。

         2.第二个问题才是大问题。切换场景后,现在出现了三种情况,直接被销毁的物体,包括大部分脚本和GameObject. 不被销毁的静态变量和全局数据。  最后就是挂了不销毁脚本的一堆GameObject.让我们一种一种看。

         第一种是最简单的,既然被销毁了,那么下次重新构造一个就好了,也是问题最少的做法,当然性能最差。

         第二种最常见的就是事件,你给物体挂上了事件一般都是存在一个事件管理器里的,当然正常的做法肯定是在销毁流程的时候会把所有的事件移除,但是切换场景可能是中途退出,所以不一定会把流程走完,所以建议在OnDestroy函数中处理这些问题。因为不论是否走正常流程,被销毁的物体肯定会进入OnDestroy函数,你只要在里面移除事件即可。

        第三种最复杂,首先由于你已经标记为不销毁GameObject,所以你必须在场景切换前自己把所有的物体打回对象池。你可以用代理或者消息实现。这里要注意如果物体已经在对象池中,务必将所有的事件先移除,不然会重复调用。最后将物体移入对象池后,仍然需要注意下次取出的时候,有些东西可能已经不是正常的了。特别是你是对象池中的物体,而你的有些变量是被销毁的物体的引用,这个就需要你自己写逻辑维护了。

        总之对象池虽好,但碰到这种蛋疼问题还是要早发现早处理。

    展开全文
  • 因此,UGUI的事件设置也是很重要的,下面举个例子来说明,Unity3D中如何进行场景切换、UGUI组件事件、开始游戏与关闭游戏的。如下图所示: 我们将设置2个场景,其中一个场景极其简单,只有

    在《【Unity3D】公告栏与开始界面的布置》(点击打开链接)我曾经简单地提到UGUI是怎么布置与使用的,但这根本不完整,就像单身狗缺个另一半永远只能被喂狗粮似的,组件也因为事件的存在才能够精彩。因此,UGUI的事件设置也是很重要的,下面举个例子来说明,Unity3D中如何进行场景切换、UGUI组件事件、开始游戏与关闭游戏的。如下图所示:


    我们将设置2个场景,其中一个场景极其简单,只有“开始游戏”这个按钮,点击之后能进到我们的主场景,在主场景里面我们将设置slider和toggle控制一个cube的旋转。具体如下图所示:


    具体做法如下。

    一、开始场景Start

    1、这一个场景的UGUI布置没什么好说的,就一个Canvas和Button,可以参详《【Unity3D】公告栏与开始界面的布置》(点击打开链接),自己利用矩形工具调好位置,设置好文字的大小之后。新建一个空物体,这物体之后用于附着脚本。


    2、新建一个脚本StartScript,里面写下如下的代码,然后附着于空白物体GameObject上面,至于Unity3D的脚本具体怎么弄,可以参考《【Unity3D】Helloworld》(点击打开链接)。

    using UnityEngine;
    using System.Collections;
    
    public class StartScript : MonoBehaviour
    {
    
        // Use this for initialization
        void Start()
        {
    
        }
    
        // Update is called once per frame
        void Update()
        {
    
        }
    
        //之所以要如此复杂写一个函数接口,是因为UGUI事件函数需要。
        //理论上是可以直接写 public void OnStartGame(){Application.LoadLevel("Game");}
        //但这样一、不规范,二、脚本的复用性大大降低,如果这里有N个地方要实现场景撤换,那么则会有N个脚本
        //所以要这样写,我也不想弄这样的函数接口!-_-!
        public void OnStartGame(string sceneName)
        {
            Application.LoadLevel(sceneName);
        }
    }
    
    另外再提一句,如果是Unity5.x可能会报过时,可以参考《【Unity3D】物体、材质的设置、物体位移与旋转》(点击打开链接)写成SceneManager.LoadScene("XX");,其头文件是using UnityEngine.SceneManagement;,自求多福吧,我发现Unity5.x是个坑,文档少得可以,还是自觉退回Unity4.x继续学,以后估计就像Hibernate打死不用4.x一样,死守3.x阵线。

    3、废话说多了,言归正传,将这个脚本付给空物体GameObject,还需要在Button设置这个事件,具体如下图所示。线画得有点乱,没有艺术修养的屌丝就这尿性,将就着看吧~


    至此这个场景就做完了,Ctrl+S保存一下个场景,Save一下这个场景,命名为Start,这个场景叫啥没所谓,关键是一会儿你要创建的新场景叫啥,你这个OnClick()事件就传个啥名字给函数接口。

    二、主场景Game

    1、【File】->【New Scene】创建一个新场景,由于我们的Onclick表示要切到Game场景里面去,所以我们马上【File】->【Save Scene】一个叫Game就可以,然后Game场景我们需要布置如下的UI,具体如下图所示,除了Slider部分属性需要调整一下以外,其余没什么好说的,其中这里的Whole Numbers表示Slider是全条都可以使用,而不是一格一格的只有整数位,然后value意表开始的默认值为500:


    2、接下来轻点上面的2D,切回3d视图,视角就没所谓了,反正在3D视角从来不好拖,我们直接设坐标算了,如《【Unity3D】物体、材质的设置、物体位移与旋转》(点击打开链接)所示,【GameObject】,布置一个【3D】->【Cube】和【Light】->【Directional Light】,Directional Light如果是Unity3D 5.x就本身自带。对Cube、Main Camera和Directional Light进行如下的调整。


    3、之后就是对脚本的编写,首先,我们先从简单的关闭游戏按钮,事件入手,具体脚本如下,与上面设置开始游戏这个场景切换的道理完全一模一样,操作过场一模一样,就是新建一个CloseScript脚本赋予一个空物体GameObject,再对“关闭游戏”按钮设置OnClick事件而已,不再赘述。

    using UnityEngine;
    using System.Collections;
    
    public class CloseScript : MonoBehaviour
    {
    
        // Use this for initialization
        void Start()
        {
    
        }
    
        // Update is called once per frame
        void Update()
        {
    
        }
    
        //这里还是无参数的,因为关闭游戏本身就不需要任何参数,好嘛-_-!
        public void OnCloseGame()
        {
            Application.Quit();
        }
    }
    
    4、最后就是我们的重中之重,也就是这个游戏的最后一步了。编写RotationScript脚本如下,直接赋予给Cube这个物体。至于物体为甚可以旋转,请参考《【Unity3D】物体、材质的设置、物体位移与旋转》(点击打开链接)。

    using UnityEngine;
    using System.Collections;
    
    public class RotationScript : MonoBehaviour
    {
        public float speed = 0f;//旋转的速度,循例初始化而已,其实这个值没任何意义,后面通过slider当前值赋予
        public float orientation = 1f;//旋转的方向,故意写成float而不是bool,省得类型转换了
    
        // Use this for initialization
        void Start()
        {
    
        }
    
        //如英文缩写的,这个函数里面的内容将会被每帧执行,也就是说,此乃死循环函数,永远被执行
        // Update is called once per frame 
        void Update()
        {
            //让脚本被赋予者,用Vector3表示,永远在旋转
            transform.Rotate(Vector3.forward * Time.deltaTime * speed * orientation);
            transform.Rotate(Vector3.right * Time.deltaTime * speed * orientation);
        }
    
        //此函数接口将会被赋予给Slider的On Value Changed事件
        //Slider被滑动一下,此函数将会被触发,更新旋转速度
        public void ChangeSpeed(float newSpeed)
        {
            speed = newSpeed;
        }
    
        //此函数接口将会被赋予给Toggle的On Value Changed事件
        //(bool a)代表Toggle传过来的参数,虽然没用,但以免传接参数的时候有莫名其妙的错误
        //还是循例写上了
        public void ChangeOrientation(bool a)
        {
            if (orientation == 1f)
            {
                orientation = -1f;
            }
            else
            {
                orientation = 1f;
            }
        }
    }
    

    之后对Toggle组件设置使用Cube组件的ChangeOrientation函数,如下图:


    最后对Slider组件的On Value Changed事件,设置使用Cube组件的ChangeSpeed函数,这里有个大坑,弄了我N久。如下图,大家注意到,这个选项有2个同名的ChangeSpeed函数。


    具体有什么区别呢?请注意,如果你选择的ChangeSpeed后面不带参数的,意为,我要传当前Slider的值进public void ChangeSpeed(float newSpeed),也就是说Slider的值就是newSpeed的值,这也是我们这个程序需要的。

    而,选择ChangeSpeed(float)的话,你会发现这sb的Unity3D非要你设置一个定值参数,如下图所示:


    之后发现什么,大家对照着什么脚本想吧。这就意味着,传进public void ChangeSpeed(float newSpeed)的值永远是0,那么这个立方体永远不会动。

    至此,整个程序做完了。Ctrl+S保存下这个场景。

    三、发布时的部分调整

    因为这里有两个场景,同时UGUI没有做自适应屏幕,所以发布之前我们要做如下的调整,固定程序的分辨率。


    展开全文
  • 问题在使用Unity开发ar客户端的过程中遇到一个问题:每个识别图对应一个场景场景里面有不同的交互,但是在一个场景怎么在识别到另一张图片时跳转到对应的场景中呢?过程经过了解发现Vuforia提供的sdk中...

    问题

    在使用Unity开发ar客户端的过程中遇到一个问题:每个识别图对应一个场景,场景里面有不同的交互,但是在一个场景中怎么在识别到另一张图片时跳转到对应的场景中呢?

    过程

    经过了解发现Vuforia提供的sdk中DefaultTrackableEventHandler.cs是一个重要的脚本,里面注册了识别的监听,通过OnTrackableStateChanged()方法来判断识别图是否被探测到,最初的想法是当探测到时判断当前的图片名字是什么然后进行场景跳转,然而由于摄像头设备清晰度极差带来的log难度以及Vuforia api的不熟悉并没有实现… … 但是之后发现1
    也就是每次在识别到图片时,都能根据此ImageTarget的Inspector面板中的设置来打印名字的
    2

    不完美解决

    每个场景中添加所有的imagetarget,并在脚本识别到方法中添加(假如一共有两个识别图1 and demo_shibie和对应的两个场景ar_firsttest and taikong)

            private void OnTrackingFound(){
            Renderer[] rendererComponents = GetComponentsInChildren<Renderer>(true);
            Collider[] colliderComponents = GetComponentsInChildren<Collider>(true);
            // Enable rendering:
            foreach (Renderer component in rendererComponents)
            {
                component.enabled = true;
            }
    
            // Enable colliders:
            foreach (Collider component in colliderComponents)
            {
                component.enabled = true;
            }
    
            Debug.Log("Trackable " + mTrackableBehaviour.TrackableName + " found");
    
            // 测试场景识别跳转
            if (mTrackableBehaviour.TrackableName == "1" && SceneManager.GetActiveScene().name != "ar_firsttest") {
                loadingPageSchdule.ArSenceName = "ar_firsttest";
                UnityEngine.SceneManagement.SceneManager.LoadScene("loading");
            }
    
            if (mTrackableBehaviour.TrackableName == "demo_shibie" && SceneManager.GetActiveScene().name != "taikong") {
                loadingPageSchdule.ArSenceName = "taikong";
                UnityEngine.SceneManagement.SceneManager.LoadScene("loading");
            }
    
            // 播放音频
            if (audio != null && !audio.isPlaying)
            {
                audio.Play();
            }
        }
    

    3

    可能存在问题

    1. 如果一个程序中有多个识别图片,那样每个对应的场景都要放入所有的imagetarget会不会对设备性能产生大量消耗
    2. 在game视图中显得很乱…
    3. 同时多张识别图片出现在相机视野中,那么会来回跳转场景… 不过我们的客户端没有这种使用场景,可以忽略这种情况带来的影响
    4. // todo find

    所以说这种方式只是一种暂时的替代方案,本人也是刚接触unity3d开发,希望随着学习的深入可以找到更好的办法

    展开全文
  •   在游戏中不可避免的要进行场景切换,如果切换场景要加载的资源太多太大,那么就要耗时很长时间,这对于用户的体验来说很不舒服,也就是常说的游戏卡了。怎么解决这种尴尬呢。   比较推荐的就是异步加载场景...

    推荐阅读

    一、前言

      在游戏中不可避免的要进行场景切换,如果切换的场景要加载的资源太多太大,那么就要耗时很长时间,这对于用户的体验来说很不舒服,也就是常说的游戏卡了。怎么解决这种尴尬呢。
      比较推荐的就是异步加载场景,然后中间加一个过渡场景,过渡场景做的美观一些,然后加一个进度条,看起来就不会那么尴尬了。然后在场景过渡的时候,加一个淡入淡出的效果,就很nice了。
       今天就实现一个场景切换的时候淡入淡出的效果。
       剩下的场景异步加载还有中间过渡场景有时间再写。

    先看一下效果
    在这里插入图片描述

    二、参考文章

    【unity3d 用RawImage组件实现场景淡入淡出】https://blog.csdn.net/qq_34593121/article/details/82107113
    【Unity 实现背景图片淡入淡出】https://blog.csdn.net/liuyanlei1990/article/details/72853307
    【Unity 启动画面淡入淡出】https://www.cnblogs.com/wuzhang/p/wuzhang20150524.html
    【浅谈Unity淡入淡出的效果的实现】https://www.cnblogs.com/MoRanQianXiao/p/7691790.html

    三、实现过程

    1、搭建场景

    在这里插入图片描述
    新建一个RawImage

    2、编写脚本

    FadeInOut.cs

    using UnityEngine;
    using UnityEngine.UI;//注意添加RawImage命名空间
    
    public class FadeInOut : MonoBehaviour, IFadeInOut
    {
        [HideInInspector]
        public bool isBlack = false;//不透明状态
        [HideInInspector]
        public float fadeSpeed = 1;//透明度变化速率
        public RawImage rawImage;
        public RectTransform rectTransform;
    
        void Start()
        {
            rectTransform.sizeDelta = new Vector2(Screen.width, Screen.height);//使背景满屏
            rawImage.color = Color.clear;
        }
    
        void Update()
        {
            if (isBlack == false)
            {
                rawImage.color = Color.Lerp(rawImage.color, Color.clear, Time.deltaTime * fadeSpeed * 0.5f);//渐亮
                //之所以这么写主要是因为Lerp函数的原因,具体详解可以看这篇文章
                //【Unity中Lerp的用法】https://blog.csdn.net/MonoBehaviour/article/details/79085547
                if (rawImage.color.a < 0.1f)
                {
                    rawImage.color = Color.clear;
                }
            }
            else if (isBlack)
            {
                rawImage.color = Color.Lerp(rawImage.color, Color.black, Time.deltaTime * fadeSpeed);//渐暗
                if (rawImage.color.a > 0.9f)
                {
                    rawImage.color = Color.black;
                }
            }
        }
    
        //切换状态
        public void BackGroundControl(bool b)
        {
            if (b == true)
                isBlack = true;
            else
                isBlack = false;
        }
    }
    

    把这个脚本挂载到场景中任意物体上
    在这里插入图片描述
    然后新建一个测试脚本test.cs

    using UnityEngine;
    
    public class test : MonoBehaviour
    {
        public FadeInOut m_Fade;
    
        void Update()
        {
            if (Input.GetKeyDown(KeyCode.A))
            {
                m_Fade.BackGroundControl(true);
            }
            else if (Input.GetKeyDown(KeyCode.D))
            {
                m_Fade.BackGroundControl(false);
            }
        }
    }
    
    

    也挂载到任意物体上
    在这里插入图片描述

    展开全文
  • 应用场景这个非常适合制作翻书的效果,粉丝每点击一次都可以切换下一张图片,当然可以发挥自己的想象力,比如时光流逝的,人物成长的,历年的变化等效果都是非常合适的。实际效果连续点击切换图片 ...
  • 这个跟场景切换时的进度条不同的是, 场景之间的切换是从一个已经打开了的场景跳转到另一个没有打开的场景, 是从 1 加载 2 而这个游戏刚刚启动时的加载是从 0 加载 1,  那这个游戏刚刚启动时的进度条是怎么...
  • unity刚学,场景切换后提示错误不知道怎么修改,求大神![图片说明](https://img-ask.csdn.net/upload/202002/12/1581516045_337623.png)![图片说明]...
  • Unity Editor中打开您的项目和:>在Unity中启用外部选项→首选项→软件包→存储库(仅当Unity ver &...从文件菜单中保存场景和项目。>退出Unity,然后可以删除项目目录中的Library和Temp目录。您可以删除所有...
  • Unity3D入门: 多个摄像机之间的切换

    千次阅读 2014-04-02 11:28:47
    内容描述:这章,我们来学习一下同个场景中多个摄像机怎么切换。 首先,我们来搭建一下场景,2个cube,3个camera,1个平行光。如下   随便调整一下三个摄像机的位置,例如视角如下   侧视图 ...
  • 其实发布出webgl之后,页面上场景窗口右下会有一个按钮,就是切换全屏的,但是想用代码在程序里实现 首先看页面上那个按钮的js脚本是怎么写的 <div class="fullscreen" onclick="gameInstance.SetFullscreen(1)"&...
  • 内容描述:这章,我们来学习一下同个场景中多个摄像机怎么切换。 首先,我们来搭建一下场景,2个cube,3个camera,1个平行光。如下   随便调整一下三个摄像机的位置,例如视角如下 侧视图 前视图 ...
  • 往往不怎么清楚unity 这个方法的具体含义的时候,很容易犯一些令人苦笑不得的错误。比如,有一个物体挂载着一个脚本,里面执行了一句DontDestroyOnLoad(this)。乍看之下没任何问题。但是如果考虑下如下的情形,你...
  • Unity3D 开启协程注意事项

    千次阅读 2018-01-16 19:21:45
    答:将单例类挂到当前场景中的一个空物体上,如果要切换场景,那么这个脚本要挂到需要执行这个脚本内容的那个场景中对应的一个物体上,不能挂到DontDestroyOnLoad那个物体上,虽然在挂在他上面的脚本还存在,依然还...
  •  今天学习了摄像机的应用,具体用途就是在游戏中,主角在行走时是远距离的跟随照射,当打怪物是近距离的照射,这样的切换有利于我们更好的观察游戏中的场景,下面我们就来看看这个是怎么完成的吧!  先来...
  • 状态模式(State)理解模式所针对的情况状态模式优点状态模式与switch-case对比在unity中实现状态模式需要怎么实现状态模式?? 模式所针对的情况 状态模式适用于包含“切换”关键词的几乎任何情况:场景界面切换...
  • 最近在使用unity编辑器的过程中,总是遇到第二次运行游戏unity直接crash的问题,甚为苦恼。...监听编辑器退出游戏运行的事件,在游戏退出的时候自动切换场景就可以了。 查看了一下文档,可以监听EditorApplication...
  • Unity多选题功能开发

    2020-12-01 17:01:29
    新手一直不知道该怎么做一个多选题开发模块!对于文件流又不够熟悉,就只能在场景中做题目更换和分数统计。 提示:以下是本篇文章正文内容,下面案例可供参考 一、场景物体 解释一下: Dati_Multiply——整个答题...
  • 其实Unity自身的SceneManager已经继承了很多内容,为什么这里面我们要重新写一套场景管理器呢,其目的是为了更方便的管理场景已经线性打开切换场景怎么样做到线性,就是不使用脚本驱动,使用生成顺序控制实例化的...
  •   一些童鞋烘焙完场景之后,光影图中会出现如下图所示的一圈一圈的条带状瑕疵,怎么调整参数,烘焙之后都是一样的结果。   上图中的光影图瑕疵也称之为渐变抖动(gradient dither),出现这种缺陷的原因有两种...
  • 怎么跑 克隆项目并在Unity中打开它。 由于存在额外的资源,因此没有Library文件夹的项目约为200 MB。 对于VRTK要求,您不需要进行任何额外的安装,因为所需的文件位于存储库本身中。 该项目可以在没有VR头盔的情况...
  • UGUI学习的第一天

    2016-07-27 10:45:03
    本人之前没怎么接触过UGUI,甚至没怎么接触过Unity,所以算是一个初学者,从这篇日志开始记录自己的学习之路。 首先我在场景中新建了一个canvas,然后在网上下了一张1024*582的图片想当背景图,发现canvas的...
  • Q1:请教个问题,我用Unity 5 里提供的Sprite Packer把A.png,B.png打进一张图集,在运行时我怎么方便地加载这两张图呢?使用场景:某个Image控件根据不同的条件显示A,或者显示B。 目前通常是在脚本序列化信息中...
  • 可以Unity导出场景数据,给服务端做recast寻路。做MMO非常方便,demo演示了服务端3d寻路功能 12. 服务端支持repl,也可以动态执行一段新代码 这样就可以打印出进程中任何数据,大大简化了服务端查找问题的难度,...

空空如也

空空如也

1 2
收藏数 24
精华内容 9
关键字:

unity怎么切换场景