Unity项目 - 坦克大战3D TankBattle
目录
游戏原型
- 游戏玩法:在有界的战场上,玩家将驾驶坦克,代表绿色阵营,与你的队友一起击溃红蓝阵营的敌人,在这场三方大战中夺得胜利!
- 操作指南:
- 移动:WASD
- 开火:Space
- 第一/第三人称视角转换:PgDn
- 第三人称下的视角转动:← →
项目演示


Github项目地址:3D坦克大战 TankBattle
绘图资源
主要素材来源于官方Tanks教程中的Tanks!Tutorial素材包
- 战场搭建:直接使用素材包内的LevelArt即可,当然也可在此基础上修改、扩展
- 玩家:
- 物体:选用素材包内绿色坦克模型作为Player,除了模型外还包含子物体:发射点ShootPoint,第一人称摄像机FirstCamera,血条画布HealthCanvas
- 组件/脚本挂载:AudioSource,Tank.cs,TankWeapon.cs
- 敌人/队友:
- 物体:除了模型外还包含子物体血条画布HealthCanvas
- 组件/脚本挂载:AudioSource,NavMeshAgent,AITank.cs,TankWeapon.cs
- 相机:默认开局为第三人称视角
- ThirdCamera:采用Orthographic模式,作为TankCamera的子物体,在TankCamera挂载TankCamera.cs脚本进行控制
- FirstCamera:采用Perspective模式,作为玩家坦克Player的子物体,调整适当位置及角度
- 阵营:
- 创建Layer:Ground、Players、Blue、Green、Red,并对应设置
- 将创建多个敌人归并于各自阵营的空物体下,本例为BlueEnemy,RedEnemy,GreenEnemy
- UI:
- 全局UI:建立Canvas,用于显示屏幕左下角玩家血量,及左侧操作指导,此外还包括死亡、胜利等UI
- 坦克外围血条UI:新建HealthCanvas,包含血量背景条Health Background及实时血条HealthSlider(素材均来自官方包内)。后将HealthCanvas设于各方坦克预制体下,调整合适大小、高度及显示方式
- 其他:
- 背景音乐:另设空物体BackGroundMusic添加AudioSource,开始时即循环播放
- GameManager空物体:挂载GameManager.cs及全局UI的脚本UI.cs
- 导航网络烘培:Window->AI->navigation内设置
- 坦克残骸:另取坦克模型保留基本的物件,修改为灰暗色,修改BoxCollider保持间隔不相互碰撞,添加素材包内TankExplosion爆炸特效。死亡后实现爆冲力将各部件被冲散

