综合练习:滚球小游戏
这是什么:经典入门游戏 Roll-a-Ball 的精简版——用键盘滚一颗球,吃完全部金币,屏幕上实时显示得分。
为什么用:前置知识:物理与碰撞,毕业作品来了,前面四章的知识点全部上场。看小球滚起来的那一刻,你就知道这一路学的不是零件而是一台机器。
如何用:本章先搭场地和小球,再写控制脚本和吃金币的计分逻辑,最后把得分显示在屏幕上。
游戏规划
| 要素 | 实现 | 用到的知识 |
|---|---|---|
| 玩家小球 | Sphere + Rigidbody + 脚本控制 | 第 3、4 章 |
| 场地 | Plane 当地板,四周 Cube 围墙 | 第 2 章 |
| 金币 | 旋转的小球,勾 Is Trigger | 第 4 章 |
| 得分 | UI 文本 + 计数脚本 | 本章新学 |
第一步:搭场地
- 新建 3D 项目(或
File → New Scene),加Plane,Position 归零,Scale 改为(2, 1, 2)——地板变大 - 加 4 个
Cube做围墙,分别摆到地板四边(比如(10, 0.5, 0)处的那个,Scale 设(0.5, 1, 21)拉成长墙),再复制三面旋到另外三边 - 加
Sphere命名Player,位置(0, 0.5, 0),Add Component挂 Rigidbody
第二步:玩家控制脚本
Project 里新建脚本 PlayerController,完整代码:
using UnityEngine;
public class PlayerController : MonoBehaviour
{
public float speed = 8f; // 移动力度,Inspector 可调
private int score = 0; // 得分
void FixedUpdate() // 物理相关逻辑推荐写这里,每固定时间步执行
{
float h = Input.GetAxis("Horizontal");
float v = Input.GetAxis("Vertical");
// 给刚体施加力,球会被"推"着滚,比直接改 position 更真实
Rigidbody rb = GetComponent<Rigidbody>();
rb.AddForce(new Vector3(h, 0, v) * speed);
}
void OnTriggerEnter(Collider other) // 幽灵式穿过金币时触发
{
if (other.CompareTag("PickUp")) // 只吃带 PickUp 标签的东西
{
other.gameObject.SetActive(false); // 金币隐身
score++;
Debug.Log("得分:" + score);
}
}
}
| 代码 | 作用 |
|---|---|
FixedUpdate() |
物理帧专用回调(默认每秒 50 次),施力都写这里才稳定 |
GetComponent<Rigidbody>() |
拿自己身上的刚体组件——"组件是演技",演技也能互相调用 |
rb.AddForce(...) |
给球施力,物理引擎负责滚动效果 |
CompareTag("PickUp") |
判断对方标签;吃金币只认标签,别按名字一个个比 |
写完把脚本挂到 Player 上。
第三步:金币工厂
- 加一个
Sphere,Scale 设(0.5, 0.5, 0.5)做金币,摆在(1, 0.5, 1) - 选中它 →
Add Component→ 勾上 Box Collider 里的 Is Trigger(或者给它加个 Sphere Collider 并勾 Is Trigger) - Inspector 左上角 Tag 下拉 →
Add Tag…→ 点 + 新建标签PickUp,再把金币的 Tag 设为它 - 新建脚本
RotateCoin并挂到金币上:
using UnityEngine;
public class RotateCoin : MonoBehaviour
{
void Update()
{
// 绕 y 轴每秒转 120 度,金币闪闪发亮
transform.Rotate(0, 120 * Time.deltaTime, 0);
}
}
- 选中金币,
Ctrl + D复制 7 颗,分别拖到场地各处
第四步:计分 UI
- Hierarchy 右键 →
UI→Text - TextMeshPro,首次会弹窗让你Import TMP Essentials,点导入 - 展开自动生成的
Canvas,把文本改名ScoreText,锚点设到左上角,字号加大、内容填得分:0 - 给 Player 的脚本补上 UI 显示:在
PlayerController里加两个字段,并在吃金币处更新文本
using UnityEngine;
using TMPro; // TextMeshPro 的命名空间,记得加在文件顶部
public class PlayerController : MonoBehaviour
{
public float speed = 8f;
public TextMeshProUGUI scoreText; // 待会儿在 Inspector 里拖入 UI 文本
private int score = 0;
void Start()
{
UpdateScoreText();
}
void FixedUpdate()
{
float h = Input.GetAxis("Horizontal");
float v = Input.GetAxis("Vertical");
GetComponent<Rigidbody>().AddForce(new Vector3(h, 0, v) * speed);
}
void OnTriggerEnter(Collider other)
{
if (other.CompareTag("PickUp"))
{
other.gameObject.SetActive(false);
score++;
UpdateScoreText();
}
}
void UpdateScoreText()
{
scoreText.text = "得分:" + score;
}
}
- 运行前最后一步:选中 Player,把 Hierarchy 里的
ScoreText拖到 Inspector 的Score Text槽上(让脚本认识这个 UI)
第五步:开玩!
点 ▶:WASD 推球滚动,撞上金币"嗖"地消失、左上角得分 +1,吃满 8 颗——通关 🎉 这就是你亲手做的第一个完整小游戏。
想继续打磨?试试加倒计时、金币吃光后弹出"胜利"大字、或者把墙撞出缺口——每一项都是把已学知识换个地方再用一遍。
记忆口诀:搭场摆物体,刚体加力气,触发吃金币,UI 显战绩。
动手改
- 把
speed调到 20,感受"漂移";再降到 3,体会力与质量的关系(试着把 Rigidbody 的Mass也改成 5 对比) - 加一个悬空的大金币(Scale 0.8),被吃时一次加 5 分——提示:给它单独建标签
BigPickUp,在OnTriggerEnter里多写一个else if - 吃光 8 颗金币后,让
ScoreText显示通关!——提示:if (score >= 8)时改文本内容
Unity 入门毕业 🎓 全站教程到此完结!回到首页回顾六大板块,动手做出你自己的作品吧 🐸