Unity3D基础案例-双人坦克
引言:小生今日分享的是双人坦克大战,这也是Unity的官方案例。
开发版本:unity 5.3.5f
适合人群:初学Unity者
源文件链接请见文末!
开启学习之旅吧!
玩法:双方分别用WSAD键或上下左右键来控制两个坦克移动,用空格键或回车键来控制发射炮弹,当一方血条为0,则重新开始
01 场景搭建
新建3D工程TankWar,新建MainScene场景,导入Assets资源,将Prefabs文件夹中LevelArt预制体拖入场景中。
场景预制体中已经包含方向光,可以将场景原有的方向光删除。
如果出现如下场景,由于渲染原因
Window-lighting窗口 build一下场景 等右下的进度结束就可了,时间稍微有点长~
02 开发坦克
将Models中Tank模型拖入场景,并设为预制体,标签设置为Play
注意,对场景中的Tank进行一些操作后,需要Apply一下,才可以将这些操作映射到其他预制体上。
给Tank添加BoxCollider,并对Collider大小进行调节,可以切换到正交视图进行调节
刚体需要冻结Y轴移动,X轴和Z轴的旋转
为Tank添加拖尾效果,将Prefabs文件夹中的DustTrail粒子特效,放在Tank左右后轮
将拖尾粒子特效分别作为左右后轮的子物体,方便随Tank一起移动
在Tank身上挂载TankController.cs脚本
添加Move方法,在FixedUpdate()内调用,FixedUpdate是固定帧时间调用
void Move(){//Input.GetAxis("Vertical")在键盘按下W/S键或上下键时候,会返回范围在-1到1的值float v = Input.GetAxis("Vertical");//修改刚体速度,transform.forward控制物体在Z轴移动_rigidbody.velocity = transform.forward * v * speed;//Input.GetAxis("Horizontal")在键盘按下A/D键或左右键时候,会返回范围在-1到1的值float h = Input.GetAxis("Horizontal");//angularVelocity是刚体角速度向量,可以控制物体旋转,transform.up是物体旋转的轴_rigidbody.angularVelocity = transform.up * h * rotateSpeed;}
03 开发子弹
控制Tank子弹发射
Models文件夹中的Shell拖入场景,添加Rigidbody和CapsuleCollider,并设为预制体
为坦克添加一个发射子弹的位置ShootPos,设为Tank的子物体,要注意这个位置不要在坦克自身的碰撞体内
在PlayerController.cs中添加发射子弹的方法Attack(),在FixedUpdate()方法内调用
void Attack(){//发射键_keyCode可以在Inspector面板设置if (Input.GetKeyDown(_keyCode)){//在发射位置ShootPos实例化子弹GameObject go = GameObject.Instantiate(shellPrefab, shootPos.position, shootPos.rotation) as GameObject;//方法一:可以通过修改刚体速度//go.GetComponent<Rigidbody>().velocity = go.transform.forward * shellSpeed;//方法二:可以给物体添加一个方向的力go.GetComponent<Rigidbody>().AddForce(go.transform.forward * shellSpeed);}}
可以玩家一设置发射键为空格键,玩家二设置发射键为回车键
在子弹身上挂载脚本ShellController.cs
public class ShellController : MonoBehaviour
{//prefabs文件夹中的爆炸预设public GameObject explosionPrefabs;private void OnTriggerEnter(Collider other){//实例化爆炸效果,并赋值给go GameObject go = GameObject.Instantiate(explosionPrefabs, transform.position, transform.rotation) as GameObject;//在爆炸效果实例化1.5s后销毁,因为这个爆炸效果的时长就是1.5sDestroy(go, 1.5f);//立即销毁该子弹Destroy(this.gameObject);//如果子弹碰到的是坦克,则调用对象身上的TakeDamage()方法if (other.CompareTag("Player")){//SendMessage()消息推送,可以调用该对象身上的私有或公有方法other.SendMessage("TakeDamage");}}
}
TakeDamage()方法请看下文。
04 优化坦克控制
由于游戏中需要有两个坦克,目前的代码会让两个Tank控制方式一致
我们希望一台Tank由WSAD键控制,另一台由上下左右来控制
在InputManager里添加两个新的虚拟键
Edit-Project Setting-Input
将原有的Horizontal右键复制两个新的,并修改名称和监听按键
Vertical同样的操作
我们根据不同的虚拟键名来分别控制两个Tank
新建一个枚举类型,用来区别操作方式
public enum Player
{Player01,Player02
}//public可以外部设置,默认为玩家一public Player player = Player.Player01;private int PlayerNum = 1;private Rigidbody _rigidbody;private void Start(){_rigidbody = gameObject.GetComponent<Rigidbody>();switch (player){case Player.Player01:PlayerNum = 1;_keyCode = KeyCode.Space;break;case Player.Player02:PlayerNum = 2;_keyCode = KeyCode.Return;break;}}private void FixedUpdate(){Move();//Attack();}void Move(){float v = Input.GetAxis("VerticalPlayer0" + PlayerNum);float h = Input.GetAxis("HorizontalPlayer0" + PlayerNum);_rigidbody.velocity = transform.forward * v * speed;_rigidbody.angularVelocity = transform.up * h * rotateSpeed;}
在Inspector面板,玩家一可以设置为Player01,玩家二可以设置为Player02
修改两个坦克的颜色,可以将Materials文件夹中的不同颜色材质直接拖到场景中坦克对象上即可
05 摄像机跟随
public class CamFellowPlayer : MonoBehaviour
{public Transform player1;public Transform player2;public float maxSize = 20f;public float minSize = 6.5f;private Vector3 offset;private float ratio;private float distance;private void Start(){//计算摄像机距离两个坦克中心点的偏差值offset = transform.position - (player1.position + player2.position) / 2f;//计算初始的两个坦克的距离distance = Vector3.Distance(player1.position, player2.position);//计算初始正交大小和初始Tank距离的比例ratio = minSize / distance;}private void Update(){//防止因为坦克销毁后报错if (player1!=null&&player2!=null){transform.position = (player1.position + player2.position) / 2f + offset;distance = Vector3.Distance(player1.position, player2.position);//计算当前的坦克距离和比例的乘积,则得到当前的正交大小float size = distance * ratio;//Mathf.Clamp可以限制Size的值在minSize和maxSize之间size = Mathf.Clamp(size, minSize, maxSize);//将得到的size赋值给主摄像机的正交大小//Camera.main返回的是主摄像机Camera.main.orthographicSize = size;}}
}
06 计算伤害并设计血条
为tank添加脚本TankHealth.cs
我们使用UGUI的滑动条来设计血条
因为涉及到UGUI一些知识,我先将血条做成了预制体
注意别忘记在Inspector面板,把血条hpSlider赋值
public class TankHealth : MonoBehaviour
{//设计血量为100,可以在Inspector面板调整public int hp = 100;//prefabs文件夹中的坦克爆炸效果预设public GameObject tankExplosion;public Slider hpSlider;private int hpTotal;private void Start(){//初始化hpTotalhpTotal = hp;}private void TakeDamage(){//如果当前hp值已经低于0,则返回if (hp <= 0) return;hp -= Random.Range(10, 20);//根据当前的hp和总血量hpTotal的比值还赋予滑动条的值hpSlider.value = (float)hp / hpTotal;//受到伤害之后,血量为零,则实例化爆炸效果,并销毁该坦克if (hp<=0){//transform.position + Vector3.up因为坦克的中心点在坦克的底部,可以向上偏移一米,爆炸效果更好GameObject.Instantiate(tankExplosion, transform.position + Vector3.up, transform.rotation);//销毁该坦克对象Destroy(this.gameObject);//重新加载当前场景UnityEngine.SceneManagement.SceneManager.LoadScene("MainScene");}}
}
至此,游戏基本开发完成,如果觉得单调可以加一些音乐音效,可以参照我之前的案例,就不在此赘述啦!
喜欢我的,就关注我吧,你的关注,就是我的动力!
素材及工程链接:百度云盘链接 密码:ly74
Unity3D基础案例-双人坦克相关推荐
- Unity3D基础案例-双人乒乓
引言:人生无处不代码,无代码处不人生.今天给大家分享双人打乒乓游戏的主要开发流程. 开发版本:unity 5.3.5f 适合人群:初学Unity者 源文件链接请见文末! 开启学习之旅吧! 游戏效果预览 ...
- Unity3D基础案例-见缝插针
引言:人生无处不代码,无代码处不人生.小生作为U3D学习之旅中的一员,将基础案例主要开发流程记录下来,与共同兴趣的你分享. 开发版本:unity 5.3.5f 适合人群:初学Unity者 源文件链接请 ...
- Unity3D基础入门之粒子系统(属性介绍+火焰粒子系统案例制作)
Unity3D基础入门之粒子系统(属性介绍+火焰粒子系统案例制作) 一.属性介绍 1.主面板Particle System (1)Duration:粒子发射周期 图中,5.00即在发射5秒后进入下一个 ...
- 双人坦克大战 - Unity3D
一个简单的双人坦克游戏(3D). GitHub https://github.com/SSGamble/TanksGame 文章目录 总结 创建场景 创建坦克 添加脚本控制坦克移动 双人操作坦克 控制 ...
- 【初阶】unity3d官方案例_太空射击SpacingShooter 学习笔记 显示分数时,如何让函数之间相互交流...
[初阶]unity3d官方案例_太空射击SpacingShooter 学习笔记 显示分数时,如何让函数之间相互交流 一.关于 显示分数时,如何让函数之间相互交流 这是一个非常好的逻辑问题 1 思路:主 ...
- 【Unity3D基础教程】给初学者看的Unity教程(四):通过制作Flappy Bird了解Native 2D中的RigidBody2D和Collider2D...
作者:王选易,出处:http://www.cnblogs.com/neverdie/ 欢迎转载,也请保留这段声明.如果你喜欢这篇文章,请点[推荐].谢谢! 引子 在第一篇文章[Unity3D基础教程] ...
- TF学习:Tensorflow基础案例、经典案例集合——基于python编程代码的实现
TF学习:Tensorflow基础案例.经典案例集合--基于python编程代码的实现 目录 Tensorflow的使用入门 1.TF:使用Tensorflow输出一句话 2.TF实现加法 3.TF实 ...
- mysql核心数据库_从MySQL基础进军MySQL核心架构 178集MySQL数据库核心基础视频教程 MySQL基础案例教程...
从MySQL基础进军MySQL核心架构 178集MySQL数据库核心基础视频教程 MySQL基础案例教程 课程目录 (1) 01MySQL基础_课程引入.avi (2) 02MySQL基础_为什么学习 ...
- JQuery-学习笔记04【基础——JQuery基础案例】
Java后端 学习路线 笔记汇总表[黑马程序员] JQuery-学习笔记01[基础--JQuery基础]--[day01] JQuery-学习笔记02[基础--JQuery选择器] JQuery-学习 ...
最新文章
- 没有执行力,谈什么目标理想?
- feign 请求超时,请求没有到服务端
- 模糊数学笔记:五、模糊聚类
- 用JavaScript玩转游戏物理(一)运动学模拟与粒子系统
- Grid++Report问题集!
- android.view.InflateException: Binary XML file line #34: Error inflating class
- System.FormatException: GUID 应包含带 4 个短划线的 32 位数(xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)。...
- c++byte数组和文件的相互转换_终于!word、excel、ppt文件相互转换技巧来了!
- 到底绿茶能不能减肥瘦小肚子? - 生活至上,美容至尚!
- C++跨平台开发——SOCKET网络编程中实现客户端对聊
- stc15w4k32s4芯片引脚图片_STC15W4K32S4系列
- MyBatis批量的增删改查操作
- 获取电脑ip并输入微信发送
- 基于MATLAB的MIMO信道估计(附完整代码与分析)
- IOS10系统终于可以降级IOS9了,赶紧围观
- iTunes备份到电脑F盘
- Codevs 打鼹鼠
- 网络安全 中间人攻击-ARP欺骗 工具:Cain
- 【考研】(转载)考研数学高数公式知识点整理
- 用JS实现:图片压缩、图片加密
热门文章
- 基于ssm的志愿者招募网站设计与实现-计算机毕业设计源码+LW文档
- 常用的字符串函数strcpy(a,b) / strlen(a) / strcat(a,b)/ strcmp(a, b)/ strupr(a) /strlwr(a)
- Strusts框架学习(一)
- python做数据分析时缺失值填补、缺失值填充方法汇总
- 图像处理中的滤波器之均值滤波,中值滤波,高斯滤波
- temp = (temp 0x55555555) + ((temp 0xaaaaaaaa) 1)
- 一致 先验分布 后验分布_先验分布、后验分布、似然估计这几个概念是什么意思,它们之间的关系是什么?...
- Python实用案例
- 【微信小程序】生命周期
- 查询建立连接的IP地址