unity3d 多场景切换

2019-07-29 18:04:11 weixin_43378878 阅读数 1391

LevelSelect

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

public class LevelSelect : MonoBehaviour {

	// Use this for initialization
	public bool isSelect=false;

	private void Awake(){
		
	}
	void Start () {
		if(transform.parent.GetChild(0).name==gameObject.name){
			
		}
	}
	
	// Update is called once per frame
	void Update () {
		
	}
	public void Selected(){
		PlayerPrefs.SetString("nowLevel","level"+gameObject.name);
		SceneManager.LoadScene(*);
	}
}

LoadLevel

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class LoadLevel : MonoBehaviour {

	// Use this for initialization
	
	private void Awake(){
		Instantiate(Resources.Load(PlayerPrefs.GetString("nowLevel")));
		
	}
}

2017-04-15 11:27:55 yongh701 阅读数 40699

在《【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没有做自适应屏幕,所以发布之前我们要做如下的调整,固定程序的分辨率。


2018-09-11 10:49:16 weixin_42513339 阅读数 2300

在Unity3D中,一个场景在运行中切换到另一个场景的方法

1.  在Unity中 File->Build Settings->把要切换的场景添加到Scenes In Build下面,也可以Add Open Scenes,添加完关闭这个页面,不要点 Build 或者 Build And Run 。

2. 添加需要加转换场景的代码。

//首先要记得加上引用命名空间

using UnityEngine.SceneManagement;

//然后在需要的代码区域加上:

SceneManager.LoadScene("SceneName");//要切换到的场景名

或者

SceneManager.LoadScene(0); //数字不一定是0,括号里数字是场景的编号,这个编号就是在 File->Build Settings ,上方 Scene In Build,场景名字那行最右边的数字

2018-11-14 10:38:59 hddghhfd 阅读数 1951

分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow

也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴!

               

