Unity5.1.1p3 Personal(2015年7月)
前回の続きです〜
今回はゾンビAIを作成していきます〜
UNET Part 12 - Zombies! - YouTube
【目標】ゾンビAIを出現させる
①ゾンビオブジェクトを作成する
まずはゾンビAIを作っていきましょう〜HierarchyビューからCreate > 3DObject > Cubeを選択し、名前を「Zombie」にし、Transformを以下のように設定します〜
Zombieオブジェクト作成
続いてMaterialを作成し、Zombieオブジェクトに取り付けます〜
名前は「Zombie Green」で、色は緑色です〜
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)の手前で止まるようにします〜
Nav Mesh Agent設定
続いてZombieオブジェクトをプレハブ化します〜
ドラッグ&ドロップ! 元オブジェクトは削除
最後にAIの移動範囲を設定します〜Window > Navigationを選択し、
Window > Navigation
NavigationビューにてMesh Rendererを選択します〜すると、HierarchyビューにMesh Rendererのついたオブジェクトのみが表示されます〜
表示されたオブジェクトを全て選択し、Navigation Staticにチェックを入れて下さい〜
Navigation Staticにチェック
次にBakeビューに切り替え、デフォルト設定のままBakeボタンを押します〜すると、Navigationビュー下にExporting Tilesというバーが出てきます〜
Mesh RendererにAIが動ける範囲を焼いているところなので、バーが満タンになるまで待ちましょう〜
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に変更しておきます〜
続いてZombieプレハブに先ほど作成したZombie_Targetスクリプトを取り付けて下さい〜すると、Network系のスクリプトのため自動的にNetwork Identityコンポーネントが取り付けられます〜
ついでにAdd Component > Network > Network Transformも取り付けて下さい〜
また、Rotation Axisのみ「Y (Top-Down 2D)」に変更しておいて下さい〜
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が自動的に付くのを確認して下さい〜
SerializeFieldの変数2つも、Inspectorビューから指定してあげましょう〜
ドラッグ&ドロップ!
Hostサーバーがログインした時にOnStartServerメソッドが実行され、SpawnZombiesメソッドが10回繰り返されます〜
SpawnZombiesメソッドではzombiePrefabをInstantiateによって生成し、NetworkServer.Spawnメソッドにてゾンビを全てのクライアントと同期します〜
NetworkServer.Spawnの対象となったプレハブは、Network Managerにて登録しておかなければなりません〜
というわけでMenuシーンを開き、NetworkManagerのSpawn Info一番下にあるRegistered Spawnable PrefabにZombieプレハブを登録して下さい〜
ドラッグ&ドロップ!
これでゾンビが発生してくれるはずです〜
⑤結果
実行する前にZombieSpawnオブジェクトの位置を遠くにしておきます〜
遠くに離す
それでは実行してみましょう〜
近い
結構離したつもりですが、あっという間に間合いを詰められました〜
とにかくゾンビを出現させることに成功しました!
今回はここまでです〜
ありがとうございました〜
【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】