上一篇【试用Unity3D体验(二):添加一个启动界面】

本次目标

上一篇做完启动页面有2个问题,

  1. 从启动页面跳转到游戏场景以后,本来应该隐藏的鼠标没有隐藏(同时也担心将来回到启动页面鼠标不出现)
  2. 点击新游戏以后,会有很长时间的卡顿。这个是加载场景导致的(如果只是例子不会,例子里的playground场景其实没有多少东西)。

本次主要是解决这两个问题。

鼠标的问题

这个比较简单,我们在跳转新场景的时候把鼠标锁定,然后回来以后在启动的时候接触锁定。这个需求是针对我们的场景来说的,我们的场景要求游戏的时候不显示鼠标。

上次我们创建了一个 ButtonClick 代码,这个现在看起来名字不是很合适,我们先调整名称为 IndexController,然后修改其代码如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;public class IndexController : MonoBehaviour
{// Start is called before the first frame updatevoid Start(){Cursor.visible = true;Cursor.lockState = CursorLockMode.None;}// Update is called once per framevoid Update(){}public void StartGame(){Cursor.visible = false;Cursor.lockState = CursorLockMode.Locked;SceneManager.LoadScene("Playground");}
}

在点击启动按钮的时候把鼠标锁定隐藏,在加载的时候显示出来。当然,隐藏的动作放到下一个场景的Start来做更合适一些。但是我就是懒得修改了,先挖一个坑给后人。

添加Loading场景

大部分游戏都有一个Loading场景,比如这样的:

我们也计划做一个这样的动画,在页面加载的时候给用户更好的体验效果。不过为了简单,我们不做进度条了,做一个转圈的效果就好了。

和上一篇一样,我们新建并保存一个场景,起名Loading。添加画布和图像,然后从网上找到授权为 Free 的图片作为背景。 别忘记了加摄像头和修改 EventSystem 的 Input Module; 这些调整完的效果如下:

我这里随意找了一张图片,重点是授权是免费的,这一定要非常确认。不要忽略任何素材的版权问题,不要忽略任何素材的版权问题、不要忽略任何素材的版权问题。宁可不用,也不要用未授权图片。推荐使用 bing 查询,筛选条件 选择 free 。

PS:不要吐槽我们的图片的不搭配,我们目前体验功能是首位。这些可以后期找有缘人去修改(如果有那么一天的话)

这里有2个问题:

  1. 我们希望这个Loading页面尽可能被复用,也就是说它异步加载的场景是不固定的
  2. 需要做消息的传递,有可能上一个场景需要传递消息给下一个场景

检查了一下SceneManager.LoadScene ,然而它并没有能传递消息的功能,所以我们需要想别的方式处理。最简单的方式:static。我们创建一个 LoadingHelper 的类,它每次先加载 Loading 场景,然后由 Loading 场景去加载我们真实要加载的场景。

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;public class LoadingHelper
{public static LoadingHelper Instance = new LoadingHelper();private const string LoadingSceneName = "Loading";private const string DefaultSceneName = "Index";private bool isLoading = false;private string nextSceneName = null;public void LoadScene(string sceneName, Dictionary<string, object> sceneOneshotData = null){if (isLoading){Debug.LogError("The last one was still being doing.");return;}this.isLoading = true;this.nextSceneName = string.IsNullOrWhiteSpace(sceneName) ? DefaultSceneName : sceneName;SceneOneshotDataManager.Instance.WriteSceneData(sceneOneshotData);SceneManager.LoadScene(LoadingSceneName, LoadSceneMode.Single);}public string GetNextSceneName(){return this.nextSceneName;}public void FinishLoading(){this.nextSceneName = null;this.isLoading = false;}
}

我们还定义了一个 SceneOneshotDataManager 类,它负责传递数据。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class SceneOneshotDataManager
{public static SceneOneshotDataManager Instance = new SceneOneshotDataManager();Dictionary<string, object> sceneOneshotData = null;public bool Exist(){return sceneOneshotData != null;}public bool WriteSceneData(Dictionary<string, object> data){if (this.sceneOneshotData != null){Debug.LogError("The last data was not used.");return false;}this.sceneOneshotData = data;return true;}public Dictionary<string, object> ReadSceneData(){Dictionary<string, object> result = sceneOneshotData;sceneOneshotData = null;return result;}
}

