[Unity3d]场景管理插件-SceneManager

简介:

Unity3d中提供了场景Scene的概念,Scene就是一组相关联的游戏对象的一个集合,通常每个集合就是一个场景,但是也有可能只是一个场景的一部分!

场景中的游戏对象是任意的,可以是HUD的UI组件,场景地图,模型等等

Unity3d提供了一些切换场景的规则和方法(例如在切换场景时不销毁某些GameObject,同步,异步加载场景API),但是并没有提供一个通用的场景管理的模块(想要做到“通用”是很难的)

在实际开发中,有些开发者摒弃了Scene模块,即整个游戏只有一个Scene,然后自己实现一套“窗口”对象以及“窗口”管理模块,以达到场景管理和通信的目的,这样的好处在于更灵活的控制场景对象;同样,坏处也很明显,即工作量会很大!

我在开发中也做了一套简单的场景管理模块,其主要功能包括:

1.使用一个栈来保存玩家在游戏中场景的载入先后关系(方便Back功能实现以及记录当前场景ID)

2.提供切换场景,压栈场景,出栈场景方法

3.提供异步加载场景,并提供加载进度(用以显示Loading条)

Unity3d将组件设计模式发挥的淋漓尽致,很多开发者都可以方便灵活的制作各种插件,如果足够抽象,便可以为其它项目很方便的使用!Scene Manager就是其中一个,官网地址


1.功能

Scene Manager提供了2个场景的概念:Screen和Level

Screen:即相互之间没有关联的场景模块(例如登陆场景,主菜单场景,游戏场景之间的关系),其之间并没有严格的先后关系,更接近于Unity3d中Scene的概念

Level:即游戏场景中的关卡模块,有一定的先后关系,并且逻辑相同,Scene Manager为Level提供了一些关卡关系的方法,包括当前关卡,上一个关卡,关卡状态,参考 SMLevelProgress 类

这2个场景的概念在Unity3d看来都是Scene的意义,之所以这样区分是为了将Scene的概念更细化!

其提供了下图的编辑界面,我们只需要创建一个SceneConfiguration来编辑游戏中所有Scene的类别和关系



2.实现

(1)SMSceneManager

一旦Scene Configuration创建完成之后,即可以在第一个“Screen场景”中创建出单例类SMGameEnvironment实例,其

其构造方法中完成对SMSceneManager与SMLevelProgress实例的创建:

(注意一定要在Screen场景中实例化SMGameEnvironment,如果是Level场景,则有可能对各个Level之间的关系有错误)

SMSceneManager提供切换场景的接口(包括加载场景,加载关卡,加载第一个关卡)

SMLevelProgress用以保存Level之间的关系(包括当前Level,上一Level,当前Level状态)


(2)SMTransition

SMTransition及其子类,提供了很多方便的切换场景(包括Screen和Level)动画效果,包括 淡入淡出,闪烁,卡通等等

(这些动画效果都作为Prefab保存在SceneManager/Resources/Transitions/下)

SMTransition作为基类,提供了是否异步加载场景,实际调用Unity3d API切换场景方法,但主要提供了一个动画的模板方法 DoTransition(),代码如下:

[csharp]  view plain copy print ?
  1. protected virtual IEnumerator DoTransition() {  
  2.         // 第一部分:之前场景退出动画  
  3.         state = SMTransitionState.Out;  
  4.         Prepare();  
  5.         float time = 0;  
  6.           
  7.         while(Process(time)) {  
  8.             time += Time.deltaTime;  
  9.             // wait for the next frame  
  10.             yield return 0;  
  11.         }  
  12.           
  13.         // wait another frame...  
  14.         yield return 0;  
  15.           
  16.         // 第二部分:保证SMTransition对象不被销毁(完成后续动画)  
  17.         state = SMTransitionState.Hold;  
  18.         DontDestroyOnLoad(gameObject);  
  19.   
  20.   
  21.         // wait another frame...  
  22.         yield return 0;  
  23.           
  24.         IEnumerator loadLevel = DoLoadLevel();  
  25.         while (loadLevel.MoveNext()) {  
  26.             yield return loadLevel.Current;  
  27.         }  
  28.            
  29.         // wait another frame...  
  30.         yield return 0;  
  31.   
  32.   
  33.         // 第三部分:新场景载入动画  
  34.         state = SMTransitionState.In;  
  35.         Prepare();  
  36.         time = 0;  
  37.   
  38.   
  39.         while(Process(time)) {  
  40.             time += Time.deltaTime;  
  41.             // wait for the next frame  
  42.             yield return 0;  
  43.         }  
  44.   
  45.   
  46.         // wait another frame...  
  47.         yield return 0;  
  48.           
  49.         Destroy(gameObject);  
  50.     }  

