-------小基原创,转载请给我一个面子

  主角都能移动了,那不得做点什么伸张正义,守护世界和平的事嘛,拿起家伙biu~biu~biu~

首先得做一个好人和一个坏人

老规矩,Canvas下创建两个Image,一个叫做player,一个叫做enemy1好了

 

一个红色,一个蓝色(自古红蓝出CP,不好意思,走错片场了●﹏●)

新知识:要加BoxCollider2D

子弹打到别人,其实是碰撞检测的过程

一种是根据位置坐标,判断子弹有没有打中,另一种是使用物理碰撞系统(小基这里使用后者)

两个物体物理碰撞检测条件

1.物体A,物体B,必须都有Collider

2.运动的一方要有刚体(本例对应的是子弹,后面介绍)

最终效果是这样的。

下面开始制作子弹

Canvas下创建一个Image,修改名字叫做Bullet,使用自带的圆形图片凑合用吧

同样添加BoxCollider2D,最后切记添加RigidBody,不然没法碰撞成功

额外提一句,重力调成0吧,不然子弹抛物线飞=_=

现在看起来是这样的。

接下来想想怎么让子弹动起来,上代码(创建一个脚本Bullet),给那个子弹挂上

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4.  
  5. public class Bullet : MonoBehaviour {
  6.  
  7. public float speed = ;
  8. public Vector2 dir = new Vector2(, );
  9. public float lifeTime = 5f;
  10.  
  11. public float damage = ;
  12. // Use this for initialization
  13. void Start () {
  14. DestroySelf(lifeTime);
  15. }
  16.  
  17. // Update is called once per frame
  18. void Update () {
  19. this.transform.Translate(dir * speed * Time.deltaTime, Space.World);
  20. }
  21.  
  22. void DestroySelf(float time)
  23. {
  24. Destroy(this.gameObject, time);
  25. }
  26.  
  27. void OnTriggerEnter2D(Collider2D other)
  28. {
  29. //Debug.Log("enter");
  30. if (other.gameObject.tag == "Enemy")
  31. {
    Destroy(this.gameObject);
  32. }
  33. }
  34. }

start()里面调用DestroySelf(),意思是子弹存活lifeTime 时间后,自动消失。不然“让子弹飞”飞到啥时候是个头啊,飞出屏幕外就没有意义了。存活时间可以自己控制

Update()方法里面,每帧都在按照指定的dir方向移动,你想让子弹怎么飞,朝哪飞,就自行设计吧,螺旋升天都没有问题~

OnTriggerEnter2D这个方法是Unity自带的,用处就是当进入碰撞盒Collider时调用,小基的内容是销毁自己,不是~意思是销毁掉子弹

这里加了一个if的判断,判断tag是不是Enemy,毕竟打到友军可是会被喷猪队友的

Tag一般默认是Untagged的,点击一下后有弹出AddTag这个选项,然后

点击加号,可以自己创建需要的tag,这样可以给不同类别的物体做区分。

