unity零基础开始学习做游戏(四)biu~biu~biu发射子弹打飞机
-------小基原创,转载请给我一个面子
主角都能移动了,那不得做点什么伸张正义,守护世界和平的事嘛,拿起家伙biu~biu~biu~
首先得做一个好人和一个坏人
老规矩,Canvas下创建两个Image,一个叫做player,一个叫做enemy1好了
一个红色,一个蓝色(自古红蓝出CP,不好意思,走错片场了●﹏●)
新知识:要加BoxCollider2D
子弹打到别人,其实是碰撞检测的过程
一种是根据位置坐标,判断子弹有没有打中,另一种是使用物理碰撞系统(小基这里使用后者)
两个物体物理碰撞检测条件
1.物体A,物体B,必须都有Collider
2.运动的一方要有刚体(本例对应的是子弹,后面介绍)
最终效果是这样的。
下面开始制作子弹
Canvas下创建一个Image,修改名字叫做Bullet,使用自带的圆形图片凑合用吧
同样添加BoxCollider2D,最后切记添加RigidBody,不然没法碰撞成功
额外提一句,重力调成0吧,不然子弹抛物线飞=_=
现在看起来是这样的。
接下来想想怎么让子弹动起来,上代码(创建一个脚本Bullet),给那个子弹挂上
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- public class Bullet : MonoBehaviour {
- public float speed = ;
- public Vector2 dir = new Vector2(, );
- public float lifeTime = 5f;
- public float damage = ;
- // Use this for initialization
- void Start () {
- DestroySelf(lifeTime);
- }
- // Update is called once per frame
- void Update () {
- this.transform.Translate(dir * speed * Time.deltaTime, Space.World);
- }
- void DestroySelf(float time)
- {
- Destroy(this.gameObject, time);
- }
- void OnTriggerEnter2D(Collider2D other)
- {
- //Debug.Log("enter");
- if (other.gameObject.tag == "Enemy")
- {
Destroy(this.gameObject);- }
- }
- }
start()里面调用DestroySelf(),意思是子弹存活lifeTime 时间后,自动消失。不然“让子弹飞”飞到啥时候是个头啊,飞出屏幕外就没有意义了。存活时间可以自己控制
Update()方法里面,每帧都在按照指定的dir方向移动,你想让子弹怎么飞,朝哪飞,就自行设计吧,螺旋升天都没有问题~
OnTriggerEnter2D这个方法是Unity自带的,用处就是当进入碰撞盒Collider时调用,小基的内容是销毁自己,不是~意思是销毁掉子弹
这里加了一个if的判断,判断tag是不是Enemy,毕竟打到友军可是会被喷猪队友的
Tag一般默认是Untagged的,点击一下后有弹出AddTag这个选项,然后
点击加号,可以自己创建需要的tag,这样可以给不同类别的物体做区分。
下面考虑怎么让主角射出子弹,这个就需要代码控制了
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- public class MyInput2 : MonoBehaviour {
- //移动方向枚举
- enum MoveDir
- {
- None = , //不动
- Up = , //上8
- Down = -, //下2
- Left = , //左4
- Right = -, //右6
- UL = , //左上7
- UR = -, //右上9
- DL = , //左下1
- DR = -, //右下3
- }
- //输入按键常量(之后走配置)
- const KeyCode INPUT_UP = KeyCode.W;
- const KeyCode INPUT_DOWN = KeyCode.S;
- const KeyCode INPUT_LEFT = KeyCode.A;
- const KeyCode INPUT_RIGHT = KeyCode.D;
- //默认移动方向
- private MoveDir moveDir = MoveDir.None;
- //按压值
- private int moveDirValue = ;
- //按压记录
- private bool isUpPress = false;
- private bool isDownPress = false;
- private bool isLeftPress = false;
- private bool isRightPress = false;
- //是否可以移动
- private bool canMove = true;
- //右移动
- private Vector3 MOVE_RIGHT = new Vector3(, , );
- //上移动
- private Vector3 MOVE_UP = new Vector3(, , );
- //外部调控速度
- public float speed = 2f;
- //移动速度向量
- private Vector3 move_speed_dir = Vector3.zero;
- //移动距离
- private Vector3 move_dis = Vector3.zero;
- //控制目标
- public Transform target;
- //鼠标按下时的坐标
- private Vector3 mouseStartPos = Vector3.zero;
- //鼠标是否按下
- private bool isMousePress = false;
- //鼠标枚举
- const KeyCode INPUT_MOUSE = KeyCode.Mouse0;
- //鼠标拖动范围
- const float MOUSE_RADIUS = ;
- //鼠标移动向量
- private Vector3 mouseDir = Vector3.zero;
- //鼠标速度衰减
- private float mouseSpeedRate = ;
- //鼠标速度
- public float mouseSpeed = ;
- //摇杆底
- public RectTransform joyStickDown;
- //摇杆顶
- public RectTransform joyStickUp;
- //摄像机
- public Camera camera;
- //子弹prefab
- GameObject prefabBullet;
- //是否开火
- bool isFire = false;
- // Use this for initialization
- void Start () {
- prefabBullet = (GameObject)Resources.Load("Prefab/Bullet");
- //Debug.Log("bullet:" + prefabBullet);
- }
- // Update is called once per frame
- void Update () {
- CheckInputKey();
- CheckMoveDir();
- CheckMouseDir();
- }
- void FixedUpdate()
- {
- CheckMove();
- CheckFire();
- }
- //检测输入按键
- void CheckInputKey()
- {
- //检测单一输入
- foreach (KeyCode kcode in System.Enum.GetValues(typeof(KeyCode)))
- {
- if (Input.GetKeyDown(kcode))
- {
- //Debug.Log("Single KeyCode Down: " + kcode);
- ChangeKeyPressState(kcode, true);
- }
- if (Input.GetKeyUp(kcode))
- {
- //Debug.Log("Single KeyCode Up: " + kcode);
- ChangeKeyPressState(kcode, false);
- }
- }
- }
- //记录按键的按压状态
- void ChangeKeyPressState(KeyCode keyCode, bool isPress)
- {
- switch(keyCode)
- {
- case INPUT_UP:
- isUpPress = isPress;
- break;
- case INPUT_DOWN:
- isDownPress = isPress;
- break;
- case INPUT_LEFT:
- isLeftPress = isPress;
- break;
- case INPUT_RIGHT:
- isRightPress = isPress;
- break;
- case INPUT_MOUSE:
- MouseStateChange(isPress);
- break;
- case INPUT_FIRE:
- isFire = isPress;
- break;
- }
- }
- //鼠标按键输入
- void MouseStateChange(bool isPress)
- {
- isMousePress = isPress;
- mouseStartPos = isPress ? Input.mousePosition : Vector3.zero;
- joyStickDown.gameObject.SetActive(isPress);
- joyStickDown.position = camera.ScreenToWorldPoint(mouseStartPos);
- }
- //鼠标移动
- void CheckMouseDir()
- {
- if(isMousePress)
- {
- mouseDir = Input.mousePosition - mouseStartPos;
- mouseSpeedRate = Mathf.Min(mouseDir.magnitude / MOUSE_RADIUS, );
- move_dis = mouseSpeed * mouseSpeedRate * Time.deltaTime * mouseDir.normalized;
- target.position += move_dis;
- joyStickUp.localPosition = mouseDir.normalized * mouseSpeedRate * MOUSE_RADIUS;
- }
- }
- //确定移动方向
- void CheckMoveDir()
- {
- moveDirValue = ;
- //确定方向
- if(isUpPress)
- {
- moveDirValue += (int)MoveDir.Up;
- }
- if (isDownPress)
- {
- moveDirValue += (int)MoveDir.Down;
- }
- if (isLeftPress)
- {
- moveDirValue += (int)MoveDir.Left;
- }
- if (isRightPress)
- {
- moveDirValue += (int)MoveDir.Right;
- }
- }
- //检测是否可以移动
- void CheckMove()
- {
- //某些情况下可能禁止移动,例如暂停,播放CG等
- if(canMove && moveDirValue != (int)MoveDir.None)
- {
- PlayerMove(target, speed);
- }
- }
- //移动
- void PlayerMove(Transform target, float speed)
- {
- move_dis = speed * Time.deltaTime * GetSpeedDir();
- target.position += move_dis;
- }
- //速度向量
- Vector3 GetSpeedDir()
- {
- switch(moveDirValue)
- {
- case (int)MoveDir.Up:
- move_speed_dir = MOVE_UP;
- break;
- case (int)MoveDir.Down:
- move_speed_dir = -MOVE_UP;
- break;
- case (int)MoveDir.Left:
- move_speed_dir = -MOVE_RIGHT;
- break;
- case (int)MoveDir.Right:
- move_speed_dir = MOVE_RIGHT;
- break;
- case (int)MoveDir.UL:
- move_speed_dir = MOVE_UP - MOVE_RIGHT;
- break;
- case (int)MoveDir.UR:
- move_speed_dir = MOVE_UP + MOVE_RIGHT;
- break;
- case (int)MoveDir.DL:
- move_speed_dir = -MOVE_UP - MOVE_RIGHT;
- break;
- case (int)MoveDir.DR:
- move_speed_dir = -MOVE_UP + MOVE_RIGHT;
- break;
- }
- return move_speed_dir.normalized;
- }
- //开火
- public const KeyCode INPUT_FIRE = KeyCode.Space;
- //开火时间cd
- public float fireCD = 0.5f;
- //上次开火时间
- float lastTime = ;
- //当前时间
- float curTime = ;
- void CheckFire()
- {
- if(isFire)
- {
- Fire();
- }
- }
- void Fire()
- {
- curTime = Time.time;
- if(curTime - lastTime > fireCD)
- {
- //创建子弹
- CreateBullet();
- lastTime = curTime;
- }
- }
- //画布
- public Canvas canvas;
- //创建子弹
- void CreateBullet()
- {
- GameObject bullet = Instantiate(prefabBullet, target.localPosition, target.rotation);
- bullet.transform.SetParent(canvas.transform, false);
- }
- }
还是之前的移动代码,增加了
这里是需要先把Bullet制作成Prefab预制体,使用Resources.Load方法载入子弹prefab
在Project下创建文件夹Resources(必须用这个才可以载入)下面Prefab里面都是做好的预制体,做法就是把Hierarchy下的对象直接拖到Prefab文件夹下(请无视与本例无关的东西)
ChangeKeyPressState()方法里面增加判断开火的按键,FixedUpdate里面检测是不是开火,if里面可以加很多条件,比如CG时候不能开火,没有子弹不能开火等等。
Fire()这个方法里面记录了开火的当前时间,下次开火的时候判断是不是已经过了CD时长,不然按住按键,每帧都会开火,火力太猛没法玩了,氪金大佬专属。
CreateBullet()这里面使用了Instantiate这个自带的方法,通过前面载入的子弹预设体prefab可以克隆出bullet(就是通过模版复制的过程)
切记要把bullet的父物体设置成Canvas,就是通过代码把bullet放到canvas下面,不然你子弹可能不在UI里面哦~
SetParent()方法的第二个参数用false,这样可以保证bullet的size不会因为父节点变化而变化。好奇的话,你可以写成true试试
来试试发射子弹,打到敌人就消失了。
不过这敌人木头人太愣了,给他点反应吧,enemy1上添加脚本enemy1(脚本名字你随便起)
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- public class Enemy : MonoBehaviour {
- void ByHit()
- {
- Debug.Log("byHit");
- this.transform.Translate(Vector2.one);
- }
- }
就写一个方法,被揍了,效果就是朝着vector2.one也就是(1,1)这个方向移动。你想让有啥反映就在这里写就可以,想变大变小变色都没问题
那么怎么才能被调用呢?
- void OnTriggerEnter2D(Collider2D other)
- {
- Debug.Log("enter");
- if (other.gameObject.tag == "Enemy")
- {
- other.gameObject.SendMessage("ByHit");
- Destroy(this.gameObject);
- }
- }
刚才子弹的碰撞里面,增加sendMessage这个方法,参数是被调用方法的名字。这样就可以调用到碰撞的对方身上的脚本里面的"ByHit"这个方法
虽然敌人暂时还不能反击,不过起码不那么木讷了∠( ᐛ 」∠)_
敌人怎么反击的话,大家自己发挥想象力去做就好了,让他发出散弹打你也是可以的哦~
但愿你可以不用参考这个工程就能自己做出来https://pan.baidu.com/s/1e9rQIJt8AYDgHVPvbyJEuQ
不过,这个敌人为啥打不死呢?!哦,因为他没有血条啊!那咋整啊?下一篇介绍制作通用进度条(血条)(= ̄ω ̄=)
unity零基础开始学习做游戏(四)biu~biu~biu发射子弹打飞机的更多相关文章
- unity零基础开始学习做游戏(五)看看你的完成度,进度条了解一下?
-------小基原创,转载请给我一个面子 上回书说道,英雄和魔王都做完了,子弹也能发射了,就是不知道啥时候能干死魔王.那小基得做个血条来展示一下,他离死不远了(•౪• ) 其实血条也可以看作是进度条 ...
- unity零基础开始学习做游戏(三)鼠标输入,来个虚拟摇杆怎么样?
-------小基原创,转载请给我一个面子 现在移动游戏越来越火,大家都拿手机平板玩游戏,没有键盘和手柄输入,所以就不得不看看虚拟摇杆怎么搞?(小基对于没有实体反馈不是很喜欢呢) 首先要清楚,鼠标操作 ...
- unity零基础开始学习做游戏(一)为了实现你的游戏,你需要提前做的准备工作
-------小基原创,转载请给我一个面子 正所谓,工欲善其事,必现准备好电脑.接下来跟着小基一步一步来搭建你的开发环境吧 1.下载安装unity 上面的那个是破解软件,下面是unity5.5.6的安 ...
- unity零基础开始学习做游戏(二)让你的对象动起来
-------小基原创,转载请给我一个面子 小基认为电子游戏与电影最重要的区别就是交互,如果电子游戏没有让你输入的交互功能的话,全程都"只可远观,而不可鼓捣"的话,你可能是在看视频 ...
- unity零基础开始学习做游戏(六)背景给我“滚”~
-------小基原创,转载请给我一个面子 一望无际的...空旷场景,看着实在是难受,不如添加些背景吧.如果要真的想好好设计关卡背景的话,最好是做一个地图编辑器,不过做开发工具毕竟有点点复杂且枯燥,以 ...
- 零基础如何学习 Web 安全?(转)
在网上看了一篇文章<零基础如何学习 Web 安全?>,虽然很多东西的都不是很懂,感觉挺好的copy过来,慢慢消化: 文章地址:https://www.zhihu.com/question/ ...
- 零基础如何学习java更有效呢?
零基础学java,不知道该如何入手?也不知道学习的方向,很多人会问零基础怎么样学习,有没有什么入门的书籍推荐:只要方法正确,零基础学好java也是有机会的哦. 一.理解Java思想 Java是一门面向 ...
- javascript入门视频第一天 小案例制作 零基础开始学习javascript
JavaScript 是我们网页设计师必备的技能之一.我们主要用javascript来写的是网页特效.我们从零基础开始学习javascript入门. 但是,好的同学刚开始不知道怎么学习,接触js,因此 ...
- 大牛整理最全Python零基础入门学习资料
大牛整理最全Python零基础入门学习资料 发布时间:『 2017-11-12 11:56 』 帖子类别:『人工智能』 阅读次数:3504 (本文『大牛整理最全Python零基础入门学习资料 ...
随机推荐
- 毕加索的艺术——Picasso,一个强大的Android图片下载缓存库,OkHttpUtils的使用,二次封装PicassoUtils实现微信精选
毕加索的艺术--Picasso,一个强大的Android图片下载缓存库,OkHttpUtils的使用,二次封装PicassoUtils实现微信精选 官网: http://square.github.i ...
- FSG报表打印报错,log文件显示java.sql.SQLException: No corresponding LOB data found
报错信息: +---------------------------------------------------------------------------+ Plsql 程序的日志信息开始 ...
- 08_Android中的SimpleAdapter的使用
1 目的界面 2.编写Android清单文件 <?xml version="1.0" encoding="utf-8"?> <manif ...
- 控件的基本使用-iOS—UI笔记
学习目标 1.[掌握]第一个UI项目 2.[掌握]控件连线 3.[掌握]按钮的基本操作 4.[掌握]控件的常用属性 一.第一个UI项目 UI (User Interface)也是就用户界面,是App的 ...
- ECMAScript中所有的函数的参数都是按值传递的
看下面一段代码 function setName(obj){ obj.name='Nicholas'; obj=new Object(); obj.name="Greg"; } v ...
- Leetcode_123_Best Time to Buy and Sell Stock III
本文是在学习中的总结,欢迎转载但请注明出处:http://blog.csdn.net/pistolove/article/details/43740415 Say you have an array ...
- PDA开发数据由本地上传至DB
private void btnUpLoad_Click(object sender, EventArgs e) { if (!System.IO.File.Exists(LoadFile)) { M ...
- 虚拟机linux挂载光盘显示:mount: you must specify the filesystem type
虚拟机内 linux 挂载光盘显示:mount: you must specify the filesystem type 今天在虚拟机上挂载镜像文件时提示: 初步断定原因有2: 1.在卸载光盘时使用 ...
- plsql 导入导出表、数据、序列、视图
一.导出: 1.打开plsql-->工具---->导出用户对象(可以导出表结构和序列.视图) ps:如果上面不选中"包括所有者",这样到导出的表结构等就不包含所有 ...
- C/C++语言中NULL、'\0’和0的区别
注:本文参考了http://blog.csdn.net/mylinx/article/details/6873253及书籍<征服C指针>([日]前桥和弥著). NULL.'\0'和0的值是 ...