然后我们打开之前的 IndexController 类,修改 StartGame 的代码:

    public void StartGame(){Cursor.visible = false;Cursor.lockState = CursorLockMode.Locked;LoadingHelper.Instance.LoadScene("Playground");}

和之前一样,在【生成设置】里添加我们新的 Loading 场景。然后测试一下,现在跳转到 Loading 的页面了。

接下来我们创建一个 LoadingContrller 脚本,并添加到画布

然后修改脚本,在 Start 的时候获取真正要跳转的场景名称,并且动态加载。首先先禁用了鼠标,用户安心的看 Loading 就好了。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;public class LoadingController : MonoBehaviour
{// Start is called before the first frame updatevoid Start(){Cursor.visible = false;Cursor.lockState = CursorLockMode.Locked;var nextSceneName = LoadingHelper.Instance.GetNextSceneName();StartCoroutine(loadScene(nextSceneName));}private IEnumerator loadScene(string sceneName){AsyncOperation asyncLoad = SceneManager.LoadSceneAsync(sceneName);while (!asyncLoad.isDone){yield return null;}}
}

执行以下,完美。接下来我们对 Loading 做一些美化。这里不用进度条,我们就做一个问题提升吧。在屏幕下面添加一航文字 【按任意键继续】。

然后修改一下 LoadingController 脚本,找了一堆古典词句。这里因为示例里playground场景内容太少,本来就是一下加载完成了,所以只能通过 yield return new WaitForSeconds(15); 这里模拟时间,后期可以去掉

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.SceneManagement;
using UnityEngine.UI;public class LoadingController : MonoBehaviour
{private bool finish = false;private AsyncOperation asyncLoad;private string PressAnyKeyString = "按任意键继续!";private string[] messages = new string[11] {"时间,转瞬即逝,不复再来。","夫天地者,万物之逆旅也。","时间,转瞬即逝,不复再来。","少年易老学难成,一寸光阴不可轻。","草木也知愁,韶华竟白头。","少年辛苦终身事,莫向光阴惰寸功。","读书不觉已春深,一寸光阴一寸金。","仰天大笑出门去,我辈岂是蓬蒿人。","长风破浪会有时,直挂云帆济沧海。","书山有路勤为径,学海无涯苦作舟。","千磨万击还坚劲,任尔东西南北风。"};public Text PressAnyKey;// Start is called before the first frame updatevoid Start(){if (this.PressAnyKey == null){Debug.LogError("Please select the text box.");return;}Cursor.visible = false;Cursor.lockState = CursorLockMode.Locked;this.finish = false;this.PressAnyKey.text = string.Empty;StartCoroutine(slideshow());var nextSceneName = LoadingHelper.Instance.GetNextSceneName();StartCoroutine(loadScene(nextSceneName));}void Update(){pressAnyKey();}private IEnumerator loadScene(string sceneName){if (string.IsNullOrWhiteSpace(sceneName)){Debug.LogError("Please input the next scene name.");yield return null;}else{this.asyncLoad = SceneManager.LoadSceneAsync(sceneName, LoadSceneMode.Single);this.asyncLoad.allowSceneActivation = false;while (this.asyncLoad.progress < 0.9f){yield return new WaitForSeconds(15); //fake//yield return WaitForEndOfFrame;}this.finish = true;this.PressAnyKey.text = PressAnyKeyString;yield return new WaitForEndOfFrame();}}private IEnumerator slideshow(){while (!this.finish){int n = (int)(Random.value * 10);var message = messages[n];this.PressAnyKey.text = message;yield return new WaitForSeconds(5);}}private void pressAnyKey(){if (this.finish&& ((Gamepad.current != null && Gamepad.current.aButton.isPressed)|| (Keyboard.current != null && Keyboard.current.anyKey.isPressed))){this.asyncLoad.allowSceneActivation = true;}}
}

运行一下,看起来还不错。今天太晚了,参数跨场景传递的内容明天再测试吧。

最后提示一下,脚本里定义了一个 Text PressAnyKey 属性,这个没有在代码里初始化。初始化的方式我采用的是在检查器里进行配置。

再见。

