0. 对本次实践的介绍 #

学习 Unity 5.x 原生态 UGUI 的开发实践, 学习参考自 58 开发网, 这是一个跑酷类游戏的 UI 界面, 包含了游戏开始的 主界面|主角的 UI 设置|时间 UI 设置以及所获得的金币 UI 设置等. 通过此次实践可以了解到以下内容, 对 UGUI 有一个深入的认识 :

  • Sprite 资源导入及切割
  • 制作主界面欢迎文字
  • 制作主界面开始|退出按钮
  • 制作人物 HUD 和金币 HUD 和时间 HUD
  • CanvasGroup 的使用
  • UI 动画制作及显示
  • 实现金币 UI 数量显示功能
  • 实现生命数量 UI 更新功能
  • 实现时间倒计时功能
  • UI 自适应调整

想要实现的效果

1. Sprite 资源导入及切割 #

UISprites.psd

把准备好的素材 UISprites.psd 导入项目, 检查 Texture Type 的类型是 Sprite(2D and UI) 模式, Sprite Mode 改成 Multiple, 进而 Apply 一下.

点击进入 Sprite Editor 精灵的编辑器.

在 Sprite Editor 左键圈住内容选择切割区域, Apply 一下便切割开了.

切割之前与切割之后的项目目录对比 :

2. 制作主界面欢迎文字 #

新建一个 Canvas>Image, 把切好的 UISprites 的 Title 作为 Source Image 给它. 调整大小和位置.

修改文字锚点的位置, 保持四个角的相对位置, 使之自适应屏幕大小的改变.

改成

Image Title 下添加文字 Text, 修改内容和字体等格式, 选中 Best Fit, 同样, 也需要修改其锚点.

欢迎界面就做好了.

3. 制作主界面开始|退出按钮 #

Canvas 下面创建3个 Button, 分别对应为 Start | Options | Exit, 关联 Source Image 以及修改背景颜色和文字

界面效果

4. 制作人物 HUD 和金币 HUD 和时间 HUD#

添加一个新的 Canvas 里面有一个 Image 和两个 Text, 如下图所示

为了适应屏幕, 将 Image 的 Rect Transform 设置为 left + top

Coin 的图标同理, 锚点设为 right + top.

新建 Create Empty 添加时间轴图片, 操作同上, 最终效果

5. CanvasGroup 的使用 #

MainMenuCanvas 里新建一个 Create Empty 作为其他对象的父物体, 即 Title StartBtn OptionsBtn ExitBtn 都属于同一个 GameObject 命名为 MainMenu, 这个 MainMenu 的锚点设为 Stretch - Stretch.

MainMenu Add Component 添加 CanvasGroup 组件, 可以通过控制他的 Alpha 通道来显示或者隐藏界面

同理, 把原先的 MainMenuCanvas 重命名为 Canvas, 给其增加一个 HUD 用于放置原先的 Canvas 的子物体.增加 CanvasGroup, 可以通过控制他的 Alpha 通道来显示或者隐藏界面

上述描述的结果如下图所示

MainMenu 的 CanvasGroup>Alpha 初始化为 1, HUD 的 CanvasGroup>Alpha 初始化为 0.

给 StartBtn 按钮的 On Click() 添加事件通知 MainMenu 上面的 Alpha 属性值置为 0, 再添加一个事件通知 HUD 的 Alpha 属性值置为 1.

动图效果

6. UI 动画制作及显示 #

但是界面的切换有点生硬, 最好使用一下 UI 的动画制作, 使显示的更自然.

打开 Window>Animation 编辑器, 为 MainMenu 创建一个 Animator 和 一个 Animation Clip. Add Property MainMenu : Canvas Group.Alpha 范围设为动画的0~1对应其1~0

默认的 Animator 设置为只动画一次, 不要循环 : 把 MainMenuFadeOutLoop Time 的勾选去掉.

实现 HUD 的动画操作类似.

为了有更好的衔接效果, 最好给 Animator 里做个过渡, 即可以添加一个 Create Empty New State 作为默认的 Default State 再由它 Make Transition 到原有的 MainMenuFadeOut. HUD 操作同理

触发相关 Trigger 的过程如下, 点击 Start 按钮触发 MainMenu 的 FadeOut 使之淡出, 紧接着也触发 HUD 的 FadeIn 使之淡入, 这样就做好了. 对 Trigger 的控制需要脚本. 脚本内容如下

脚本 MainMenuController

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class MainMenuController : MonoBehaviour {private Animator mainMenuAnim;void Awake(){mainMenuAnim = GetComponent<Animator> ();}public void MenuFade(){mainMenuAnim.SetTrigger ("FadeOut");}}

脚本 HudController

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class HudController : MonoBehaviour {private Animator hudAnim;void Awake(){hudAnim = GetComponent<Animator> ();}public void HudFade(){hudAnim.SetTrigger ("FadeIn");}}

StartBtn 删除原来的事件, 换成与上述脚本绑定的 OnClick() 事件

至此, 渐出渐入的动画效果就做好了. 效果如下所示 :

7. 实现金币 UI 数量显示功能 #

