Unity开发2d游戏全套教程[入门案例]

Unity开发2d游戏全套教程

官方手册:https://docs.unity.cn/cn/2023.2/Manual/class-EdgeCollider2D.html

项目素材地址(Github),欢迎star:https://github.com/ziyifast/ziyifast-code_instruction/tree/main/unity-demo/SnakeRun

  • 本期只演示最基本的操作,大家可以在这个基础上进行修改,比如添加背景或者添加音乐

环境准备:下载Unity

  1. 下载Unity

进入官网,选择对应操作系统、对应版本下载即可

官网地址:https://unity.cn/releases

下载地址:https://unity.cn/releases/lts/6000

我这里是mac,直接下载最新长期支持版的mac即可:

也可以直接下载Unity Hub,从Unity Hub中安装

下载好后,根据自己后续游戏开发的必要,下载对应的扩展包,但需要勾选WebGL Build Support,因为我们后续会将游戏打包为Web发布到网站上。

  1. 下载.net环境

游戏开发语言使用C#,所以需要准备.net环境。

下载地址:https://dotnet.microsoft.com/zh-cn/download

创建项目

我们开发的是2D游戏,这里选择2D游戏模板

实战开发

场景搭建+实现小蛇跳跃

1. assets中导入角色与背景图片
2. 创建Snake物品,create empty
3. 给这个Snake物品添加一个sprite renderer,将小蛇图片拖入其中,按住shit键可以等比例缩放小蛇

相当于我们这里用这个小蛇图片进行渲染


4. 调整渲染图颜色及物体大小
5. 点击播放,查看效果

效果:

6. 给Snake这个物品添加Rigidbody 2D重力,让其实现自然坠落
7. 添加C#脚本代码,实现Snake跳跃操作
csharp 复制代码
using UnityEngine;

public class SnakeController : MonoBehaviour
{
    //每次跳动的高度
    public float jumpForce = 5f;
    private Rigidbody2D rb;
    public GameObject gameOverPanel;
    private bool isGameOver = false;

    public float upperLimit = 1000000000f; // Set this to the top of your screen
    public float lowerLimit = -1000000000f; // Set this to the bottom of your screen


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

    private void Update()
    {
        if (isGameOver) return;

        if (Input.GetKeyDown(KeyCode.Space))
        {
            Jump();
        }
    }

    private void Jump()
    {
        rb.linearVelocity = Vector2.up * jumpForce;
    }
}
运行游戏查看效果

创建障碍物+实现物体碰撞

1. 创建空物品Barrier,在下面分别创建topBarrier、bottomBarrier

分别给topBarrier、bottomBarrier添加Sprite Renderer,并调整物品页面布局

点击运行游戏,查看效果:

2. 添加C#脚本,让障碍物实现向左移动(从视觉上实现小蛇向右移动)
csharp 复制代码
using UnityEngine;

public class BarrierController : MonoBehaviour
{
    public float speed = 2f;
    public float lifetime = 10f;

    private void Start()
    {
        //实现超出范围后,销毁多余的障碍物
        Destroy(gameObject, lifetime);
    }

    private void Update()
    {
        MoveLeft();
    }

    private void MoveLeft()
    {
        //向左移动障碍物
        // Debug.Log("move left....");
        transform.Translate(Vector2.left * speed * Time.deltaTime);
    }
}

效果:

3. 给小蛇、障碍物都添加collider,实现碰撞效果

障碍物、小蛇添加:Box collider 2D

  • 因为障碍物、小蛇类似正方体,所以添加box collider更合理。当然大家也可以根据自己角色进行调整

给障碍物添加collider:

小蛇同理

效果:

4. 解决碰撞后,翻滚问题

目前小蛇和障碍物碰撞后,小蛇会翻滚

解决:调整小蛇的rigidbody 2d属性,冻结Z方向

效果

脚本实现障碍物自动随机生成

目前游戏场景中的障碍物是我们自己手动拖进去的,如果要添加多个障碍物肯定不能由我们手动去操作。这里我们可以通过C#代码实现自动生成。

1. 在Assets目录下新建Prefab文件夹,用于存储我们的复制品
2. 将Barrier拖到Prefab文件夹中,这样Barrier就成了复制品,然后我们就可以删除场景里的Barrier了

