博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Unity3d--Space Shooter(官方教程)--学习感想(3)
阅读量:5052 次
发布时间:2019-06-12

本文共 5187 字,大约阅读时间需要 17 分钟。

游戏环境已经基本搭建完成。

接下来需要用脚本实现飞船的移动、射击、爆炸等效果。


脚本语言采用C#

并在Project视图中创建一个专门存放脚本的目录。

选择Assets。Create->Folder创建一个新文件夹,更名为Scripts。

3.1  给飞船添加移动功能

点击Player,Add Component->New Script。更名为Player Controller。

并将它放在Scripts目录中。

通过物理的方式移动飞船,需要用到FixedUpdate()函数。

此函数会在每个固定的物理步骤前自动调用。

Input.GetAxis----->return the value of the virture axis identified by axisname.

可通过键盘或是操纵杆去实现输入。它返回的值在-1与1之间。

如果通过鼠标控制,则返回的值不在-1与1之间,而是根据鼠标的灵敏度而定。

首先定义水平和垂直方向的移动参数:

1 float moveHorizontal = Input.GetAxis("Horizontal");2 float moveVertical = Input.GetAxis("Vertical");

 Vector3: 表示3D的点和矢量。Vector3(x,y,z)类似于空间坐标系。

由于飞船在Y轴上移动无任何改变,可设置y值为0.0f。

x可表示水平移动,赋值为moveHorizontal。

z代表垂直移动,赋值为moveVertical。

rigidbody.velocity: 刚体的速度向量。

定义一个全局变量speed,使其与Vector3对象相乘,而此值可赋值给velocity用来调节飞船移动速度。

1 Vector3 movement = new Vector3(moveHorizontal, 0.0f, moveVertical);2 GetComponent
().velocity = movement * speed;

 3.2  限制飞船移动范围

当飞船移动时,会出现一个问题。

当我们无限左移(或是其他方向移动)飞船时,由于游戏界面是有限的,

我们可能会将飞船移至视野之外。因此,控制飞船的移动范围是十分必要的。

我们通过rigidbody.velocity移动飞船,也可以通过限制rigidbody的位置来限制飞船。

在移动飞船之前,需要先限制飞船的移动范围。

当我们要把飞船移动到范围之外时,代码会限制它停在边缘。

利用rigidbody.position去限制飞船位置。

rigidbody.position=new Vector3(x,y,z);

飞船的上下位置不需要设置(y值的大小对飞船在Game View中的位置显示没有影响)

因此设置其值为0.0f(float类型)。

飞船四个方向的位置移动显示只受x和z的影响。

在此之前,了解一下Mathf:A collection of common math function.

我们要用的函数是“Clamp”,它包含两个值,最大和最小。

Clamp:Clamps a value between a minimum float and maximum float value.

public static int Clamp(int value,int min ,int max);

 

通过测试飞船位置,可得到飞船行驶的位置范围,并将其赋值给相应的变量。

1 GetComponent
().position = new Vector32 (3 Mathf.Clamp(GetComponent
().position.x, boudary.xMin, boudary.xMax),4 0.0f,5 Mathf.Clamp(GetComponent
().position.z, boudary.zMin, boudary.zMax)6 );

 

其中xMin等变量设置为全局变量,这样可在Inspector视图对应的Script中调节变量值。

但这四个变量占用了不少的空间,而且只能被此脚本使用。

那么,能不能想办法整理这个空间,使它能重复调用。

重建一个class命名为Boundary

1 [System.Serializable]2 public class Boundary3 {4     public float xMin, xMax, zMin, zMax;5 }

 

然后,创建一个Boundary对象boundary。利用该对象调用xMin等值。

注意[System.Serializable]不能少。它能够序列化我们的class,只有完成了序列化,

才能显示在Inspector中。

如下图:

3.3  使飞船在运动的时候倾斜

利用rigidbody.rotation。

rigidbody.rotation = Quaternion.Euler(x,y,z);

我们只需让飞船沿z轴旋转,因此可设置x,y值为0.0f。

代码如下:

GetComponent
().rotation = Quaternion.Euler(0.0f,0.0f,GetComponent
().velocity.x * -tilt);

 

其中tilt为全局变量,可通过它调节飞船的旋转幅度。

3.4  创建子弹

注意一点,当创建完子弹以后如何去掉黑边、如何令子弹高亮。

即,将子弹的Shader设置为Additive(Mobile->Particles->Additive)

之后,需要给子弹添加rigidbody(去掉Use Gravity)

为了更准确的完成碰撞效果,添加Capsule Collider,根据子弹形状大小去调整Collider。

3.4.1  子弹运动脚本

 Start()函数,会在对象实例化的最前帧执行。

我们需要子弹沿z轴向上移动,因为障碍物会从反方向飞过来。

z轴是子弹运动的方向。同时,还需控制子弹运动的速度。