在SMTransition的子类中,分别实现Prepare()虚方法和Process(float elapsedTime)抽象方法

例如 SMFadeTransition 类中,通过传入参数elapsedTime与配置淡入淡出参数duration计算得到当前进度,正交化进度,得到当前遮盖的alpha值,并在OnGUI绘制,代码如下:

[csharp]  view plain copy print ?
  1. protected override bool Process(float elapsedTime) {  
  2.         float effectTime = elapsedTime;  
  3.         // invert direction if necessary  
  4.         if (state == SMTransitionState.In) {  
  5.             effectTime = duration - effectTime;  
  6.         }  
  7.           
  8.         progress = SMTransitionUtils.SmoothProgress(0, duration, effectTime);  
  9.           
  10.         return elapsedTime < duration;  
  11.     }  
[csharp]  view plain copy print ?
  1. public void OnGUI() {  
  2.         GUI.depth = 0;  
  3.         Color c = GUI.color;  
  4.         GUI.color = new Color(1, 1, 1, progress);  
  5.         GUI.DrawTexture(new Rect(0, 0, Screen.width, Screen.height), overlayTexture);  
  6.         GUI.color = c;  
  7.     }  

其它SMTransition子类也通过Process(float elapsedTime)实现切换动画效果!


PS: 在异步加载场景中,Scene Manager中并没有提供一个获取当前加载进度的接口,需要自己实现,在SMTransition类中

[csharp]  view plain copy print ?
  1. protected virtual YieldInstruction LoadLevel() {  
  2.         if (loadAsync) {  
  3.                     AsyncOperation ao = Application.LoadLevelAsync(screenId);  
  4.                     Debug.Log("Progress: " + ao.progress);  
  5.                     return ao;  
  6.                     //return Application.LoadLevelAsync(screenId);  
  7.         } else {  
  8.             Application.LoadLevel(screenId);  
  9.             return null;  
  10.         }  
  11.     }  

转载自:http://blog.csdn.net/onerain88/article/details/12303511
























本文转蓬莱仙羽 51CTO博客,原文链接:http://blog.51cto.com/dingxiaowei/1366100,如需转载请自行联系原作者
相关文章
|
4月前
|
搜索推荐 算法 C#
【Unity 3D】C#中冒泡排序、选择排序、插入排序等算法的详解(附源码 超详细)
【Unity 3D】C#中冒泡排序、选择排序、插入排序等算法的详解(附源码 超详细)
47 1
|
4月前
|
C# 图形学
【Unity 3D】元宇宙案例之虚拟地球信息射线实战(附源码、演示视频和步骤 超详细)
【Unity 3D】元宇宙案例之虚拟地球信息射线实战(附源码、演示视频和步骤 超详细)
48 0
|
4月前
|
人工智能 自然语言处理 区块链
【Unity 3D】元宇宙概念、应用前景、价值链等概述
【Unity 3D】元宇宙概念、应用前景、价值链等概述
51 0
|
4月前
|
vr&ar C# 图形学
【Unity 3D】VR飞机拆装后零件说明功能案例实战(附源码和演示视频 超详细)
【Unity 3D】VR飞机拆装后零件说明功能案例实战(附源码和演示视频 超详细)
37 0
|
4月前
|
vr&ar C# 图形学
【Unity 3D】VR飞机动态拆装及引擎开关控制案例(附源码和演示视频 超详细)
【Unity 3D】VR飞机动态拆装及引擎开关控制案例(附源码和演示视频 超详细)
38 0
|
4月前
|
vr&ar 图形学
【Unity 3D】VR飞机起飞喷火游戏案例实战(附源码和演示视频 超详细)
【Unity 3D】VR飞机起飞喷火游戏案例实战(附源码和演示视频 超详细)
50 0
|
4月前
|
vr&ar 开发工具 图形学
【Unity 3D】使用EasyAR实现单图识别的AR增强现实功能(附实现步骤)
【Unity 3D】使用EasyAR实现单图识别的AR增强现实功能(附实现步骤)
84 0
|
4月前
|
图形学
【Unity 3D】3D游戏跑酷小子实战教学(附源码和步骤 超详细)
【Unity 3D】3D游戏跑酷小子实战教学(附源码和步骤 超详细)
100 0
|
4月前
|
开发框架 数据可视化 前端开发
【Unity 3D】GameFramework、QFramework框架简介及应用实战(超详细 附源码)
【Unity 3D】GameFramework、QFramework框架简介及应用实战(超详细 附源码)
124 0
|
4月前
|
数据可视化 安全 定位技术
【Unity 3D】常用插件DOTween、Haste、Exploder、KGFMapSystem介绍(图文解释)
【Unity 3D】常用插件DOTween、Haste、Exploder、KGFMapSystem介绍(图文解释)
43 0