如果我们想要Pipe,直接到Asset目录下的Prefab文件夹下拖动Pipe即可,想要多个就拖动多个。优化:后续会采用代码来实现自动生成

3. 新建BarrierSpawner物品,并添加BarrierSpawner脚本实现自动生成障碍物
csharp 复制代码
using UnityEngine;

public class BarrierSpawner : MonoBehaviour
{
    public GameObject barrierPrefab;
    public float spawnDelay = 2f;
    public float minSpawnHeight = -2f;
    public float maxSpawnHeight = 2f;

    private void Start()
    {
        //重复调用函数,实现物品复制重复创建
        InvokeRepeating("SpawnBarrier", 0f, spawnDelay);
    }

    private void SpawnBarrier()
    {
        float randomHeight = Random.Range(minSpawnHeight, maxSpawnHeight);
        Vector2 spawnPosition = new Vector2(transform.position.x, randomHeight);
        Instantiate(barrierPrefab, spawnPosition, Quaternion.identity);
    }
}
效果

实现加分机制

当小蛇通过一个障碍物时,我们应该实现加分,实现思路:

在上下两个障碍物之间添加trigger,当小蛇通过后,触发trigger,执行加分函数

1. Barrier下添加scoreCheck,scoreCheck添加box collider 2d,并勾选Is Trigger
2. 添加ScoreManager物品,同时添加ScoreManager代码

ScoreManager.cs:

csharp 复制代码
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI; 

public class ScoreManager : MonoBehaviour
{
    public static int score = 0;
    public Text scoreText;

    private void Update()
    {
        // Update the text field with the current score
        //scoreText.text = score.ToString();
    }


    
    // public void OnRestartButtonClick() // Connect this function to your button's onClick event in the inspector
    // {
    //     SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
    //     score = 0;
    // }
}

SnakeController.cs代码中添加分数逻辑:

3. 新增Canvas物品,添加分数面板展示分数
4. 添加Text展示分数
5. 调整页面分数字体大小、颜色等
6. ScoreManager.cs添加分数展示逻辑,并将Score Text文字展示框拖动到ScoreManager物品下
csharp 复制代码
    private void Update()
    {
        // Update the text field with the current score
        scoreText.text = score.ToString();
    }
效果

实现游戏结束逻辑

1. Canvas下添加Panel,并调整页面展示位置与大小
2. GameOverPanel下添加Text与Button,提示游戏结束与重新开始按钮

UI - Legacy - Text

UI - Legacy - Button

效果:

3. 隐藏游戏结束页面,当触发碰撞💥条件时,游戏才结束

SnakeController.cs中新增游戏结束逻辑:

csharp 复制代码
    //当snake与Barrier相撞时,游戏结束
    private void OnCollisionEnter2D(Collision2D collision)
    {
        if (collision.gameObject.CompareTag("Barrier"))
        {
            // Game over
            GameOver();
        }
    }

    private void GameOver()
    {
        isGameOver = true; // Add this line

        // Freeze the Snake's motion
        rb.linearVelocity = Vector2.zero;

        if (gameOverPanel != null)
        {
        	//展示游戏结束页面
            gameOverPanel.SetActive(true);
        }
    }

SnakeController.cs全部代码:

csharp 复制代码
using UnityEngine;

public class SnakeController : MonoBehaviour
{
    //每次跳动的高度
    public float jumpForce = 5f;
    private Rigidbody2D rb;
    public GameObject gameOverPanel;
    private bool isGameOver = false;

    public float upperLimit = 1000000000f; // Set this to the top of your screen
    public float lowerLimit = -1000000000f; // Set this to the bottom of your screen

    //public AudioSource jumpSFX;

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

    private void Update()
    {
        if (isGameOver) return;

        // Check if Snake is out of bounds【小蛇超出页面也触发游戏结束】
        // if (transform.position.y > 50f || transform.position.y < -50f)
        // {
        //     //Debug.Log(transform.position.y);
        //     GameOver();
        // }

        if (Input.GetKeyDown(KeyCode.Space))
        {
            Jump();
        }
    }

    private void Jump()
    {
        rb.linearVelocity = Vector2.up * jumpForce;
        //jumpSFX.Play();
    }


    //与Trigger部分碰撞时,触发分数加操作
    private void OnTriggerEnter2D(Collider2D collision)
    {
        // if (isGameOver) return; // Add this line

        //Debug.Log("Score: " + ScoreManager.score);
        ScoreManager.score++;
    }