实现界面右上角金币的数量逻辑.

找到 HUD>CoinsUI>TexCoinsCount 添加一个 CoinCounter.cs 脚本.

僵尸吃硬币就是僵尸与金币进行碰撞, 每吃一个硬币就使右上角加1. 硬币 Coin 脚本 :

using UnityEngine;
using System.Collections;public class Coin : MonoBehaviour
{private CoinCounter coinCounter;void Awake(){coinCounter = GameObject.FindGameObjectWithTag ("TextCoinsCount").GetComponent<CoinCounter> ();}void OnTriggerEnter2D(Collider2D other){if(other.gameObject.tag == "Player")print ("You picked up a coin!");coinCounter.coinCount++;gameObject.SetActive(false);}}

脚本 CoinCounter

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;public class CoinCounter : MonoBehaviour {public int coinCount = 0;void Start () {}void Update () {GetComponent<Text>().text = coinCount.ToString ();}
}

效果如图所示

8. 实现生命数量 UI 更新功能 #

硬币收集到一定数量就增加一个生命值的数量, 当收满 24 个金币的时候就会增加一条命.

脚本 LivesCounter

using UnityEngine;
using UnityEngine.UI;
using System.Collections;
[ExecuteInEditMode]public class LivesCounter : MonoBehaviour
{public int initialLives = 3; // 游戏刚开始的时候的生命数量public int extraLives = 0; // 游戏进行时额外增加的生命数量public int totalLives; // 主角生命数量的总数void Start(){GetLives();}// Update is called once per framevoid Update (){totalLives = initialLives + extraLives;GetComponent<Text> ().text = totalLives.ToString ();}void GetLives(){totalLives = initialLives + extraLives;}
}

脚本 GameState

using UnityEngine;
using UnityEngine.UI;
using System.Collections;public class GameState : MonoBehaviour
{private GameObject[] coins;public int totalCoins; // 所有的金币总数public bool gameRunning = false;private CoinCounter coinCounter;private LivesCounter liveCounter;void Awake (){coinCounter = GameObject.FindGameObjectWithTag ("TextCoinsCount").GetComponent<CoinCounter> ();liveCounter = GameObject.FindGameObjectWithTag ("TextLiveCount").GetComponent<LivesCounter> ();coins = GameObject.FindGameObjectsWithTag("Coin");totalCoins = coins.Length;}void Update (){int collectedCoins;collectedCoins = coinCounter.coinCount; // 当前收集到的金币数量liveCounter.extraLives = collectedCoins / totalCoins;if (liveCounter.totalLives < 0) {print ("Game Over!");}}public void StartGame(){gameRunning = true;}public void GameOver(){gameRunning = false;print ("Game Over!");}
}

9. 实现时间倒计时功能 #

也就是界面最上方中间的时间计数器的逻辑实现.

随着时间的流逝, 上面的颜色池减少. (图片由右向左的长度的减少), 把 TimerFillImageImage Type 换成 Filled, 并且将 Fill Method 设置为 Horizontal, 那么 Fill Amount 就可以用来做计时了.

