坦克大战小游戏,想必只要是能刷到这篇博客的,无一例外都是玩过这款经典童年游戏的。记得小时候每到放学或者周六日,都会一起聚到有影碟机的小伙伴家里,然后打开“屁股超级大”的电视机和影碟机,将游戏碟放进去、手柄插上去。这个时候哪怕一天不吃饭也能在电视机前坐一天。
尤其是坦克大战更是经典中的经典,小时候手残,最多打几关就打不过了。唉,真是又菜又爱玩。正好昨天逛博客的时候,发现了一位叫明世隐的大佬用Java写了一个坦克大战,真是又让我们回忆起了童年的味道呀。然后我就想着用Unity来做一个坦克大战的升级版——“坦克大战3D”版
先来看一下效果图,场景之类的就忽略我的UI能力哈哈,以后可以找个好点的场景,或者自己搭个地形,再搞个好看的UI就好啦。害,就是玩~
感觉这个游戏做起来应该不难,正好拿来一起练练手嘿,做之前先理一下思路。
首先,有一个主角坦克,那就是我们自己要控制的坦克啦~
有什么功能呢?当然是移动、转弯、打炮弹啦。这个时候可以考虑一下,既然是号称”3D升级版”,那是不是应该显得特别一点呢!那好,我们待会可以考虑给他加上跳跃(虽然感觉跳跃没啥用…但是这就是我们主角应该跟小兵不一样的地方!哈哈哈哈嗝。当然我们还要有生命,加血条或者打一下就嗝屁都行,这个看心情
其次要有敌方坦克,敌方坦克的话要在地图上随机生成,然后要给一个随机移动,还要有一个可以检测玩家的攻击范围,当然也要有生命值啦。还应该有炮弹,让我们的炮弹更霸气一点!地方的就弱一点哈哈~
然后就是该有一个游戏场景啦,可以在场景中加一些障碍物,也可以简单一点制作,我这里分别使用了一个Unity官方的坦克大战地形和自己搭建的一个,这个看心情叭~
好了,坦克大战中该有的元素都差不多了,接下来就是要动手操作啦!
首先,我们需要搭建一个游戏场景,我们的坦克们才能激情的对打呀!⛅️
那么我们就来随便搭建一个简陋的游戏场景
边缘围墙就是我们的边界,我们的坦克们就只能在场景里面玩耍啦
或者直接找个场景先放上就好啦
我们只需要一个简单的跟随主角坦克移动的相机就好啦,想要更复杂的可以参考我之前写的几种相机跟随方法哦。在这里就不多做研究了,只要能看到我们的坦克大杀四方就好啦~
Unity ❉ 使用心得 ☀️| Unity中 多种相机视角跟随方式 (第一、三人称都有哦,快来看看叭)☆(ゝω・)v
先添加我们的坦克预制体,主角坦克要给他加个Tag为Player,这样我们的坦克就有一个属于自己的标志了。然后加上碰撞体和刚体,用来模拟物理效果。
因为我想让我们的坦克炮筒可以按照我们的鼠标方向进行旋转,所以又给炮筒单独写了个脚本用于转向和开炮操作的,然后脚本挂到炮筒上就好啦~~
敌方坦克,也要加碰撞体和刚体,因为敌方坦克的攻击范围逻辑我是用检测器来做的,然后检测到玩家后就转向玩家,开始触发开炮!
然后就是我方炮弹和敌方炮弹的预制体啦,需要给炮弹加上自己的标签用来区分,我这里是给自己的炮弹加了bullet,再挂上我们之前做的脚本就好啦,然后想弄怎样的炮弹就看我们的心情啦哈哈,我这炮弹怎么样,看着就霸气!!
炮弹图
游戏演示图
我做了两种版本,一个是炮筒不动的,一种是炮筒跟随鼠标移动的。上面演示的是鼠标不跟随的,然后给大家演示一下这个鼠标跟随的效果
游戏演示图
由于录制画面的图片太大,过了5M就上传不了了,所以只能展示部分效果,想看的可以自己导入工程看哦
这个工程源码,和我已经打包出来的apk都有,想要玩玩的可以下载试试呀
其实两种方式很好切换,只要把挂在炮筒上这个脚本的这行代码开启就可以跟随鼠标移动啦!
好了,简单说了一下在Unity引擎里操作,那接下来就是各部分代码的组成部分啦
刚才说了一下玩家坦克需要有的操作。玩家坦克移动、转身等。那就用代码来实现一下吧,下面就是简单的代码逻辑:
//挂在我们的主角坦克身上的
public class playerTank : MonoBehaviour
{
[Header("移动速度")]
public float movespeed = 5f;
[Header("转身速度")]
public float turnspeed = 5f;
[Header("炮弹预设体")]
public GameObject bulletPrefab;
private float hor, ver;
private Transform firePoint;
private GameObject crtBlt;
private Rigidbody rig;
private void Awake()
{
firePoint = transform.Find("Buttom/Top/Gun/firePoint");//获取炮筒位置
rig = GetComponent<Rigidbody>();//获取加速
}
void Update()
{
hor = Input.GetAxis("Horizontal");
ver = Input.GetAxis("Vertical");
//前后移动
transform.position += ver* transform.forward * Time.deltaTime * movespeed;
//左右转身
transform.eulerAngles += hor* Vector3.up * turnspeed;
}
}
因为我想要给我们的坦克的炮筒可以按照鼠标的方向进行单独旋转,所以就单独加了一个脚本,将开炮操作也加到炮筒上了,这个看自己心情,想怎么做就怎么做啦,就是玩儿!
//这是要挂在我方坦克炮筒上的代码
public class turnMouse : MonoBehaviour
{
[Header("炮弹预设体")]
public GameObject bulletPrefab;
[Header("连续发射炮弹时间间隔")]
public float continuousEmissionInterval = 0.1f;
public float rotionspeed = 1f;
private float timer = 0f;
private Ray ray;
private RaycastHit hit;
private Transform firePoint;
private GameObject crtBlt;
private void Awake()
{
firePoint = transform.Find("Top/Gun/firePoint");//获取炮筒位置
}
void Update()
{
//鼠标在屏幕的位置
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray,out hit))
{
Debug.DrawLine(Camera.main.transform.position,hit.point,Color.red);
}
Vector3 target = hit.point;//获取鼠标的位置
// target.y = transform.position.y;//将鼠标Y轴目标传给玩家
target.y = hit.point.y;
transform.LookAt(target);//保证目标是鼠标的Y轴
transform.eulerAngles += Vector3.up * rotionspeed;
ContinuousEmission();//发射炮弹
}
//连发
void ContinuousEmission()
{
if (Input.GetButton("Fire"))
{
timer += Time.deltaTime;//计时器计时
if (timer > continuousEmissionInterval)
{
//生成炮弹
crtBlt = Instantiate(bulletPrefab, firePoint.position,
Quaternion.identity);
crtBlt.GetComponent<bullet>().dir = transform.forward;
timer = 0;//计时器归零
}
}
}
然后是挂在敌方坦克身上的脚本,让他们可以随机移动转向,发现我们之后还会自动攻击!可得小心点,别把我们心爱的小坦克给打炸了~~
//挂在敌方坦克身上的代码
public class enemyTanks : MonoBehaviour
{
[Header("炮弹预设体")]
public GameObject bulletPrefab;
[Header("敌人坦克移动速度")]
public float moveSpeed = 1f;
[Header("敌人坦克旋转速度")]
public float turnSpeed = 1f;
[Header("寻路目标距离")]
public float attackDistance = 4;
[Header("寻路时的速度")]
public float moveStence = 0.05f;
private float times1 = 0f;//旋转计时器
private float times2 = 0f;//开火计时器
void tankmove()//坦克随机移动
{
transform.position += transform.forward * Time.deltaTime * moveSpeed;//坦克移动
if (timeInterval==true)
{
times1 += Time.deltaTime;
if(times1 > 3)
{
transform.localEulerAngles += Vector3.up * Random.Range(0,360)*turnSpeed;//坦克随机转弯
times1 = 0;
}
}
}
void CreateBullt() //生成炮弹
{
crtBlt = Instantiate(bulletPrefab,transform.position,
Quaternion.identity);
crtBlt.GetComponent<bulletTwo>().dir1 = transform.forward;
}
private void OnTriggerStay(Collider other)//30米以内转向玩家
{
if (other.transform.tag ==("Player"))
{
timeInterval = false;
Vector3 target = player.position;
target.y = transform.position.y;//将自身Y轴目标传给敌人
transform.LookAt(target);//保证敌人目标是自己的Y轴
transform.position += transform.forward * Time.deltaTime * moveStence;
times2 += Time.deltaTime;
if (times2 >= 3)
{
CreateBullt();//开炮
times2 = 0;
}
float distance = Vector3.Distance(target,transform.position);
if (distance<=attackDistance)
{
transform.position += transform.forward * moveStence*0;
}
}
}
}
然后要有一个控制随机生成敌方坦克的,控制游戏的进程
//挂在场景的GameObject上
public class randomEnemy : MonoBehaviour
{
[Header("敌方坦克预设体")]
public GameObject tanks;
private float times = 2f;
private GameObject tank;
private void produceTanks()
{
if (number <= 40)//控制坦克数量
{
times -= Time.deltaTime;//计算产生坦克时间
if (times < 0)
{
int lenth = Random.Range(0, 100);
int wide = Random.Range(0, 100);
Vector3 enemyposition = new Vector3(lenth, 1, wide);//随机位置
//产生坦克
tank = Instantiate(tanks, enemyposition, Quaternion.identity);
times = 1;//两秒产生一个坦克
} } }
还有玩家坦克炮弹和敌方坦克炮弹的代码,因为我这里是想让双方炮弹产生一个不同的效果才用了两个脚本。只是一种处理方法,也可以精简成一个脚本,然后通过定义个标签或者枚举之类的来区分双方炮弹也可以,这里就仅供参考嘿嘿_
//挂在我方打出的炮弹身上的
public class bullet : MonoBehaviour
{
// Start is called before the first frame update
[Header("移动速度")]
public float moveSpeed = 20;
//方向向量
public Vector3 dir;
void Update()
{
// transform.SetParent(null);
//位移
// transform.Translate(transform.forward * speed * Time.deltaTime);
transform.position += dir.normalized * Time.deltaTime * moveSpeed;
}
}
挂在敌方打出的炮弹身上的
public class bulletTwo : MonoBehaviour
{
[Header("移动速度")]
public float moveSpeed = 5f;
//方向向量
public Vector3 dir1;
void Start()
{
//延时销毁
Destroy(this.gameObject, 3f);
}
void Update()
{
transform.position += dir1 * Time.deltaTime * moveSpeed;
}
private void OnCollisionEnter(Collision collision)
{
if (collision.transform.tag=="Player")
{
Destroy(collision.gameObject);
Destroy(this.gameObject);
}
}
}
好了,以上差不多就是一个小游戏坦克大战3D版的简单开发思路和过程啦,因为时间不够多,就简单做成这样了。
最好可以找个牛逼克拉斯的场景配上就更完美啦,也可以用Photon或者socket做成可以进房间联机的就更好了
如果大家有需要的也可以评论说一下,以后如果有时间我也可以做成个可以联网的,然后把场景弄个好看的,再加几个UI做个小成品一起玩。嘿嘿!就是玩儿~
如果有想做但是对Unity引擎不熟悉的小伙伴,那就需要在网上找一些介绍基础引擎使用的文章啦,后续有时间我也会更新一些自己使用Unity的经验和基础知识。嘿嘿~~还要更加努力呀