    //当snake与Barrier相撞时,游戏结束
    private void OnCollisionEnter2D(Collision2D collision)
    {
        if (collision.gameObject.CompareTag("Barrier"))
        {
            // Game over
            GameOver();
        }
    }

    private void GameOver()
    {
        isGameOver = true; // Add this line

        // Freeze the Snake's motion
        rb.linearVelocity = Vector2.zero;

        if (gameOverPanel != null)
        {
        	//展示游戏结束页面
            gameOverPanel.SetActive(true);
        }
    }
}
4. SnakeController中添加游戏结束Panel
5. 为障碍物添加Barrier标签

因为c#代码中是通过Barrier Tag来判断

给topBarrier、bottomBarrier分别添加tag:


效果

实现重玩逻辑

给游戏结束页面的[重新开始]按钮绑定事件,点击时,触发游戏重新开始

1. ScoreManager.cs新增重玩逻辑代码:
csharp 复制代码
//游戏重新开始,分数清零,重新加载游戏场景
public void OnRestartButtonClick() // Connect this function to your button's onClick event in the inspector
{
    SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
    score = 0;
}

ScoreManager.cs全部代码:

csharp 复制代码
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI; 

public class ScoreManager : MonoBehaviour
{
    public static int score = 0;
    public Text scoreText;

    private void Update()
    {
        // Update the text field with the current score
        scoreText.text = "Score:" + score.ToString();
    }


    //游戏重新开始,分数清零,重新加载游戏场景
    public void OnRestartButtonClick() // Connect this function to your button's onClick event in the inspector
    {
        SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
        score = 0;
    }
}
2. GameOverPanel下的Button绑定重新开始逻辑
效果

游戏打包

1. File - Build Profile

2. 选择打包参数

因为我们这里是打包发布到web服务器上,所以这里直接选择web,然后点击切换平台

3. 修改压缩参数,改为gzip或不压缩

因为Brotli 在http上不支持压缩,改成G-zip或不压缩


4. 点击Build打包游戏,然后选择打包后文件存放位置

游戏上线(itch.io

itch.io可以算是全球最大的独立游戏平台。它和steam一样,你可以把你的游戏上架到itch上,可以是免费的,也可以让大家捐赠,也可以让大家付费购买。

  1. 注册账号之后,创建项目:

  2. 填写游戏基本信息

  3. 填写完后选择save,保存为draft(第一次只能保存为草稿)

  4. 保存完后,点击项目,改为public,表明游戏公开,然后就可以把体验链接发给其他人体验了

本地运行游玩

打包后的游戏,有两个文件夹(Build、TemplateData),一个文件(index.html)

python 复制代码
# 本地运行项目:可以通过python直接起http服务,也可以下载nginx或Tomcat等
# 9999指定运行端口
# --directory 指定unity打包后的路径
python3 -m http.server 9999 --directory /Users/ziyi/Desktop/ZiyiSnakeRun

浏览器访问localhost:9999

效果:

全部代码地址(资源文件地址)

Github(欢迎star~):https://github.com/ziyifast/ziyifast-code_instruction/tree/main/unity-demo/SnakeRun

相关推荐
CreasyChan2 小时前
Unity Shader 入门指南
unity·c#·游戏引擎·shader
漂视数字孪生世界2 小时前
Unity团结引擎的前世今生
unity·游戏引擎·数字孪生
心前阳光8 小时前
Unity通过ScriptableObject学习访问者模式
学习·unity·访问者模式
串流游戏联盟8 小时前
永劫无间新模式更新!低配手机怎么玩?
游戏·远程工作
fcm199 小时前
unity之重新导入TMP
unity
心疼你的一切9 小时前
【技术创作的璀璨盛宴——2025年CSDN博客之星总评选深度总结】
microsoft·unity·游戏引擎·游戏程序·csdn·博客之星
心前阳光9 小时前
Unity批量实例化UI后设置UI位置失效
unity
心前阳光10 小时前
Unity的VideoPlayer准备完成回调注意
unity·游戏引擎
LYOBOYI12310 小时前
qml练习:绘制rgp游戏地图(1)
游戏
巨人张10 小时前
C++零基础游戏----“大鱼吃小鱼”
java·c++·游戏