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

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

【Unity9】UNETでゾンビAIを出現させる!【UNET12】

Unity5.1.1p3 Personal(2015年7月)


前回の続きです〜


今回はゾンビAIを作成していきます〜



UNET Part 12 - Zombies! - YouTube

【目標】ゾンビAIを出現させる

①ゾンビオブジェクトを作成する

まずはゾンビAIを作っていきましょう〜HierarchyビューからCreate > 3DObject > Cubeを選択し、名前を「Zombie」にし、Transformを以下のように設定します〜


f:id:hiyotama:20150716092905p:plain
Zombieオブジェクト作成


続いてMaterialを作成し、Zombieオブジェクトに取り付けます〜
名前は「Zombie Green」で、色は緑色です〜


f:id:hiyotama:20150716093241p:plain
Material作成


続いてZonbieオブジェクトにNav Mesh Agentコンポーネントを取り付けていきます〜Add ComponentからNavigation > Nav Mesh Agentを選択して下さい〜


Nav Mesh Agentは、指定した範囲内でAIを移動させるための機能です〜
移動範囲が限定されているため、障害物を自動的に避けさせたりしたい時に便利です〜


Agent SizeのRadius(半径)を0.6にし、AIの半径を若干大きくします〜
また、Stopping Distanceを2.5にし、ターゲット(Player)の手前で止まるようにします〜


f:id:hiyotama:20150716094745p:plain
Nav Mesh Agent設定


続いてZombieオブジェクトをプレハブ化します〜


f:id:hiyotama:20150716095059p:plain
ドラッグ&ドロップ! 元オブジェクトは削除


最後にAIの移動範囲を設定します〜Window > Navigationを選択し、


f:id:hiyotama:20150716095540p:plain
Window > Navigation


NavigationビューにてMesh Rendererを選択します〜すると、HierarchyビューにMesh Rendererのついたオブジェクトのみが表示されます〜
表示されたオブジェクトを全て選択し、Navigation Staticにチェックを入れて下さい〜


f:id:hiyotama:20150716095724p:plain
Navigation Staticにチェック


次にBakeビューに切り替え、デフォルト設定のままBakeボタンを押します〜すると、Navigationビュー下にExporting Tilesというバーが出てきます〜
Mesh RendererにAIが動ける範囲を焼いているところなので、バーが満タンになるまで待ちましょう〜


f:id:hiyotama:20150716100106p:plain
Bakeボタンをクリック


②AI用のスクリプトを作成する
ゾンビAIの元となるオブジェクトの作成と、AIが移動できる範囲指定が完了しました〜


続いてAI用のスクリプトを作成していきます〜
名前はZombie_Targetにします〜以下ソースです〜

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;
	//ゾンビがPlayerを探知する半径
	private float radius = 100f;
	
	// Use this for initialization
	void Start () {
		agent = GetComponent<NavMeshAgent>();
		myTransform =transform;
		raycastLayer = 1<<LayerMask.NameToLayer("Player");
	}
	
	// Update is called once per frame
	void FixedUpdate () {
		SearchForTarget();
		MoveForTarget();
	}
	
	void SearchForTarget ()
	{
		//サーバーじゃなければメソッド終了
		if (!isServer) {
			return;
		}
		
		//Playerをまだ取得していない時
		if (targetTransform == null) {
			//Physics.OverlapSphere: ある地点を中心に球を作り、衝突したオブジェクトを取得する
			//第1引数: 中心点 第2引数: 半径 第3引数: 対象のレイヤー
			Collider[] hitColliders = Physics.OverlapSphere (myTransform.position, radius, raycastLayer);
			if (hitColliders.Length > 0) {
				int randomInt = Random.Range(0, hitColliders.Length);
				targetTransform = hitColliders[randomInt].transform;
			}
		}
		//Playerは取得しているがBox Colliderが非アクティブの時 = isDeadがtrueの時
		if(targetTransform != null && targetTransform.GetComponent<BoxCollider>().enabled == false){
			targetTransform = null;
		}
	}
	
	void MoveForTarget ()
	{
		//Playerオブジェクト取得済みで、自分がサーバーの時
		if (targetTransform != null && isServer) {
			SetNavDestination(targetTransform);
		}
	}
	
	void SetNavDestination (Transform dest)
	{
		//ゾンビAIの目的地設定
		agent.SetDestination(dest.position);
	}
}

