游戏和编程两不误:用Unity做一个简单小游戏

玩游戏不如做游戏。今天带你从零开始,用Unity开发一款可玩的"星星收集者",顺便学会C#编程基础。

👋 你好,我是 Evan,一名计算机专业的学长,也是《大一突围》专栏的作者。大一时我沉迷游戏,后来想:与其被动玩,不如主动做。于是自学Unity,花两周做出了第一个小游戏。那种"我的代码创造了世界"的成就感,比通关任何3A大作都爽。今天,我就把这套方法教给你------不需要游戏开发经验,只要会一点编程基础,就能跟着做出一个能玩的小游戏。你会发现,游戏和编程本就是天生一对。

欢迎来到 《大一突围》 专栏。

一、为什么大一就要尝试做游戏?

  • 即时正反馈:你改一个数字,游戏里角色就跑得更快,这种刺激让你愿意持续优化。

  • 综合能力锻炼:涉及逻辑、数学、美术(至少布局)、音效、用户体验。

  • 作品集杀手锏:一份能玩的游戏,比10个控制台项目更让面试官记住你。

二、准备:安装Unity并创建第一个项目

2.1 下载并安装Unity Hub

  • 访问 unity.com/cn,下载 Unity Hub

  • 在Hub中安装 Unity 2022 LTS 版本(长期支持版,稳定)。

  • 安装时勾选 Windows Build Support (如果使用Mac则选Mac)和 Visual Studio(或VS Code)组件。

2.2 创建新项目

  • 打开Unity Hub → New project → 选择 2D Core(我们做2D游戏更简单)。

  • 项目名称:StarCollector

  • 位置:自己记住的文件夹

  • 点击 Create project

界面速览

  • Scene 视图:摆放游戏物体的工作区。

  • Game 视图:运行时看到的画面。

  • Hierarchy:场景中所有物体列表。

  • Inspector:选中物体的属性面板。

  • Project:项目文件(脚本、素材等)。

💡 首次打开可能需要编译,耐心等待。

三、游戏设计:星星收集者

游戏玩法

  • 玩家控制一个小球(Player)在场景中移动。

  • 场景中随机生成若干星星(Star),触碰星星则得分,星星消失并重生到新位置。

  • 显示当前得分。

  • 加上一个倒计时(60秒),时间到显示最终分数。

核心知识点

  • 玩家移动(通过键盘方向键/WASD)。

  • 碰撞检测(触发器)。

  • UI 文本更新(得分、倒计时)。

  • 随机生成位置。

  • 游戏循环(Update、FixedUpdate、协程)。

四、搭建游戏场景(一步一步截图说明,这里用文字+图示)

4.1 创建玩家(Player)

  • Hierarchy 右键 → 2D ObjectSpritesCircle ,命名为 Player

  • Inspector 中设置 Transform 的 Position 为 (0, 0, 0)。

  • 添加 Rigidbody 2D 组件(用于物理移动):

    • 点击 PlayerAdd ComponentRigidbody 2D

    • Body Type 设为 Dynamic

    • Linear Drag 设为 2(让移动有摩擦力,不会一直滑)

    • Gravity Scale 设为 0(不要受重力影响)

  • 添加 Circle Collider 2D 组件(用于碰撞检测):

    • 点击 PlayerAdd ComponentCircle Collider 2D

    • 勾选 Is Trigger?不,我们想要物理碰撞,所以不勾。但为了收集星星,星星的碰撞器要设为触发器。

4.2 创建星星(Star)

  • 创建一个 2D ObjectSpritesStar (如果默认没有星星形状,可用 Square 代替,稍后改颜色或贴图)。

  • 命名为 Star

  • 添加 Circle Collider 2D (或 Box Collider 2D),勾选 Is Trigger,这样玩家碰到它不会物理反弹,而是触发事件。

  • 将星星做成 Prefab (预制体):将 Star 从 Hierarchy 拖拽到 Project 窗口中的文件夹(例如新建 Prefabs 文件夹)。然后删掉场景中的星星,我们稍后用代码生成多个。

4.3 创建地面(边界墙壁)

为了让玩家不跑出屏幕,我们创建四面墙壁:

  • 创建四个 2D ObjectSpritesSquare ,分别命名为 WallTopWallBottomWallLeftWallRight

  • 调整它们的 Transform:

    • 位置:根据 Camera 视图(默认Camera是正交,大小5,意味着屏幕高度10单位,宽度取决于分辨率)。简易做法:设置墙壁厚度0.5,长度足够。

    • 建议:Top 墙位置 (0, 5.5),Scale (12, 0.5);Bottom 墙 (0, -5.5);Left 墙 (-6.5, 0),Scale (0.5, 11);Right 墙 (6.5, 0)。

  • 给每个墙壁添加 Box Collider 2D(不要勾选 Is Trigger),使玩家无法穿过。

也可以采用另一种方法:给玩家添加移动范围限制代码,但墙壁更直观。

