Unityを使った3Dゲームの作り方(かめくめ)Unityを使った3Dゲームの作り方(かめくめ)ゲーム開発エンジンUnityを使った3Dゲームの制作に参考になる情報を公開しています。5今回は主人公との距離が縮まったら敵キャラが主人公を攻撃してくる機能を作ってみます。前回までで主人公が敵キャラの検知エリアに入った時に追いかけてくるところまで作りました。Unityで主人公キャラが近づいてきたら追いかける敵キャラを作るUnityで主人公キャラクターが敵キャラクターに近づいたら敵が主人公に近づいてくるようにしたいと思います。13:11まずは前回まで敵の移動スクリプトをMoveEnemyとしていましたが、攻撃機能も取り付けるのでファイル名とクラス名をEnemyに変更します(面倒な方は特に変えなくてもいいです)。それに伴いSetPositionスクリプトのMoveEnemyとしていた箇所をEnemyに変更します。Storeでアニメーション用のデータをインポートしましょう。Zombieをインポートしました。キャラクターに付いているattackとdamageいうアニメーションを使います。敵キャラクターが主人公に近づいた時に攻撃する為には前回作成した機能のように敵キャラクターが主人公を追いかける必要があります。主人公を追いかけている状態で、一定の距離内に主人公がきたら敵は攻撃を繰り出します。一回攻撃をした後も主人公がその場に留まっている場合は攻撃の範囲内にいるのですぐにまた攻撃をしてしまいます。そこで一回攻撃をしたら次に攻撃するまでのフリーズ状態を作ることにします。フリーズ状態が終わったら見回りに戻ります。この時敵のSearchAreaのコライダ内にまだ主人公がいた時は見回り状態(Walk)→追いかける状態(Chase)と遷移し、さらに攻撃範囲内にいれば追いかける状態(Chase)→攻撃状態(Attack)と遷移させるようにします。敵キャラクターの攻撃処理を作成していきます。敵キャラの状態を追記Enemyスクリプトに処理を加えます。敵キャラクターの状態を増やします。{Walk,Wait,Chase,Attack,Freeze};EnemyStateに攻撃状態と攻撃後のフリーズ状態を作ります。次は敵キャラが攻撃に遷移するスクリプト部分をEnemyスクリプトのUpdateメソッド内に追加します。Time.deltaTime);}攻撃後のフリーズ状態を続ける時間をインスペクタで設定出来るようにします。状態がEnemyState.Chaseの時に主人公と1mの距離内に入ったらEnemyState.Attack状態にします。距離の計算はVector3.Distanceで計算出来ます。SetStateメソッドに攻撃状態と攻撃後状態を追加EnemyスクリプトのSetStateメソッド内にEnemyState.Attack状態と攻撃後のEnemyState.Freeze状態へ変更する処理を追加します。false);}}アタック状態、フリーズ状態ともにvelocityの値をVector3.zeroで0にして、移動処理を行わないようにします。アニメーションパラメータのSpeedも0にしておきます。SetStateでEnemyState.Freeze状態に変更されるのは攻撃アニメーションが終わった時にイベントとして受け取ったメソッドで行われます。次に敵のAnimatorControllerの設定をしていきます。アニメーションパラメータAttackをBoolとして作成します。Transitionします。ConditionsにAttackを追加し、WalkとIdleからatack01への遷移条件に『Attackがtrue』の時を入れます。Timeのチェックを外しておきます。このチェックが入っていると条件がOnになっても元のアニメーションの再生が終わらないと次のアニメーションに行きません。Transitionを繋げます。Timeのチェックを外し、条件にAttackがfalseになった時を入れておきます。攻撃が終了したら何もしていない状態に遷移させる為です。敵キャラの攻撃の当たり判定部分(コライダ)を作るアニメーターコントローラーの設定が終わったので、次は敵キャラの攻撃の当たり判定部分を作成していきます。プレハブを修正するので、一旦、敵キャラのプレハブをヒエラルキー上にドラッグ&ドロップし、修正します。攻撃の辺り判定部分にコライダを設定します。↑のように敵キャラの右手の部分にSphereColliderを追加します。SphereColliderはスクリプトでOn・Offするので最初はチェックを外しておきます。AttackZombieという名前で新しいスクリプトを作成し、SphereColliderの設定してある右手の手の部分に設定します。AttackZombieスクリプトは後で作成します。SphereColliderを上のような感じで設定し当たり部分を大きめに取ります。この部分が主人公のCharacterControllerのコライダに当たったら攻撃が当たったという処理をします。修正が終わったら敵キャラのインスペクタ上にあるPrefabのApplyボタンをクリックしプレハブに反映させておきます。反映させたらヒエラルキー上の敵キャラはいらないのでチェックをはずすか削除しておきます。anime.fbxを選択し、インスペクタでRigがHumanoidになるようにし、次にAnimationタブをクリックします。atack01を選択したら赤く印をつけた場所にチェックを入れます。アニメーションの動きによってオブジェクトに回転や移動を加えないようにし、スクリプトで制御する為です。アニメーションイベントを作成する次はアニメーションの再生位置でイベントを発生させるようにしてみます。上のようにEventsの所をクリックし、下のマークをクリックします。新しいウインドウが出てくるのでAttackStartとAttackEnd、StateEndというイベントを作り、赤でマークをした位置に移動させます。終了を設定する為にこの位置にしています。(微調整してください)FloatやIntはそのイベント発生時に渡せる引数の値です。渡さない場合は変更しなくて大丈夫です。これでこのアニメーションが再生され、イベントの個所にくるとAnimatorが設定されているオブジェクトにAttackStart、AttackEnd、StateEndというイベントが送られます。このイベントを受け取るスクリプトはあとで作成します。これでアニメーションの途中でイベントを投げる事が出来るようになりました。アニメーションイベントを受け取り、当たり判定のオン・オフをするスクリプト敵のゲームオブジェクトにProcessEnemyAnimEventスクリプトを新しく作成し取り付けます。ProcessEnemyAnimEventスクリプトはアニメーションのイベントを受け取るスクリプトになります。{enemy.SetState(Enemy.EnemyState.Walk);}}インスペクタでSphereCollider(手に取り付けた攻撃の当たり判定用コライダ)を設定出来るようにします。Startメソッド内でEnemyスクリプトを取得しています。AttackStartとAttackEndはさきほど設定したアニメーションから送られてくるイベントを受け取りますので、AttackStartを受け取ったらコライダをOnにし、当たり判定を有効にします。AttackEndを受け取ったら、コライダをOffにし、当たり判定を無効にします。攻撃後(StateEnd)はEnemyState.Freezeに設定します。アニメーションイベントの問題?このアニメーションイベントで全てうまくいきそうですが、場合によっては呼ばれない事があります。それは例えば敵が攻撃開始後すぐに主人公に攻撃を受けて攻撃アニメーションのアニメーションイベント部分までの再生がされず、ダメージアニメーションへ遷移してしまう時です。AttackEndが呼ばれないと敵の手のコライダがオフにならないままになってしまいます。そんな時はビヘイビアを使用するとうまくいきます。Unityでアニメーションイベントが実行されない時の為にビヘイビアを設定しておくUnityでアニメーションを即時遷移させているとアニメーションイベントが実行されない時があります。そんな時にビヘイビアを設定しておくと確実に処理を実行する事が出来ます。Timeにチェックをして攻撃アニメーションを最後まで再生させます。攻撃の当たり判定をするスクリプト次はAttackZombieスクリプトです。{Debug.Log("当たり");col.GetComponent<CharacterScript>().TakeDamage(transform.root);}}}Playerタグを持つインスタンスに当たったらキャラクター操作スクリプトCharacterScriptのTakeDamageメソッド(ダメージ処理メソッド)を実行させます。引数としてこのスクリプトが設定されているオブジェクトのルート(敵キャラ)のTransform情報(位置情報)を渡しています。主人公キャラのCharacterScriptスクリプトのTakeDamageメソッドに敵キャラのTransform情報を渡すという事になります。これで敵キャラの攻撃の処理が出来ました。攻撃された主人公キャラ側の処理をまだ作っていないので、攻撃されても主人公は棒立ち状態のままです。敵キャラクターの子要素のSearchAreaに取り付けた主人公検知スクリプトのSearchCharacterスクリプト内を修正します。col.transform);}}}以前は敵キャラクターがEnemyState.Chase状態以外の時のチェイス状態にしましたが、EnemyState.WaitもしくはEnemyState.Walk状態の時だけチェイス状態にするようにします。主人公側の攻撃を受けた時の処理を作成していきます。攻撃を受けた時の処理を主人公操作スクリプトに追加します。さきほど攻撃を受けた時にTakeDamage関数を実行する処理を記述したので、主人公側で攻撃を受けた時の処理を書いていきます。state;主人公側でも今何をしている状態か?を列挙体と記憶しておくフィールドstateを作ります。0.5f);}TakeDamageメソッドが呼ばれたら、状態stateをダメージを受けている状態MyState.Damageに変更し、主人公キャラのアニメーションパラメータのDamageトリガーをOnにします。攻撃を受けた際に敵の向いている方向に動かしたい時は、コメントアウトしている部分を有効にします(今回は攻撃を受けても動かしません)。主人公のアニメーターコントローラにダメージ状態と遷移を作成する主人公キャラクターのAnimatorControllerを修正します。StateからDamageに遷移するように作ります。Stateに変更し、何もしていない状態から歩き状態への遷移をスムーズにします)。Timeのチェックを外し、Damageがトリガーされた時にすぐに遷移するようにします。Timeにチェックをします。Timeにチェックをし、SpeedがGreaterで0.1を設定します。Timeにチェックをいれているのでダメージアニメーションが終わるまでは次の状態へ遷移しません。主人公のダメージアニメーションに設定したアニメーションイベントのEndDamageが発生することになります。主人公のダメージアニメーションでイベントを発生させておきます。Zombieのdamageアニメーションを使用します。アニメーションが終了した時にEndDamageイベントを発生させています。主人公キャラクターのダメージアニメーションにアニメーションイベントを設定したので、このイベントを受け取るスクリプトを作成します。ProcessCharaAnimEventスクリプトを新しく作り主人公のゲームオブジェクトに取り付けます。{characterScript.SetState(CharacterScript.MyState.Normal);}}主人公はダメージを受けた後はMyState.Normalに設定します。キャラクター操作処理部分を修正する次に主人公操作スクリプトのUpdateメソッド内を修正します。ダメージを受けている時に方向キー等を押した場合、ダメージを受けながら移動してしまいますので、そうならない為の条件を加えます。Time.deltaTime);}キャラクターの状態がMyState.Normalの時だけ移動処理を行います。終わりにこれで敵の攻撃と主人公が攻撃を受けた時の処理が出来ました。当たり判定の大きさと主人公キャラとの距離の調整をすればそれなりに見えるんではないかと・・・・・。今回の作業はいろいろな個所の設定が必要なので、慣れてない人はどれがどれだか解らないという状態になるかもしれません。説明下手なもので、飛び飛びの解説になってしまいました・・・・。(;_;)次回は攻撃されてばかりではストレスがたまるので主人公も攻撃を出来るようにしてみます。18:39こんばんは、いつもお世話になってます。敵が攻撃したあとウエイトに移行せず攻撃のモーションのまま固まります。それとAttackZombi・ProcessEnemyAnimEvent・ProcessCharaAnimEventのスクリプトを原文そのままunityにいれてもエラーが起きます。18:32こんばんは。いつもお世話になっております。質問しても宜しいでしょうか。この記事の通りにやったのはいいのですが、色々と問題が起こっています。1敵が近づいて攻撃した後、ウエイトに移行せず攻撃のポーズのまま動かなくなる(その後は攻撃のポーズのまま近づいてくる)2ProcessEnemyAnimEvent・ProcessCharaAnimEvent・AttackZombiのスクリプトをUNITYに入れるとエラーが起きる(スクリプトはこの記事の原文そのまま)色々試してみましたがどうしてもできませ出来ません、よろしくお願いします。12:19はじめまして、Unityを始めたばかりの超初心者です。記事通りにスクリプトを記入しても、「敵キャラが出現した瞬間にAttackを行う」「主人公キャラが近づいてもAttackをしてこない」状態になってしまいます。04:01いつも楽しく閲覧させてもらっています。3点ほど気になる箇所がございましたのでコメントさせていただきます。1点目は「主人公用のダメージアニメーションにアニメーションイベントを追加」章の“”アニメーションが終了した時にDamageEndイベントを発生させています。解説スクリプトの都合上、ここの名前をEndDamageにしなくては永遠にstateがNormalにならない問題がありました。2点目は「アニメーターコントローラーで攻撃の状態と遷移を作成」章でParametersでAttackを追加した際に横にある□にチェックを入れないと主人公キャラが攻撃された際、当たり判定周りが動かず、躓きました。GetComponent();上記2つは現時点では特に必要がないように感じました。2点目に関しては過去の記事で解説されている可能性があるかもしれないので見逃していたら申し訳ございません。今後も頑張ってください。22:02まずは1点目EndDamageとDamageEndはいつのまにやら逆に書いていたようです・・・(^_^;)これは修正しました。「アニメーターコントローラーで攻撃の状態と遷移を作成」の部分はアニメーションパラメータのAttackに最初からチェックを入れておくということでしょうか?主人公が攻撃された際ということなので、ゾンビの手の攻撃用のコライダのオン・オフがされていないということで当たり判定がされていないとしたらアニメーションイベントの受け取りがうまくいっていないのかもしれません。アニメーションイベントの受け取りがされているかどうかをAttackStartメソッド内等でDebug.Logを使って処理が行われているかどうかを判定してみるといいかもしれません。次に3点目スクリプトはC#に書き換えた時に前後の記事の機能を一緒に作っていたりしたので、使っていないものが載っていたりすることもあります。(-_-)またブログの当初は機能を積み上げていく形で記事を作っていたのですが、現在は個別にしているのでその影響もあってその記事内で使っていないものが載っていたりもします。コメントをキャンセルメールアドレスが公開されることはありません。コメントデータの処理方法の詳細はこちらをご覧ください。サイト内検索が出来ますプロフィール管理人のかめくめちゃんです。(-_-)メールはこちらにお願いします(記事への質問はコメント欄にお願いいたします)。kamekumechan@gmail.comいずれはSIRENやバイオハザードみたいなアクションゲームを作りたいと思っています。ゲームシナリオが書けないので面白いゲームはなかなか作れません・・・・。(^_^;)名前の由来はカメが好きだからです。プロフィールになってないな・・・・(-.-)Unityをこれから始める人へこれからUnityを使ってみようという方はUnityを使った3Dゲームの作り方(かめくめ)の歩き方Unityを使った3Dゲームの作り方(かめくめ)で、はじめてUnityの学習をする時の当ブログの記事を読む順番を書きました。21:43の記事に記載の順番で見て頂くとUnityの基本的な使い方がわかり、簡単なTPSゲームの作成までが出来ます。Д`)シクシク...お知らせ2020/02/15個人的にUnity2019.3.1f6をインストールしました。2020/01/31個人的にUnity2020.1.0a21(アルファ版)をインストールしました。2018/08/07コメント欄へのわたくしの返信は停止しております。わたくしに出来る事は既に記事にしてあるので、ブログ右上の検索窓を活用してください。(._.)またブログの最初の方の機能を積み上げていく記事に関しての疑問点は当ブログ記事のスクリプトの説明と寄せられた質問への回答Unityを使った3Dゲームの作り方(かめくめ)の機能積み上げ形式の記事のスクリプトの説明と寄せられた記事の機能についての質問への回答を掲載しています。21:41も参照してみてください。コメントの返信はありませんが、回答は記事に反映されている可能性があります。当ブログはハイスピードプランです。WordPressの編集画面の動作が早くなった。Unityを使った3Dゲームの作り方(かめくめ).。