void Awake()
{
shootableMask = LayerMask.GetMask("Shootable");
gunParticles = GetComponent<ParticleSystem>();
gunLine = GetComponentsInChildren<LineRenderer>();
(省略)
}
public void Shoot
(
bool isPierce,
bool isDiffuse,
int numBullet,
AudioClip fireClip,
float range,
int damagePerShot,
int maxNbPower,
int maxAmmo
)
{
//ワンクリックで同時発射するRayの本数を指定
numRay = numBullet;
shootRay = new Ray[numRay];
//射撃SEへ差し替え&再生
gunAudio.clip = fireClip;
gunAudio.Play();
//マズルフラッシュの表示
gunLight.enabled = true;
//射撃エフェクト 直前に出てたものの中断と新たに表示
gunParticles.Stop();
gunParticles.Play();
//Rayの始点(マズル固定)と方向(一定範囲内でランダム)をnumRayの数だけ設定。
//弾道を表す
for (int i = 0; i < numRay; i++)
{
shootRay[i].origin = transform.position;
float x;
float z;
//SG用の処理
if (isDiffuse)
{
//弾の拡散範囲
float shootAngle = Random.Range(45.0f, 135.0f);
x = Mathf.Cos(shootAngle);
//z = Mathf.Sin(shootAngle);
}
else
{
x = 0f;
//z = 0f;
}
shootRay[i].direction = transform.forward + new Vector3(x, 0, 0);
//射線の表示と始点位置指定
gunLine[i].enabled = true;
gunLine[i].SetPosition(0, transform.position);
}
for (int i = 0; i < numRay; i++)
{
//SRの処理
if (isPierce)
{
RaycastHit[] hits = Physics.RaycastAll(shootRay[i]);
foreach (var obj in hits)
{
//Rayがぶつかった対象にEnemyHealthコンポーネントがついていたら(=エネミーだったら)
EnemyHealth enemyHealth = obj.collider.GetComponent<EnemyHealth>();
if (enemyHealth != null)
{
enemyHealth.TakeDamage(damagePerShot, obj.point);
//ノックバック角度の振れ幅
float x = Random.Range(-0.5f, 0f);
float z = Random.Range(-0.5f, 0f);
//ノックバック距離の振れ幅
int nbPower = Random.Range(1, maxNbPower);
//角度の振れ幅を加算
//距離の振れ幅を乗算して代入
obj.collider.GetComponent<UnityEngine.AI.NavMeshAgent>().velocity = (shootRay[i].direction.normalized + new Vector3(x, 0, z)) * nbPower;
}
}
//射線の終点を射程とイコールに
gunLine[i].SetPosition(1, shootRay[i].origin + shootRay[i].direction * range);
}
else
{
if (Physics.Raycast(shootRay[i], out shootHit, range, shootableMask))
{
//Rayがぶつかった対象にEnemyHealthコンポーネントがついていたら(=エネミーだったら)
EnemyHealth enemyHealth = shootHit.collider.GetComponent<EnemyHealth>();
if (enemyHealth != null)
{
//エネミーの体力減らす&&被弾エフェクト表示処理
enemyHealth.TakeDamage(damagePerShot, shootHit.point);
//ノックバックの実装
//NavmeshAgentが付与されているオブジェクトにAddForceしても効かない
//https://docs.unity3d.com/Manual/nav-MixingComponents.html
//Move the player agent using NavMeshAgent.velocity, so that other agents can predict the player movement to avoid the player.
//ノックバック角度の振れ幅
float x = Random.Range(-0.5f, 0f);
float z = Random.Range(-0.5f, 0f);
//ノックバック距離の振れ幅
int nbPower = Random.Range(1, maxNbPower);
//角度の振れ幅を加算
//距離の振れ幅を乗算して代入
shootHit.collider.GetComponent<UnityEngine.AI.NavMeshAgent>().velocity = (shootRay[i].direction.normalized + new Vector3(x, 0, z)) * nbPower;
}
//衝突地点を終点に
gunLine[i].SetPosition(1, shootHit.point);
}
else
{
//rayが何にもぶつからなかった時の射線終点指定
gunLine[i].SetPosition(1, shootRay[i].origin + shootRay[i].direction * range);
}
}
}
//残弾数を減らす
currentAmmo--;
//残弾数UIを減らす
//1でなく1.0fで書かないとちゃんと割り算の結果が小数で返らないっぽい
ammoFullImg.fillAmount -= 1.0f / maxAmmo;
}