【Unity9】UNETでゾンビに攻撃させる!【UNET15】
Unity5.1.1p3 Personal(2015年7月)
前回の続きです〜
今回は、ゾンビにPlayerを攻撃させてダメージを与えていきたいと思います〜
UNET Part 15 - Zombies Bite Back! - YouTube
【目標】ゾンビにPlayerを攻撃させる!
①Zombie_Attackスクリプトを新規作成
まずはMaterialを新規作成します〜「Zombie Red」という名前で、赤色にして下さい〜
Zombie Redを新規作成
次にZombie_Targetスクリプトを1箇所変更します〜
using UnityEngine; using System.Collections; using UnityEngine.Networking; public class Zombie_Target : NetworkBehaviour { private NavMeshAgent agent; private Transform myTransform; //********** 開始 **********// // private Transform targetTransform; public Transform targetTransform; //********** 終了 **********// private LayerMask raycastLayer; private float radius = 100f; void Start () { 〜省略〜
Zombie_Target.cs
targetTransform変数をpublic変数に変更しました〜
それではZombie_Attackスクリプトを新規作成していきます〜
完成したスクリプトは、Zombieプレハブにつけましょう〜
using UnityEngine; using System.Collections; using UnityEngine.Networking; public class Zombie_Attack : NetworkBehaviour { //次の攻撃までの間隔(秒) private float attackRate = 3; //次に攻撃する時間 private float nextAttack; private int damage = 10; //ダメージ量 private float minDistance = 2; //攻撃の射程距離 //現在のゾンビとPlayerとの距離 private float currentDistance; private Transform myTransform; //現在位置 private Zombie_Target targetScript; //ターゲットの位置 [SerializeField] private Material zombieGreen; //通常時の色 [SerializeField] private Material zombieRed; //攻撃時の色 void Start () { //現在位置とZombie_Targetスクリプトをキャッシュ myTransform = transform; targetScript = GetComponent<Zombie_Target>(); //自分がサーバーだったらコルーチン実行 if (isServer) { StartCoroutine (Attack ()); } } void CheckIfTargetInRange () { //ターゲットが決まっていたら if (targetScript.targetTransform != null) { //ターゲットと自分の距離を計算 currentDistance = Vector3.Distance (targetScript.targetTransform.position, myTransform.position); //ターゲットが射程距離内&ゲーム開始からの経過時間がnextAttackより大きかったら if (currentDistance < minDistance && Time.time > nextAttack) { //nextAttackに3秒足す nextAttack = Time.time + attackRate; //Playerにダメージを与える targetScript.targetTransform.GetComponent<Player_Health>().DeductHealth(damage); StartCoroutine(ChangeZombieMat()); //ホストサーバー向け RpcChangeZombieAppearance(); //クライアントサーバー向け } } } IEnumerator ChangeZombieMat() { //攻撃を実行したら1.5秒間赤くなり、緑に戻る GetComponent<Renderer>().material = zombieRed; yield return new WaitForSeconds(attackRate / 2); GetComponent<Renderer>().material = zombieGreen; } [ClientRpc] void RpcChangeZombieAppearance () { //クライアントサーバー向け StartCoroutine(ChangeZombieMat()); } IEnumerator Attack () { //無限ループ 0.2秒に1回メソッド実行 for (;;) { yield return new WaitForSeconds(0.2f); CheckIfTargetInRange(); } } }
Zombie_Attack.cs
まずはSerialize Fieldに各Materialを指定していきます〜
StartメソッドにてAttackコルーチンを呼び出し、0.2秒に1度CheckIfTargetInRangeメソッドを呼び出します〜
1秒に5回攻撃できるかどうか確認している感じです〜
CheckIfTargetInRangeメソッド内では、まずTargetが決まっているか確認し、決まっていたら射程距離内にいるか&攻撃するタイミングかを確認しています〜
Time.timeがゲームの経過時間を表すので、nextAttackを過ぎていたら攻撃します〜
nextAttackは攻撃の度にattackRate分(デフォルトは3秒)加算されていきます〜
次にPlayer_HealthスクリプトのDeductHealthメソッドを呼び出し、ダメージを与えます〜
次にChangeZombieMatメソッドを呼び出し、攻撃後1.5秒間ゾンビを赤くしています〜
ChangeZombieMatメソッドはホストサーバーからとクライアントサーバーからで別々のルートから呼び出されています〜理由はよく分かりません〜
②なぜかうまくいかなかった点を修正
動画では特別問題なく進んでいたのですが、僕がやったら1つ問題が出てしまいました〜
ゾンビのターゲットに、Player以外にCubeが指定されるパターンがあり、その場合NullReferenceExceptionエラーとなってしまいます〜
Cubeがターゲットに指定される
エラー発生
ゾンビがPlayer_HealthスクリプトのDeductHealthメソッドを呼び出そうとした時、メソッドが付いているのはCubeオブジェクトではなくPlayerオブジェクトなので、NullReferenceExceptionエラーとなったと思われます〜
とりあえずPlayerプレハブをHierarchyビューに戻してCubeを選択し、
CubeのレイヤーをDefaultに戻し、Applyボタンを押し、HierarchyからPlayerを削除します〜
レイヤーを戻してApply
これでエラーは発生しなくなりました〜
③結果
それでは結果を見ていきましょう〜
ゾンビ達の猛攻
しっかりと攻撃モードとなり、ダメージも与えられています〜
今回はここまでです〜
ありがとうございました〜
【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】