所谓无缝场景切换,无非是涉及到场景或物体的预读,复杂点涉及下场景卸载,在复杂点涉及到场景二维数组,再在复杂点涉及数据结构用二叉树实现场景资源有序的读取与卸载。当然,复杂的我以后慢慢再说,比较懒,先写最简单的,如果能起到抛砖引玉作用,那这篇文章也算是物有所值了。


  无缝场景切换的优缺点:


  优点:


  1.场景(游戏)连贯性。


  2.相对于多场景游戏,不需要等待场景更换(在进入场景后已经在实时加载下一个场景了)


  3.相对于单个大场景,这种方式能避免所有的场景数据被装入内存(尽管U3D优化很好并不会被渲染出来),很大的数据在内存里影响你游戏的性能(特别是在iphone这种小内存环境)。


  缺点:


  1.操作繁琐(本文介绍比较基础简单的方式)


  2.开发者要求较高(注意保持逻辑清晰,不然后期你会全乱掉的)


  涉及到几个U3D函数:


  Application.LoadLevel(lv)     场景读取(记着用多场景前要现在File-Build Setting里登记下场景,才能在脚本里读取到) DontDestroyOnLoad(object)  保持物体在场景切换的时候不被卸载(能保持他的所有属性哦)


  *AssetBundle 类       预读资源(主要用于web3d,运行时实时从服务器下载需要的场景资源)


  涉及到几个基础知识:


  static 静态类、静态变量:在整个游戏中都不会被重新加载,所以可以当全局全场景变量使用,主要用于记录场景数组。


  Collider的Is Trigger属性:设置成True,他是可以穿越不会产生能量传递的,但是,他是可以接受碰撞侦测的。配合主角的OnTriggerEnter事件,就可以知道你是否正在穿越一个Trigger了。在这里,我们用在判断何时加载新场景上。


  简单的无缝场景切换方案:


  1.建立场景(已经做好很大场景的就准备做切割吧)


  场景尽量小,如果是web3d,那需要更小,已保证场景在网络上传输时间不至于太长,在漫游中再实时读取其他场景数据。一般来说,场景大小考虑因素有两种:如果是web3d模式,考虑网络传输速度;如果是pc,mac,wii,iphone,那就得考虑内存或显存能吃你多少场景数据并且处理起来不费力。


  按照你所需要建立的无缝场景切换方式,你可以按场景的坐标建立以下几种方式:


  1 ) 双场景切换(本文重点)                2)九宫格场景切换


  1)双场景切换:用于单个场景较大的情况。同一时间只加载1个到2个场景(预读周围4个场景),场景间需要交错,避免让用户看到场景的边界深渊=.=.当用户走到边界,就加载下一个场景,如果走到4个顶点,加载下两个场景(如果场景庞大应尽量用障碍物避免用户走到顶点,因为走到顶点要加载的数据是走到边界加载的2倍-,-)


  2)九宫格场景切换:用于单个场景较小的情况。因为同一时间需要在内存中载入以用户为中心的周围(包括本地)9个场景资源,不同于双场景切换的是,场景间不需要交错,因为用户视野永远不会看到当前场景界限。用9宫格方式需要将场景预先存入静态的二维数组,以便读取使用。


  2.制作场景边界


  使用Cube + IsTrigger=True属性是最好的办法。


  1)如果是双场景切换,注意两个场景边界坐标别重在一起,不然你走到边界会发现两个边界不停的切换=.=,要让2个场景边界互相交错一起(做的时候你自然会明白)。有必要的话,边界可以往里面缩一点(甚至可以吧场景重叠1/3,但这样两个场景你要做很多重复的东西),避免用户看到边界。然后建议是把Cube的名字设置成邻接场景名称,因为待会儿写脚本时候方便。


  2)如果是九宫格场景,那就不需要重在一起了,边界Cube名字建议使用本场景的名字,因为这样你一走到下一个场景,就可以知道你在的场景位置而读取周围新场景了。


  3.编写脚本


  好了,现在可以开始写脚本了,我一如既往的很懒,所以不会吧全部代码粘帖出来[unity3D]无缝场景切换解决方案(1) - 简单场景切换 - kingmax_res - kingmax_res的博客。


  先理清楚逻辑关系以及一些常识:


  1.是主摄像机走到边界才会做场景加载或卸载动作。所以代码是放在主摄像机上或者主角上。


  2.场景可以加载,但是没有卸载场景这个东西(也没必要卸载,因为同一时间只会有一个场景为当前场景),所以如果你用九宫格方式做无缝连接,你需要把场景读取,然后让场景里所有物体DontDestroyOnLoad(当然包括主角,也就是this),然后其他场景也这么操作,当需要卸载场景时,只要把所有那个场景Object给Destroy掉就可以了。而做双场景连接则不需要这样,也简单的多。


  3.如果是九宫格,你需要一个静态二维数组去记录每个位置场景的名字。这里也可以不需要这么做,有个技巧,你可以格式化场景名字规则来推算下一个需要加载的场景名字,比如M1N1表示(1,1)场景,那你就可以用字符串拆分的方法知道需要读取M0N0,M1N0,M2N0等等的场景。


  4.接下来就是处理碰撞,获取下一个场景(双场景方式)或者当前场景(九宫格方式)的名字,这里你就可以看到一个被格式化过的场景名有多么重要。


  function OnTriggerEnter(other:Collider){


  Application.LoadLevel(other.name);  //这是双场景方式直接把边界Cube名字设为了下一个场景名


  }


  更加复杂化的无缝切换方案思路:


  1.使用角色与边界距离动态判断,以确定载入时机以及载入哪个方位的场景。


  2.加入判断角色为中心的圆内的物体加载(操作起来有点复杂,除非你整个场景是数字化的,或者干脆是动态生成的),这需要一个加权的二叉搜索树将大地图所有的物体放进去,在满足条件时候去载入最近的。


  (仅提供思路,可能有更好的数据结构去优化他)

转自:http://www.unitymanual.com/thread-5573-1-1.html



           

给我老师的人工智能教程打call!http://blog.csdn.net/jiangjunshow

这里写图片描述
2016-05-05 20:33:16 u014581901 阅读数 47499

首先新建两个场景:Scene_1与Scene_2


在第一个场景Scene_1中加入UI控件Button,Text设置为“点击切换场景”,名称为默认值“Button”


新建一个脚本,命名为ChangeScene,作为组件添加到Button按钮中:


在代码中加入点击事件:

using UnityEngine;
using System.Collections;
using UnityEngine.UI;//注意这个不能少
public class ChangeScene : MonoBehaviour {
    // Use this for initialization
    void Start () {

        GameObject btnObj = GameObject.Find("Button");//"Button"为你的Button的名称
        Button btn = btnObj.GetComponent<Button>();
        btn.onClick.AddListener(delegate ()
        {
            this.GoNextScene(btnObj);
        });
    }

    // Update is called once per frame
    void Update()
    {
    }

    public void GoNextScene(GameObject NScene)
    {
        Application.LoadLevel("Scene_2");//切换到场景Scene_2
    }
}
这样场景切换就成功了,运行结果如下:

运行Scene_1:

点击按钮后进入Scene_2:



Unity3d场景切换

阅读数 1270