杰瑞科技汇

Unity3D小游戏教程从哪开始学?

我们将以一个经典的小游戏类型——“2D 平台跳跃小游戏”(类似于《超级马里奥》或《蔚蓝》的简化版)为例,因为它能很好地涵盖 Unity 的核心概念。

Unity3D小游戏教程从哪开始学?-图1
(图片来源网络,侵删)

教程总览:我们将制作什么?

游戏名称:《方块大冒险》

游戏玩法:

  1. 玩家控制一个蓝色方块角色。
  2. 可以左右移动和跳跃。
  3. 目标是到达红色的终点旗帜。
  4. 途中会碰到绿色敌人,碰到敌人会重置到起点。
  5. 通过收集黄色金币来增加分数。

最终效果预览:


第一步:准备工作与项目创建

  1. 安装 Unity Hub 和 Unity Editor

    Unity3D小游戏教程从哪开始学?-图2
    (图片来源网络,侵删)
    • 如果你还没安装,请先去 Unity 官网 下载并安装 Unity Hub。
    • 打开 Unity Hub,点击 Installs -> Install Editor,选择一个稳定的 LTS 版本(推荐 2025.3.x 或更新版本)进行安装。
    • 安装完成后,在 Unity Hub 中点击 New,创建一个新项目。
    • 在模板选择界面,选择 2D (Core) 模板,给你的项目起一个名字(如 BlockAdventure),然后点击 Create project
  2. 熟悉 Unity 编辑器界面

    • 项目创建后,你会看到几个主要窗口:
      • Scene (场景):你的游戏世界,在这里摆放和编辑所有物体。
      • Game (游戏):游戏运行时的预览窗口,也就是玩家最终看到的样子。
      • Hierarchy (层级):显示当前场景中所有物体的列表,像一个“家谱树”。
      • Project (项目):存放你所有游戏资源(模型、贴图、脚本等)的地方。
      • Inspector (检视):显示在 Hierarchy 中选中物体的所有组件和属性,是你修改物体细节的地方。

第二步:创建游戏场景

  1. 创建地面

    • Hierarchy 窗口中,右键点击 Create -> 2D Object -> Sprite,创建一个 Sprite 物体,我们把它作为地面。
    • Inspector 窗口中,找到 Sprite Renderer 组件,点击 Sprite 右边的小圆圈,选择 Import New Sprite...,然后从你的电脑上选择一张地面图片(如果没有,可以在网上搜索 "ground tileset" 下载免费的)。
    • 调整 Transform 组件中的 Scale 值,比如把 XY 都设置为 10,把 Z 设置为 1,调整 PositionY 设置为 -2,让它位于屏幕下方。
    • 快捷技巧:按住 Alt 键,用鼠标左键拖动 Transform 中的位置、旋转或缩放,可以精确调整数值。
  2. 创建玩家

    • 同样,在 Hierarchy 中右键 Create -> 2D Object -> Sprite,创建一个代表玩家的 Sprite
    • Inspector 中,给它换一个蓝色的图片(或者直接修改 Color 属性为蓝色)。
    • 调整 TransformPosition,比如设置为 (0, 0, 0),把它放在地面上方。
  3. 创建终点和敌人

    Unity3D小游戏教程从哪开始学?-图3
    (图片来源网络,侵删)
    • 再创建两个 Sprite,一个作为终点(红色),一个作为敌人(绿色),分别调整它们的位置。

现在你的 HierarchyScene 窗口应该看起来像这样:


