如何使用Unity制作你的第一个2D平台游戏

发布时间:2025/03/26

如何使用Unity制作你的第一个2D平台游戏

Unity是一个强大的游戏引擎,非常适合开发2D和3D游戏。 本文将引导你完成使用Unity制作第一个2D平台游戏的步骤,从创建新项目到角色移动、摄像机跟随、添加敌人和完成关卡。 本教程面向初学者,力求简单易懂。

准备工作

在开始之前,请确保您已经安装了Unity。 你可以从 Unity 官网下载最新版本,并根据提示安装。Unity官网

Unity Hub

强烈推荐使用Unity Hub来管理您的Unity项目和版本。 Unity Hub可以很方便地创建、打开、管理多个Unity项目,并且能够轻松切换不同的Unity版本。

第一步:创建Unity项目

  1. 打开Unity Hub: 启动 Unity Hub。
  2. 新建项目: 点击 "新建项目" 按钮。
  3. 选择模板: 在模板列表中,选择 "2D" 模板。
  4. 项目名称和位置: 输入项目名称(例如: My2DPlatformer)并选择项目保存的位置。
  5. 创建项目: 点击 "创建" 按钮。

第二步:导入资源

游戏资源包括角色动画、场景背景、地形、敌人图像等。 你可以自己制作资源,也可以从Unity Asset Store或其他资源平台下载。 对于初学者,建议先使用免费资源进行练习。

从Asset Store导入资源(示例):

  1. 打开Asset Store: 在 Unity 编辑器中,点击菜单栏的 "Window" -> "Asset Store"。
  2. 搜索资源: 在 Asset Store 中搜索 "2D Platformer Assets" 或类似关键词。
  3. 选择资源包: 选择一个适合的免费或付费资源包。 推荐一些常用的免费资源包,例如 "Kenney's Platformer Kit"。
  4. 导入资源: 点击资源包页面上的 "Import" 按钮,下载资源并导入到你的项目中。

导入的资源通常会出现在 "Project" 窗口中。

第三步:创建和设置场景

创建场景:

  1. 新建场景: 在 "Project" 窗口中,右键点击 "Assets" 文件夹,选择 "Create" -> "Scene"。
  2. 命名场景: 将新场景命名为 "Level1"(或其他你喜欢的名字)。
  3. 双击打开: 双击 "Level1" 场景文件打开它。

添加地形和背景:

  1. 导入地形资源: 将导入的资源包中的地形图像拖拽到 "Hierarchy" 窗口中。
  2. 调整位置和缩放: 在 "Inspector" 窗口中调整地形的位置(Position)和缩放(Scale),确保它覆盖了游戏区域。
  3. 创建背景: 可以使用 Tilemap 系统来创建复杂的2D地形。 首先,创建一个 Tilemap 对象 (GameObject -> 2D Object -> Tilemap -> Rectangular)。
  4. 绘制地形: 选择 Tile Palette 窗口 (Window -> 2D -> Tile Palette), 创建一个新的 Palette,并将地形图块拖放到 Palette 上。 使用 Tile Palette 工具在 Tilemap 上绘制地形。

第四步:创建角色和角色控制

创建角色:

  1. 导入角色图像: 将角色图像(Sprite)拖拽到 "Hierarchy" 窗口中。
  2. 添加组件: 在 "Inspector" 窗口中,点击 "Add Component" 按钮,添加以下组件:
    • Rigidbody 2D: 使角色具有物理特性,可以进行碰撞检测和移动。 设置 Body TypeKinematicDynamicKinematic 需要脚本控制移动, Dynamic 允许物理引擎影响角色。
    • Box Collider 2D: 定义角色的碰撞区域。 调整 SizeOffset 属性,使其与角色图像匹配。
    • Animator: 用于控制角色的动画。

角色控制脚本:

  1. 创建脚本: 在 "Project" 窗口中,右键点击 "Assets" 文件夹,选择 "Create" -> "C# Script"。 将脚本命名为 "PlayerController"。
  2. 编辑脚本: 双击 "PlayerController" 脚本打开它,添加以下代码:
using UnityEngine;

public class PlayerController : MonoBehaviour
{
    public float moveSpeed = 5f;      // 移动速度
    public float jumpForce = 10f;     // 跳跃力度
    public Transform groundCheck;       // 用于检测角色是否在地面上的 Transform
    public float groundCheckRadius = 0.2f; // 检测半径
    public LayerMask groundLayer;      // 地面 Layer

