Unity3D--学习太空射击游戏制作(三)
步骤四:创建敌人
创建敌人的方式与创建主角类似,不过敌人的行为需要由计算机来控制,它将从上方迎着主角缓慢飞出来,并左右来回移动:
01:创建Enemy.cs脚本,添加代码:
using UnityEngine;
using System.Collections; [AddComponentMenu("MyGame/Enemy")]
public class Enemy : MonoBehaviour
{ //移动速度
public float m_Movespeed = ;
//旋转速度
public float m_RotationSpeed = ;
public Transform m_transform;
void Start()
{
m_transform = this.transform;
} void Update()
{
UpdateMove();
} protected void UpdateMove()
{
//左右移动
float rx = Mathf.Sin(Time.time) * Time.deltaTime;
//前进
m_transform.Translate(new Vector3(rx, , -m_Movespeed * Time.deltaTime));
}
}
UpdateMove函数用来执行敌人的移动,使用了Sin函数使游戏体在x方向的移动始终在(-1,1)区间内,敌人在飞行的同时还会左右迂回;在Project窗口找到Enemy.fbx文件,拖动到Hierarchy窗口,然后参考前面内容为其创建Prefab,指定Enemy脚本作为其组件。然后将Prefab从Project窗口拖动到游戏场景中,然后在Hierarchy窗口选中Enemy按Ctrl+D复制多个,然后再Scene窗口中自己排列下位置就OK了。
游戏运行后:

步骤五:添加物理碰撞
现在的游戏虽然有了主角、敌人,也可以发射子弹,但主角和敌人之间却没有任何的交互。我们需要分别给主角、子弹、敌人添加碰撞体,并添加触发碰撞的代码,使其在发生碰撞的时候产生交互。
01:先给敌人添加碰撞体,在Scene面板选中任意一个敌人,在菜单栏选择Component->Physics->Box Collider为敌人添加一个立方体碰撞体组件,在后在Inspector窗口找到Box Collider组件,选中Is Trigger,使其具有触发作用:

02:接着在菜单栏选择Component->Physics->Rigidbody为敌人添加一个刚体组件,所有需要参与物理计算的游戏体都需要有一个刚体组件才能正常工作。在Insperctor->Rigidbody取消选择Use Gravity去掉重力作用影响,选中Is Kinematic使游戏体运动不受物理模拟影响,现在已经为一个敌人添加了物理碰撞效果组件,然后再Insperctor最上面找到Apply按钮点击,这样所有的Enemy都更新了此物理碰撞的设置。此处如果是在编辑器的Project窗口修改原始敌人的Prefab的属性,那么场景中的所有的敌人都会自动更新与Prefab一样的属性设置,如图:

然后参考给敌人设置物理碰撞组件的做法,给主角和子弹也类似的设置。
03:接下来触发碰撞,上面已经给主角、敌人、子弹添加了碰撞体,但是运行游戏的时候看不到任何的互动效果,我们将要为他们分别指定一个Tag标识,然后添加触发碰撞事件的代码,在菜单栏选择Edit->Project Settings->Tags在size中输入2,创建两个tag,名为PlayerRocket和Enemy,如图:

然后在Project窗口选择敌人的Prefab,在Inspector窗口设置Tag为Enemy;选择子弹的Prefab,在Inspector窗口设置它的Tag为PlayerRocket;选择主角设置他的Tag为Player,这个Tag是Unity预设在工程内的。

