开发者社区> shy丶gril> 正文

Unity3d之无缝地形场景切换–解决方法和代码

简介:
+关注继续查看

当我们开发一个大型项目的时候-会遇到这样的问题(地形场景的切换)这个只是字面意思-并不是重场景1的100 100 100坐标一下切换到场景2的100 100 100坐标这样的方法--(如果您以为是这样的技术和代码)那就不用看了。这个技术的实质意义是为了解决--多地形场景带来的大量内存占用问题-举个我的例子-我的测试项目是1013张绘制地形--在不用上面的技术情况下-占用了我4.2G的内存。想想下-如果一个大型的游戏直接这么运行的话)一下就会带来5-8G的内存占用--这个游戏还能玩吗?

下面让我们来研究实现的方法和代码

涉及到几个U3D函数:(引用高人的文档介绍)

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

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

涉及到几个基础知识:

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

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

2.制作场景边界

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

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

3.编写脚本

好了,现在可以开始写脚本了,我一如既往的很懒,所以不会吧全部代码粘帖出来 。(我会别看到这里不看了,这是以前高人写的)

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

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

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

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

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

function OnTriggerEnter(other:Collider){

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

}

上面的介绍是大概的描述-具体实现方法如下

我们在使用这个技术之前要将你的地形--在U3D里的File-Build Setting里登记下场景,才能在脚本里读取到-Add Current(这个是登记地形)

之后我们来制作一个简单的-2个地形的切换方法


这个图是做好了的2张地形--中间的Cube是用来接受角色的碰撞的--这样我们就知道在何时去载入我们的下张地形场景了(不包括其他-数据。。列入--坐骑这类的-这个需要另一段代码单独给坐骑-马或者车子这类的--还有很多)

Cube---把Inspector--Is Trigger--划勾--(这个作用是接受碰撞但不产生能量传递-也就是说他接受碰撞,但可以让同样具有 Is Trigger-划勾的属性物体通过--列入-我们的角色或坐骑)(补充--我们的角色也需要去勾选-Is Trigger-这些才可以通过,但官方自带的FPS--没有Is Trigger-这个勾选像-可以用如下方法解决-创建一个新的Cube为他重新命名-把他作为FPS-父物体--然后勾选-Cube的 Is Trigger-子物体就会有这项属性了)

这些工作建立好了以后-开始我们的脚本工作。

脚本如下:

function OnTriggerEnter(other:Collider)

{

if (other.gameObject.name=="Cube1")

Application.LoadLevel("Terrain 1");

};

复制代码

为了方便大家理解--我没有重新命名--Cube1--就是我们接受碰撞体,Terrain 1是我们的要载入的下张地形。(大家可以用很多方法去优化他--有优化的方法请发在这个帖子内-方便大家查看-非常感谢)

这段代码要放在角色上或角色摄像机上或FPS的父物体Cube上。

以上的操作就完成了-一个重地形0到地形1的切换--(可以解决100M或跟高的内存占用问题-这个要看你的地形场景而定了)

但这并不完整--我们也可能要重地形1回到地形0---这个要你们自己解决了-以上的内容已经把这个解决的方法说出来了--大家自己学习发挥下--这样才有进步。

下面我们来说明4张地形场景的载入--逻辑(这里只说明逻辑,具体代码和上方一样,需要大家自己发挥下)


这个图中可以看到4张地形场景--我重点讲解--中间的2个大的Cube逻辑--那4个长方形的大家应该都清楚了。除非你没认真看。

中间最大的Cube是来判断--角色走的这个范围内的时候他要去载入那张地形场景-如果在这个大的Cube的范围内折载入其他的2张地形场景。(这个大的Cube可以根据自己的地形规格-做出调整这里给出的并不准确)

中间最小的Cube是来判断--角色走的这个范围内的时候他要去载入那张地形场景-如果角色走入小的Cube中后-载入其他3地形。

原文链接:http://keigoliye.blog.163.com/blog/static/146213359201081923658957/

作者:码瘾少年·麒麟子 
出处:http://www.cnblogs.com/geniusalex/ 
蛮牛专栏:麒麟子 
简介:09年入行,喜欢游戏和编程,对3D游戏和引擎尤其感兴趣。 
版权声明:本文版权归作者和博客园共有,欢迎转载。转载必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
Unity3D热更新之LuaFramework篇[09]--资源热更新与代码热更新的具体实现
Unity3D热更新之LuaFramework篇[09]--资源热更新与代码热更新的具体实现一、准备工作1、制作一个用于热更新的界面此前我制作了一个大厅界面,并且放置了两个按钮:”排行榜“和”商城“,排行榜按钮已经用于打开排行榜页面。
1184 0
《区块链DAPP开发入门、代码实现、场景应用》笔记4——Ethereum Wallet中部署合约
账号创建完成之后,账号余额是0,但是部署合约是需要消耗GAS的,因此需要获取一定的以太币才能够继续本次实现。
1593 0
MaxCompute在电商场景中如何进行漏斗模型分析
本文以某电商案例为例,通过案例为您介绍如何使用离线计算并制作漏斗图。
3625 0
[Unity3d]场景管理插件-SceneManager
Unity3d中提供了场景Scene的概念,Scene就是一组相关联的游戏对象的一个集合,通常每个集合就是一个场景,但是也有可能只是一个场景的一部分! 场景中的游戏对象是任意的,可以是HUD的UI组件,场景地图,模型等等 Unity3d提供了一...
1186 0
8 cocos2dx添加场景切换效果,控制场景切换彻底完成之后再执行动画
 1 添加场景切换效果 供场景切换的类: CCTransitionJumpZoom CCTransitionProgressRadialCCW CCTransitionProgressRadialCW CCTransitionProgressHorizontal CCTransitionProgressVertical
1505 0
阿里云AIoT云端一体:迎接云原生+低代码时代的到来
十多年物联网开发之路,十多年风雨,物联网离普罗大众越来越近,随着整个物联网体系的建设越来越完善,物联网开发越来越容易,在低代码思想的引领下,人人都是开发者,未来可期
906 0
《区块链DAPP开发入门、代码实现、场景应用》笔记1——天外飞仙DAPP
Solidity编程语言解决了编写智能合约的不友好的问题,但是当合约编译并部署之后,对与这些接口的访问,对于一般的使用者来说,门槛有点高, 对普通用户来说也是非常不友好,为了使广大用户理解并方便快捷的访问区块链,以及区块链上的智能合约系统,开发者必须提供操作界面和结果查看界面,来简化用户访问和操作区块链的方式。
4151 0
Java中关于OOM的场景及解决方法(转)
http://developer.51cto.com/art/201112/305696.htm 1、OOM for Heap=>例如:java.lang.OutOfMemoryError: Java heap space 分  析 此OOM是由于JVM中heap的最大值不满足需要,将设置heap的最大值调高即可,参数样例为:-Xmx2G 解决方法 调高heap的最大值,即-Xmx的值调大。
965 0
得到Go程序的汇编代码的方法
有多种方式可以获得Go程序的汇编代码, 尽管输出的格式有些不同,但是都是方便阅读的汇编代码,可以帮助我们更好的了解程序的底层运行方式。 我们看下面一段代码, 它是sync.Once的实现,去掉了不必要的注释,复制出来用来研究的一段小代码: once.
21175 0
+关注
1876
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
JS零基础入门教程(上册)
立即下载
性能优化方法论
立即下载
手把手学习日志服务SLS,云启实验室实战指南
立即下载