Zombie_Target.cs


FixedUpdateメソッド内で、2つのメソッドを呼び出しています〜


1つ目はSearchForTargetメソッドで、Playerを探しています〜

まずは自分がサーバーで無い場合はメソッドを抜けます〜

続いてOverlapSphereを使い、ゾンビの位置からradiusを半径とした球を作り、その範囲内のPlayerオブジェクトを取得します〜

取得できたら、複数取得した場合はPlayer1体に絞り込みます〜

取得したPlayerオブジェクトのBoxColliderが非アクティブの時、つまり殺されてisDeadがtrueになった時は、ターゲットから外します〜


2つ目はMoveForTargetメソッドです〜

Playerオブジェクト取得済みで自分がサーバーの時、SetNavDestinationメソッドを呼び、AIが進む目的地としてPlayerの位置が指定されます〜

③ゾンビを発生させるポイントを作成

ゾンビを発生させるポイントを作っていきます〜Mainシーンで、HierarchyビューからCreate > Create Emptyを選択し、名前を「ZombieSpawn」に変更して下さい〜
Position.yだけ1に変更しておきます〜


f:id:hiyotama:20150716123426p:plain


続いてZombieプレハブに先ほど作成したZombie_Targetスクリプトを取り付けて下さい〜すると、Network系のスクリプトのため自動的にNetwork Identityコンポーネントが取り付けられます〜


ついでにAdd Component > Network > Network Transformも取り付けて下さい〜
また、Rotation Axisのみ「Y (Top-Down 2D)」に変更しておいて下さい〜


f:id:hiyotama:20150716123745p:plain
Network Transformを取り付ける

④ゾンビ生成用スクリプトを作成

ZombieSpawnができたので、そこからゾンビを発生させるスクリプトを作っていきます〜


今回はGameManagerにつけていくので、「GameManager_ZombieSpawner」という名前にします〜

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

public class GameManager_ZombieSpawner : NetworkBehaviour {

	[SerializeField] GameObject zombiePrefab;
	[SerializeField] GameObject zombieSpawn;
	
	private int counter;
	private int numberOfZombie = 10;
	
	public override void OnStartServer ()
	{
		for (int i = 0; i < numberOfZombie; i++) {
			SpawnZombies();
		}
	}
	
	void SpawnZombies()
	{
		//counter(後ほど何かを実装)
		
		GameObject go = GameObject.Instantiate(zombiePrefab, zombieSpawn.transform.position, Quaternion.identity) as GameObject;
		NetworkServer.Spawn(go);
	}
	
	// Use this for initialization
	void Start () {
	
	}
	
	// Update is called once per frame
	void Update () {
	
	}
}

GameManager_ZombieSpawner.cs


まずはGameManagerオブジェクトに取り付けます〜
すると、先程と同様にNetwork Identityが自動的に付くのを確認して下さい〜


f:id:hiyotama:20150716132535p:plain


SerializeFieldの変数2つも、Inspectorビューから指定してあげましょう〜


f:id:hiyotama:20150716132725p:plain
ドラッグ&ドロップ!


Hostサーバーがログインした時にOnStartServerメソッドが実行され、SpawnZombiesメソッドが10回繰り返されます〜


SpawnZombiesメソッドではzombiePrefabをInstantiateによって生成し、NetworkServer.Spawnメソッドにてゾンビを全てのクライアントと同期します〜


NetworkServer.Spawnの対象となったプレハブは、Network Managerにて登録しておかなければなりません〜

というわけでMenuシーンを開き、NetworkManagerのSpawn Info一番下にあるRegistered Spawnable PrefabにZombieプレハブを登録して下さい〜


f:id:hiyotama:20150716133436p:plain
ドラッグ&ドロップ!


これでゾンビが発生してくれるはずです〜

⑤結果

実行する前にZombieSpawnオブジェクトの位置を遠くにしておきます〜


f:id:hiyotama:20150716134028p:plain


f:id:hiyotama:20150716134036p:plain
遠くに離す


それでは実行してみましょう〜


f:id:hiyotama:20150716134100p:plain
近い


結構離したつもりですが、あっという間に間合いを詰められました〜

とにかくゾンビを出現させることに成功しました!


今回はここまでです〜

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


【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】