下面考虑怎么让主角射出子弹,这个就需要代码控制了

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4.  
  5. public class MyInput2 : MonoBehaviour {
  6. //移动方向枚举
  7. enum MoveDir
  8. {
  9. None = , //不动
  10. Up = , //上8
  11. Down = -, //下2
  12. Left = , //左4
  13. Right = -, //右6
  14. UL = , //左上7
  15. UR = -, //右上9
  16. DL = , //左下1
  17. DR = -, //右下3
  18. }
  19.  
  20. //输入按键常量(之后走配置)
  21. const KeyCode INPUT_UP = KeyCode.W;
  22. const KeyCode INPUT_DOWN = KeyCode.S;
  23. const KeyCode INPUT_LEFT = KeyCode.A;
  24. const KeyCode INPUT_RIGHT = KeyCode.D;
  25.  
  26. //默认移动方向
  27. private MoveDir moveDir = MoveDir.None;
  28. //按压值
  29. private int moveDirValue = ;
  30. //按压记录
  31. private bool isUpPress = false;
  32. private bool isDownPress = false;
  33. private bool isLeftPress = false;
  34. private bool isRightPress = false;
  35.  
  36. //是否可以移动
  37. private bool canMove = true;
  38. //右移动
  39. private Vector3 MOVE_RIGHT = new Vector3(, , );
  40. //上移动
  41. private Vector3 MOVE_UP = new Vector3(, , );
  42.  
  43. //外部调控速度
  44. public float speed = 2f;
  45. //移动速度向量
  46. private Vector3 move_speed_dir = Vector3.zero;
  47. //移动距离
  48. private Vector3 move_dis = Vector3.zero;
  49.  
  50. //控制目标
  51. public Transform target;
  52.  
  53. //鼠标按下时的坐标
  54. private Vector3 mouseStartPos = Vector3.zero;
  55. //鼠标是否按下
  56. private bool isMousePress = false;
  57. //鼠标枚举
  58. const KeyCode INPUT_MOUSE = KeyCode.Mouse0;
  59. //鼠标拖动范围
  60. const float MOUSE_RADIUS = ;
  61. //鼠标移动向量
  62. private Vector3 mouseDir = Vector3.zero;
  63. //鼠标速度衰减
  64. private float mouseSpeedRate = ;
  65. //鼠标速度
  66. public float mouseSpeed = ;
  67. //摇杆底
  68. public RectTransform joyStickDown;
  69. //摇杆顶
  70. public RectTransform joyStickUp;
  71. //摄像机
  72. public Camera camera;
  73.  
  74. //子弹prefab
  75. GameObject prefabBullet;
  76. //是否开火
  77. bool isFire = false;
  78. // Use this for initialization
  79. void Start () {
  80. prefabBullet = (GameObject)Resources.Load("Prefab/Bullet");
  81. //Debug.Log("bullet:" + prefabBullet);
  82. }
  83.  
  84. // Update is called once per frame
  85. void Update () {
  86. CheckInputKey();
  87. CheckMoveDir();
  88. CheckMouseDir();
  89. }
  90.  
  91. void FixedUpdate()
  92. {
  93. CheckMove();
  94. CheckFire();
  95. }
  96.  
  97. //检测输入按键
  98. void CheckInputKey()
  99. {
  100. //检测单一输入
  101. foreach (KeyCode kcode in System.Enum.GetValues(typeof(KeyCode)))
  102. {
  103. if (Input.GetKeyDown(kcode))
  104. {
  105. //Debug.Log("Single KeyCode Down: " + kcode);
  106. ChangeKeyPressState(kcode, true);
  107. }
  108.  
  109. if (Input.GetKeyUp(kcode))
  110. {
  111. //Debug.Log("Single KeyCode Up: " + kcode);
  112. ChangeKeyPressState(kcode, false);
  113. }
  114. }
  115. }
  116.  
  117. //记录按键的按压状态
  118. void ChangeKeyPressState(KeyCode keyCode, bool isPress)
  119. {
  120. switch(keyCode)
  121. {
  122. case INPUT_UP:
  123. isUpPress = isPress;
  124. break;
  125. case INPUT_DOWN:
  126. isDownPress = isPress;
  127. break;
  128. case INPUT_LEFT:
  129. isLeftPress = isPress;
  130. break;
  131. case INPUT_RIGHT:
  132. isRightPress = isPress;
  133. break;
  134. case INPUT_MOUSE:
  135. MouseStateChange(isPress);
  136. break;
  137. case INPUT_FIRE:
  138. isFire = isPress;
  139. break;
  140. }
  141. }
  142.  
  143. //鼠标按键输入
  144. void MouseStateChange(bool isPress)
  145. {
  146. isMousePress = isPress;
  147. mouseStartPos = isPress ? Input.mousePosition : Vector3.zero;
  148. joyStickDown.gameObject.SetActive(isPress);
  149. joyStickDown.position = camera.ScreenToWorldPoint(mouseStartPos);
  150. }
  151.  
  152. //鼠标移动
  153. void CheckMouseDir()
  154. {
  155. if(isMousePress)
  156. {
  157. mouseDir = Input.mousePosition - mouseStartPos;
  158. mouseSpeedRate = Mathf.Min(mouseDir.magnitude / MOUSE_RADIUS, );
  159. move_dis = mouseSpeed * mouseSpeedRate * Time.deltaTime * mouseDir.normalized;
  160. target.position += move_dis;
  161. joyStickUp.localPosition = mouseDir.normalized * mouseSpeedRate * MOUSE_RADIUS;
  162. }
  163. }
  164.  
  165. //确定移动方向
  166. void CheckMoveDir()
  167. {
  168. moveDirValue = ;
  169. //确定方向
  170. if(isUpPress)
  171. {
  172. moveDirValue += (int)MoveDir.Up;
  173. }
  174. if (isDownPress)
  175. {
  176. moveDirValue += (int)MoveDir.Down;
  177. }
  178. if (isLeftPress)
  179. {
  180. moveDirValue += (int)MoveDir.Left;
  181. }
  182. if (isRightPress)
  183. {
  184. moveDirValue += (int)MoveDir.Right;
  185. }
  186. }
  187.  
  188. //检测是否可以移动
  189. void CheckMove()
  190. {
  191. //某些情况下可能禁止移动,例如暂停,播放CG等
  192. if(canMove && moveDirValue != (int)MoveDir.None)
  193. {
  194. PlayerMove(target, speed);
  195. }
  196. }
  197.  
  198. //移动
  199. void PlayerMove(Transform target, float speed)
  200. {
  201. move_dis = speed * Time.deltaTime * GetSpeedDir();
  202. target.position += move_dis;
  203. }
  204.  
  205. //速度向量
  206. Vector3 GetSpeedDir()
  207. {
  208. switch(moveDirValue)
  209. {
  210. case (int)MoveDir.Up:
  211. move_speed_dir = MOVE_UP;
  212. break;
  213. case (int)MoveDir.Down:
  214. move_speed_dir = -MOVE_UP;
  215. break;
  216. case (int)MoveDir.Left:
  217. move_speed_dir = -MOVE_RIGHT;
  218. break;
  219. case (int)MoveDir.Right:
  220. move_speed_dir = MOVE_RIGHT;
  221. break;
  222. case (int)MoveDir.UL:
  223. move_speed_dir = MOVE_UP - MOVE_RIGHT;
  224. break;
  225. case (int)MoveDir.UR:
  226. move_speed_dir = MOVE_UP + MOVE_RIGHT;
  227. break;
  228. case (int)MoveDir.DL:
  229. move_speed_dir = -MOVE_UP - MOVE_RIGHT;
  230. break;
  231. case (int)MoveDir.DR:
  232. move_speed_dir = -MOVE_UP + MOVE_RIGHT;
  233. break;
  234. }
  235. return move_speed_dir.normalized;
  236. }
  237.  
  238. //开火
  239. public const KeyCode INPUT_FIRE = KeyCode.Space;
  240. //开火时间cd
  241. public float fireCD = 0.5f;
  242. //上次开火时间
  243. float lastTime = ;
  244. //当前时间
  245. float curTime = ;
  246.  
  247. void CheckFire()
  248. {
  249. if(isFire)
  250. {
  251. Fire();
  252. }
  253. }
  254.  
  255. void Fire()
  256. {
  257. curTime = Time.time;
  258. if(curTime - lastTime > fireCD)
  259. {
  260. //创建子弹
  261. CreateBullet();
  262. lastTime = curTime;
  263. }
  264. }
  265.  
  266. //画布
  267. public Canvas canvas;
  268. //创建子弹
  269. void CreateBullet()
  270. {
  271. GameObject bullet = Instantiate(prefabBullet, target.localPosition, target.rotation);
  272. bullet.transform.SetParent(canvas.transform, false);
  273. }
  274. }