然后打开敌人Enemy.cs脚本,添加一个生命属性:
public float m_life = 10;
void OnTriggerEnter(Collider other) //这是一个派生自MonoBehaviour的函数,在碰撞体互相接触时
//会被触发
{
if (other.tag.CompareTo("PlayerRocket") == 0)//如果碰到的物体是主角子弹PlayerRocket
{
Rocket rocket = other.GetComponent<Rocket>();//获得对方碰撞提的Rocket脚本组件
if (rocket != null)
{
m_life -= rocket.m_power;
if (m_life <= 0)
{
Destroy(this.gameObject);//如果生命小于等于0就自动销毁
}
}
}
else if (other.tag.CompareTo("Player") == 0)
{
m_life = 0;
Destroy(this.gameObject);//如果碰到主角就立即自动销毁
}
}
然后在子弹Rocket.cs脚本中也添加一个OnTriggerEnter函数,当子弹撞击到敌人,则自我销毁。
void OnTriggerEnter(Collider other)
{
if (other.tag.CompareTo("Enemy") == 0)
{
return;
}
Destroy(this.gameObject);
}
然后在主角Player.cs脚本中添加一个生命属性,添加一个OnTriggerEnter函数,当主角与非自己发出的子弹相碰撞的时候都会损失一些生命,当生命为0时候自行销毁。
public float m_life = 3;
void OnTriggerEnter(Collider other)
{
if (other.tag.CompareTo("PlayerRocket") != 0)//如果主角与非己方子弹相撞
{
m_life -= 1;
if (m_life <= 0)
{
Destroy(this.gameObject);
}
}
}
此时我们注意到当敌人没有与主角或者主角的子弹发生碰撞的时候就会一直存活,从而造成了资源的浪费,这时候我们需要添加一个空的游戏体,把他放到最下面,然后让他的范围可以控制到整个下方横向区域,添加物理碰撞组件,为他指定一个名为Bound的Tag,然后在Enemy.cs中添加一句代码,当敌人没有被子弹消灭和主角碰撞消灭的时候飞到屏幕下方与之碰撞就会自行销毁。
else if (other.tag.CompareTo("Bound") == 0)
{
m_life = 0;
Destroy(this.gameObject);//如果碰到边界就立即自动销毁
}
步骤六:添加高级敌人(可以向主角发射子弹的敌人)
01:在Project窗口找到Enemy2.fbx模型,为其创建Prefab,为其创建脚本SuperEnemy.cs,该类继承自Enemy.cs,然后打开Enemy.cs,,将UpdateMove()方法写成Vitual方法,然后再SuperEnemy.cs中重写该方法,同时将新敌人的Tag改为Enemy:
using UnityEngine;
using System.Collections;
[AddComponentMenu("MyGame/SuperEnemy")]
public class SuperEnemy : Enemy
{
protected override void UpdateMove()
{
//向前移动
m_transform.Translate(new Vector3(0, 0, -m_Movespeed * Time.deltaTime));
}
}
此时运行游戏发现新敌人缓慢向前移动
02:新敌人向主角发射子弹
使用rocket.fbx创建一个新的子弹Prefab,取名为EnemyRocket,为其创建新的材质,使用rocket2.png作为贴图,使敌人的子弹看上去与主角的子弹不同,为敌人添加RigidBody和Box Collider组件(这里我添加组件的时候子弹就发不出来了,不知道为啥???),为敌人子弹新建一个名为EnemyRocket的Tag,创建EnemyRocket.cs脚本,继承自Rocket类:
using UnityEngine;
using System.Collections;
[AddComponentMenu("MyGame/EnemyRocket")]
public class EnemyRocket : Rocket
{
void OnTriggerEnter(Collider other)
{
if (other.tag.CompareTo("Player") == 0)
{
return;
}
Destroy(this.gameObject);
}
}
将EnemyRocket的脚本指定给敌人子弹的Prefab,在Inspector窗口设置EnemyRocket组件,降低敌人子弹的移动速度,增加生存时间,然后关联SuperEnemy和子弹,在SuperEnemy.cs脚本中添加代码:
using UnityEngine;
using System.Collections;
[AddComponentMenu("MyGame/SuperEnemy")]
public class SuperEnemy : Enemy
{
public Transform m_rocket;
protected float m_fireTimer = 2;//控制发射子弹的时间间隔
protected Transform m_player;//用来指向主角的飞船 void Awake()//Awake方法继承自MonoBehaviour它会在游戏体实例化时执行一次,并先于Start方法
{
GameObject obj = GameObject.FindGameObjectWithTag("Player");//获得主角的游戏体实例
if (obj != null)
{
m_player = obj.transform;
}
}
protected override void UpdateMove()
{
m_fireTimer -= Time.deltaTime;
if (m_fireTimer <= 0)
{
m_fireTimer = 2;
if (m_player != null)
{
Vector3 relativePos = m_transform.position - m_player.position;
//Quaternion.LookRotation使子弹在初始化时朝向主角的方向
Instantiate(m_rocket, m_transform.position, Quaternion.LookRotation(relativePos));
}
}
//向前移动
m_transform.Translate(new Vector3(0, 0, -m_Movespeed * Time.deltaTime));
}
}
然后选择SuperEnemy的Prefab,在Inspector窗口中选择Rocket属性,与敌人的子弹的Prefab相关联,然后运行游戏。
注意:我在添加子弹游戏体的时候如果是添加了Box Collider就会看不到子弹了,不知道是不是坐标的问题??????
下面是添加声音和特效...
Unity3D--学习太空射击游戏制作(三)的更多相关文章
- Unity3D--学习太空射击游戏制作(一)
近期买了本书在学习一些Unity3D的东西,在了解了Unity3D工具的基本面板后开始学习一个太空射击游戏的开发过程. 首先下载一个关于本游戏的资源文件,(百度云下载地址:http://pan.bai ...
- Unity3D--学习太空射击游戏制作(二)
步骤三:创建主角 游戏的主角是一艘太空飞船,我们将使用一个飞船模型作为游戏的主角,并赋予他一个脚本,控制他的运动,游戏体的组件必须依赖于脚本才能运行. 01:在Project窗口找到Player.fb ...
- Unity3D--学习太空射击游戏制作(四)
步骤七:添加声音和特效(射击声音和爆炸效果) 01:在Project窗口单机右键,选择Import Package->Custome Package,然后到资源文件目录packages浏览uni ...
- 用canvas制作酷炫射击游戏--part1
好久没写博客了,因为过年后一直在学游戏制作方面的知识.学得差不多后又花了3个月时间做了个作品出来,现在正拿着这个作品找工作. 作品地址:https://betasu.github.io/Crimonl ...
- cocos2d-x学习日志(10) --射击游戏(喵星战争)
转载请标明:转载自[小枫栏目],博文链接:http://blog.csdn.net/rexuefengye/article/details/10553487 一.纵版射击游戏的特点 纵版射击游戏是一种 ...
- 少儿编程Scratch第四讲:射击游戏的制作,克隆的奥秘
上周的宇宙大战射击游戏中,我们只完成了宇宙飞船发射子弹的部分.还未制作敌对方.这周制作了敌方-飞龙,飞龙随机在屏幕上方出现,如果被子弹打中,则得分,飞龙和子弹都消失. 敌方:飞龙:计分. 目的 目的: ...
- Unity3D学习笔记(一):Unity3D简介
Unity3D简介一.什么是Unity.U3D?全面整合的专业引擎 二.这个软件能做什么?1.内容:3D2D游戏,教育,建筑,网页,VRAR,家庭娱乐系统2.媒体:PC平台,主机,移动,VR 1.UE ...
- 使用Cocos2dx-JS开发一个飞行射击游戏
一.前言 笔者闲来无事,某天github闲逛,看到了游戏引擎的专题,引起了自己的兴趣,于是就自己捣腾了一下Cocos2dx-JS.由于是学习,所谓纸上得来终觉浅,只是看文档看sample看demo,并 ...
- 《Genesis-3D开源游戏引擎完整实例教程-2D射击游戏篇:简介及目录》(附上完整工程文件)
G-3D引擎2D射击类游戏制作教程 游戏类型: 打飞机游戏属于射击类游戏中的一种,可以划分为卷轴射击类游戏. 视觉表现类型为:2D 框架简介: Genesis-3D引擎不仅为开发者提供一个3D游戏制作 ...
随机推荐
- Tomcat配置域名访问
在server.xml文件中的<Host>标签里面添加 <Alias>你的域名(比如:www.baidu.com)</Alias> <Context path ...
- windows远程关机重启
windows远程关机 http://lsscto.blog.51cto.com/779396/245681 shutdown http://baike.baidu.com/view/596875.h ...
- jQuery执行请求demo
Ajax教程地址 4.3.2 执行GET请求 使用jQuery来执行GET请求有多种可选的方法.最简单的方法是使用$.get(),其参数是一个URL和一个回调函数:该回调函数有两个参数:一个是从服务器 ...
- [转]javascript指定事件处理程序包括三种方式:
javascript指定事件处理程序包括三种方式: (1):DOM0级事件处理程序 如: 代码如下: var btn=document.getElementById("mybtn" ...
- swift 定义类方法(type methed)
swift 中声明结构体或者枚举的类型方法,需要在func前加上关键字 ststic ,但是如果要定义一个类的类方法时,需要用关键字 class class SomeClass { class ...
- android开发之路04(初级android工程师必会,你懂得!)
Android初级Android工程师重点掌握内容如下: 1.Android开发基础: ①UI界面设计: ②SQLite数据库: ③android四大组件: ④android网络编程: ⑤androi ...
- 让ubuntu开启ssh服务以及让vi/vim正常使用方向键与退格键
VIM 修复方法: 安装vim full版本,在full版本下键盘正常,安装好后同样使用vi命令.ubuntu预装的是vim tiny版本,而需要的是vim full版本.执行下面的语句安装vim f ...
- npm更换淘宝镜像
镜像使用方法(三种办法任意一种都能解决问题,建议使用第三种,将配置写死,下次用的时候配置还在): 1.通过config命令 npm config set registry https://regist ...
- Map集合的两种遍历方式
Map集合:即 接口Map<K,V> map集合的两种取出方式: 1.Set<k> keyset: 将map中所有的键存入到set集合(即将所有的key值存入到set中) ...
- think straight系列读书笔记之《暗时间》
一周一篇读书笔记,这是第零篇,为啥从零计数,你们懂的~ 大二读了<暗时间>,这本书带我进入了心理学的大门,让我开始关注思维,专注,效率,认知,记忆等东西.两年之后重读这本书,依然收获很 ...