Unity3d--Space Shooter(官方教程)--学习感想(3)

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

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


脚本语言采用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<Rigidbody>().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<Rigidbody>().position = new Vector3
2 (
3     Mathf.Clamp(GetComponent<Rigidbody>().position.x, boudary.xMin, boudary.xMax),
4     0.0f,
5     Mathf.Clamp(GetComponent<Rigidbody>().position.z, boudary.zMin, boudary.zMax)
6 );

 

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

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

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

重建一个class命名为Boundary

1 [System.Serializable]
2 public class Boundary
3 {
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<Rigidbody>().rotation = Quaternion.Euler(0.0f,0.0f,GetComponent<Rigidbody>().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<Rigidbody>().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<AudioSource>().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<Rigidbody>().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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值