这次先加入子弹的发射吧,没用模型,先用的一个capsule的prefab代替吧。
一想到各种武器之间的随意切换,就不由的想到了设计模式中的Strategy模式。
有关策略模式的详细介绍可以通过百度和维基来学习。
这个模式其实和State模式差不多。
Weapon类是所有武器的基类,新的武器继承于它,设置发射点,子弹模型,然后实现Fire函数就可以了。
WeaponManager用于管理所有武器,切换武器。
using UnityEngine; using System.Collections; public class WeaponManager : MonoBehaviour { public Weapon m_CurWeapon; private float m_FireElapseTime = 0; // Use this for initialization void Start () { } // Update is called once per frame void Update () { m_FireElapseTime += Time.deltaTime; if (Input.GetKey(KeyCode.Space)) { if ( m_FireElapseTime > m_CurWeapon.GetBulletInterval()) { m_CurWeapon.Fire(); m_FireElapseTime = 0; } else { } } } }
记录子弹发射后的时间,然后在大于时间间隔后才能发射下一个子弹。
武器父类:
using UnityEngine; using System.Collections; using System; public class Weapon : MonoBehaviour { //子弹时间间隔 protected float m_fBulletInterval = 0; //子弹类型 public String m_typeName =""; public float GetBulletInterval() { return m_fBulletInterval; } // Use this for initialization void Start () { } // Update is called once per frame void Update () { } public virtual void Fire() { } }
最基本的一种子弹:
using UnityEngine; using System.Collections; public class WeaponNormal : Weapon { private const int MAX_FP = 2; public Transform[] m_FirePoint = new Transform[MAX_FP]; public Rigidbody m_BulletPre; WeaponNormal() { m_fBulletInterval = 2; m_typeName = "Normal"; } // Use this for initialization void Start () { } // Update is called once per frame void Update () { } public override void Fire() { for(int i = 0; i < MAX_FP; i++) { Rigidbody clone = (Rigidbody)Instantiate(m_BulletPre, m_FirePoint[i].position, m_FirePoint[i].rotation); clone.velocity = transform.TransformDirection(Vector3.forward * 20); } } }
m_FirePoint是一个数组,存储了发射子弹的位置。在编辑器中,可以在飞机周围用空的GameObject放置一系列炮口的位置,然后拖入这个数组中。MAX_FP定义了炮口的数量。这里边用到了速度属性,这个是rigidbody才有的,所以在设置子弹的prefab时一定要为它加上rigidbody才行。
结构如下图所示:
最后的效果图:
现在子弹出来了,但是我们没有加上子弹的消亡,这样子弹被创建出来后就一直存在于场景中不会消失,会越积越多,所以我们让子弹在移出屏幕时就把他销毁掉。
using UnityEngine; using System.Collections; public class BulletControl : MonoBehaviour { // Use this for initialization void Start () { } // Update is called once per frame void Update () { Vector3 screenPos = Camera.mainCamera.WorldToScreenPoint(this.transform.position); //print(screenPos.y); if (Screen.height < screenPos.y) Destroy(transform.gameObject); } }
将这个脚本挂接在子弹的prefab上就可以实现效果了。