4.4 UI 文本(得分和倒计时)

  • 右键 Hierarchy → UIText - TextMeshPro(如果没有TMP,Unity会提示导入,同意即可)。

  • 命名为 ScoreText,设置位置左上角(例如 -300, 200)。

  • 复制一个,命名为 TimerText,放在右上角。

  • 在 Inspector 中可调节字体大小、颜色。

五、编写脚本(核心代码,有详细注释)

5.1 玩家移动脚本 PlayerController.cs

在 Project 窗口中右键 → CreateC# Script ,命名 PlayerController,双击打开(Visual Studio)。

java 复制代码
using UnityEngine;

public class PlayerController : MonoBehaviour
{
    public float moveSpeed = 10f;      // 移动速度
    private Rigidbody2D rb;

    void Start()
    {
        rb = GetComponent<Rigidbody2D>();
    }

    void Update()
    {
        // 获取输入(水平左右,垂直上下)
        float moveX = Input.GetAxisRaw("Horizontal");
        float moveY = Input.GetAxisRaw("Vertical");

        // 移动方向向量
        Vector2 moveDirection = new Vector2(moveX, moveY).normalized;
        rb.velocity = moveDirection * moveSpeed;
    }
}

将这个脚本拖拽到 Player 物体上。运行游戏,应该能用方向键移动了。

5.2 星星收集脚本 Star.cs

创建脚本 Star,挂载到 Star 预制体上。

java 复制代码
using UnityEngine;

public class Star : MonoBehaviour
{
    // 当玩家进入触发器时调用
    private void OnTriggerEnter2D(Collider2D other)
    {
        if (other.CompareTag("Player"))
        {
            // 通知 GameManager 增加分数
            GameManager.Instance.AddScore(10);
            // 将星星移动到随机位置
            Reposition();
        }
    }

    void Reposition()
    {
        // 随机位置范围:X -5.5 到 5.5,Y -4.5 到 4.5(根据边界调整)
        float randomX = Random.Range(-5.5f, 5.5f);
        float randomY = Random.Range(-4.5f, 4.5f);
        transform.position = new Vector2(randomX, randomY);
    }
}

注意 :需要给 Player 添加 Player 标签(Inspector 中 Tag 下拉菜单选择 Player,如果不存在就 Add Tag)。

5.3 游戏管理器 GameManager.cs

这个脚本负责分数、计时器、游戏结束等全局逻辑。创建脚本 GameManager

java 复制代码
using UnityEngine;
using UnityEngine.UI;   // 使用 UI 需要引入
using TMPro;            // TextMeshPro

public class GameManager : MonoBehaviour
{
    public static GameManager Instance;  // 单例模式

    public int score = 0;
    public float timeRemaining = 60f;    // 倒计时60秒
    public TMP_Text scoreText;
    public TMP_Text timerText;
    public GameObject gameOverPanel;     // 游戏结束面板(稍后创建)

    private bool isGameOver = false;

    void Awake()
    {
        // 实现单例
        if (Instance == null)
            Instance = this;
        else
            Destroy(gameObject);
    }

    void Start()
    {
        UpdateScoreUI();
        UpdateTimerUI();
        gameOverPanel.SetActive(false);
    }

    void Update()
    {
        if (isGameOver) return;

        // 倒计时逻辑
        if (timeRemaining > 0)
        {
            timeRemaining -= Time.deltaTime;
            UpdateTimerUI();
        }
        else
        {
            GameOver();
        }
    }

    public void AddScore(int amount)
    {
        if (isGameOver) return;
        score += amount;
        UpdateScoreUI();
    }

    void UpdateScoreUI()
    {
        scoreText.text = "得分: " + score;
    }

    void UpdateTimerUI()
    {
        // 显示整数秒
        timerText.text = "时间: " + Mathf.CeilToInt(timeRemaining).ToString();
    }

    void GameOver()
    {
        isGameOver = true;
        gameOverPanel.SetActive(true);
        // 停止玩家移动(通过查找玩家并禁用脚本)
        GameObject player = GameObject.FindGameObjectWithTag("Player");
        if (player != null)
            player.GetComponent<PlayerController>().enabled = false;
        // 禁用所有星星的触发器(可选)
        // 显示最终分数在面板上
        Text finalText = gameOverPanel.GetComponentInChildren<Text>();
        if (finalText != null) finalText.text = "游戏结束!总分: " + score;
        Time.timeScale = 0;  // 暂停游戏
    }
}

在场景中创建一个空物体(GameObject → Create Empty),命名为 GameManager,挂载此脚本。然后将 ScoreTextTimerText 从 Hierarchy 拖到脚本对应槽位。创建 gameOverPanel

  • 在 Hierarchy 右键 → UI → Panel,命名为 GameOverPanel

  • 在其下创建 Text 作为标题,以及一个 Button(Restart)。按钮功能我们先不实现复杂重启,可以简单显示分数。

  • GameOverPanel 拖到脚本的 gameOverPanel 槽位,并在 Start 中 SetActive(false)。