还是之前的移动代码,增加了

这里是需要先把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(脚本名字你随便起)

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4.  
  5. public class Enemy : MonoBehaviour {
  6. void ByHit()
  7. {
  8. Debug.Log("byHit");
  9. this.transform.Translate(Vector2.one);
  10. }
  11. }

就写一个方法,被揍了,效果就是朝着vector2.one也就是(1,1)这个方向移动。你想让有啥反映就在这里写就可以,想变大变小变色都没问题

那么怎么才能被调用呢?

  1. void OnTriggerEnter2D(Collider2D other)
  2. {
  3. Debug.Log("enter");
  4. if (other.gameObject.tag == "Enemy")
  5. {
  6. other.gameObject.SendMessage("ByHit");
  7. Destroy(this.gameObject);
  8. }
  9. }

刚才子弹的碰撞里面,增加sendMessage这个方法,参数是被调用方法的名字。这样就可以调用到碰撞的对方身上的脚本里面的"ByHit"这个方法

虽然敌人暂时还不能反击,不过起码不那么木讷了∠( ᐛ 」∠)_

敌人怎么反击的话,大家自己发挥想象力去做就好了,让他发出散弹打你也是可以的哦~

但愿你可以不用参考这个工程就能自己做出来https://pan.baidu.com/s/1e9rQIJt8AYDgHVPvbyJEuQ

不过,这个敌人为啥打不死呢?!哦,因为他没有血条啊!那咋整啊?下一篇介绍制作通用进度条(血条)(= ̄ω ̄=)

