转载请注明,原文地址:http://www.benmutou.com/archives/2548 文章来源:笨木头与游戏开发
来自2018.11.20的补充:切换场景时,需要提供完整路径,之前是我疏忽了,误导了大家。 来自2018.12.18的补充:切换场景时,除了需要提供完整路径外,还需要提供后缀名。这个Demo是为了和大家展示Game Framework切换场景的方式,但是切换场景又涉及到切换流程,所以就一起介绍了。
using System.Collections;
using System.Collections.Generic;
using GameFramework;
using GameFramework.Procedure;
using UnityEngine;
using UnityGameFramework.Runtime;
using ProcedureOwner = GameFramework.Fsm.IFsm<GameFramework.Procedure.IProcedureManager>;
public class Demo2_ProcedureLaunch : ProcedureBase {
protected override void OnEnter(ProcedureOwner procedureOwner)
{
base.OnEnter(procedureOwner);
Log.Debug("初始!!")
SceneComponent scene
= UnityGameFramework.Runtime.GameEntry.GetComponent<SceneComponent>();
// 切换场景
scene.LoadScene("Assets/Demo2/Demo2_Menu.unity", this);
// 切换流程
ChangeState<Demo2_ProcedureMenu>(procedureOwner);
}
}
这是一个很简单的流程类,只要继承ProcedureBase,并且重写OnEnter函数即可。
SceneComponent是专门用于处理场景逻辑的框架组件,其实就是我们一直看到的这个东西:
而LoadScene就是用于切换场景的函数(Demo2_Menu是另外一个场景,等会再说),ChangeState函数用于切换流程。
按照官方的示例项目,应该是先在OnEnter切换场景,然后在Update里切换流程,而且有一个专门的流程用于处理这些切换。
本Demo仅作演示功能,不代表最佳实践,请不要随意学习。
我们在进入初始场景时,立刻就切换到菜单场景(旁白:那为什么不直接把菜单场景设为初始场景?)
对,为什么不把菜单场景设为初始场景呢?因为初始场景是用来存放框架基础组件的,所以这个场景是不会被卸载的。在切换场景的时候,实际上只是加载了新场景,初始场景并不会消失(否则那些基础组件不就没了)。
using System.Collections;
using System.Collections.Generic;
using GameFramework;
using GameFramework.Procedure;
using UnityEngine;
using ProcedureOwner = GameFramework.Fsm.IFsm<GameFramework.Procedure.IProcedureManager>;
public class Demo2_ProcedureMenu : ProcedureBase {
protected override void OnEnter(ProcedureOwner procedureOwner)
{
base.OnEnter(procedureOwner);
Log.Debug("进入菜单流程,可以在这里加载菜单UI。");
}
}
这是一个很简单的流程类,只要继承ProcedureBase,并且重写OnEnter函数即可。
因为只是Demo,我们只在进入这个流程时打印一条日志。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityGameFramework.Runtime;
public class Demo2_Controller : MonoBehaviour {
public void EnterGame() {
SceneComponent Scene
= UnityGameFramework.Runtime.GameEntry.GetComponent<SceneComponent>();
Scene.LoadScene("Assets/Demo2/Demo2_Game.unity", this);
}
}
最后,在场景里创建一个空的GameObject对象,然后把这个Demo2_Controller脚本拖上去:
啊,不对,还有一个最后,那就是给按钮添加一个点击事件:
这个点击事件自然是我们的EnterGame函数。
using System.Collections;
using System.Collections.Generic;
using GameFramework;
using GameFramework.Procedure;
using UnityEngine;
using ProcedureOwner = GameFramework.Fsm.IFsm<GameFramework.Procedure.IProcedureManager>;
public class Demo2_ProcedureGame : ProcedureBase {
protected override void OnEnter(ProcedureOwner procedureOwner)
{
base.OnEnter(procedureOwner);
Log.Debug("进入游戏流程,可以在这里处理游戏逻辑,这条日志不会打印,因为没有切换到Game流程");
}
}
由于切换流程需要在继承了ProcedureBase的类里操作,而我们的Demo2_Controller类只是一个普通的MonoBehavior类,所以没法在切换场景的时候同时切换流程。
只好作罢,我们下一个Demo再一起看看怎么用框架的方式加载UI,那样就能进行比较完整的流程和场景切换演示了。本Demo不想太复杂,点到即止。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityGameFramework.Runtime;
public class Demo2_Controller : MonoBehaviour {
public void EnterGame() {
// 获取框架场景组件
SceneComponent Scene
= UnityGameFramework.Runtime.GameEntry.GetComponent<SceneComponent>();
// 卸载所有场景
string[] loadedSceneAssetNames = Scene.GetLoadedSceneAssetNames();
for (int i = 0; i < loadedSceneAssetNames.Length; i++)
{
Scene.UnloadScene(loadedSceneAssetNames[i]);
}
// 加载游戏场景
Scene.LoadScene("Assets/Demo2/Demo2_Game.unity", this);
}
}
在加载新的场景之前,我们先读取所有已存在的场景,然后主动卸载掉(初始场景会被排除),这样就不会同时出现多个场景了。
OK,本Demo到此结束,由于不想涉及太多内容,所以在某些操作上是不太符合框架的思路的,仅供参考。