第三步:让玩家动起来(核心:C# 脚本)

这是最关键的一步,我们将用 C# 编写代码来控制玩家。

  1. 创建 C# 脚本

    • Project 窗口中,右键点击 Create -> C# Script,命名为 PlayerController
    • 双击这个脚本,它会在你默认的代码编辑器(如 Visual Studio)中打开。
  2. 编写移动和跳跃代码

    • 将下面的代码复制并粘贴到 PlayerController.cs 文件中,并仔细阅读注释,理解每一行的作用。
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    public class PlayerController : MonoBehaviour
    {
        // --- 在 Inspector 窗口中可以调节的变量 ---
        [Header("移动设置")]
        public float moveSpeed = 5f; // 移动速度
        public float jumpForce = 10f; // 跳跃力度
        [Header("检测设置")]
        public Transform groundCheck; // 一个空的子物体,用来检测是否在地面上
        public LayerMask groundLayer; // 定义什么是“地面”的层级
        public float groundCheckRadius = 0.2f; // 地面检测范围
        // --- 私有变量 ---
        private Rigidbody2D rb; // 玩家的刚体组件
        private bool isGrounded; // 是否在地面上
        private float horizontalInput; // 水平输入值 (-1, 0, 1)
        // --- Unity 生命周期函数 ---
        // Start is called before the first frame update
        void Start()
        {
            // 获取附加到此物体上的 Rigidbody2D 组件
            rb = GetComponent<Rigidbody2D>();
        }
        // FixedUpdate is called at a fixed interval and is used for physics calculations
        void FixedUpdate()
        {
            // 获取水平输入 (A/D 或 左/右箭头)
            horizontalInput = Input.GetAxis("Horizontal");
            // 调用移动函数
            Move();
            // 调用地面检测
            CheckGrounded();
        }
        // Update is called once per frame
        void Update()
        {
            // 在 Update 中检测输入,因为输入检测需要非常灵敏
            // 按下空格键并且在地面上时,执行跳跃
            if (Input.GetButtonDown("Jump") && isGrounded)
            {
                Jump();
            }
        }
        // 移动函数
        private void Move()
        {
            // 使用刚体的速度来实现移动
            // new Vector2(horizontalInput * moveSpeed, rb.velocity.y) 保持垂直速度不变,只改变水平速度
            rb.velocity = new Vector2(horizontalInput * moveSpeed, rb.velocity.y);
        }
        // 跳跃函数
        private void Jump()
        {
            // 给刚体一个向上的力
            rb.AddForce(Vector2.up * jumpForce, ForceMode2D.Impulse);
        }
        // 地面检测函数
        private void CheckGrounded()
        {
            // 检测 groundCheck 点周围半径为 groundCheckRadius 的圆形区域内,是否有属于 groundLayer 的物体
            isGrounded = Physics2D.OverlapCircle(groundCheck.position, groundCheckRadius, groundLayer);
        }
        // 在 Scene 视图中可视化地面检测范围(可选,但很有用)
        void OnDrawGizmosSelected()
        {
            if (groundCheck != null)
            {
                Gizmos.color = Color.green;
                Gizmos.DrawWireSphere(groundCheck.position, groundCheckRadius);
            }
        }
    }
  3. 将脚本附加到玩家并配置

    • 回到 Unity 编辑器,选中 Hierarchy 中的玩家 Sprite
    • Project 窗口中的 PlayerController 脚本拖拽Inspector 窗口中。
    • 你会发现 Inspector 中多了 Player Controller 脚本组件,以及我们定义的 public 变量。
    • 添加刚体:玩家需要物理属性(如重力、速度),在 Inspector 中点击 Add Component,搜索并添加 Rigidbody 2D
    • 配置地面检测
      • 在玩家 Sprite 下,右键 Create -> Empty,创建一个空的子物体,命名为 GroundCheck
      • 调整 GroundCheckPosition(0, -0.5, 0),让它位于玩家脚下的位置。
      • 选中玩家,在 Player Controller 脚本组件中,将 Ground Check 变量拖拽到这个槽位里。
      • 创建一个新的图层:点击 Layers 下拉菜单,选择 Add Layer...,在 User Layer 8(或其他空位)中输入 Ground
      • 选中地面物体,在 Layer 下拉菜单中选择 Ground
      • Player Controller 脚本的 Ground Layer 变量中,选择 Ground
  4. 测试!

    • 点击编辑器顶部的播放按钮,你就可以在 Game 窗口中控制你的方块左右移动和跳跃了!如果不行,检查一下上面的步骤是否有误。

第四步:添加游戏逻辑(碰撞与交互)

现在玩家能动了,但还不会与游戏世界交互,我们需要使用 Unity 的碰撞器触发器

  1. 设置碰撞器

    • 玩家和地面:默认创建的 Sprite 已经有一个 Box Collider 2D 组件,这很好,确保玩家和地面都有这个组件。
    • 终点和敌人:同样,为它们也添加 Box Collider 2D 组件。
  2. 创建管理脚本

    • Project 中创建一个新的 C# 脚本,命名为 GameManager,这个脚本将处理游戏的核心逻辑,如分数、重置等。
  3. 编写碰撞检测代码

    • 修改 PlayerController 脚本,添加碰撞检测逻辑。
    // 在 PlayerController.cs 中添加以下代码
    // 在类的开头添加一个变量来引用游戏管理器
    private GameManager gameManager;
    void Start()
    {
        rb = GetComponent<Rigidbody2D>();
        // 找到场景中的 GameManager 对象
        gameManager = FindObjectOfType<GameManager>();
    }
    // OnCollisionEnter2D 在物体发生碰撞时被调用
    private void OnCollisionEnter2D(Collision2D collision)
    {
        // 检查碰撞的物体是否是敌人(假设敌人的标签是 "Enemy")
        if (collision.gameObject.CompareTag("Enemy"))
        {
            Debug.Log("碰到敌人了!");
            // 调用游戏管理器的重置函数
            gameManager.RespawnPlayer();
        }
    }
    // OnTriggerEnter2D 在物体进入触发器时被调用
    private void OnTriggerEnter2D(Collider2D other)
    {
        // 检查是否触碰到金币
        if (other.CompareTag("Coin"))
        {
            Debug.Log("收集到金币!");
            // 增加分数
            gameManager.AddScore(10);
            // 销毁金币物体
            Destroy(other.gameObject);
        }
        // 检查是否触碰到终点
        if (other.CompareTag("Goal"))
        {
            Debug.Log("恭喜通关!");
            // 可以在这里显示胜利信息或加载下一关
            gameManager.WinLevel();
        }
    }
  4. 编写 GameManager 脚本

    • GameManager.cs 中编写如下代码:
    using UnityEngine;
    using UnityEngine.SceneManagement; // 需要这个命名空间来加载场景
    public class GameManager : MonoBehaviour
    {
        public static GameManager instance; // 单例模式,方便其他脚本调用
        public int score = 0;
        public Transform playerSpawnPoint; // 玩家的重生点
        private void Awake()
        {
            // 单例模式的实现
            if (instance == null)
            {
                instance = this;
                // DontDestroyOnLoad(gameObject); // 如果你想让 GameManager 在场景切换时保留,取消这行注释
            }
            else
            {
                Destroy(gameObject);
            }
        }
        public void AddScore(int points)
        {
            score += points;
            Debug.Log("当前分数: " + score);
            // TODO: 更新 UI 上的分数显示
        }
        public void RespawnPlayer()
        {
            // 找到玩家
            GameObject player = GameObject.FindGameObjectWithTag("Player");
            if (player != null && playerSpawnPoint != null)
            {
                // 将玩家位置重置到重生点
                player.transform.position = playerSpawnPoint.position;
                // 重置玩家的速度,避免卡住
                player.GetComponent<Rigidbody2D>().velocity = Vector2.zero;
            }
        }
        public void WinLevel()
        {
            Debug.Log("你赢了!");
            // TODO: 显示胜利UI,然后加载下一关或返回主菜单
            // 示例:重新加载当前场景
            // SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
        }
    }
  5. 配置游戏物体

    • 设置标签:选中敌人物体,在 InspectorTag 下拉菜单中选择 Add Tag...,创建一个新标签 Enemy,然后选中敌人,将其 Tag 设置为 Enemy,同理,为金币创建 Coin 标签,为终点创建 Goal
    • 设置触发器:选中金币和终点物体,在它们的 Box Collider 2D 组件中,勾选 Is Trigger 选项,这样它们就不会产生物理碰撞,只会触发事件。
    • 创建 GameManager 物体:在 Hierarchy 中右键 Create -> Empty,创建一个空物体,命名为 GameManager,将 GameManager.cs 脚本拖给它,然后在 Inspector 中,为其创建一个 Player 标签(如果还没有的话),并选中玩家物体,将其 Tag 设置为 Player,将玩家初始位置拖拽到 GameManagerPlayer Spawn Point 变量槽中。

第五步:完善与发布

  1. 添加UI(用户界面)

    • Hierarchy 中右键 UI -> Canvas,创建一个画布。
    • 右键 Canvas -> UI -> Text - TextMeshPro,创建一个文本用来显示分数。
    • 调整文本的位置和内容,我们需要用脚本动态更新它。
    • 创建一个 ScoreUI.cs 脚本:
    using TMPro;
    using UnityEngine;
    public class ScoreUI : MonoBehaviour
    {
        public TextMeshProUGUI scoreText; // 在Inspector中拖拽这个文本组件进来
        void Start()
        {
            // 确保我们引用到了文本组件
            if (scoreText == null)
            {
                scoreText = GetComponent<TextMeshProUGUI>();
            }
            UpdateScoreText();
        }
        // 提供给GameManager调用的公共方法
        public void UpdateScoreText()
        {
            scoreText.text = "分数: " + GameManager.instance.score;
        }
    }
    • ScoreUI.cs 挂载到分数文本物体上,并把该文本组件拖拽到 Score Text 变量槽中。
    • 修改 GameManager.cs 中的 AddScore 方法:
    // 在 GameManager.cs 中添加
    public ScoreUI scoreUI;
    public void AddScore(int points)
    {
        score += points;
        Debug.Log("当前分数: " + score);
        if (scoreUI != null)
        {
            scoreUI.UpdateScoreText();
        }
    }
    • Hierarchy 中的分数文本物体拖拽到 GameManagerScore UI 变量槽中。
  2. 添加音效和粒子效果(可选)

    • 音效:在 Project 中导入 .wav.mp3 音效文件,创建一个 Audio Source 组件,将音效文件拖拽给它,然后在跳跃、收集金币、碰撞敌人等事件中,调用 audioSource.Play() 来播放声音。
    • 粒子效果:在 Package Manager 中导入 Effects 包,创建 Particle System,调整其参数(如颜色、速度、生命周期)来制作跳跃的尘埃或收集金币的闪光。
  3. 构建与发布

    • 点击 File -> Build Settings
    • 将当前场景拖拽到 Scenes In Build 列表中。
    • 选择你想要发布的平台(如 Windows, macOS, Android, iOS 等)。
    • 点击 Switch Platform,然后点击 Build
    • 选择一个文件夹来保存你的游戏,等待构建完成,你就可以在文件夹中找到并运行你制作的小游戏了!

进阶学习路径

当你完成了这个小游戏后,你可以尝试以下内容来提升自己:

  • 制作动画:学习使用 Animator 组件和 Animation 窗口,为玩家添加待机、跑动、跳跃等动画。
  • 关卡设计:学习使用 Tilemap 功能来高效地绘制平台和关卡。
  • 敌人 AI:为敌人编写简单的巡逻 AI,比如让它们在两点之间来回移动。
  • 游戏存档:学习使用 PlayerPrefs 来保存玩家的最高分或进度。
  • UI 系统:学习使用 EventSystem 和按钮制作开始菜单、暂停菜单和游戏结束界面。

推荐学习资源

  • 官方资源
    • Unity Learn: Unity 官方教程,质量极高,从入门到精通应有尽有。
    • Unity 手册: 遇到问题随时查阅的“字典”。
  • 视频教程
    • Brackeys: (已停更,但仍是经典入门教程) 他的视频非常有趣且易于理解。
    • Code Monkey: 专注于编程和特定功能实现,教程非常深入。
    • Sebastian Lague: 专注于算法和创意编程,水平很高,能激发灵感。
  • 社区
    • Unity Forum: 官方论坛,可以提问和交流。
    • Reddit (r/Unity3D): 全球最大的 Unity 社区,有大量分享和讨论。

祝你开发愉快,享受创造游戏的乐趣!

分享:
扫描分享到社交APP
上一篇
下一篇