unity零基础开始学习做游戏(四)biu~biu~biu发射子弹打飞机的更多相关文章

  1. unity零基础开始学习做游戏(五)看看你的完成度,进度条了解一下?

    -------小基原创,转载请给我一个面子 上回书说道,英雄和魔王都做完了,子弹也能发射了,就是不知道啥时候能干死魔王.那小基得做个血条来展示一下,他离死不远了(•౪• ) 其实血条也可以看作是进度条 ...

  2. unity零基础开始学习做游戏(三)鼠标输入,来个虚拟摇杆怎么样?

    -------小基原创,转载请给我一个面子 现在移动游戏越来越火,大家都拿手机平板玩游戏,没有键盘和手柄输入,所以就不得不看看虚拟摇杆怎么搞?(小基对于没有实体反馈不是很喜欢呢) 首先要清楚,鼠标操作 ...

  3. unity零基础开始学习做游戏(一)为了实现你的游戏,你需要提前做的准备工作

    -------小基原创,转载请给我一个面子 正所谓,工欲善其事,必现准备好电脑.接下来跟着小基一步一步来搭建你的开发环境吧 1.下载安装unity 上面的那个是破解软件,下面是unity5.5.6的安 ...

  4. unity零基础开始学习做游戏(二)让你的对象动起来

    -------小基原创,转载请给我一个面子 小基认为电子游戏与电影最重要的区别就是交互,如果电子游戏没有让你输入的交互功能的话,全程都"只可远观,而不可鼓捣"的话,你可能是在看视频 ...

  5. unity零基础开始学习做游戏(六)背景给我“滚”~

    -------小基原创,转载请给我一个面子 一望无际的...空旷场景,看着实在是难受,不如添加些背景吧.如果要真的想好好设计关卡背景的话,最好是做一个地图编辑器,不过做开发工具毕竟有点点复杂且枯燥,以 ...

  6. 零基础如何学习 Web 安全?(转)

    在网上看了一篇文章<零基础如何学习 Web 安全?>,虽然很多东西的都不是很懂,感觉挺好的copy过来,慢慢消化: 文章地址:https://www.zhihu.com/question/ ...

  7. 零基础如何学习java更有效呢?

    零基础学java,不知道该如何入手?也不知道学习的方向,很多人会问零基础怎么样学习,有没有什么入门的书籍推荐:只要方法正确,零基础学好java也是有机会的哦. 一.理解Java思想 Java是一门面向 ...

  8. javascript入门视频第一天 小案例制作 零基础开始学习javascript

    JavaScript 是我们网页设计师必备的技能之一.我们主要用javascript来写的是网页特效.我们从零基础开始学习javascript入门. 但是,好的同学刚开始不知道怎么学习,接触js,因此 ...

  9. 大牛整理最全Python零基础入门学习资料

    大牛整理最全Python零基础入门学习资料 发布时间:『 2017-11-12 11:56 』     帖子类别:『人工智能』  阅读次数:3504 (本文『大牛整理最全Python零基础入门学习资料 ...

随机推荐

  1. 毕加索的艺术——Picasso,一个强大的Android图片下载缓存库,OkHttpUtils的使用,二次封装PicassoUtils实现微信精选

    毕加索的艺术--Picasso,一个强大的Android图片下载缓存库,OkHttpUtils的使用,二次封装PicassoUtils实现微信精选 官网: http://square.github.i ...

  2. FSG报表打印报错,log文件显示java.sql.SQLException: No corresponding LOB data found

    报错信息: +---------------------------------------------------------------------------+ Plsql 程序的日志信息开始 ...

  3. 08_Android中的SimpleAdapter的使用

     1 目的界面 2.编写Android清单文件 <?xml version="1.0" encoding="utf-8"?> <manif ...

  4. 控件的基本使用-iOS—UI笔记

    学习目标 1.[掌握]第一个UI项目 2.[掌握]控件连线 3.[掌握]按钮的基本操作 4.[掌握]控件的常用属性 一.第一个UI项目 UI (User Interface)也是就用户界面,是App的 ...

  5. ECMAScript中所有的函数的参数都是按值传递的

    看下面一段代码 function setName(obj){ obj.name='Nicholas'; obj=new Object(); obj.name="Greg"; } v ...

  6. Leetcode_123_Best Time to Buy and Sell Stock III

    本文是在学习中的总结,欢迎转载但请注明出处:http://blog.csdn.net/pistolove/article/details/43740415 Say you have an array ...

  7. PDA开发数据由本地上传至DB

    private void btnUpLoad_Click(object sender, EventArgs e) { if (!System.IO.File.Exists(LoadFile)) { M ...

  8. 虚拟机linux挂载光盘显示:mount: you must specify the filesystem type

    虚拟机内 linux 挂载光盘显示:mount: you must specify the filesystem type 今天在虚拟机上挂载镜像文件时提示: 初步断定原因有2: 1.在卸载光盘时使用 ...

  9. plsql 导入导出表、数据、序列、视图

     一.导出: 1.打开plsql-->工具---->导出用户对象(可以导出表结构和序列.视图) ps:如果上面不选中"包括所有者",这样到导出的表结构等就不包含所有 ...

  10. C/C++语言中NULL、'\0’和0的区别

    注:本文参考了http://blog.csdn.net/mylinx/article/details/6873253及书籍<征服C指针>([日]前桥和弥著). NULL.'\0'和0的值是 ...