基于Unity2019最新ECS架构开发MMO游戏笔记9
官方ECS进阶案例解析之场景切换器
开始之前的准备工作:
0下载Unity编辑器(2019.1.0f1 or 更新的版本),if(已经下载了)continue;
1下载官方案例,打开Git Shell输入:
git clone https://github.com/Unity-Technologies/EntityComponentSystemSamples.git --recurse
or 点击Unity官方ECS示例下载代码
if(已经下载了)continue;
2用Unity Hub打开官方的项目:ECSSamples
3在Assets目录下找到Tests/SceneSwitcher,并打开其下的SceneSwitcher场景
ECS进阶:SceneSwitcher
场景切换器,顾名思义是用来切换场景的,这种功能很早就学会了。可是官方既然在这里做了案例,是想表达ECS的场景切换和之前的有什么不同吗?一起来看看吧:
场景中仅有一个SceneSwitcher空对象,上面挂了一个SceneSwitcher脚本,看来只有打开脚本看看了:
/// <summary>
/// 场景切换器
/// </summary>
public class SceneSwitcher : MonoBehaviour
{
/// <summary>
/// 场景配置
/// </summary>
[Serializable]
public class SceneConfig
{
public string SceneName;//场景名称
public int CustomDuration;//自定义持续时间
}
/// <summary>
/// 场景切换间隔
/// </summary>
public int SceneSwitchInterval = 5;
/// <summary>
/// 下次切换时间
/// </summary>
public float TimeUntilNextSwitch = 0.0f;
/// <summary>
/// 当前场景索引
/// </summary>
public int CurrentSceneIndex = 0;
/// <summary>
/// 是否已摧毁实体
/// </summary>
public bool EntitiesDestroyed = false;
/// <summary>
/// 场景配置
/// </summary>
public SceneConfig[] SceneConfigs;
// Use this for initialization
void Start ()
{
DontDestroyOnLoad(this);
LoadNextScene();
}
/// <summary>
/// 摧毁场景中的所有实体
/// </summary>
private void DestroyAllEntitiesInScene()
{
//1.获取实体管理器
var entityManager = World.Active.EntityManager;
//2.获取所有实体
var entities = entityManager.GetAllEntities();
//3.摧毁之
entityManager.DestroyEntity(entities);
//4.释放实体管理器
entities.Dispose();
//5.已摧毁
EntitiesDestroyed = true;
}
/// <summary>
/// 加载下一个场景
/// </summary>
private void LoadNextScene()
{
//获取在构建设置里的场景数量
var sceneCount = SceneManager.sceneCountInBuildSettings;
var nextIndex = CurrentSceneIndex + 1;
if (nextIndex >= sceneCount)
{
Quit();
return;
}
var nextScene = SceneUtility.GetScenePathByBuildIndex(nextIndex);
TimeUntilNextSwitch = GetSceneDuration(nextScene);
CurrentSceneIndex = nextIndex;
SceneManager.LoadScene(nextIndex);
EntitiesDestroyed = false;
}
private int GetSceneDuration(string scenePath)
{
foreach (var scene in SceneConfigs)
{
if (!scenePath.EndsWith(scene.SceneName +".unity"))
continue;
if (scene.CustomDuration <= 0)
continue;
return scene.CustomDuration;
}
return SceneSwitchInterval;
}
private void Quit()
{
#if UNITY_EDITOR
UnityEditor.EditorApplication.isPlaying = false;
#else
Application.Quit();
#endif
}
// Update is called once per frame
void Update ()
{
TimeUntilNextSwitch -= Time.deltaTime;
if (TimeUntilNextSwitch > 0.0f)
return;
if (!EntitiesDestroyed)
{
DestroyAllEntitiesInScene();
}
else
{
DestroyAllEntitiesInScene();
LoadNextScene();
}
}
}
这个脚本逻辑非常简单,加载实体场景的方式和咱们原来的用法一样,都是使用SceneManager。
唯一值得注意的是要把上一个场景的实体全部摧毁,这个过场官方还没有封装到SceneManager里面去,所有需要手动调用一下。我猜想Unity也许会重写SceneManager来管理实体场景,毕竟改变要做得彻底才行,目前由于ECS的不完善,开发的时候是混合式的,也就是说实体和对象同时存在。所以这个阶段比较尴尬,正处于新老两代引擎过渡的时候,但也是思维模式转换的最佳时期,我们可以很好的理解ECS,跟着Unity一起进化。
小结
场景切换流程大体如下:
更新计划
作者的话
如果喜欢我的文章可以点赞支持一下,谢谢鼓励!如果有什么疑问可以给我留言,有错漏的地方请批评指证!
如果有技术难题需要讨论,可以加入开发者联盟:566189328(付费群)为您提供有限的技术支持,以及,心灵鸡汤!
当然,不需要技术支持也欢迎加入进来,随时可以请我喝咖啡、茶和果汁!( ̄┰ ̄*)