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游戏制作 ...
随机推荐
- File transfer in android with asmack and Openfire
http://harryjoy.com/2012/08/18/file-transfer-in-android-with-asmack-and-openfire/ http://www.javacod ...
- 学习笔记之Python
http://baike.baidu.com/view/21087.htm?fr=aladdin#reference-[12]-21087-wrap Python 基础教程(http://www.w3 ...
- 四、Socket之UDP异步传输文件-用控件显示文件传输进度
上一篇文章三.Socket之UDP异步传输文件中,实现了多文件的传输和MD5校验,还显示了文件传输过程中的信息,在这一篇文章中,将介绍怎样实现传输文件的进度显示和实现选择保存文件路径. 首先,来实现一 ...
- C#_IComparer实例 - 实现ID或者yearOfscv排序
调用LIST的Sort的时候会调用IComparer的默认实现,quicksort会调用每个元素的CompareTo的IComparable实现 using System; using System. ...
- VS2012 编译GDAL
先安装VS 2012, 然后下载GDAL最新版本代码,解压. 用管理员权限打开Developer Command Prompt for VS2012终端,进入代码目录. 然后运行命令: nmake / ...
- (转载)c语言指针学习
前言 近期俄罗斯的陨石.四月的血月.五月北京的飞雪以及天朝各种血腥和混乱,给人一种不详的预感.佛祖说的末法时期,五浊恶世 ,十恶之世,人再无心法约束,道德沦丧,和现在正好吻合.尤其是在天朝,空气,水, ...
- 检测 NSObject 对象持有的强指针
在上一篇文章中介绍了 FBRetainCycleDetector 的基本工作原理,这一篇文章中我们开始分析它是如何从每一个对象中获得它持有的强指针的. 如果没有看第一篇文章这里还是最好看一下,了解一下 ...
- 使用GDB调试Android NDK native(C/C++)程序
使用GDB调试Android NDK native(C/C++)程序 先说明下,这里所谓的ndk native程序跟Android上层java应用没有什么关系,也不需要涉及jni来封装native接口 ...
- 将Word、Excel内容显示在Winform界面
这里使用到dsoframer.ocx插件 1. 首先下载dsoframer.ocx插件,下载地址: http://pan.baidu.com/s/1kTKHeIj 2. 注册该插件 Win7的做法是按 ...
- C#一些小知识点
1. 在Load时候由代码来做控件PictureBox,并且用代码将图片加载进去: private void Form2_Load(object sender, EventArgs e) { Dire ...