    private Rigidbody2D rb;           // 刚体组件
    private Animator animator;         // 动画组件
    private bool isGrounded;          // 是否在地面上
    private float horizontalInput;    // 水平输入

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

    void Update()
    {
        // 获取水平输入
        horizontalInput = Input.GetAxis("Horizontal");

        // 跳跃
        if (Input.GetButtonDown("Jump") && isGrounded)
        {
            rb.velocity = new Vector2(rb.velocity.x, jumpForce);
        }

        // 设置动画参数
        animator.SetFloat("Speed", Mathf.Abs(horizontalInput));
        animator.SetBool("IsGrounded", isGrounded);
    }

    void FixedUpdate()
    {
        // 检测是否在地面上
        isGrounded = Physics2D.OverlapCircle(groundCheck.position, groundCheckRadius, groundLayer);

        // 移动
        rb.velocity = new Vector2(horizontalInput * moveSpeed, rb.velocity.y);

        //角色朝向
        if (horizontalInput > 0)
            transform.localScale = new Vector3(1, 1, 1);
        else if (horizontalInput < 0)
            transform.localScale = new Vector3(-1, 1, 1);
    }

    // 在 Gizmos 中绘制地面检测圆
    void OnDrawGizmosSelected()
    {
        Gizmos.color = Color.green;
        Gizmos.DrawWireSphere(groundCheck.position, groundCheckRadius);
    }
}
  1. 将脚本添加到角色: 将 "PlayerController" 脚本拖拽到角色对象上。
  2. 配置脚本属性
    • 在 "Inspector" 窗口中,设置 Move SpeedJump Force 的值,调整角色的移动速度和跳跃力度。
    • 创建一个空对象作为 Ground Check 的子对象,将其放置在角色脚下,用于检测角色是否在地面上。 将该对象的 Transform 拖拽到 "PlayerController" 脚本的 Ground Check 属性上。
    • 创建一个新的 Layer,命名为 "Ground",并将地形对象的 Layer 设置为 "Ground"。 在 "PlayerController" 脚本的 Ground Layer 属性中选择 "Ground" Layer。

角色动画

  1. 创建动画状态机: 在 "Project" 窗口中,右键点击 "Assets" 文件夹,选择 "Create" -> "Animation" -> "Animator Controller"。 将动画状态机命名为 "PlayerAnimatorController"。
  2. 打开动画窗口: 点击菜单栏的 "Window" -> "Animation" -> "Animation"。
  3. 创建动画剪辑: 在 "Animation" 窗口中,点击 "Create" 按钮创建动画剪辑:
    • Idle: 角色站立不动时的动画。
    • Run: 角色跑步时的动画。
    • Jump: 角色跳跃时的动画。
  4. 将动画剪辑添加到状态机: 双击 "PlayerAnimatorController" 打开动画状态机。 将创建的动画剪辑拖拽到状态机窗口中。
  5. 创建状态转换
    • 从 "Idle" 到 "Run": 创建一个 Transition,设置 Condition 为 "Speed" > 0.1。
    • 从 "Run" 到 "Idle": 创建一个 Transition,设置 Condition 为 "Speed" < 0.1。
    • 从 "Idle" 或 "Run" 到 "Jump": 创建一个 Transition,设置 Condition 为 "IsGrounded" 为 false。
    • 从 "Jump" 到 "Idle": 创建一个 Transition,设置 Condition 为 "IsGrounded" 为 true。
  6. 配置Animator组件: 将 PlayerAnimatorController 拖拽到角色上的Animator组件中.

第五步:摄像机跟随

为了让玩家的视角始终跟随角色,需要创建一个摄像机跟随脚本。

  1. 创建脚本: 在 "Project" 窗口中,右键点击 "Assets" 文件夹,选择 "Create" -> "C# Script"。 将脚本命名为 "CameraFollow"。
  2. 编辑脚本: 双击 "CameraFollow" 脚本打开它,添加以下代码:
using UnityEngine;

public class CameraFollow : MonoBehaviour
{
    public Transform target;       // 要跟随的目标
    public float smoothSpeed = 0.125f; // 平滑速度
    public Vector3 offset;         // 相机偏移量

    private Vector3 velocity = Vector3.zero;

