来源:蜘蛛抓取(WebSpider)
时间:2018-02-10 11:45
标签:
unity打开没反应
他的最新文章
他的热门文章
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)Unity2D游戏开发2D Roguelike拾荒者
726 || this.offsetHeight>700){if(this.offsetWidth/726 > this.offsetHeight/700){this.width=726;}else{this.height=700;}}" style="max-width:726max-height:700" title="点击查看原图" onclick="if(this.parentNode.tagName!='A') window.open('http://www.ceeger.com/forum/attachment/1602/thread/7_97895_fbe6f2d1126729a.jpg');" />
最新的课程出来了《拾荒者》,这个课程一共22个课时,教你学习Unity2D游戏开发,这个课程也是根据Unity5.2来开发的哦!里面的代码量比坦克大战要多一些,大家要慢慢研究学习!马上春节快到了,祝福大家新年快乐哦!
课时列表:01-游戏介绍02-创建游戏工程,素材介绍03-创建游戏主角04-创建敌人1号和2号的Prefab05-创建游戏的其他元素地板,围墙,墙和食物06-创建地图管理器-用于地图生成07-控制障碍物的生成08-完成敌人和食物的随机生成09-代码优化10-完善主角和敌人的动画状态机11-控制主角的移动12-控制主角对墙体的攻击13-控制主角吃食物14-控制敌人的移动15-奔跑吧,僵尸16-控制敌人的攻击17-控制游戏食物数量UI的显示18-控制游戏的失败19-游戏关卡的胜利判断20-完成关卡的加载21-控制天数UI的显示22-给游戏添加音效《游戏结束》
百度网盘下载地址:
其他课程:Tanks坦克大战视频教程 公众号内回复119DOTween动画插件视频教程 & &公众号内回复118游戏编程进阶篇 第二季 Windows游戏开发 公众号内回复112Unity5.2入门课程 - 进入Unity开发的奇幻世界 公众号内回复109C#编程课程 公众号内回复102、103、104、105游戏中广告SDK接入课程 公众号内回复 106、107游戏中支付SDK接入课程 公众号内回复108Unity游戏开发学习路线 & &公众号内回复100
请关注siki的微信公众号 devsiki 接收最新视频 开发资源和文章信息
726 || this.offsetHeight>700){if(this.offsetWidth/726 > this.offsetHeight/700){this.width=726;}else{this.height=700;}}" style="max-width:726max-height:700" onclick="if(this.parentNode.tagName!='A'&&this.width>screen.width-461) window.open(this.src);" />
要评论请先&或者&
nice!!!!!!!!!!!!!!!!!!!!
很不错啊 谢谢 !!!!
感谢楼主分享
感谢楼主分享!
我表示非常感谢!
感谢楼主分享!
顶贴,谢谢分享<option value='/video/av5480978/index_1.html' cid='、01.2D Roguelike 1 of 14 - Project Introduction
<option value='/video/av5480978/index_2.html' cid='、02.2D Roguelike 2 of 14 - Animations
<option value='/video/av5480978/index_3.html' cid='、03.2D Roguelike 3 of 14 - Tile Prefabs
<option value='/video/av5480978/index_4.html' cid='、04.2D Roguelike 4 of 14 - Board Manager
<option value='/video/av5480978/index_5.html' cid='、05.2D Roguelike 5 of 14 - Game Manager
<option value='/video/av5480978/index_6.html' cid='、06.2D Roguelike 6 of 14 - Moving Objects
<option value='/video/av5480978/index_7.html' cid='、07.2D Roguelike 7 of 14 - Walls
<option value='/video/av5480978/index_8.html' cid='、08.2D Roguelike 8 of 14 - Player Animator Controller
<option value='/video/av5480978/index_9.html' cid='、09.2D Roguelike 9 of 14 - Player Script
<option value='/video/av5480978/index_10.html' cid='、10.2D Roguelike 10 of 14 - Enemy Script
<option value='/video/av5480978/index_11.html' cid='、11.2D Roguelike 11 of 14 - Enemy Animator Controller
<option value='/video/av5480978/index_12.html' cid='、12.2D Roguelike 12 of 14 - UI & Levels
<option value='/video/av5480978/index_13.html' cid='、13.2D Roguelike 13 of 14 - Audio
<option value='/video/av5480978/index_14.html' cid='、14.2D Roguelike 14 of 14 - Mobile
视频地址复制
Flash地址复制
Html地址复制
离线看更方便
用或其他应用扫描二维码
Unity官方教程视频~
广播电视节目制作经营许可证:(沪)字第1248号
| 网络文化经营许可证:沪网文[6号 | 信息网络传播视听节目许可证:0910417 | 互联网ICP备案:沪ICP备号-3 沪ICP证:沪B2- | 违法不良信息举报邮箱: | 违法不良信息举报电话:转3
公司名称:上海宽娱数码科技有限公司 | 公司地址:上海市杨浦区政立路485号 | 客服电话:Unity 9 Unity2D游戏开发 Roguelike拾荒者
任务1:游戏介绍
Food:相当于血量:每走一步下降1,吃东西可以回复(果子10药水20),被怪物攻击会减少中间的障碍物可以打破,人走两步僵尸走一步;走到Exit进入下一关
最外圈的过道会保证是空的,其他的随机生成(--确保主角能够到达出口)
任务2:创建工程、素材
pan.baidu.com/s/1kTYS8ez
Unity5.2.1
2D Project -- Roguelike 导入Assets.unitypackage
Sprites-&所有切好的图片 -- 主角/地形/出口/围墙/僵尸等
任务3:创建游戏主角
Sprites中找到6个主角Scavengers的sprite图片,拖入Hierachy中 会自动在游戏物体Scavengers_SpritesSheet_0中创建一个动画Animator,并将Animation 和AnimationController保存在Sprites文件夹中,重命名控制器为Player/ 动画为PlayerIdle 并创建文件夹分类Assets-&Animations-&Animation/AnimatorController
此时,运行游戏,会自动播放Idle动画
双击AnimatorController打开动画编辑器,修改速度为0.5
创建攻击动画: 将两个攻击Sprites拖入Player物体,会自动在Player中创建一个新的动画PlayerAttack
创建受攻击动画:相似 -- PlayerUnderAttack
创建主角的Prefab
任务4:创建敌人
与创建主角相似
创建完Enemy1,创建Enemy1的Prefab
因为Enemy2的动画控制器AnimatorController与Enemy1相同 在Project视窗中右键Create-&Animator Override Controller 将Enemy1的Animator赋值给新建的Animator -- 表示两个Enemy共用一个状态机 将Hierarchy中的Enemy1-&GameObject-&Break prefab instance,重命名为Enemy2 将Enemy2 Animator赋值给Enemy2 创建Enemy2的两个动画,将动画拖入Enemy2 Animator赋值即可
相当于:Enemy1和Enemy2共用了Enemy1的状态机(Animator),但是使用了不同动画
创建Enemy2的Prefab
任务5:创建地板/ 围墙/ 食物
创建地板:
把8种地板和出口分别拖入,并重命名Floor1~8/ Exit
把8中障碍物拖入,重命名为Wall1~8
做成Prefab&
创建围墙:三种围墙,重命名为OutWall1~3并做成Prefab
创建食物:拖入Soda和Food,做成Prefab
任务6:生成地图
创建空物体GameManager
创建MapManager.cs // 地图左下角设置为(0, 0) public GameObject[] outWallArray/ floorA // 创建根物体 private Transform mapH mapHolder = new GameObject("Map").
// 初始化围墙 for x for y(...) { GameO if (x==0 || y==0 || x==cols-1 || y==rows-1) { int index = Random.Range(0, outWallArray.Length); cell = GameObject.Instantiate (outWallArray[index], ...(x, y, 0), Quaternion.identity) as GameO // as GameObject -- .Instantiate()生成的为Object类型,强制转化为GameObject // 在(x,y,0)处生成一个旋转为0的围墙 } else ... cell.transform.SetParent(mapHolder); }
// 初始化地板 else { int index = Random.Range(0, floorArray.Length); cell = GameObject.Instantiate (floorArray[index], ...(x,y,0), Quaternion.identity) as GameO }
此时生成的地图并不位于相机正中心 -- 地图长10宽10 -- (每一格长宽为1,从(0,0)开始,即画面从(-0.5, -0.5开始)) --& Camera位置:(4.5, 4.5, 0),颜色改为黑色
private void InitMap() {
for (int x = <span style="color: #; x & x++) {
for (int y = <span style="color: #; y & y++) {
if (x == <span style="color: # || x == cols - <span style="color: # || y == <span style="color: # || y == rows - <span style="color: #) {
int index = Random.Range(<span style="color: #, outWallArray.Length);
cell = GameObject.Instantiate
(outWallArray[index], new Vector3(x, y, <span style="color: #), Quaternion.identity);
int index = Random.Range(<span style="color: #, floorArray.Length);
cell = GameObject.Instantiate
(floorArray[index], new Vector3(x, y, <span style="color: #), Quaternion.identity);
cell.transform.SetParent(mapHolder);
任务7:控制障碍物的生成
在InitMap()中
private List&Vector2& positionList = new List&Vector2&(); // 用于取得中间部分的格子位置
positionList.Clear();
for(int x/y = 0 + 2; x/y & cols/rows - 2; x/y++) {& // 围墙一列,空道一列 positionList.Add(new Vector2(x, y));}
// 从上面的positionList中随机取得格子放入障碍物/食物/敌人// 创建障碍物public GameObject[] wallArray;public int min/maxCountWall = 2/8;int wallCount = Random.Range(minCountWall, maxCountWall + 1);for(int i = 0~wallCount) { // 随机取得格子位置 int positionIndex = Random.Range(0, positionList.Count); // 随机取得index Vector2 pos = positionList[positionIndex]; // 得到位置信息 positionList.RemoveAt[positionIndex]; // 移除该位置 -- 保证一个格子只能有一个东西 // 随机取得障碍物 int wallIndex = Random.Range(0, wallArray.Length); GameObject cell = GameObject(wallArray[...], pos, ...) as GameO cell.transform.SetParent(mapHolder);}
避免地板将障碍物覆盖,设置Layer:Background/ Items/ Roles
positionList = new List&Vector2&();
positionList.Clear();
for(int x = <span style="color: #+<span style="color: #; x & cols - <span style="color: #; x++) {
for(int y = <span style="color: # + <span style="color: #; y & rows - <span style="color: #; y++) {
positionList.Add(new Vector2(x, y));
int wallCount = Random.Range(minCountWall, maxCountWall + <span style="color: #);
for(int i = <span style="color: #; i & wallC i++) {
int positionIndex = Random.Range(<span style="color: #, positionList.Count);
Vector2 pos = positionList[positionIndex];
positionList.RemoveAt(positionIndex);
int wallIndex = Random.Range(<span style="color: #, wallArray.Length);
GameObject cell = GameObject.Instantiate
(wallArray[wallIndex], pos, Quaternion.identity) as GameO
cell.transform.SetParent(mapHolder);
任务8&9:敌人和食物的随机生成 & 代码优化
食物和敌人的数量与关卡有关 -- 数量成正比
创建GameManager.cs -- 控制游戏关卡 public int level = 1;
在MapManager.cs中 // 获取GameManager private GameManager gameM gameManager = GetComponent&GameManager&();
创建食物 -- 数量2~level*2 int foodCount = Random.Range(2, gameManager.level * 2 + 1); // 取得随机位置 -- 重复代码写成Vector2 RandomPosition() Vector2 pos = RandomPosition(); // 随机取得物体 -- 重复代码写成GameObject RandomPrefab(GameObject[] prefabs); GameObject foodPrefab= Instantiate(RandomPrefab(foodArray)) as GameO foodPrefab.transform.setParent(mapHolder);
// get a random available position
private Vector2 RandomPosition() {
int positionIndex = Random.Range(<span style="color: #, positionList.Count);
Vector2 pos = positionList[positionIndex];
positionList.RemoveAt(positionIndex);
// get a random gameobject
private GameObject RandomPrefab(GameObject[] prefabs) {
int index = Random.Range(<span style="color: #, prefabs.Length);
return prefabs[index];
创建敌人 -- 数量为level / 2 int enemyCount = gameManager.level/2; for(0~enemyCount) { Vector2 pos = ...; GameObject enemyPrefab = GameObject.Instantiate(...) as GameO enemyPrefab.transform.setParent(mapHolder); }
创建出口 -- 位置固定在右上方 GameObject exit = (Instantiate(exitPrefab, new Vector2(cols-2, rows-2), Quaternion.identity) as GameO exti.transform.SetParent(mapHolder);
-- 代码优化
上面的创建代码是可重用的 -- 写成method
private void InstantiateItems(int count, GameObject[] itemArray) {
for(int i = <span style="color: #; i & i++) {
GameObject item = GameObject.Instantiate(RandomPrefab
(itemArray), RandomPosition(), Quaternion.identity) as GameO
item.transform.SetParent(mapHolder);
任务10:完善主角和敌人的动画状态机
Player的动画:PlayerIdle/ PlayerUnderAttack/ PlayerAttack
PlayerIdle&--&PlayerUnderAttackPlayerIdle&--&PlayerAttack
在Animator中添加触发器Trigger分别称为Damage和Attack
Idle-&Attack/UnderAttack: 将Has Exit Time取消勾选 -- 在Idle动画的任何时候都可以随时切换到另一个动画 Transition Duration = 0 -- 因为这里的动画是帧动画,因此可以进行瞬时切换成其他动画 Conditions 切换方式:添加Attack/Damage Trigger
拖动左边的箭头可以手动播放动画;拖动右边的两个箭头可以手动控制何时切换
Attack/UnderAttack-&Idle: 勾选Has Exit Time即可 -- 播放完Attack/UnderAttack后自动切换到Idle动画 Transition Duration = 0 -- 瞬时间切换 Exit Time = 1 -- 退出时间(多久进行切换)
Enemy的动画:EnemyIdle/ EnemyAttack
Idle-&Attack: 添加触发器Attack Has Exit Time uncheck Transition Duration = 0
Attack-&Idle: Has Exit Time check Exit Time = 1 Transistion Duration = 0
检测动画:
运行游戏;选中Player/ Enemy;在Animator视窗中查看状态机
点击Trigger右边的小圆点,即为触发该Trigger
任务11:控制主角的运动
为Player添加刚体,用于控制移动,勾选Is Kinematic
为Player添加BoxCollider2D,用于检测碰撞(大小不能设置为(1,1),0.9就好)
为Player添加Player.cs来控制移动 private int posx/posy = 1; // 当前位置 private int Vector2 targetPos = new Vector2(1,1); // 目标位置
float h/v = Input.GetAxisRaw("Horizontal"/"Vertical"); // GetAxisRaw()的返回值为-1/0/1 targetPos += new Vector2(h,v); // 按键后,目标位置发生改变 private Rigidbody2D rigidbody = GetComponent&Rigidbody2D&(); // 得到刚体,用于移动 rigidbody.MovePosition(Vector2.Lerp(transform.position, targetPos, smoothing*Time.deltaTime)); // MovePosition(目标位置):向目标位置移动 // Lerp(起点,终点,速度);这里设smoothing=1
发现此时按下按钮会移动很长的距离 -- Update中不停调用targetPos += Vector2();&
需要设置一个休息时间: public float restTime = 0.5f; public float restTimer = 0.5f; // 计时器
在Update()中 restTimer += Time.deltaT // 每次增加时间间隔 if(restTimer &= restTime) { // 还在休息间隔中 // 不进行其他操作 }
当有按键按下时: if(h!=0 || v!=0) { targetPos += ...; // 更新目标位置 rigidbody.MovePosition(...); // 移动 restTimer = 0; // 重置计时器 }
按下按键时,只能移动一点点距离 将rigidbody.MovePosition()代码移出if条件 因为每一帧都需要调用而不是只有按键的时候调用
发现可以一次同时在水平和竖直移动 -- 和游戏规则有悖 if(h!=0) v=0; // 优先控制竖直方向
void Update () {
rigidbody.MovePosition(Vector2.Lerp(transform.position, targetPos, smooth * Time.deltaTime));
if (restTimer & restTime) {
restTimer += Time.deltaT
float h = Input.GetAxisRaw("Horizontal");
float v = Input.GetAxisRaw("Vertical");
if (h != <span style="color: #) {
v = <span style="color: #;
if (h != <span style="color: # || v != <span style="color: #) {
// 有按键输入时
targetPos += new Vector2(h, v);
restTimer = <span style="color: #; // 计时器归零
任务12:控制主角对墙体的攻击
给outWall添加BoxCollider2D,scale=0.9;添加tag = OutWall
给wall添加BoxCollider2D,scale=0.9;添加tag = Wall
在每次按键的时候,进行碰撞检测: RaycastHit2D hit = Physics2D.Linecast(targetPos, targetPos + new Vector2(h, v)); // Physics2D.Linecast(起点,终点) 从起点向终点发射射线做检测,返回RaycastHit2D if(hit.transform == null) { // 没有碰撞,可以行走 } else { // 有碰撞 switch(hit.collider.tag) { case "OutWall": // 不做处理 case "Wall": // 进行攻击 // 向墙发送攻击的通知 // 在Wall里添加Wall.cs来处理行为 Wall.TakeDamage(); hit.collider.SendMessage("TakeDamage");
public int hp = <span style="color: #;
public Sprite damageS // 受损后的墙体图片
public void TakeDamage() {
hp -= <span style="color: #;
GetComponent&SpriteRenderer&().sprite = damageS
if(hp&=<span style="color: #) Destroy(this.gameObject);
禁用自身的collider,因为可能射线会碰到自身的collider: private BoxCollider2D collider = GetComponent&...&(); collider.enabled = ... // 射线检测 collider.enabled = // 检测后再启用
无论是移动还是攻击,都需要休息 -- 只要按下了按键,restTimer = 0;
攻击时,播放PlayerAttack动画 Player.cs private Animator animator = GetComponent&Animator&(); animator.SetTrigger("Attack"); // 触发触发器
rigidbody.MovePosition(
Vector2.Lerp(transform.position, targetPos, smooth * Time.deltaTime));
if (restTimer & restTime) {
restTimer += Time.deltaT
float h = Input.GetAxisRaw("Horizontal");
float v = Input.GetAxisRaw("Vertical");
if (h != <span style="color: #) {v = <span style="color: #;}
if (h != <span style="color: # || v != <span style="color: #) {
// 有按键输入时
collider.enabled = false; // 禁用自身collider
// 碰撞检测
RaycastHit2D hit =
Physics2D.Linecast(targetPos, targetPos + new Vector2(h, v));
if (hit.transform == null) {
// 没有检测到碰撞
targetPos += new Vector2(h, v);
// 检测到碰撞
switch (hit.collider.tag) {
case "OutWall":
case "Wall":
hit.collider.SendMessage("TakeDamage");
animator.SetTrigger("Attack");
restTimer = <span style="color: #; // 计时器归零
collider.enabled = true; // 检测完碰撞后 开启自身collider
任务13:控制主角吃食物
对食物进行碰撞检测:
对食物添加BoxCollider2D;设置为Is Trigger,scale=0.9,tag=food
存储当前食物 GameManager.public int food = 100; 将GameManager设置为单例模式
private static GameManager _
public static GameManager Instance {
private void Awake() {
_instance = this;
增加/减少食物的method:public void Add/ReduceFood(int count) food +=/-=
case "Food": // 用if判断hit.collider.name是Food(Clone)还是Soda(Clone) GameManager.Instance.AddFood(10 | 20); // 同时,需要移动Player位置 && 销毁食物 targetPos += new Vector2(h, v); Destroy(hit.collider.gameObject);
case "Food":
targetPos += new Vector2(h, v);
Destroy(hit.collider.gameObject);
if (hit.collider.name == "Food(Clone)") {
GameManager.Instance.AddFood(<span style="color: #);
} else if(hit.collider.name == "Soda(Clone)") {
GameManager.Instance.AddFood(<span style="color: #);
任务14&15:控制敌人的移动
当Player移动两步时,敌人移动一步
给Enemy添加BoxCollider2D进行碰撞检测,size=0.9,&
给Enemy添加Rigidbody2D进行移动,勾选Is Kinematic:很重要 如果没有勾选,会导致后面Enemy被Player推走
给Enemy添加tag=Enemy
case "Enemy": // 说明所走的路径不通,判断失误,浪费一步 &
给Enemy添加Enemy.cs Enemy是被动移动 -- 提供移动方法,供其他对象调用 public void Move() { // 判断Player所在位置的方向 // Transform player = GameObject.FindGameObjectWithTag(...)& Vector2 offset = player.position - transform. if (offset.magnitude & 1.9f) { // 距离小于一格 // 攻击 } else { // 追 -- 哪个轴偏移大,就往哪里追 if (Mathf.Abs(offset.x) & Mathf.Abs(offset.y)) { // x轴移动 if(offset.x&0) x=-1; else x=1; } else { // y轴移动 if(offset.y&0) y=-1;&else y=1; } targetPos += new Vector(x, y); }
在GameManager.cs中统一管理游戏进程: public List&Enemy& enemyList = new List...;
在Enemy.cs中: GameManager.Instance.enemyList.Add(this);
在GameManager.cs中控制Enemy是否行走: bool sleepStep = // 是否为休息状态 OnPlayerMove() { if(sleepStep) sleepStep = else { foreach enemy in enemyList { enemy.Move(); sleepStep = } }
在Player.cs中 有按键按下的时候调用OnPlayerMove() GameManager.Instance.OnPlayerMove();
此时,Enemy会随着主角移动而移动,但是Enmey没有碰撞检测
设置目标位置targetPos之前先做检测
// 更新位置之前,做碰撞检测
collider.enabled = false; // 否则会碰撞到自己的collider
RaycastHit2D hit = Physics2D.Linecast(targetPos, targetPos+new Vector2(x,y));
collider.enabled = true;
if (hit.collider == null) {
// 没有碰撞
targetPos += new Vector2(x, y);
switch (hit.collider.tag)
case "Wall":
case "OutWall": // 不可能出现外墙的情况
case "Food":
Destroy(hit.collider.gameObject);
targetPos += new Vector2(x, y);
任务16:控制敌人的攻击
private Animator animator = GetComponent&...&();animator.SetTrigger("Attack");player.SendMessage("TakeDamage", lossFood);& // 不同敌人的伤害不同
public void TakeDamage(int lossFood) { GameManager.Instance.ReduceFood(lossFood); animator.SetTrigger("UnderAttack");&}
任务17:控制游戏食物数量UI的显示
在Player每走一步就消耗一定量食物: GameManager.Instance.ReduceFood(1);
在屏幕上显示食物: 右键创建UI-&Text,重命名FoodText 字体剧中,字号25,字体为Font-&PressStart2P-Regular,内容:Food: 100 放置在屏幕下方,Anchor Presets设置为bottom-center
在GameManager.cs中控制UI的更新 private Text foodT 在void Awake()中&加入 InitGame(); void InitGame() { foodText = GameObject.Find("FoodText").GetComponent...;& UpdateFoodText(0); }
private void UpdateFoodText(int foodChange) {
if (foodChange == <span style="color: #) {
foodText.text = "Food: " +
} else if (foodChange & <span style="color: #) {
foodText.text = "+" + foodChange + "
foodText.text = foodChange + "
在ReduceFood()/ AddFood(){}&中加上 UpdateFoodText(count/-count);
任务18:控制游戏的失败
游戏失败:Food &= 0; Player每走完一步:检测food的数量 --&我的优化:在GameManager中的ReduceFood()中检测 --&没有必要每一步都检测
if(food&=0){& GameObject.FindGameObjectWithTag("Player").SetActive(false);& //&显示游戏失败 -- UI-&Text,居中,白色,字号,字体,GameOver等等 gameOverText.enabled = }
任务19&20:游戏关卡的胜利判断 && 下一关卡的加载
判断Player是否到达了Exit的位置(8,8)
每次Player移动,判断是否到达终点 Player每次移动,都会调用GameManager中的OnPlayerMove() 在OnPlayerMove()中加入 //&需要得到player的targetPos,与destinationPos比较 将targetPos改为[HideInInspector]public targetP Player player = GameObject.Find...Tag(...).GetComponent...; // 还需得到Exit的位置 MapManager mapManager = GetComponent...; if(player.targetPos.x == mapManager.cols-2 && ...y==rows-2) { private bool missionCompleted = //&加载下一关卡 Application.LoadLevel(Application.loadedLevel); // 重新加载本关卡 --&已弃用 SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);& // 需要记住某些值 -- 使用系统函数OnLevelWasLoaded()& }
运行 -- 发现可以重置关卡了,但是所有数据会重置
GameManager实例不能销毁 -- 否则数据会重置 在GameManager.cs的Awake()中:
DontDestroyOnLoad(gameObject);
运行 -- 发现原来的GameManager没有销毁,但是新建了另一个GameManager
不将GameManager放在场景中 --&将GameManager做成Prefab -- 删除场景中的GameManager 在MainCamera中添加GameLoader.cs
// 实例化GameManager
public GameObject gameM
void Awake() {
if(GameManager.Instance == null) {
GameObject.Instantiate(gameManager);
任务21:控制天数UI的显示
当前天数的显示 UI-&Image-&DayI alt+上下左右居中;颜色设置为黑色 在DayImage中创建一个Text叫DayText;居中偏上;字号32;字体自定义;颜色白色
什么时候显示呢? -- 初始化UI的时候需要显示
GameManage.InitGame()中: private Image dayImage = GameObject.Find("DayImage").GetComponent&Image&(); private Text dayText ...; dayText.text = "Day " +
显示完天数,需要隐藏
void HideDayImage() {
dayImage.gameObject.SetActive(false);
在InitGame()最后调用 Invoke("HideDayImage", 1);&即可& --&过1s后调用
任务22:添加音效
GameManager.cs
阅读(...) 评论()