弹幕的实现参考了蛮牛上清风的文章 http://www.manew.com/thread-142463-1-1.html
首先是最简单的弹幕——散弹
按照清风的思路,只需要修改发射点的方向,然后让子弹一直往自身前方走就可以了。但是清风只实现了三个子弹的散弹。我改造成了比较灵活的方法,参数里传几就发几颗子弹。思路大致如下:
散弹弹幕是以中心方向为起点向左右两边转向的,那么奇数和偶数的起点就不一致了,如果是奇数还是按照以中心方向为起点,如果是偶数则以左边第一个方向为起点。
子弹发射顺序为一左一右,如下图:
那么只需要给定一个偏移量(每次偏移多少)和一个标志位(标识在左边还是在右边)然后去遍历即可。标识位使用一个整型,为负时在左边,正数时在右边,当为整数时表明这一轮已经结束,要进入下一轮,此时偏移量增加一倍。代码如下:
public void FanBarrage(int bulletID,int num,Vector3 position)
{
//设置为永久奇数
//num = num % 2 == 0 ? num + 1 : num;
//子弹中间子弹发射方向
Vector3 bulletDir = Vector3.up;
//Vector3 bulletDir = player.position - position;
//Debug.Log(bulletDir);
//偏移量
float offset = num % 2 != 0 ? 10 : 5;
//初始偏移量
float firstOffset = (num % 2) == 0 ? offset : 0;
//生成子弹
int left = (num % 2) == 0 ? -1 : 1;
for (int i = 0; i < num; i++)
{
//设置方向
Quaternion dir = Quaternion.AngleAxis(left * firstOffset, bulletDir);
//从对象池或一个对象
GameObject go = ObjectPool.Instance.GetObj(ShootConst.BULLETNAMES[bulletID]);
//设置子弹位置
go.transform.position = position;
EnemyBullet enemyBullet = go.AddComponent<EnemyBullet>();
//设置子弹旋转
enemyBullet.qua = dir;
//开火
enemyBullet.Fire(bulletID);
//下一轮
if (left > 0)
{
firstOffset += offset;
}
left = -left;
}
}
圆形弹幕和螺旋弹幕
圆形弹幕
只要设置的子弹数量够多,自然就成圆形弹幕了。
进阶圆形弹幕
只需要将圆形弹幕做成一个预设体,这样再圆形弹幕销毁时再发射原型弹幕的预设体就可以了。
螺旋弹幕
同原型弹幕类似,只是发射时需要做一个延迟,每发一颗子弹停一下再发另一颗,发出来的子弹也是圆形弹幕预设体。
public void SpiralBarrage(int bulletID,int num,Vector3 position)
{
StartCoroutine(Spiral(bulletID, num,position));
}
IEnumerator Spiral(int bulletID, int num,Vector3 firPosition)
{
//子弹发射初始方向
Vector3 bulletDir = Vector3.up;
//螺旋次数
int SpiraCount = 15;
//角度偏移量
float offset = 360 / SpiraCount;
//初始弹幕爆炸时间
float boomTime = 0.002f;
//时间增量
float boomTimeIncrement = 0.0005f;
//螺旋时间间隔
float time = 0f;
for (int i = 0; i < SpiraCount; i++)
{
//计算旋转后的方向
Quaternion dir = Quaternion.AngleAxis(i*offset,bulletDir);
GameObject go = ObjectPool.Instance.GetObj(ShootConst.BULLETNAMES[bulletID]);
//设置子弹位置
go.transform.position = firPosition;
FanBarrage fanBarrage = go.AddComponent<FanBarrage>();
//设置子弹旋转
fanBarrage.qua = dir;
//开火
fanBarrage.Fire(num);
//暂停
yield return new WaitForSeconds(time);
}
}













网友评论