试用Unity3D体验(三):添加Loading页面相关推荐

  1. vue如何整个页面添加loading

    整个页面添加loading const loading = this.$loading({lock: true,fullscreen: true,text: '启动中',background:'rgb ...

  2. Angualr 加载速度慢,为页面初始化完成前添加loading

    1.在项目根目录下index.html添加loading模板: <div class="loading-box" id="loading">< ...

  3. 06.简书项目实战三:详情页面和登录功能实现

    简书项目实战三:详情页面和登录功能实现 1. 详情页面布局 这部分的布局比之前的简单多了,就一个标题加上主要内容而已. export default class Detail extends Comp ...

  4. Android:如何添加一个页面,如何跳转页面

    一.如何为安卓添加多个页面 新建一个工程 打开这样 然后删掉 @Override     public boolean onCreateOptionsMenu(Menu menu) {        ...

  5. ant design表格添加loading效果

    这里看一下ant design中表格添加loading效果. 在页面进来,获取数据时候 获取到数据的时候 实现方法: 这里只需要在要渲染的表格中添加,loading={XXXX} 即可.大括号里面的值 ...

  6. ecshop后台首页mysql_ecshop 添加后台页面以及设置权限

    ecshop 添加新页面 给ecshop后台增加管理功能页面 比如我们增加一个统计报表叫做 物流费用统计报表 放在后台"报表统计"栏目中 具体操作步骤: 第一步,我们要添加一个菜单 ...

  7. Hexo(sakura)添加说说页面

    前言 在自己的网站中添加说说页面,类似于qq空间一样: 实现操作也比较简单:css处理样式就好了, 这是静态处理的页面,如果有后台还可以实时添加发布说说,更高配一点. 快速传送门 步骤 在themes ...

  8. Unity3D项目三:牧师与魔鬼

    Unity3D项目三:牧师与魔鬼 基本介绍 列出游戏中提及的事物(Objects) 牧师,恶魔,船,河流,左侧陆地,右侧陆地 用表格列出玩家动作表(规则表),注意,动作越少越好 动作 条件 结果 点击 ...

  9. 新闻添加html页面

    新闻添加html页面 <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="New ...

最新文章

  1. Shell tips
  2. Visual Assist x 无法自动补全Snippet提示的解决方法
  3. 【Android 逆向】Android 中常用的 so 动态库 ( 拷贝 /system/lib/ 中的 Android 系统 so 动态库 )
  4. c++经典书籍--深度探索C++对象模型
  5. 寒假每日一题(入门组)【week1 完结】
  6. VTK:小部件之TexturedButtonWidget
  7. VirtualBox虚拟机Ubuntu设置共享文件夹
  8. XCode的使用心得
  9. Apache-SimpleEmail 简单应用
  10. 前端学习(2718):重读vue电商网站38之通过input输入框优化
  11. 《剑指Offer》 合并两个排序的链表
  12. 完成课件中的动手动脑的或需要验证的相关内容。
  13. dns提供商主机名_在 Kubernetes 中使用 DNS 和 Headless Service 发现运行中的 Pod
  14. 企业中MySQL高可用集群架构三部曲之MM+keepalived
  15. Docker从理论到实践(九)------使用Dockerfile创建镜像
  16. JSON 的几种简单格式和转换
  17. 拨号保护,网络电话,保护隐私,匿名通话
  18. 【JAVA】金额工具类 金额千分位、中文大写金额、英文金额
  19. 等待页面所有图片加载完毕
  20. 中间件小师妹 de 年度工作总结

热门文章

  1. informatica 学习日记整理
  2. 三生三世十里桃花用计算机怎么弄,三生三世十里桃花灵宠系统怎么玩?三生三世十里桃花灵宠系统详解...
  3. 基石为勤能补拙的迷宫之旅——第十六天(包)
  4. 联想拯救者系列嗡嗡声,风扇狂转解决办法,亲测有效
  5. SAP中显示技术名称和描述的设置
  6. 【数据追梦人】毕业6年自学代码,2周面试30家企业,1年376张报表,选择决定人生!
  7. Cadence PCB层的概念
  8. 【物联网专题】1.1_物联网基本概念_什么是物联网(IoT)?
  9. UCI银行营销数据集--缺失值处理方法
  10. Matlab中统计矩阵中每个元素出现个数的方法-------tabulate()函数