引言:小生今日分享的是双人坦克大战,这也是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基础案例-双人坦克相关推荐

  1. Unity3D基础案例-双人乒乓

    引言:人生无处不代码,无代码处不人生.今天给大家分享双人打乒乓游戏的主要开发流程. 开发版本:unity 5.3.5f 适合人群:初学Unity者 源文件链接请见文末! 开启学习之旅吧! 游戏效果预览 ...

  2. Unity3D基础案例-见缝插针

    引言:人生无处不代码,无代码处不人生.小生作为U3D学习之旅中的一员,将基础案例主要开发流程记录下来,与共同兴趣的你分享. 开发版本:unity 5.3.5f 适合人群:初学Unity者 源文件链接请 ...

  3. Unity3D基础入门之粒子系统(属性介绍+火焰粒子系统案例制作)

    Unity3D基础入门之粒子系统(属性介绍+火焰粒子系统案例制作) 一.属性介绍 1.主面板Particle System (1)Duration:粒子发射周期 图中,5.00即在发射5秒后进入下一个 ...

  4. 双人坦克大战 - Unity3D

    一个简单的双人坦克游戏(3D). GitHub https://github.com/SSGamble/TanksGame 文章目录 总结 创建场景 创建坦克 添加脚本控制坦克移动 双人操作坦克 控制 ...

  5. 【初阶】unity3d官方案例_太空射击SpacingShooter 学习笔记 显示分数时,如何让函数之间相互交流...

    [初阶]unity3d官方案例_太空射击SpacingShooter 学习笔记 显示分数时,如何让函数之间相互交流 一.关于 显示分数时,如何让函数之间相互交流 这是一个非常好的逻辑问题 1 思路:主 ...

  6. 【Unity3D基础教程】给初学者看的Unity教程(四):通过制作Flappy Bird了解Native 2D中的RigidBody2D和Collider2D...

    作者:王选易,出处:http://www.cnblogs.com/neverdie/ 欢迎转载,也请保留这段声明.如果你喜欢这篇文章,请点[推荐].谢谢! 引子 在第一篇文章[Unity3D基础教程] ...

  7. TF学习:Tensorflow基础案例、经典案例集合——基于python编程代码的实现

    TF学习:Tensorflow基础案例.经典案例集合--基于python编程代码的实现 目录 Tensorflow的使用入门 1.TF:使用Tensorflow输出一句话 2.TF实现加法 3.TF实 ...

  8. mysql核心数据库_从MySQL基础进军MySQL核心架构 178集MySQL数据库核心基础视频教程 MySQL基础案例教程...

    从MySQL基础进军MySQL核心架构 178集MySQL数据库核心基础视频教程 MySQL基础案例教程 课程目录 (1) 01MySQL基础_课程引入.avi (2) 02MySQL基础_为什么学习 ...

  9. JQuery-学习笔记04【基础——JQuery基础案例】

    Java后端 学习路线 笔记汇总表[黑马程序员] JQuery-学习笔记01[基础--JQuery基础]--[day01] JQuery-学习笔记02[基础--JQuery选择器] JQuery-学习 ...

最新文章

  1. 没有执行力,谈什么目标理想?
  2. feign 请求超时,请求没有到服务端
  3. 模糊数学笔记:五、模糊聚类
  4. 用JavaScript玩转游戏物理(一)运动学模拟与粒子系统
  5. Grid++Report问题集!
  6. android.view.InflateException: Binary XML file line #34: Error inflating class
  7. System.FormatException: GUID 应包含带 4 个短划线的 32 位数(xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)。...
  8. c++byte数组和文件的相互转换_终于!word、excel、ppt文件相互转换技巧来了!
  9. 到底绿茶能不能减肥瘦小肚子? - 生活至上,美容至尚!
  10. C++跨平台开发——SOCKET网络编程中实现客户端对聊
  11. stc15w4k32s4芯片引脚图片_STC15W4K32S4系列
  12. MyBatis批量的增删改查操作
  13. 获取电脑ip并输入微信发送
  14. 基于MATLAB的MIMO信道估计(附完整代码与分析)
  15. IOS10系统终于可以降级IOS9了,赶紧围观
  16. iTunes备份到电脑F盘
  17. Codevs 打鼹鼠
  18. 网络安全 中间人攻击-ARP欺骗 工具:Cain
  19. 【考研】(转载)考研数学高数公式知识点整理
  20. 用JS实现:图片压缩、图片加密

热门文章

  1. 基于ssm的志愿者招募网站设计与实现-计算机毕业设计源码+LW文档
  2. 常用的字符串函数strcpy(a,b) / strlen(a) / strcat(a,b)/ strcmp(a, b)/ strupr(a) /strlwr(a)
  3. Strusts框架学习(一)
  4. python做数据分析时缺失值填补、缺失值填充方法汇总
  5. 图像处理中的滤波器之均值滤波,中值滤波,高斯滤波
  6. temp = (temp 0x55555555) + ((temp 0xaaaaaaaa) 1)
  7. 一致 先验分布 后验分布_先验分布、后验分布、似然估计这几个概念是什么意思,它们之间的关系是什么?...
  8. Python实用案例
  9. 【微信小程序】生命周期
  10. 查询建立连接的IP地址