代码实现
| 脚本名 | 挂载于 | 功能 |
|---|---|---|
| shell.cs | 炮弹Shell预制体 | 实现发射的炮弹的爆炸(特效,冲击力,销毁炮弹) |
| TankWeapon.cs | 所有坦克的预制体 | 实现坦克发射炮弹的过程(实例化炮弹,赋予初速度,开火声,炮弹冷却) |
| Tank.cs | 玩家Player | 实现玩家与坦克的交互(前后左右移动,空格开火) |
| TankCamera.cs | TankCamera | 实现第三人视角跟随玩家坦克移动,且还进行第一/第三人称视角的切换控制 |
| Unit.cs | 作为Tank.cs和AItank.cs的父类 | 实现所有坦克的基本属性(阵营,血量,死亡爆炸特效,伤害计算) |
| AITank.cs | 除玩家外的所有坦克预制体 | 实现npc坦克的功能(设置阵营、搜索敌人、自动导航、攻击、自身血条UI) |
| UI.cs | GameManager | 实现主界面下玩家的血条UI及玩家坦克外围的血条UI,胜利及失败UI,此外还有胜利判定 |
| LayerManager.cs | 设置静态方法供其他脚本调用 | 实现设置阵营(设置Layer)的函数 |
| GameManager.cs | GameManager | 判定玩家是否死亡,若死亡则重置游戏 |
技术探讨
1.炮弹实现射出的方法:
- 赋予炮弹初速度:
ShellRigidbody.velocity = shootPoint.forward * shootPower;,(本例方案) - 施加力:
ShellRigidbody.AddForce(shootPoint.forward * shootPower * 50f);
2.开火时炮弹的实例化位置:
- 产生问题:运动中开火时,实例化的炮弹与自身碰撞
- 问题分析:炮弹发射机理就是炮弹shell在炮口前一定位置实例化并赋予初速度,但是坦克也存在移动,因此假若距离较近,坦克移动速度较快时,容易造成实例化的炮弹立即与自身碰撞
- 解决方案:需要留意位置调整、角度及坦克运动速度,本例实例化炮弹位置即为shootPoint的position
3.AI坦克对敌判定
- 产生问题:原思路想采用射线检测来判定前面一定范围是否存在敌人,即
if (hit.collider.gameObject.layer == enemy.layer),但现象是:敌人/队友是否开火呈随机发生,无规律 - 问题分析:射线检测到的一直是tank上的部件,而那些部件物体不是enemy,if不满足无法进行射击
- 解决方案:在AITank.cs脚本内另设SearchEnemy()函数,功能是搜索返回距离自己最近的敌人;在Update内首先导航跟踪这个敌人,然后判断当这个搜索到的敌人在开火范围内即可开火,否则重新SearchEnemy(),详细描述见脚本内注释
4.AI坦克导航:
- 产生问题:敌人及队友坦克的NavMeshAgent导航混乱
- 问题分析:很大原因在于导航网络的烘培,及NavMeshAgent的参数设置
- 解决方案:方法就是合理设置Navigation内的各项参数及NavMashAgent上的参数,也可直接采用官方教程视频内的参数
5.第一人称视角:
- 产生问题:玩家在第一人称视角下被销毁是报错,第一人称视角消失,再无法切换视角
- 问题分析:FirstCamera挂载于Player,当玩家死亡时Player销毁,造成FirstCamera的销毁
- 解决方案:在TankCamera.cs内添加判定,若玩家不存在则启用第三人称视角相机
- 理想方案:两个视角的相机都挂载在物体TankCamera上,统一由本脚本使用;FirstCamera不仅跟随Player正常移动、旋转,且不会在玩家死亡时销毁;该方案暂未较好实现
参考来源
- Unity3D坦克大战项目实例 - TRULYSPINACH
- Unity设置物体旋转角度误区 - feng
- Unity3D中的Layers和LayerMask解析 - AaronBlogs
- Unity3D射线碰撞检测+LayerMask的使用 - 丁小未
- Tanks - unityLearn
- Tanks!Tutorial - unityAssetStore
Unity项目 - 坦克大战3D TankBattle的更多相关文章
- Java小项目--坦克大战(version1.0)
Java小项目--坦克大战<TankWar1.0> 这个小项目主要是练习j2se的基础内容和面向对象的思想.项目实现了基本的简单功能,我方一辆坦克,用上下左右键控制移动方向,按F键为发射炮 ...
- 《杜增强讲Unity之Tanks坦克大战》1-准备工作
0.案例介绍 0.1开始界面 点击Play Now 进入游戏界面 左边的坦克使用ws控制前后移动,ad键左右旋转,空格键开火 右边的坦克使用方向键上下控制前后移动,方向键左右键实现左右旋转 ...
- 《杜增强讲Unity之Tanks坦克大战》2-场景设置
2 场景设置 2.1 本节效果预览 2.2 项目目录设置 点击Project面板的Create按钮,在根目录下面新建wm文件夹 Wm文件夹用于存放我们自己生成的Prefab和脚本等其他资源, ...
- 3D坦克大战游戏源码
3D坦克大战游戏源码,该游戏是基于xcode 4.3,ios sdk 5.1开发.在xcode4.3.3上完美无报错.兼容ios4.3-ios6.0 ,一款ios平台上难得的3D坦克大战游戏源码,有2 ...
- 3D坦克大战游戏iOS源码
3D坦克大战游戏源码,该游戏是基于xcode 4.3,ios sdk 5.1开发.在xcode4.3.3上完美无报错.兼容ios4.3-ios6.0 ,一款ios平台上难得的3D坦克大战游戏源码,有2 ...
- 《杜增强讲Unity之Tanks坦克大战》10-相机控制
10 相机控制 本节主要学习如何控制相机自动调整位置和焦距,使两个坦克一直同时在视野内. image 在Hierarchy点击右键 image 点击 Create Empty,生成空对象,改名 ...
- 《杜增强讲Unity之Tanks坦克大战》11-游戏流程控制
11 游戏流程控制 使用协程来控制游戏流程 11.1 添加MessageText 首先添加一个Text来显示文字 image 设置GameMgr image 11.2 游戏整体流程 下面Gam ...
- 《杜增强讲Unity之Tanks坦克大战》9-发射子弹时蓄力
9 发射子弹时蓄力 实现效果如下 image 按下开火键(坦克1为空格键)重置力为最小力,一直按着的时候蓄力,抬起的时候发射.如果按着的时候蓄力到最大,则自动发射,此时在抬起则不会重复发射. 首先 ...
- 《杜增强讲Unity之Tanks坦克大战》4-坦克的移动和旋转
4 坦克移动和旋转 本节课的目标是实现同时wsad和上下左右控制两个坦克分别移动和旋转 4.1 本节代码预览 image 将上节课场景s2另存为s3. 4.2 添加车轮扬沙效果 从Prefabs里 ...
随机推荐
- 洛谷P2877 [USACO07NOV]防晒霜Sunscreen
题目 此题有多种贪心方法. 首先简化题意: 有几个在数轴上的区间,和几个在数轴上确定的位置的点,问用这些数目的点,最多能满足多少个区间里有点. 注意:此题跟区间选点问题不一样,每个点只能满足一个区间, ...
- mysql 字段添加以及删除
mysql> select * from user; +------+-----------+-----------+ | id | name | address | +------+----- ...
- 【2019.11.18】SDN阅读作业
为什么需要SDN?SDN特点? 随着网络的快速发展,传统互联网出现了如传统网络配置复杂度高等诸多问题,这些问题说明网络架构需要革新,可编程网络的相关研究为 SDN 的产生提供了可参考的理论依据 SDN ...
- CodeMirror在线代码编辑器使用
CodeMirror官网地址为:https://codemirror.net/ CodeMirror作为一款代码编辑器,其应用场景主要是在线网站写代码.如现在的leetcode.洛谷.code-vs等 ...
- rust控制流
fn main() { let number = 6; if number % 4 == 0 { println!("number is divisible by 4"); } e ...
- ·分布式文件系统HDFS 练习
作业要求来源于:https://edu.cnblogs.com/campus/gzcc/GZCC-16SE2/homework/3292 1.目录操作 在HDFS中为hadoop用户创建一个用户目录( ...
- how does SELECT TOP works when no order by is specified?
how does SELECT TOP works when no order by is specified? There is no guarantee which two rows you ge ...
- 啃OBS源码-界面汉字
插件对应该字体目录:D:\project\vs\obs\obsstudio21.12\build\rundir\Debug\data\obs-plugins obs对应该字体目录:D:\project ...
- Bi-Directional ConvLSTM U-Net with Densley Connected Convolutions
Bi-Directional ConvLSTM U-Net with Densley Connected Convolutions ICCV workshop 2019 2019-09-15 11 ...
- Activiti task claim concurrent
Activiti task claim cocurrent - 国内版 Binghttps://cn.bing.com/search?q=Activiti+task+claim+cocurrent&a ...