【Unity公式チュートリアル】 サバイバルシューター part.9 敵を攻撃する!
こんにちは!ヤギです!
Unity公式チュートリアルのサバイバルシューターをやってみるpart.9になります。
記事概要
今回の記事では、敵を攻撃する方法についてご説明していきます。プレイヤーの銃から弾が発射されるようにしていきます!
※part.9に対応する公式チュートリアルは、
Harming Enemies - Unityとなります。
※前回の記事はこちら
www.yagigame.com
銃を撃つエフェクトの作成
まず初めに、銃を撃つエフェクトを作っていきます。1. Project > Assets > Prefabs > GunParticles > Inspector > Particle System > ギアマークをクリックし、Copy Componentを選択します。
2. Hierarchy > Player > GunBulletEnd > Inspector > Transform > ギアマークをクリックし、Paste Component As Newを選択します。
3. Hierarchy > Player > GunBulletEnd > Inspector > Add Componentを選択し、Line Rendererコンポーネントを追加します。
※Line Rendererコンポーネントを利用して、レーザーのような射線を描写していきます!
4. Line Rendererコンポーネントを以下の内容に修正します。
・Materials > Element0 > LineRenderMaterial
・Width > 0.05
・Line Renderer > すぐ左のチェックをオフにします。※デフォルトでは描写せず、銃を撃った時のみ描写するようにします。
5. Hierarchy > Player > GunBulletEnd > Inspector > Add Componentを選択し、Lightコンポーネントを追加します。
※銃を光らせるエフェクトを追加します。
6. Lightコンポーネントを以下の内容に修正します。
・Color > 黄色
・Ligh > すぐ左のチェックをオフにします。※デフォルトでは光らせず、銃を撃った時のみ光るようにします。
7. Hierarchy > Player > GunBulletEnd > Inspector > Add Componentを選択し、Audio Sourceコンポーネントを追加します。
※銃の効果音を追加します。
8. Audio Sourceコンポーネントを以下の内容に修正します。
・Audio Clip > Player GunShot
・Play On Awake > チェックをオフにします。※ゲーム開始と共に音を鳴らさず、銃を撃った時のみ鳴るようにします。
※これで銃を発射するエフェクトが完成しました。
弾を撃つスクリプトを作成
1. Project > Assets > Scripts > Player > PlayerShootingをHierarchy > GunBarrelEndにドラッグし適用します。2. PlayerShooting.csを弾を撃つためのスクリプトとして作成していきます。Rayという機能を使用しています。
※スクリプト内に解説を記載しています。
using UnityEngine; public class PlayerShooting : MonoBehaviour { public int damagePerShot = 20; //弾のダメージ public float timeBetweenBullets = 0.15f; //弾を撃つ間隔 public float range = 100f; //弾の飛距離 float timer; //経過時間 Ray shootRay = new Ray(); //rayを、弾の攻撃範囲とする RaycastHit shootHit; //弾が当たった物体 int shootableMask; //撃てるもののみ識別する //弾を打った時のエフェクト ParticleSystem gunParticles; LineRenderer gunLine; AudioSource gunAudio; Light gunLight; float effectsDisplayTime = 0.2f; void Awake () { //Shootable Layerを取得 shootableMask = LayerMask.GetMask ("Shootable"); //コンポーネントを取得 gunParticles = GetComponent<ParticleSystem> (); gunLine = GetComponent <LineRenderer> (); gunAudio = GetComponent<AudioSource> (); gunLight = GetComponent<Light> (); } void Update () { //経過時間を計測 timer += Time.deltaTime; //弾を打つボタンを押した時、かつ経過時間が弾を打つ間隔よりも大きい場合 if(Input.GetButton ("Fire1") && timer >= timeBetweenBullets && Time.timeScale != 0) { //弾を打つ Shoot (); } //経過時間がエフェクトの表示時間よりも大きくなった場合 if(timer >= timeBetweenBullets * effectsDisplayTime) { //エフェクトを非表示にする DisableEffects (); } } //銃を撃つエフェクトをオフにする処理 public void DisableEffects () { gunLine.enabled = false; gunLight.enabled = false; } //弾を撃つ処理 void Shoot () { //経過時間を初期化 timer = 0f; //弾を撃つエフェクトをオンにする gunAudio.Play (); gunLight.enabled = true; //弾を連写することを想定して、オフにしてからオンにする gunParticles.Stop (); gunParticles.Play (); //射線のスタート位置を設定する gunLine.enabled = true; gunLine.SetPosition (0, transform.position); //弾の攻撃範囲のスタート位置を設定する shootRay.origin = transform.position; //弾の飛んでいく方向を設定する shootRay.direction = transform.forward; //弾を飛ばし、(Rayを飛ばし、障害物に当たった場合 if(Physics.Raycast (shootRay, out shootHit, range, shootableMask)) { //弾が当たった障害物のEnemyHealthスクリプトコンポーネントを取得する EnemyHealth enemyHealth = shootHit.collider.GetComponent <EnemyHealth> (); //EnemyHealthスクリプトコンポーネントがnullではない場合(敵に弾が当たった場合) if(enemyHealth != null) { //敵にダメージを与える enemyHealth.TakeDamage (damagePerShot, shootHit.point); } //射線を障害物で当たった場所で止める gunLine.SetPosition (1, shootHit.point); } //障害物に当たらなかった場合 else { //射線を弾の飛距離分表示する gunLine.SetPosition (1, shootRay.origin + shootRay.direction * range); } } }
3. Hierarchy > Player > Inspector > Applyをクリックし、変更内容をPlayer Prefabに反映します。
※これで弾を撃つスクリプトが完成しました。
EnemyMovement.csを修正
1. EnemyMovement.csを修正します。※敵とプレイヤーが生きている場合のみ、敵を移動させるようにします。
using UnityEngine; using System.Collections; public class EnemyMovement : MonoBehaviour { Transform player; PlayerHealth playerHealth; //プレイヤーのHP EnemyHealth enemyHealth; //敵のHP UnityEngine.AI.NavMeshAgent nav; //NavMesh Agent(敵) void Awake () { //プレイヤータグのゲームオブジェクトを探し、場所を取得する player = GameObject.FindGameObjectWithTag ("Player").transform; playerHealth = player.GetComponent <PlayerHealth> (); //プレイヤーのHPを取得する enemyHealth = GetComponent <EnemyHealth> (); //敵のHPを取得 //NavMeshAgentコンポーネントを取得する nav = GetComponent <UnityEngine.AI.NavMeshAgent> (); } void Update () { //敵とプレイヤーが生きている場合 if(enemyHealth.currentHealth > 0 && playerHealth.currentHealth > 0) { //NavMesh Agent(敵)をプレイヤーに向かって動かす nav.SetDestination (player.position); } //敵もしくは、プレイヤーが倒されている場合 else { nav.enabled = false; } } }
※これで、敵とプレイヤーが生きている場合のみ、敵が移動するようになりました。
PlayerHealth.csの修正
1. PlayerHealth.csを修正します。※プレイヤーが倒された場合、弾を撃てなくします。
using UnityEngine; using UnityEngine.UI; //UIを使うために必要 using System.Collections; using UnityEngine.SceneManagement; public class PlayerHealth : MonoBehaviour { public int startingHealth = 100; //スタート時点のHP public int currentHealth; //最新のHP public Slider healthSlider; //HPバー public Image damageImage; //攻撃された時の画像 public AudioClip deathClip; //倒された時の効果音 public float flashSpeed = 5f; //攻撃された時の画像の表示速度 public Color flashColour = new Color(1f, 0f, 0f, 0.1f); //攻撃された時の画像の色 Animator anim; //アニメーション AudioSource playerAudio; //音楽 PlayerMovement playerMovement; //PlayerMovementスクリプト PlayerShooting playerShooting; //PlayerShootingスクリプト bool isDead; //プレイヤーが倒されているかのフラグ bool damaged; //プレイヤーがダメージを受けているかのフラグ void Awake () { //コンポーネントを設定 anim = GetComponent <Animator> (); playerAudio = GetComponent <AudioSource> (); playerMovement = GetComponent <PlayerMovement> (); playerShooting = GetComponentInChildren <PlayerShooting> (); //体力を初期化 currentHealth = startingHealth; } void Update () { //プレイヤーがダメージを受けた場合 if(damaged) { //攻撃された時の画像の色を設定する damageImage.color = flashColour; } //ダメージを受けていない場合 else { //攻撃された時の画像の色をクリアする damageImage.color = Color.Lerp (damageImage.color, Color.clear, flashSpeed * Time.deltaTime); } //ダメージを受けているかのフラグをオフにする damaged = false; } //プレイヤーが攻撃された時の処理 public void TakeDamage (int amount) { //ダメージを受けているかのフラグをオンにする damaged = true; //プレイヤーのHPを減らす currentHealth -= amount; //HPバーを減らす healthSlider.value = currentHealth; //攻撃を受けた時の効果音を鳴らす playerAudio.Play (); //HPが0以下になった場合、かつ既にたい押されていない場合、倒される if(currentHealth <= 0 && !isDead) { Death (); } } //プレイヤーが倒された場合の処理 void Death () { //プレイヤーが倒されているかのフラグをオンにする isDead = true; //弾を撃つエフェクトをオフにする playerShooting.DisableEffects (); //倒された時のアニメーションのフラグをオンにする anim.SetTrigger ("Die"); //倒された時の効果音を設定する playerAudio.clip = deathClip; //倒された時の効果音を鳴らす playerAudio.Play (); //プレイヤーを動けなくする playerMovement.enabled = false; //弾を撃てなくする playerShooting.enabled = false; } public void RestartLevel () { SceneManager.LoadScene (0); } }
※これでプレイヤーが倒された場合、弾が撃てなくなります。
実行してみましょう!
マウスを左クリックすると弾が発射され、敵を倒すことができれば大成功です!次回予告
次回は、敵を倒した時に加算されるスコア機能を作成していきます!次回に対応する公式チュートリアルは、「Scoring points」です!
読んでいただきありがとうございました!