    void LateUpdate()
    {
        if (target != null)
        {
            Vector3 desiredPosition = target.position + offset;
            Vector3 smoothedPosition = Vector3.SmoothDamp(transform.position, desiredPosition, ref velocity, smoothSpeed);
            transform.position = smoothedPosition;
        }
    }
}
  1. 将脚本添加到主摄像机: 将 "CameraFollow" 脚本拖拽到主摄像机对象上。
  2. 配置脚本属性: 将角色对象拖拽到 "CameraFollow" 脚本的 Target 属性上。 调整 Offset 属性,设置相机与角色的相对位置。 调整 Smooth Speed 属性,控制相机跟随的平滑程度。

第六步:添加敌人

创建敌人:

  1. 导入敌人图像: 将敌人图像(Sprite)拖拽到 "Hierarchy" 窗口中。
  2. 添加组件: 在 "Inspector" 窗口中,点击 "Add Component" 按钮,添加以下组件:
    • Rigidbody 2D: 使敌人具有物理特性。
    • Box Collider 2D: 定义敌人的碰撞区域。
    • 脚本: 创建一个控制敌人行为的脚本,例如移动、巡逻或攻击。

敌人控制脚本 (示例):

using UnityEngine;

public class EnemyController : MonoBehaviour
{
    public float moveSpeed = 2f;       // 移动速度
    public float patrolDistance = 5f;   // 巡逻距离
    private Vector3 startPosition;       // 初始位置
    private Vector3 currentDirection = Vector3.right; // 初始方向

    void Start()
    {
        startPosition = transform.position;
    }

    void Update()
    {
        // 移动
        transform.Translate(currentDirection * moveSpeed * Time.deltaTime);

        // 检测是否到达巡逻点
        if (Vector3.Distance(transform.position, startPosition) > patrolDistance)
        {
            currentDirection = -currentDirection; // 反向移动
            // 反转朝向确保敌人始终面向移动方向
            transform.localScale = new Vector3(-transform.localScale.x, transform.localScale.y, transform.localScale.z);

            if (currentDirection == Vector3.right)
            {
                transform.position = startPosition + new Vector3(patrolDistance, 0, 0);
            }
            else
            {
                transform.position = startPosition - new Vector3(patrolDistance, 0, 0);
            }
        }
    }
}

碰撞检测

处理玩家与敌人之间的碰撞,可以在玩家或敌人脚本中添加 OnCollisionEnter2D 函数。 例如,玩家碰到敌人时,扣除生命值或者游戏结束。

void OnCollisionEnter2D(Collision2D collision)
{
    if (collision.gameObject.CompareTag("Enemy"))
    {
        // 处理碰撞
        Debug.Log("Player hit by enemy!");
        // 可增加死亡动画等
        Destroy(gameObject); // 摧毁玩家对象
        // 也可以调用GameManager的函数来执行游戏结束逻辑
    }
}

请确保敌人对象具有 "Enemy" 标签。 (在Inspector窗口顶部的Tag下拉菜单中添加 Tag)。

第七步:关卡设计与完成

添加收集品

添加金币、宝石等收集品来增加游戏的乐趣。

添加完成区域

创建一个特殊的区域,当玩家到达该区域时,表示完成了关卡。 可以使用 Trigger Collider 2D 进行检测。

  1. 创建目标对象: 创建一个空对象,并添加 Box Collider 2D 组件。
  2. 设置为 Trigger: 将 Box Collider 2D 的 Is Trigger 属性勾选上。
  3. 添加脚本: 创建一个脚本,用于检测玩家是否到达完成区域。
using UnityEngine;
using UnityEngine.SceneManagement;

public class LevelComplete : MonoBehaviour
{
    public string nextSceneName; //下一个场景的名字

    void OnTriggerEnter2D(Collider2D collision)
    {
        if (collision.gameObject.CompareTag("Player"))
        {
            Debug.Log("Level Complete!");
            // 加载下一个场景
            SceneManager.LoadScene(nextSceneName);
        }
    }
}

确保玩家对象具有 "Player" 标签。 (在Inspector窗口顶部的Tag下拉菜单中添加 Tag)。

总结

通过本教程,你已经学习了使用 Unity 制作一个简单的 2D 平台游戏的基础知识。 你可以继续学习更高级的技术,例如:

  • 更复杂的动画
  • 更多的敌人类型
  • 更智能的敌人 AI
  • UI 设计和游戏菜单
  • 音效和音乐

祝你游戏开发愉快!