游戏制作之路(14)模拟子弹的制作

前面介绍对角色的控制,以及对视野的控制,接着下来需要为这个游戏更加有趣一点,就是要发射子弹出去,把挡着角色的物体破坏掉,或者说把游戏里的NPC打死,让每个过上英雄的美梦,当成一个救世主,当成一个现代的花木兰。那么你会问怎么样来添加子弹到这个游戏里呢?先来认识一个问题,子弹也是一个物体,也是一个游戏物体,为了简单起见,我们使用一个球体来当作子弹,当这个子弹碰到其它物体时,就要爆炸,接着子弹就消失了。如果玩家不断地发射,又会出来一个新的子弹,因此,子弹是可以克隆的。另外子弹与其它游戏物体有交互的,就是碰撞交互,当子弹碰到别的物体时,就要做相应的处理,比如子弹要消失,而消失就是子弹要删除掉。

在unity里已经备好了很多功能,现在就来创建子弹,先来创建一个球体,如下图:

这样就创建了一个球体,把它命名为Rocket,接着把它的缩放参数设置为(0.5, 0.5,0.5),如下图:

从上图看到,子弹的球体已经创建起来了,关键是大小的设置,位置是为了查看到,所以把它提高了一点。接着下来要设置子弹与其它物体的碰撞关系,先要这项Sphere Collider component Is Trigger设置为true,如下图:

在这里把Rocket设置IsTigger为true,意思就是说子弹是一个触发器,而不是碰撞器。你也许会问,勾选这个选项有什么用呢?可以从官方的解释来先看一下:

public bool isTrigger;
Description
Is the collider a trigger?

A trigger doesn't register a collision with an incoming Rigidbody. Instead, it sends OnTriggerEnter, OnTriggerExit and OnTriggerStay message when a rigidbody enters or exits the trigger volume.

其意思就是说,当物体当作一个触发器时,它不会注册到刚体碰撞检测系统里,它只会发送碰撞信息到函数OnTriggerEnter、OnTriggerExit和OnTriggerStay。那你又会问,为什么不要注册呢?其实我们知道物理的碰撞检测系统是很费资源的,它需要计算所有三角形是否相交,并且还要计算物理力的方向等等,另外一个原因,就是碰到另外一个物体时,不让这个物体做运动。比如子弹非常小,打入一个很大的物体,这个物体惯性很大,是基本不会动的,比如子弹打到大地里,地球是不会感觉动的。如果不勾选这个选项,那么这个物体就是一个碰撞器了。另外,由于子弹一般是深入被打的物体里面的,所以子弹不能作为一个刚体碰撞器,被弹飞出去,所以也要选择为触发器。

碰撞器和触发器的区别?
1、碰撞器是触发器的载体,而触发器只是碰撞器身上的一个属性。
2、当IsTrigger=false时,碰撞器根据物理引擎引发碰撞,产生碰撞的效果,可以调用OnCollisionEnter/Stay/Exit函数;
3、当IsTrigger=true时,碰撞器被物理引擎所忽略,没有碰撞效果,可以调用OnTriggerEnter/Stay/Exit函数。
4、如果既要检测到物体的接触又不想让碰撞检测影响物体移动或要检测一个物件是否经过空间中的某个区域这时就可以用到触发器。

到这里,我们设计子弹作为一个触发器,当子弹碰到任何物体时都想触发OnTriggerEnter消息,其实刚刚有这个Sphere Collider是办不到的,为什么呢?我们来看下unity里的手册:

从上表可以看到,如果没有刚体组件,与其它一些物体碰撞时并没有碰撞消息触发,因此需要给子弹再添加一个组件Rigidbody,并且设置Kinematic为true,这时子弹就被设置为最后这一行的物体属性了,不管它碰到什么物体,都会有触发消息了,这时就可以控制子弹的消失了,不会让子弹一直在飞,而没有消亡的机会。

所以,如下图地添加一个刚体组件:

设置Kinematic为true,如下图:

到这里,已经把子弹的属性全部设置好,也作好了所有考虑,就差代码了。其实与前面的角色移动一样,就是移动位置,但也有点不一样,子弹是深入其它物体里的,所以不要使用character控制器,而直接使用位置移动即可,因此,子弹的移动也需添加两个变量,一个是子弹的移动速度,一个是子弹的生命周期。为Rocket物体添加脚本代码如下:

这里增加了一个脚本名称为Rocket,并且在里面增加了两个变量,整个代码如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Rocket : MonoBehaviour {

    public float speed = 20.0f;
    public float life = 5.0f;

    // Use this for initialization
    void Start () {
		
	}
	
	// Update is called once per frame
	void Update () {
        transform.position += transform.forward * speed * Time.deltaTime;

    }
}

公共访问的变量两个,在Update函数里添加子弹移动的代码,这里使用transform.position移动子弹,前面已经说过了,因为子弹可以穿入物体里,而不使用角色控制器。为了检测到碰撞,需要在代码里增加OnTriggerEnter消息响应,如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Rocket : MonoBehaviour {

    public float speed = 20.0f;
    public float life = 5.0f;

    // Use this for initialization
    void Start () {
		
	}
	
	// Update is called once per frame
	void Update () {
        transform.position += transform.forward * speed * Time.deltaTime;

    }

    void OnTriggerEnter(Collider col)
    {
        Kill();
    }

    void Kill()
    {
        Destroy(gameObject);
    }
}

这里也增加了一个函数Kill(),它是调用Destroy()函数来删除当前脚本绑定的游戏对象gameObject,这里就子弹本身了。为了测试子弹在Start里添加一行代码,如下:

    // Use this for initialization
    void Start () {
        Invoke("Kill", life);
    }

接着下来,你就可以按play了,发现一个小球突然离开屏幕,直接往屏幕里飞去,再过一段时间,子弹对象就不见,因为它死掉了。

如果调整其它四方体的位置,让这个子弹刚好碰到,发现子弹就消失了,游戏对象也删除了。

你也能动手修改C编译器

http://edu.csdn.net/course/detail/5582

纸牌游戏开发

http://edu.csdn.net/course/detail/5538 

五子棋游戏开发

http://edu.csdn.net/course/detail/5487
RPG游戏从入门到精通
http://edu.csdn.net/course/detail/5246

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

caimouse

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值