1 public float speed;2 void Start()3 {4     GetComponent
().velocity = transform.forward * speed;5 }

 

 Transform.forward:The blue axis of the transform in world space.

 其中blue axis应该表示z axis。

3.4.2  给飞船添加发射子弹功能

 之前的子弹已经保存至Prefabs文件夹中作为资源使用。

当玩家点击屏幕时,会实例化一个子弹的克隆体。

检测按钮输入事件与物理无关,因此不需要在FixedUpdate()函数中发射子弹。

故,可将此代码写入Update()中。

Unity会在每一帧刷新前执行Update()中的代码。

实例化子弹:

Object.Instantiate(Object original,Vector3 position,Quaternion rotation) 

Clones the object original and returns the clone

实例化需要三个值,分别为:目标物体、位置、方向。

点击屏幕,发射子弹。

Input.GetButton:

Returns true while the virtual button identified by buttonName is held down。

1 public GameObject shot; //子弹 2 public Transform shotSpawn; //依附于飞船的子弹容器 3 public float fireRate; //子弹发射的速率 4 private float nextFire;  5 void Update() 6 { 7      if (Input.GetButton("Fire1") && Time.time > nextFire) 8     { 9           nextFire = Time.time + fireRate;10       Instantiate(shot, shotSpawn.position, shotSpawn.rotation);11           GetComponent
().Play();12 }13 }

 

3.4.3  子弹发射边界

在子弹连续不断的发射过程中,就会产生出无限的子弹克隆体。

这样会很影响电脑的运行效果。

因此,需要给子弹设置一个边界,当它超出这个边界之后就会销毁。

Create->Cube

由于边界与子弹之间需要用到触发器,故勾选Is Trigger。

调节Cube(边界),使它铺满整个Game View。

禁用Mesh Renderer,在Game View中便看不到Cube了。

当子弹离开Cube之后,销毁它。

Collider.OnTriggerExit(Collider):

OnTriggerExit is called when the Collider other has stopped touching the trigger.

1 void OnTriggerExit(Collider other)2 {3     Destroy(other.gameObject);4 }

 

3.5  添加障碍物

障碍物添加方法与之前的飞船、子弹相似,不再阐述。(Rigidbody、Capsule Collider)

给障碍物添加旋转效果:

rigidbody.angularVelocity:物体旋转的速率。

给它设置一个随机数,这样看起来更真实。

Random.insideUnitSphere:Vector3类型方法,它会产生x,y,z随机数。

1 public float tumble;2 void Start()3 {4     GetComponent
().angularVelocity = Random.insideUnitSphere * tumble;5 }

 

当障碍物在旋转的过程中,由于受到阻力的影响,最终会停下。

因此,需要将Rigidbody下的drag和angular drag设置为0。

3.5.1  障碍物与子弹碰撞

Collider.OnTriggerEnter:

OnTriggerEnter is called when the Collider other enters the trigger。

此时要做一个判断,因为障碍物是处于Cube中的,如果单纯的利用该方法,

那么只要运行,障碍物就会消失。

void OnTriggerEnter(Collider other){   if(other.tag == "Boundary")  //判断是否为Cube,将Boundary的Tag设置为"Boundary"     {           return;     }       Destroy(other.gameObject);  //销毁障碍物       Destroy(gameObject);  //销毁子弹   }

 

3.5.2  爆炸

当子弹或是飞船和障碍物碰撞时,实例化对应的爆炸效果。

子弹:

Instantiate(explosion, transform.position, transform.rotation);

 

飞船:

1 if (other.tag == "Player")  //将Player的Tag设置为"Player"2 {3     Instantiate(playerExplosion, other.transform.position, other.transform.rotation);4     gameController.GameOver();5 }

 

令障碍物向飞船方向移动。

将之前写好的子弹的Mover脚本拖拽至障碍物中去,改变它的速度为负值。

 

转载于:https://www.cnblogs.com/wkcode/p/7246062.html

你可能感兴趣的文章
cocos2d-x 2.2.6 之 .xml文件数据读取
查看>>
枚举的使用
查看>>
BZOJ 1531 二进制优化多重背包
查看>>
BZOJ 2324 (有上下界的)费用流
查看>>
python3基础06(随机数的使用)
查看>>
Zookeeper系列(二)特征及应用场景
查看>>
【HTTP】Fiddler(三)- Fiddler命令行和HTTP断点调试
查看>>
Spring Boot使用Druid和监控配置
查看>>
poi 处理空单元格
查看>>
Android 内存泄漏优化总结
查看>>
luogu4849 寻找宝藏 (cdq分治+dp)
查看>>
Spring Cloud微服务笔记(五)Feign
查看>>
C语言键盘按键列表
查看>>
Codeforces Round #374 (Div. 2)
查看>>
oracle数据类型
查看>>
socket
查看>>
Vue中使用key的作用
查看>>
二叉索引树 树状数组
查看>>
日志框架--(一)基础篇
查看>>
Java设计模式之原型模式
查看>>