news 2026/6/15 18:37:55

Unity教学 项目1 2D赛车小游戏

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Unity教学 项目1 2D赛车小游戏

视频链接:

https://www.bilibili.com/video/BV1wT9rYZEKe?spm_id_from=333.788.videopod.sections&vd_source=25b783f5f945c4507229e9dec657b5bb

本教程涉及到 Unity 常用组件、常用方法等核心知识点,掌握本教程相关知识后你就就可以快速掌握一些 Unity2D 常用组件了

1.需求分析

  1. 玩家通过点击屏幕上的向左、向右移动按钮控制红色小车左右移动避让黄色小车
  2. 黄色小车在屏幕最上方随机生成后向下移动
  3. 屏幕右上方分数跟随时间变化而变化
  4. 红色小车与某一辆黄色小车碰撞则游戏结束,弹出游戏结束界面
  5. 游戏结束界面上有本局游戏分数以及重新开始的按钮

2.代码实现

2.1 创建项目目录

  • Imags:静态图片

  • Prefabs:预设物体

  • Resources:动态资源

    • Audio:音频
  • Scenes:场景

  • Scripts:脚本

2.2 创建面板、小车、按钮等

2.3 按钮控制红色小车左右移动

创建游戏管理脚本 GameManager.cs

usingSystem.Collections;usingSystem.Collections.Generic;usingUnityEngine;publicclassGameManager:MonoBehaviour{/// <summary>/// 游戏管理器实例/// </summary>publicstaticGameManagerinsta;/// <summary>/// 主界面/// </summary>publicMainPanelmainPanel;privatevoidAwake(){insta=this;}// Start is called before the first frame updatevoidStart(){}// Update is called once per framevoidUpdate(){}}

红色小车挂载脚本 RedCar.cs

usingSystem.Collections;usingSystem.Collections.Generic;usingUnityEngine;publicclassRedCar:MonoBehaviour{/// <summary>/// 移动速度/// </summary>privateintmoveSpeed=100;/// <summary>/// 移动方向/// </summary>publicintmoveDirection=0;// Start is called before the first frame updatevoidStart(){}// Update is called once per framevoidUpdate(){//屏幕范围内左右移动if(moveDirection==-1&&transform.localPosition.x<=-490)return;if(moveDirection==1&&transform.localPosition.x>=490)return;transform.localPosition+=newVector3(moveDirection*moveSpeed*Time.deltaTime,0,0);}/// <summary>/// 碰撞显示结束界面/// </summary>/// <param name="collision"></param>privatevoidOnTriggerEnter2D(Collider2Dcollision){GameManager.insta.overPanel.ShowPanel();}}

主界面挂载脚本 MainPanel.cs,拖拽相应物体

usingSystem.Collections;usingSystem.Collections.Generic;usingUnityEngine;usingUnityEngine.UI;publicclassMainPanel:MonoBehaviour{/// <summary>/// 红色小车物体/// </summary>publicRedCarredCar;/// <summary>/// 分数文本/// </summary>publicTextscoreText;// Start is called before the first frame updatevoidStart(){}// Update is called once per framevoidUpdate(){}/// <summary>/// 点击按钮向左移动/// </summary>publicvoidOnLeftMoveClick(){redCar.moveDirection=-1;}/// <summary>/// 点击按钮向右移动/// </summary>publicvoidOnRightMoveClick(){redCar.moveDirection=1;}}

2.4 黄色小车自动向下移动

黄色小车挂载脚本 YellowCar.cs

usingSystem.Collections;usingSystem.Collections.Generic;usingUnityEngine;publicclassYellowCar:MonoBehaviour{/// <summary>/// 移动速度/// </summary>privateintmoveSpeed=100;// Start is called before the first frame updatevoidStart(){}// Update is called once per framevoidUpdate(){transform.localPosition-=newVector3(0,moveSpeed*Time.deltaTime,0);//向下移动if(transform.localPosition.y<=-1060)Destroy(gameObject);//如果移动到屏幕最底端则自动销毁}}

2.5 红色小车与黄色小车碰撞则游戏结束

红色小车挂载组件 Box Collider 2D 和 Rigidbody 2D

黄色小车挂载组件 Box Collider 2D

结束界面挂载脚本 OverPanel.cs

usingSystem.Collections;usingSystem.Collections.Generic;usingUnityEngine;usingUnityEngine.SceneManagement;usingUnityEngine.UI;publicclassOverPanel:MonoBehaviour{/// <summary>/// 分数文本/// </summary>publicTextscoreText;// Start is called before the first frame updatevoidStart(){}// Update is called once per framevoidUpdate(){}/// <summary>/// 显示面板/// </summary>publicvoidShowPanel(){Time.timeScale=0f;//游戏暂停gameObject.SetActive(true);}/// <summary>/// 点击按钮重新开始游戏/// </summary>publicvoidOnRestartClick(){Time.timeScale=1f;//游戏恢复gameObject.SetActive(false);SceneManager.LoadScene(0);}}

GameManager.cs 新增结束界面变量

publicclassGameManager:MonoBehaviour{/// <summary>/// 游戏管理器实例/// </summary>publicstaticGameManagerinsta;/// <summary>/// 主界面/// </summary>publicMainPanelmainPanel;/// <summary>/// 结束界面/// </summary>publicOverPaneloverPanel;...

2.6 更新界面分数

主界面

...publicclassMainPanel:MonoBehaviour{/// <summary>/// 红色小车物体/// </summary>publicRedCarredCar;/// <summary>/// 分数文本/// </summary>publicTextscoreText;/// <summary>/// 分数数值/// </summary>publicintscore;/// <summary>/// 开始时间/// </summary>privatefloatstartTime;// Start is called before the first frame updatevoidStart(){startTime=Time.time;}// Update is called once per framevoidUpdate(){//更新分数score=(int)(Time.time-startTime);scoreText.text="分数:"+score;}...

结束界面

...publicclassOverPanel:MonoBehaviour{/// <summary>/// 分数文本/// </summary>publicTextscoreText;// Start is called before the first frame updatevoidStart(){}// Update is called once per framevoidUpdate(){scoreText.text="分数:"+GameManager.insta.mainPanel.score;}...

2.7 通过预设随机生成黄色小车

创建黄色小车根目录

.../// <summary>/// 创建黄色小车上一次时间/// </summary>privatefloatlastTime;/// <summary>/// 黄色小车物体预设/// </summary>publicGameObjectpreYellowCarGo;/// <summary>/// 黄色小车根目录/// </summary>publicGameObjectyellowCarRootGo;// Start is called before the first frame updatevoidStart(){startTime=Time.time;lastTime=Time.time;}// Update is called once per framevoidUpdate(){//更新分数score=(int)(Time.time-startTime);scoreText.text="分数:"+score;//每过3秒生成一辆黄色小车if(Time.time-lastTime>=3f){CreateYellowCar();lastTime=Time.time;}}/// <summary>/// 点击按钮向左移动/// </summary>publicvoidOnLeftMoveClick(){redCar.moveDirection=-1;}/// <summary>/// 点击按钮向右移动/// </summary>publicvoidOnRightMoveClick(){redCar.moveDirection=1;}/// <summary>/// 创建黄色小车/// </summary>privatevoidCreateYellowCar(){//在x坐标为-490到490之间随机生成黄色小车GameObjectyellowCarGo=Instantiate(preYellowCarGo,yellowCarRootGo.transform);intrandomInt=Random.Range(-490,490);yellowCarGo.transform.localPosition=newVector3(randomInt,1060,0);}}

2.8 添加音频

创建游戏中音频物体

.../// <summary>/// 黄色小车根目录/// </summary>publicGameObjectyellowCarRootGo;/// <summary>/// 游戏进行中音频/// </summary>publicAudioSourcegameInAudioSource;// Start is called before the first frame updatevoidStart(){startTime=Time.time;// 开始时间赋值lastTime=Time.time;// 创建黄色小车上一次时间赋值gameInAudioSource.Play();//播放游戏进行音乐}...

创建游戏结束音频物体

.../// <summary>/// 游戏技术音频/// </summary>publicAudioSourcegameOverAudioSource;.../// <summary>/// 显示面板/// </summary>publicvoidShowPanel(){Time.timeScale=0f;//游戏暂停gameObject.SetActive(true);//停止游戏进行音频,播放游戏结束音频if(GameManager.insta.mainPanel.gameInAudioSource.isPlaying){GameManager.insta.mainPanel.gameInAudioSource.Stop();}gameOverAudioSource.Play();}...

2.9 物体换皮

3.完整代码

GameManager

usingSystem.Collections;usingSystem.Collections.Generic;usingUnityEngine;publicclassGameManager:MonoBehaviour{/// <summary>/// 游戏管理器实例/// </summary>publicstaticGameManagerinsta;/// <summary>/// 主界面/// </summary>publicMainPanelmainPanel;/// <summary>/// 结束界面/// </summary>publicOverPaneloverPanel;privatevoidAwake(){insta=this;}// Start is called before the first frame updatevoidStart(){}// Update is called once per framevoidUpdate(){}}

MainPanel

usingSystem.Collections;usingSystem.Collections.Generic;usingUnityEngine;usingUnityEngine.UI;publicclassMainPanel:MonoBehaviour{/// <summary>/// 红色小车物体/// </summary>publicRedCarredCar;/// <summary>/// 分数文本/// </summary>publicTextscoreText;/// <summary>/// 分数数值/// </summary>publicintscore;/// <summary>/// 开始时间/// </summary>privatefloatstartTime;/// <summary>/// 创建黄色小车上一次时间/// </summary>privatefloatlastTime;/// <summary>/// 黄色小车物体预设/// </summary>publicGameObjectpreYellowCarGo;/// <summary>/// 黄色小车根目录/// </summary>publicGameObjectyellowCarRootGo;/// <summary>/// 游戏进行中音频/// </summary>publicAudioSourcegameInAudioSource;// Start is called before the first frame updatevoidStart(){startTime=Time.time;// 开始时间赋值lastTime=Time.time;// 创建黄色小车上一次时间赋值gameInAudioSource.Play();//播放游戏进行音乐}// Update is called once per framevoidUpdate(){//更新分数score=(int)(Time.time-startTime);scoreText.text="分数:"+score;//每过3秒生成一辆黄色小车if(Time.time-lastTime>=3f){CreateYellowCar();lastTime=Time.time;}}/// <summary>/// 点击按钮向左移动/// </summary>publicvoidOnLeftMoveClick(){redCar.moveDirection=-1;}/// <summary>/// 点击按钮向右移动/// </summary>publicvoidOnRightMoveClick(){redCar.moveDirection=1;}/// <summary>/// 创建黄色小车/// </summary>privatevoidCreateYellowCar(){//在x坐标为-490到490之间随机生成黄色小车GameObjectyellowCarGo=Instantiate(preYellowCarGo,yellowCarRootGo.transform);intrandomInt=Random.Range(-490,490);yellowCarGo.transform.localPosition=newVector3(randomInt,1060,0);}}

OverPanel

usingSystem.Collections;usingSystem.Collections.Generic;usingUnityEngine;usingUnityEngine.SceneManagement;usingUnityEngine.UI;publicclassOverPanel:MonoBehaviour{/// <summary>/// 分数文本/// </summary>publicTextscoreText;/// <summary>/// 游戏技术音频/// </summary>publicAudioSourcegameOverAudioSource;// Start is called before the first frame updatevoidStart(){}// Update is called once per framevoidUpdate(){scoreText.text="分数:"+GameManager.insta.mainPanel.score;}/// <summary>/// 显示面板/// </summary>publicvoidShowPanel(){Time.timeScale=0f;//游戏暂停gameObject.SetActive(true);//停止游戏进行音频,播放游戏结束音频if(GameManager.insta.mainPanel.gameInAudioSource.isPlaying){GameManager.insta.mainPanel.gameInAudioSource.Stop();}gameOverAudioSource.Play();}/// <summary>/// 点击按钮重新开始游戏/// </summary>publicvoidOnRestartClick(){Time.timeScale=1f;//游戏恢复gameObject.SetActive(false);SceneManager.LoadScene(0);}}

RedCar

usingSystem.Collections;usingSystem.Collections.Generic;usingUnityEngine;publicclassRedCar:MonoBehaviour{/// <summary>/// 移动速度/// </summary>privateintmoveSpeed=100;/// <summary>/// 移动方向/// </summary>publicintmoveDirection=0;// Start is called before the first frame updatevoidStart(){}// Update is called once per framevoidUpdate(){//屏幕范围内左右移动if(moveDirection==-1&&transform.localPosition.x<=-490)return;if(moveDirection==1&&transform.localPosition.x>=490)return;transform.localPosition+=newVector3(moveDirection*moveSpeed*Time.deltaTime,0,0);}/// <summary>/// 碰撞显示结束界面/// </summary>/// <param name="collision"></param>privatevoidOnTriggerEnter2D(Collider2Dcollision){GameManager.insta.overPanel.ShowPanel();}}

YellowCar

usingSystem.Collections;usingSystem.Collections.Generic;usingUnityEngine;publicclassYellowCar:MonoBehaviour{/// <summary>/// 移动速度/// </summary>privateintmoveSpeed=100;// Start is called before the first frame updatevoidStart(){}// Update is called once per framevoidUpdate(){transform.localPosition-=newVector3(0,moveSpeed*Time.deltaTime,0);//向下移动if(transform.localPosition.y<=-1060)Destroy(gameObject);//如果移动到屏幕最底端则自动销毁}}
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/15 10:00:48

Docker镜像迁移指南

Docker镜像迁移指南 背景 在使用docker时&#xff0c;可能没办法在目标机器上使用 docker pull&#xff0c;此时最通用的解决方案是用中转机&#xff0c;在那里下载镜像并打包成文件&#xff0c;然后将文件拷贝到你的目标 Ubuntu 系统上进行加载。第一阶段&#xff1a;在中转机…

作者头像 李华
网站建设 2026/6/16 1:25:54

在基于FastAPI的Python开发框架后端,增加阿里云短信和邮件发送通知处理

1、短信通知处理的介绍 之前我在多篇随笔中介绍过基于.NET的《SqlSugar开发框架》中整合过短信接入的内容&#xff1a;《使用阿里云的短信服务发送短信》、《基于SqlSugar的开发框架循序渐进介绍&#xff08;17&#xff09;-- 基于CSRedis实现缓存的处理》、《循序渐进VUEElem…

作者头像 李华
网站建设 2026/6/14 18:08:23

Langflow终极指南:从零构建企业级AI绘画工作流完整方案

Langflow终极指南&#xff1a;从零构建企业级AI绘画工作流完整方案 【免费下载链接】langflow ⛓️ Langflow is a visual framework for building multi-agent and RAG applications. Its open-source, Python-powered, fully customizable, model and vector store agnostic.…

作者头像 李华
网站建设 2026/6/10 15:40:11

Solon Web 的“分身术”:单应用多端口监听,化身多重服务

一、概述常规 Solon Web 应用通常采用单一端口提供服务。然而在实际业务场景中&#xff0c;我们往往需要单个应用具备"多面服务"能力&#xff1a;在不同端口上提供功能完全独立的服务模块。典型应用场景&#xff1a;外部 API 服务 内部监控端口&#xff1a;对外提供…

作者头像 李华
网站建设 2026/6/15 10:05:31

LFM2-350M-ENJP-MT:颠覆性边缘AI翻译技术的终极解决方案

LFM2-350M-ENJP-MT&#xff1a;颠覆性边缘AI翻译技术的终极解决方案 【免费下载链接】LFM2-350M-ENJP-MT 项目地址: https://ai.gitcode.com/hf_mirrors/LiquidAI/LFM2-350M-ENJP-MT 在AI模型普遍追求千亿参数的时代&#xff0c;一款仅3.5亿参数的翻译模型如何在边缘设…

作者头像 李华
网站建设 2026/6/11 17:03:43

GIM图像匹配终极指南:5分钟快速上手通用匹配技术

GIM图像匹配终极指南&#xff1a;5分钟快速上手通用匹配技术 【免费下载链接】gim GIM: Learning Generalizable Image Matcher From Internet Videos (ICLR 2024 Spotlight) 项目地址: https://gitcode.com/gh_mirrors/gim1/gim GIM&#xff08;Generalizable Image Ma…

作者头像 李华