和之前的普通攻击模式不同,普通攻击是利用射线与制定层物体进行碰撞,返回单点的碰撞信息。在进行射线穿透攻击时,首先要做好各个字段以及相关变量、方法的准备工作。
修改特殊攻击相关方法的重要核心是
specialAttackHitInfo = Physics.RaycastAll(testRay, 100, attactHitMask)
与该语句相关的参量定义如下
private RaycastHit[] specialAttackHitInfo;
laser.gameObject.SetActive(true);
laser.SetPosition(0, gunBarrelEnd.position);
//枪口的粒子效果开始播放
fireParticle.Play();
//枪口灯光激活
fireLight.enabled = true;
//以枪口位置为起点,枪口正前方为方向,产生一条3D射线
Ray testRay = new Ray(gunBarrelEnd.position, gunBarrelEnd.forward);
//发射射线,记录碰撞信息和碰撞结果
specialAttackHitInfo = Physics.RaycastAll(testRay, 100, attactHitMask);
以下是specialattack的方法
private void PlayerSpecialAttack()
{
//如果按下鼠标左键
if (Input.GetAxis("Fire1") > 0)
{
//激光线激活
laser.gameObject.SetActive(true);
//枪口的粒子效果开始播放
fireParticle.Play();
//枪口灯光激活
fireLight.enabled = true;
//设置线渲染器的起点和终点
laser.SetPosition(0, gunBarrelEnd.position);
laser.SetPosition(1, gunBarrelEnd.position + gunBarrelEnd.forward * 100);
//以枪口位置为起点,枪口正前方为方向,产生一条3D射线
Ray testRay = new Ray(gunBarrelEnd.position, gunBarrelEnd.forward);
//发射射线,记录碰撞信息和碰撞结果
specialAttackHitInfo = Physics.RaycastAll(testRay, 100, attactHitMask);
//bool值,指示是否有敌人受到伤害
bool specialDamageValidState = false;
//遍历碰撞信息数组
for(int i = 0; i < specialAttackHitInfo.Length; i++)
{
//如果第i个物体时敌人
if (specialAttackHitInfo[i].transform.gameObject.layer == LayerMask.NameToLayer("Enemy"))
{
//特殊攻击处于未冷却状态
if (specialAttackColdState == false)
{
//第i个敌人受到伤害
specialAttackHitInfo[i].transform.GetComponent<Enemy>().TakeDamage(specialAttackDamage);
//有至少一个敌人受到伤害
specialDamageValidState = true;
}
}
}
//如果只要有一个敌人受到伤害
if (specialDamageValidState)
{
//特殊攻击进入冷却
specialAttackColdState = true;
}
}
//否则
else
{
StopSpecialAttack();
}
}
对比普通攻击normalattack方法
private void PlayerNormalAttack()
{
//如果按下鼠标左键
if (Input.GetAxis("Fire1") > 0)
{
//激光线激活
laser.gameObject.SetActive(true);
laser.SetPosition(0, gunBarrelEnd.position);
//枪口的粒子效果开始播放
fireParticle.Play();
//枪口灯光激活
fireLight.enabled = true;
//以枪口位置为起点,枪口正前方为方向,产生一条3D射线
Ray testRay = new Ray(gunBarrelEnd.position, gunBarrelEnd.forward);
//发射射线,记录碰撞信息和碰撞结果
bool hitResult = Physics.Raycast(testRay, out normalAttackHitInfo, 100, attactHitMask);
//如果射线和制定层的物体发生碰撞
if (hitResult)
{
//设置激光渲染器的终点
laser.SetPosition(1, normalAttackHitInfo.point);
//在渲染器的终点处生成一个粒子效果
if (hitParticle == null)
{
hitParticle = Instantiate(Resources.Load<GameObject>("Prefabs/BulletFatExplosionFire"), normalAttackHitInfo.point, Quaternion.identity) as GameObject;
}
else
{
//若之前已经生成射击点,则更新该粒子的位置
hitParticle.transform.position = normalAttackHitInfo.point;
}
}
//否则
else
{
//设置激光渲染器的终点
laser.SetPosition(1, gunBarrelEnd.position + 100 * gunBarrelEnd.forward);
}
//如果射线碰到的物体是敌人
if (normalAttackHitInfo.transform.gameObject.layer == LayerMask.NameToLayer("Enemy"))
{
//如果普通攻未冷却
if(normalAttackColdState == false)
{
//敌人受到伤害
normalAttackHitInfo.transform.GetComponent<Enemy>().TakeDamage(normalAttackDamage);
normalAttackColdState = true;
}
}
}
//否则
else
{
StopNormalAttack();
}
}