0809
视频22 作业8点评 完善游戏
- 答疑 开始——00:08:24

- prefab不能引用场景中的物体?
- prefab设计的理念可以理解为作为一个共享的assets资源 可以在不同的场景scene中进行使用 假设它可以引用场景中的资源的话,相当于它可以在特定的场景中使用 这样就不符合当初的设计理念
- 如果确实需要引用 那么就在prefab的脚本中去设置一个空间 将场景中的资源手动拖进来
- Time.deltaTime
- 它的含义是计算机渲染每一帧所需要的时间
- 要知道每帧所需要的时间乘上单位时间可以渲染的帧数是等于1的
- 背景知识:每台计算机因为性能不同 单位时间渲染的帧数是不同的
- 计算机的工作原理就是从每帧的数据进行读取的 也就是每帧去执行代码的 每帧所需要的时间=时间%帧数 所以由于帧数不同 每帧所需要的时间是不同的 这就导致在不同性能的电脑上运行代码时 由于帧数不同 每帧所需要的时间是不同时代码会造成误差 就比如在代码中设置的是每秒走1.5米 可是实际在不同电脑上运行时 每秒走的距离就会有偏差
- 因此用Time.deltaTime代替计算机渲染每一帧所需要的时间 因为计算机读取的过程就是单位时间可以渲染的帧数进行与Time.deltaTime相乘 如此在不同的性能的电脑上运行都不会影响设置的速度 不会造成误差。
- 作业评讲
- 11号 00:08:24——00:15:06
- 实现了小球碰到每个障碍物后的的速度都是一样的 不会因为小球下落的距离远近而改变小球弹起的速度
- 我的作业评讲 00:15:06——00:21:13
- BallManager和Ball这两个代码里都出现小球发射的代码 应该把Ball里的删掉
- 障碍物在销毁时 对应的Text也应该销毁
- 12号 00:21:13——00:33:37
- 增加拖尾的效果
- 代码注释清晰 有条理
- update方法下调用协程的方法需要优化 可以先判断一下是否需要 否则十分消耗性能
- 在代码中获取prefab时的命名最好加上prefab作为一种区分 因为它和gameObject还是有去别的
- 一般销毁是无法直接销毁prefab的 会报错
- 14号 00:33:37——00:41:25
- 场景比较美观
- 可以学习11号的人为控制小球的在碰到障碍物的初始速度 真实重力效果 和假物理效果
- 在销毁ui时 需要删除ui这个gameobject 所以需要区别在代码里实际调用的是ui的text组件
- 对于同一类型的物体可以多选 然后就可以同时拖入东西 防止一个一个拖容易托错也节省了时间
- 20号 00:41:25——00:46:31
- 场景有了创意 毛球逗猫
- 0808问题汇总00:46:31——00:50:52

