zoukankan      html  css  js  c++  java
  • Unity进阶之ET网络游戏开发框架 08-深入登录成功消息

    版权申明:

    • 本文原创首发于以下网站:
    1. 博客园『优梦创客』的空间:https://www.cnblogs.com/raymondking123
    2. 优梦创客的官方博客:https://91make.top
    3. 优梦创客的游戏讲堂:https://91make.ke.qq.com
    4. 『优梦创客』的微信公众号:umaketop
    • 您可以自由转载,但必须加入完整的版权声明!

    由来

    • 上篇文章中,我们修改了登录页面的异步处理,下面我们修改登录成功后进入主游戏场景的代码:
    namespace ETHotfix
    {
    	[Event(MyEventType.MyLoginFinish)]
    	class MyLoginFinish : AEvent
    	{
    		public override void Run()
    		{
    			RunAsync().Coroutine();
    		}
    
    		private async ETVoid RunAsync()
    		{
    			Log.Debug("移除登录UI");
    			UI uiLogin = Game.Scene.GetComponent<UIComponent>().Get(MyUIType.MyStartUI.ToString());
    			uiLogin.GameObject.SetActive(false);
    
    			Log.Debug("加载游戏场景");
    
    			// 方法1:同步加载
    			//SceneManager.LoadScene(1);
    
    			// 方法2:从ab包异步加载
    			var rc = ETModel.Game.Scene.GetComponent<ResourcesComponent>();
    
    			await rc.LoadBundleAsync(MySceneType.MyGame.StringToAB());
    
    			// 异步加载游戏场景
    			using (var scc = ETModel.Game.Scene.AddComponent<SceneChangeComponent>())
    			{
    				await scc.ChangeSceneAsync(MySceneType.MyGame); // => SceneManager.LoadSceneAsync(MySceneType.MyGame)
    			} // SceneChangeComponent.Dispose()会从该组件所在的Entity上移除其自身
    
    			// 发出场景加载完毕消息
    			Game.EventSystem.Run(MyEventType.MyGameSceneLoaded);
    		}
    	}
    }
    

    场景切换

    • 这里的场景切换组件就有点意思了!先上代码再分析:
    [ObjectSystem]
    public class SceneChangeComponentUpdateSystem: UpdateSystem<SceneChangeComponent>
    {
    	public override void Update(SceneChangeComponent self)
    	{
    		if (self.loadMapOperation.isDone)
    		{
    			self.tcs.SetResult();
    		}
    	}
    }
    
    public class SceneChangeComponent: Component
    {
    	public AsyncOperation loadMapOperation;
    	public ETTaskCompletionSource tcs;
    	public float deltaTime;
    	public int lastProgress = 0;
    
    	public ETTask ChangeSceneAsync(string sceneName)
    	{
    		this.tcs = new ETTaskCompletionSource();
    		// 加载map
    		this.loadMapOperation = SceneManager.LoadSceneAsync(sceneName);
    		return this.tcs.Task;
    	}
    
    	public int Process
    	{
    		get
    		{
    			if (this.loadMapOperation == null)
    			{
    				return 0;
    			}
    			return (int)(this.loadMapOperation.progress * 100);
    		}
    	}
    
    	public void Finish()
    	{
    		this.tcs.SetResult();
    	}
    
    	public override void Dispose()
    	{
    		if (this.IsDisposed)
    		{
    			return;
    		}
    
    		if (this.Entity.IsDisposed)
    		{
    			this.Entity.RemoveComponent<SceneChangeComponent>();
    		}
    
    		base.Dispose();
    	}
    }
    
    • ETTaskCompletionSource和ETTask的关系就好比Unity中Animator和AnimationClip的关系——前者是任务管理者,后者是被管理者
    • 首先,外部调用ChangeSceneAsync()方法时,该方法会创建一个ETTask对象tcs和一个异步加载场景的AsyncOperation对象loadMapOperation
    • 但是,细心的同学会发现,这两者( tcs和loadMapOperation对象)并无关联!
    • 唯一一点联系,大概就是代码最上端的组件更新系统SceneChangeComponentUpdateSystem中Update函数一直不停检测loadMapOperation.isDone标志,并据此调用tcs.SetResult()方法
    • 但即使如此,也未发现SceneChangeComponent类中Process属性和Finish被调用的痕迹(没有直接调用,也不是被override的virtual方法),经打印测试,这两个成员都没有被调用,也许是留作手动获取场景加载进度(Process)和手动结束场景加载(Finish())的吧!

    计划:

    • 下一步就要进入到游戏场景的玩法实现了,做了这么多铺垫,就要进入真正和游戏玩法相关的部分了!
  • 相关阅读:
    听过闰年闰月,可你听过闰秒吗?
    在线学习的“后浪”:现代学习系统中的人工智能
    idea在service窗口中显示现有微服务启动类
    Intellij IDEA导入项目出现Cannot load settings from file错误
    HttpServletRequest的getRequestURL方法获取不到https协议请求问题
    新增gitignore无效的解决办法
    访问腾讯存储桶中的文件,跨域问题的解决
    线程池的创建方法推荐
    TreeMap在自定义排序时的坑
    vue.js功能学习
  • 原文地址:https://www.cnblogs.com/raymondking123/p/11369739.html
Copyright © 2011-2022 走看看