Unity5(C#)初心者・入門者向けチュートリアル ひよこのたまご

AndroidやiOS向けアプリを簡単に作れるゲーム開発環境Unity(ユニティ)の使い方を、チュートリアル方式で一緒に学びましょう!

【Unity9】UNETでゾンビを撃つ!【UNET14】

いつもひよこのたまごをご利用下さいましてありがとうございます!
おかげ様でチュートリアル数も10ゲーム目となりました!
チュートリアル一覧は
こちら からどうぞ!


スポンサーリンク

Unity5.1.1p3 Personal(2015年7月)


前回の続きです〜


今回はゾンビを攻撃する処理を追加していきます〜



UNET Part 14 - Shoot Those Zombies! - YouTube

【目標】ゾンビを攻撃する

①Player_Shootingスクリプトの修正

まずはPlayer_Shootingスクリプトの修正をしていきます〜


その前に、「Zombie」という名前をタグを作成し、Zombieプレハブに取り付けていきます〜


f:id:hiyotama:20150716143327p:plain
Zombieタグを付ける


それではスクリプトを修正していきます〜以下ソースです〜

using UnityEngine;
using System.Collections;
using UnityEngine.Networking;

public class Player_Shooting : NetworkBehaviour {
	
	private int damage = 25;
	private float range = 200;
	[SerializeField] private Transform camTransform;
	private RaycastHit hit;

	void Update () {
		CheckIfShooting();
	}
	
	void CheckIfShooting ()
	{
		if (!isLocalPlayer) {
			return;
		}
		
		if (Input.GetKeyDown(KeyCode.Mouse0)) {
			Shooting();
		}
	}
	
	void Shooting ()
	{
		if (Physics.Raycast (camTransform.TransformPoint (0, 0, 0.5f), camTransform.forward, out hit, range)) {
			
			if (hit.transform.tag == "Player") {
				string uIdentity = hit.transform.name;
				CmdTellServerWhoWasShot(uIdentity, damage);
			}
			
//********** 開始 **********//
			//タグがZombieだった場合
			else if (hit.transform.tag == "Zombie") {
				//名前を取得して
				string uIdentity = hit.transform.name;
				//名前とダメージ量を引数にメソッド呼び出し
				CmdTellServerWhickZombieWasShot(uIdentity, damage);
			}
//********** 終了 **********//
		}
	}
	
	[Command]
	void CmdTellServerWhoWasShot (string uniqueID, int dmg)
	{
		GameObject go = GameObject.Find(uniqueID);
		go.GetComponent<Player_Health>().DeductHealth(dmg);
	}
	
//********** 開始 **********//
	[Command]
	void CmdTellServerWhickZombieWasShot (string uniqueID, int dmg)
	{
		//IDのオブジェクトを取得して
		GameObject go = GameObject.Find(uniqueID);
		//オブジェクトのHPをダメージ量分だけ減らす
		go.GetComponent<Zombie_Health>().DeductHealth(dmg);
	}
//********** 終了 **********//
}

Player_Shooting.cs


修正箇所は2点ですが、どちらもすぐ上の処理をコピペしています〜
タグをZombieに変更した点と、呼び出しメソッド名をCmdTellServerWhickZombieWasShotに変更した点、ダメージを与える先をZombie_Healthスクリプトに変更した点が違います〜

②Zombie_Healthスクリプトを新規作成

続いてZombie_Healthスクリプトをしんkに作成して、ゾンビにHPを付けていきます〜
作成したスクリプトはZombieプレハブに取り付けて下さい〜

using UnityEngine;
using System.Collections;
using UnityEngine.Networking;

public class Zombie_Health : NetworkBehaviour {

	private int health = 50;

	public void DeductHealth(int dmg)
	{
		health -= dmg;
		CheckHealth();
	}
	
	void CheckHealth ()
	{
		if (health < 0) {
			Destroy(gameObject);
		}
	}
}

Zombie_Health.cs


先ほどPlayer_Shootingスクリプトに追加された処理から、DeductHealthメソッドを呼び出しています〜
healthを減らし、0より少なくなったらDestroyにてゾンビを消しています〜


ゲームを実行してみましょう〜


f:id:hiyotama:20150716145949p:plain
2発当てるとゾンビが消える


HPを50に設定したので2発当てたらゾンビは消えます〜

③Zombie_Targetスクリプトの処理を軽くする

Zombie_TargetスクリプトのFixedUpdateメソッドから2つのメソッドを呼び出しています〜
FixedUpdateはデフォルトだと0.02秒に1回呼び出されるので、1秒に50回実行されます〜ちょっと多すぎます〜


なので、コルーチンを使い0.2秒に1回呼び出すように修正していきます〜以下ソースです〜

using UnityEngine;
using System.Collections;
using UnityEngine.Networking;

public class Zombie_Target : NetworkBehaviour {

	private NavMeshAgent agent;
	private Transform myTransform;
	private Transform targetTransform;
	private LayerMask raycastLayer;
	private float radius = 100f;
	
	void Start ()
	{
		agent = GetComponent<NavMeshAgent> ();
		myTransform = transform;
		raycastLayer = 1 << LayerMask.NameToLayer ("Player");
		
//********** 開始 **********//
		//コルーチンの実行
		if (isServer) {
			StartCoroutine("DoCheck");
		}
//********** 終了 **********//
	}
	
	void FixedUpdate () {
//********** 削除 **********//
//		SearchForTarget();
//		MoveForTarget();
//********** 終了 **********//
	}
	
	void SearchForTarget ()
	{
		if (!isServer) {
			return;
		}
		
		if (targetTransform == null) {
			Collider[] hitColliders = Physics.OverlapSphere (myTransform.position, radius, raycastLayer);
			if (hitColliders.Length > 0) {
				int randomInt = Random.Range(0, hitColliders.Length);
				targetTransform = hitColliders[randomInt].transform;
			}
		}
		if(targetTransform != null && targetTransform.GetComponent<BoxCollider>().enabled == false){
			targetTransform = null;
		}
	}
	
	void MoveForTarget ()
	{
		if (targetTransform != null && isServer) {
			SetNavDestination(targetTransform);
		}
	}
	
	void SetNavDestination (Transform dest)
	{
		agent.SetDestination(dest.position);
	}
	
	IEnumerator DoCheck()
	{
		//無限ループ
		for(;;)
		{
			SearchForTarget();
			MoveForTarget();
			//0.2秒待つ
			yield return new WaitForSeconds(0.2f);
		}
	}
}

Zombie_Target.cs


FixedUpdate内にあったメソッドはコルーチンへ移動させ、コルーチンはStartメソッドから呼び出されています〜
これで処理が軽くなりました〜


それでは、今回はここまでです〜

ありがとうございました〜


【Unity9】UNETでマルチプレイヤーなオンラインゲーム開発【UNET1】
【Unity9】UNETでプレイヤーの動きを補間し、なめらかな動きを実現する【UNET1-2】
【Unity9】UNETでネットワーク越しに傾き(Rotation)を同期させる【UNET2】
【Unity9】UNETでオンライン開始時のプレイヤー生成位置を変更する【UNET2-2】
【Unity9】UNETのネットワークトラフィックを軽減し、効率化する【UNET3】
【Unity9】UNETのlatency(遅延時間)を改善する【UNET4】
【Unity9】UNETのlatency(遅延時間)を表示して、ちょっとだけ改善する【UNET4-2】
【Unity9】UNETのSyncVarのhookの使用例と、前時代の同期方法【UNET5】
【Unity9】UNETを使ってRotationを同期させる【UNET6】
【Unity9】UNETで各プレイヤーにPlayerIDを設定する【UNET7】
【Unity9】UNETで敵プレイヤーにダメージを与える!【UNET8】
【Unity9】UNETでHPを画面に表示し、Playerへダメージを与える【UNET9】
【Unity9】UNETでHPが0以下になった時、Playerを破壊する!【UNET10】
【Unity9】UNETで死んだPlayerを生き返らせる!【UNET11】
【Unity9】UNETでゾンビAIを出現させる!【UNET12】
【Unity9】UNETでゾンビ生成時にユニークなIDを付ける!【UNET13】
【Unity9】UNETでゾンビを撃つ!【UNET14】
【Unity9】UNETでゾンビに攻撃させる!【UNET15】
【Unity9】UNETでゾンビの動きをスムーズにシンクロさせる!【UNET16】
【Unity9】UNETでゾンビ発生地点を増やす【UNET17】
【Unity9】UNETで発生したバグを取り除く【UNET18】
【Unity9】Unity MultiPlayerを使ってネットワーク越しにマッチメイキング!【UNET19】
【Unity9】GUIを改善して、Network Managerを見やすくする!【UNET20】
【Unity9】表示したGUI(Network Manager)を機能させる!【UNET20-2】
【Unity9】UNETでAnimationを同期させる!【UNET21】