Canvas>HUD>Timer>TimerFillImage 新建脚本 Timer.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;public class Timer : MonoBehaviour {public float currentTimer;public float startTimer = 10f;public float timerPercent;private Image image;void Awake () {currentTimer = startTimer;image = GetComponent<Image> ();}void Update () {// 计时currentTimer -= Time.deltaTime;timerPercent = currentTimer / startTimer;image.fillAmount = timerPercent;}
}

效果如图所示

但是有一点需要注意, 那就是只有当 StartBtn 被点击出现新界面之后才应该开始计时. 需要利用在 GameState.cs 里的 gameRunning 状态, 在 Timer.cs 中把 gameRunning 读取过来, 是否开始进行一下控制. 当然,还不能忘记了, 还需要给 StartBtn 再增加一个 点击事件的反馈, 即去调用 GameState.cs 里的 StartGame() 方法.

看看 Timer.cs 脚本的改进

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;public class Timer : MonoBehaviour {public float currentTimer;public float startTimer = 10f;public float timerPercent;private Image image;private GameState gameState;void Awake () {currentTimer = startTimer;image = GetComponent<Image> ();gameState = GameObject.Find ("GameState").GetComponent<GameState> ();}void Update () {// 游戏的确开始在运行的时候才开始进行倒计时if(gameState.gameRunning){// 计时currentTimer -= Time.deltaTime;timerPercent = currentTimer / startTimer;image.fillAmount = timerPercent;}}
}

目前为止的效果

10. UI 自适应调整 #

即需要调整锚点的地方就调整一下.


学习自 58 开发网视频教程 : http://www.58kaifa.com/course/35

End.

转载于:https://www.cnblogs.com/isayes/p/6380457.html

实现僵尸跑酷游戏的 UGUI 实践相关推荐

  1. [教程] 使用3D Infinite Runner Toolkit打造僵尸跑酷游戏

    使用3D Infinite Runner Toolkit打造僵尸跑酷游戏 3D Infinite Runner Toolkit是一款风格特异的3D版跑酷游戏开发包,其优点是容易使用与修改场景内的所有组 ...

  2. Unity跑酷游戏中的路点生成算法

    最近做了一个小的跑酷游戏,今天就我前几天写的 游戏玩家跟随在跑道上的路点行走的简单逻辑进行一下梳理,希望大家和我自己都能够有一定的进步. 下面我先说一下该款游戏的一些有必要知道的前提.跑道是动态生成的 ...

  3. Docker在英雄联盟游戏中的实践探索(五)

    本文讲的是Docker在英雄联盟游戏中的实践探索(五),[编者的话] 这篇博客是Riot的Docker实践系列博客的第五篇,主要讨论了如何从头创建你的Docker镜像. 在以前的帖子中,我们讲解了如何 ...

  4. pygame做的著名游戏_用python写游戏之2D跑酷游戏(一)

    2D的跑酷游戏有很多,著名的例如Chrome的彩蛋小游戏,手机上的天天酷跑等. 打开Chrome浏览器输入 chrome://dino/,按空格激活彩蛋 这篇文章来分析一下这类横版跑酷游戏的主角奔跑, ...

  5. 蓝图跑酷游戏教学的项目文件

    #虚幻4# 蓝图跑酷游戏教学的项目文件.总有人要这个,其实照着视频做一遍才好,因为工程很多东西体现不出来,功能拆分,编码思路,进度把控什么的都看不出来.连PPT一块发了. 链接: https://pa ...

  6. 基于Flink+ClickHouse构建实时游戏数据分析最佳实践

    简介:本实践介绍如何快速收集海量用户行为数据,实现秒级响应的实时用户行为分析,并通过实时流计算.云数据库ClickHouse等技术进行深入挖掘和分析,得到用户特征和画像,实现个性化系统推荐服务. 直达 ...

  7. 基于函数计算的游戏打包最佳实践

    简介:本文主要介绍了通过Serverless工作流(FNF)+ 函数计算(FC)+ 对象存储(OSS)+ 日志服务(SLS)的组合方案,实现游戏发行过程中,自动化.并行化的一键式构建游戏渠道包.同时也 ...

  8. 《Genesis-3D开源游戏引擎完整实例教程-跑酷游戏篇:简介及目录》(附上完整工程文件)...

    2019独角兽企业重金招聘Python工程师标准>>> 跑酷游戏制作 游戏类型: 此游戏Demo,为跑酷类游戏. 框架简介: 游戏通常由程序代码和资源组成.如果说模型.贴图.声音之类 ...

  9. python跑酷游戏源码_Phaser.js实现简单的跑酷游戏附源码下载

    采用的物理引擎是Phaser.js 在这里对此引擎不做过多介绍(因为我也是小白,嘿嘿) 效果展示: 源码(详细源码图片资源可点击文章下方或屏幕右上方的github链接进行clone) 1.创建游戏舞台 ...

最新文章

  1. oracle个性化,Oracle:个性化营销成功的五细则
  2. java 无锁缓存_如何在高并发环境下设计出无锁的数据库操作(Java版本)
  3. 在Linux和Windows操作系统中socket program的兼容问题
  4. 12.流水线设计方式
  5. 求助啊,被STM32的CAN折磨的疯了
  6. mysql5.7 glibcxx_3.4.15_Requires: libstdc++.so.6(GLIBCXX_3.4.15)(64bit)
  7. ITK:线性强度变换
  8. Go赋值使用:类型{} 定位使用.
  9. 使用手机游戏的新闻推送
  10. hbasehlog_HBase原理--RegionServer核心组件之HLog
  11. 代码加载 Prefabs
  12. 解决:关于启动Kafka一段时间后,进程自己停止运行的问题
  13. 华为网络设备-DHCP基础配置实验
  14. USB PD快充协议
  15. C标准库-va_list
  16. python笔记(web前端 CSS)
  17. 诺布酒店在希腊的第一家酒店餐厅圣托里尼诺布酒店餐厅今年春季开业;爱彼迎邀旅居体验者住进西西里乡村慢生活 | 全球旅报...
  18. 计算机软件专业的学术道德,遵守学术规范 恪守学术道德--计算机工程学院举行2019届毕业设计(论文)动员会...
  19. mysql 1032_mysql主从同步错误Last_SQL_Errno: 1032处理分析
  20. Android Studio 4.0 Image Asset 图标不能透明(记录)

热门文章

  1. IPSEC实验(IPSECVPN点到点,DSVPN,IPSECVPN旁挂)
  2. Python绘制世界疫情地图
  3. python list除以_每日一课 | python判断奇数和偶数
  4. 基于优化的多核局部费舍尔判别分析的故障分类
  5. a href链接弹出新窗口的方法
  6. c语言的位取反和按位异或
  7. 可以免费做题,免费查答案的模拟计算机等级考试软件
  8. 计算机网络笔记(收藏版)
  9. 肢体语言心理学+FBI阅人术(行为心理学) 用最短的时间了解一个人
  10. Android adb启动错误,使用adb shell启动Android应用程序时出现错误“活动类不存在”...