5.4 生成多个星星

GameManager 中添加一个数组 public GameObject starPrefab;public int starCount = 10;,然后在 Start 中循环生成。

java 复制代码
public GameObject starPrefab;
public int starCount = 10;

void Start()
{
    // ... 原有代码
    for (int i = 0; i < starCount; i++)
    {
        Instantiate(starPrefab, GetRandomPosition(), Quaternion.identity);
    }
}

Vector2 GetRandomPosition()
{
    float x = Random.Range(-5.5f, 5.5f);
    float y = Random.Range(-4.5f, 4.5f);
    return new Vector2(x, y);
}

在 Inspector 中将 Star 预制体拖到 starPrefab 槽位,设置 starCount 为 10。

注意:星星的 OnTriggerEnter2D 中调用 GameManager.Instance.AddScore(10); 之前已经写了。需要确保星星预制体上挂载了 Star 脚本。

六、运行与调试

  • 点击 Unity 编辑器顶部的 Play 按钮。

  • 使用 WASD 或方向键控制小球移动,触碰星星会加分并跳转到随机位置。

  • 倒计时结束后,游戏停止,显示结束面板。

常见问题

  • 玩家移动卡顿?调整 Linear Drag 或者增加速度。

  • 星星穿墙?确保墙壁的 Collider 2D 没有勾选 Is Trigger

  • 分数不增加?检查 Star 脚本中 other.CompareTag("Player") 是否准确,且 Player 标签已设置。

  • 游戏结束后还能移动?GameOver 中已经禁用 PlayerController,但如果有 Rigidbody 速度,还需设置 rb.velocity = Vector2.zero

七、让游戏更好玩:改进和扩展思路

具体改进建议

  1. 计时器加速:随着时间减少,星星移动速度变快,或玩家速度变慢。

  2. 音效 :收集星星时播放"叮"声。导入音频片段,使用 AudioSource.PlayClipAtPoint

  3. 粒子特效:收集星星时播放闪光粒子。

  4. 不同分值:金色星星+20,蓝色+5。

  5. 排行榜:保存最高分(PlayerPrefs)。

八、发布游戏给朋友玩

  • Build Settings :File → Build Settings → 点击 Add Open Scenes 添加当前场景。

  • 选择平台(PC、Mac、WebGL等)。

  • 点击 Build,选择一个文件夹,生成可执行文件(.exe)或网页版。

  • 发送给朋友,对方无需安装Unity即可运行。

九、总结与学习资源推荐

通过这个小游戏,你学会了:

  • Unity 2D 基础操作

  • Rigidbody2D 和碰撞器

  • 触发器检测和游戏逻辑

  • UI 更新、单例模式、协程(虽然没有用,但可以扩展)

  • 发布游戏

下一步学习资源

  • Unity Learn 官方教程(免费)

  • Brackeys YouTube 频道(经典)

  • 《Unity 实战》书籍

📌 Evan 说:做游戏是学习编程最快乐的方式。当你看到朋友玩你做的游戏时,那份成就感会推着你不断深入。别怕代码报错,每个Bug都是你成长的机会。
❓ 问题:你想用Unity做什么类型的游戏?RPG、平台跳跃还是射击?或者在制作过程中遇到了什么奇葩Bug?欢迎在评论区分享,我会选出 3 位同学,送出《Unity 常用脚本片段合集》和《游戏设计脑图模板》。

📌 如果本文点燃了你做游戏的热情,请点 👍 赞 + 关注 ,本专栏 《大一突围》 持续输出编程与游戏开发干货。

收藏本文,跟着步骤做出你的第一款游戏,然后分享给我玩!

相关推荐
咕噜咕噜啦啦11 小时前
从spring到spring boot——JAVA项目开发
java·前端·spring boot·后端·spring
Gopher_HBo11 小时前
DNS和HTTP DNS
后端
IT_陈寒11 小时前
Vite踩坑实录:静态资源加载把我搞懵了
前端·人工智能·后端
彦为君11 小时前
Spring定时任务开发指南(动态实现)
java·开发语言·后端·python·spring·wpf
SimonKing11 小时前
裁员、降薪潮来了,你被波及了么?
java·后端·程序员
2601_9560028111 小时前
钢铁雄心4/Hearts of Iron IV2026官方正版最新版pc免费下载(看到请立即转存 资源随时失效)手机版通用
大数据·游戏·游戏引擎·动画·游戏策划
叫我少年11 小时前
C# 基础数据类型:字符串类型
后端
樱桃花下的小猫12 小时前
幻兽帕鲁(Palworld)服务器存档回档完全指南
游戏·幻兽帕鲁·新手友好·云鸢互联·零门槛一键开服·幻兽帕鲁服务器
BingoGo12 小时前
TrueAsync Server 为 PHP 带来了原生的高性能 HTTP 服务器
后端·php