- 修复ui
-
动态生成的ui需要销毁掉 在Obstacle的类里 进行销毁
private void OnCollisionEnter2D(Collision2D collision) { //Debug.Log(collision.collider.name); var ball = collision.gameObject.GetComponent<Ball>().Damage; Hp -= ball; TextHp.text = Hp.ToString(); if (Hp <= 0) { Destroy(gameObject); Destroy(TextHp.gameObject); } }
-
修复可以一直发射的bug
只需要在BallManager的类中 update方法下 给原来只检测到按下鼠标的条件在加一个同时满足的条件 那就是检测到小球已经全部收回 之前有写过检测的方法 可以直接用if (Input.GetMouseButtonUp(0)&& CheckIfAllBallsReset()) { StartCoroutine(ShootBalls()); }
拖尾效果
- component下的effects下有个trail renderer 给特定的游戏对象可以添加拖尾的效果 相关参数需要进行调整
- 完善游戏讲解
计分00:50:52——01:04:47

-
新建一个空物体 重命名为ScoreManager 并给它建立一个脚本 可以名字一样 作为分数管理器 可以给所有的Manager建一个目录方便管理
-
在ScoreManager类中定义一个整型分数的初始值 用Score表示 一般默认为=0 可以省略
public int Score=0;
-
在ScoreManager类中自定义一个可以加分的方法 并传入参数表示增加的值用count表示 变量一般用名词比较好 在方法中让Score加等于这个增量 就实现了加分的功能
public void AddScore(int count) { Score += count; }
-
接下来在什么情形下调用加分的方法呢 应该在障碍物掉学的同时加上 障碍物掉学的语句在Obstacle的类下 因为是不同的类 这里需要用到静态成员的方法 实现在不同类下进行调用
public static ScoreManager Intstace;
-
start时给instance赋值 否则它是一个空的
Intstace = this;
-
此时就可以在其他的代码里进行使用了 在Obstacle的类中 碰撞检测的方法里 在障碍物掉血时就可以进行调用
private void OnCollisionEnter2D(Collision2D collision) { //Debug.Log(collision.collider.name); var ball = collision.gameObject.GetComponent<Ball>().Damage; Hp -= ball; ScoreManager.Instace.AddScore(ball); TextHp.text = Hp.ToString(); if (Hp <= 0) { Destroy(gameObject); Destroy(TextHp.gameObject); } }
-
创建可以显示分数的ui text 重命名为Score 注意 若字体太大 空间太小会显示不出来
-
在ScoreManager下引用一下创建的ui 类型是Text 记得引用一下命名空间
using UnityEngine.UI; public Text ScoreText;
-
此时脚本中就可以获取到Ui的text组件了 此时将代码的里的分数Score赋值给这个UI 下的text组件 记得将int转化为string类型
ScoreText.text = Score.ToString();
游戏结束处理01:04:47——01:17:51

-
理清思路 障碍物上升到一定界限就游戏结束
-
在ObstacleManager类里的ObstaclesUp()方法下 控制小球的上升 那么可以做一个判断 如果小球的位置超过了某一值 就执行游戏结束的方法
-
在场景中找到障碍物游戏结束的高度Y值 在ObstacleManager类中定义一个最高的Y值
public float HighestY =3.1f;
-
在ObstaclesUp()方法下 做一个判断
if (item.position.y >= HighestY) { OnGameOver(); }
-
将游戏结束的方法补建起来
void OnGameOver() { //todo 处理游戏结束 }
-
可以打印出游戏结束地提示
Debug.Log("GameOver");
-
最简单地处理方式就是重新加载这个场景 需要引用命名空间
using UnityEngine.SceneManagement;
-
在OnGameOver()的方法下加载场景 参数0是在build setting中可以设置 将相应的场景拖入到设置中 后面会对应一个序号相当于索引 也可以写直接写场景名称 因为有时场景的序号会改变。
SceneManager.LoadScene(0); SceneManager.LoadScene("Playground");
?为了自动生成道具 将两个道具拖入ObstaclePrefab的数组后 会出现多余的ui 并报错但不影响运行 我想用tag的方式却很难在代码里实现
细节完善01:17:51——01:35:28

- 如何满足小球之间没有碰撞 给小球设置layer层 在碰撞矩阵中进行设置

-
可是在设置完上面的碰撞矩阵后 小球在发射前也没有碰撞的物理效果了 此时需要代码设置 根据层发生碰撞的方式 用特定的方法 在代码中动态修改球的layer
-
在Ball的类下Reset方法下进行设置层
gameObject.layer = 0;
-
再次解决小球发生不准的问题 因为小球回收时发生滚动会有个初始的速度 发射时会有个初始速度 两个速度叠加后就会造成方向不准的问题 此时需要在小球发射前再次重置小球的速度和角速度 复制粘贴就好
public void BeforeShoot() { _collider2D.sharedMaterial = Bounce; isBouncing = true; gameObject.layer = 8; _rigidbody2D.velocity = Vector2.zero; _rigidbody2D.angularVelocity = 0; }
网友评论