当ブログ記事のスクリプトの説明と寄せられた質問への回答

当ブログであるUnityを使った3Dゲームの作り方(かめくめ)のブログの記事で使用しているスクリプトの説明とブログに寄せられた質問への回答を掲載していきたいと思います。

当ブログの最初の数十記事までは記事単体で完結せず機能を積み上げていく形にしていた為、途中の記事だけを見ると以前に作成した機能が出てきたり、その機能に追加するという形になっていることもあります。

そこで最初によく出てくるスクリプトがどんな処理をしているか?等を簡潔に見ていき、さらにブログに寄せられたエラーと考えられる原因を書いていきたいと思います。

基本的には以下の記事で記事の作成の順番を書いているのでどのようなスクリプトを作成しどうやって機能を作成してきたかがわかります。

Unityを使った3Dゲームの作り方(かめくめ)で、はじめてUnityの学習をする時の当ブログの記事を読む順番を書きました。機能を積み上げていく形になるので便利かも?

わたくしの個人的な理由でスクリプト名に番号を振った名前でいきなり出てくる事があるかもしれませんが、記事中では番号を付けたスクリプト名があれば番号がないものとして進めてください。

例えばCharacterScript2というスクリプト名であれば本来はCharacterScriptという名前です。

スポンサーリンク

スクリプトと概要

スクリプトとその機能について簡単に見ていきたいと思います。

主人公キャラクターに取り付けるスクリプト

まずは主人公キャラクターに取り付けるスクリプトについて見ていきます。

Move

主人公キャラクターを動かす目的で作成した最初のスクリプトで主人公に取り付けキャラクターの移動やアニメーションの制御を行っています。

記事を進める事でMoveという名前が合わなくなった為、主人公操作スクリプトはその後CharacterScriptという名前に変更しています。

CharacterScript

Moveスクリプトの名前を変えたのがCharacterScriptで以降主人公操作スクリプトはCharacterScriptとしてます(機能を積み上げる形の記事では)。

CharacterScriptでは主人公キャラクターの状態を保持していてSetStateメソッドでキャラクターの状態を変更、GetStateメソッドでキャラクターの状態を取得出来る為、外部のスクリプトからこれらのメソッドを呼んで主人公の状態を変更したり取得したりします。

CharacterScriptがないというエラーがあれば主人公操作スクリプトに列挙型の状態を表すフィールドを保持していてその値をSetStateとGetStateで設定と取得が出来る必要があります。

ProcessCharaAnimEvent

ProcessCharaAnimEventは主人公キャラクターのAnimatorControllerで使用しているアニメーションクリップに設定したアニメーションイベントの受け取りをしているスクリプトです。

アニメーションクリップにアニメーションイベントを設定しているがエラーが起きる場合はこのアニメーションイベント受け取りスクリプトProcessCharaAnimEventを取り付けていない可能性があります。

ChangeEquip

ChangeEquipは主人公キャラクターに取り付けキャラクターの装備を切り替える処理を行っています。

MyStatus

MyStatusは主人公キャラクターのステータスを管理するスクリプトでキャラクターのHPやキャラクターが装備している武器等を管理しています。

Shot

Shotスクリプトは武器に銃を装備している時に銃を撃った時の処理をするスクリプトです。

AutoRotateCamera

AutoRotateCameraは主人公キャラクターの子要素に配置したMain Cameraに取り付けるスクリプトでカメラがキャラクターの後ろ側に徐々に移動させる処理であったり、主人公とカメラの間に壁が来た時に壁の前にカメラを持っていく処理を書いたスクリプトです。

ItemDataBase

ItemDataBaseスクリプトは主人公の子要素にあるMain Cameraに取り付け、アイテムの情報を保持しているスクリプトです。ItemDataBaseは個々のアイテム情報を設定しているItemDataをリストとして管理しているスクリプトです。

PauseScript

PauseScriptは主人公の子要素のMain Cameraに取り付け、ゲームを中断するスクリプトです。

敵キャラクターに取り付けるスクリプト

敵キャラクターに取り付けるスクリプトを見ていきます。

Enemy

Enemyスクリプトは敵キャラクターに取り付け途中まではCharacterControllerの機能を使っての移動で途中からNavMeshAgentを使った移動に切り替えました。

主人公キャラクターが敵の攻撃範囲に入った時に攻撃をする処理をします。

EnemyスクリプトもCharacterScriptと同じように敵の状態をフィールドで保持していてSetStateで状態の設定、GetStateで状態の取得をしています。

SetPosition

SetPositionスクリプトは敵キャラクターに取り付け敵の移動先を設定する処理を記述しています。

SetPositionスクリプトはEnemyスクリプトで歩いている(巡回)している時と主人公を追いかけている状態の時に呼び出す目的地を設定します。

ProcessEnemyAnimEvent

ProcessEnemyAnimEventは敵のAnimatorControllerで使うアニメーションクリップで設定したアニメーションイベントを受け取るスクリプトです。

敵のアニメーションにアニメーションイベントを設定した場合はProcessEnemyAnimEventがないとエラーが発生します。

EnemyStatus

EnemyStatusスクリプトは敵キャラクターに取り付ける敵のステータスを管理するスクリプトです。

主人公が敵に攻撃を当てるとEnemyStatusでHPのバーの更新をしています。

AppearEffect

AppearEffectスクリプトは敵キャラクターに取り付け敵が出現した時にエフェクトを表示する処理をしています。

AppearSE

AppearSEスクリプトは敵キャラクターに取り付け敵が出現した時に効果音を鳴らす処理をしています。

SearchCharacter

SearchCharacterスクリプトは敵キャラクターの子要素の主人公を検知するエリアを設定したSearchAreaに取り付けるキャラクターを検知するスクリプトです。

SearchArea内に主人公が入ったら敵の状態を追いかける状態にし、範囲外に移動したら巡回に戻す処理をしています。

敵の状態を変更するのでEnemyスクリプトのGetStateメソッドで敵の状態を調べ、条件が合えばSetStateメソッドで敵の状態を変更しています。

HPUIRotateScript

HPUIRotateScriptは敵キャラクターの子要素の敵のHPバーのUIであるHPUIゲームオブジェクトに取り付けています。

HPUIRotateScriptはHPバーを常にカメラの向きに向ける為の処理をしています。

AttackZombi

AttackZombiスクリプトは敵キャラクターの子要素のボーンの右手部分に取り付けるスクリプトで、敵が攻撃をして主人公に当たった時の処理を行います。

主人公キャラクターに敵の右手に設定したコライダが接触すればCharacterScriptのTakeDamageメソッドを呼び出してダメージを与えます。

ステータス画面等で使用するスクリプト

ステータス画面等で使用しているスクリプトを見ていきます。

ProcessEquipSlot

ProcessEquipSlotスクリプトはステータス画面等でProcessEquipSlotスクリプトが設定されたアイテムアイコン(ゲームオブジェクト)をドラッグし、ドロップした時の処理を記述しています。

具体的にはアイテムスロット上でドロップした場合はそのスロットにドロップしたアイテムのアイコンを表示します。

CreateSlotScript

CreateSlotScriptはステータス画面等でアイテムスロットのプレハブを個数分インスタンス化する為の処理を記述しています。

あらかじめアイテムスロットをヒエラルキー上に置いておくのではなくアイテム数分のスロットを表示する為にプレハブにしたUIをインスタンス化して行っています。

ProcessingSlot

ProcessingSlotスクリプトはCreateSlotScriptで作成したアイテムスロットをドラッグしたりドロップした時の処理を記述しています。

その他スクリプト

主人公と敵以外に設定するスクリプトとゲームオブジェクトには取り付けないスクリプトについて見ていきます。

WeaponStatus

WeaponStatusスクリプトは武器のプレハブに設定し武器の情報を保持します。

ChangeEquipスクリプトで武器を切り替えた時に武器のプレハブを右手の子要素のEquipの子要素にインスタンス化しますが、そのインスタンス化した時の武器の位置や角度も保持しています。

AppearScript

AppearScriptは一定時間が経過すると敵を出現させるスクリプトで、敵を登場させたい場所のゲームオブジェクトに設定します。

登場場所であるゲームオブジェクトは空のゲームオブジェクトで作成しています。

ItemData

ItemDataスクリプトは個々のアイテム情報を保持するスクリプトでゲームオブジェクトには取り付けません。

ItemDataBaseスクリプトで個々のItemDataクラスからインスタンス化したものをリストで保持します。

当ブログに寄せられた質問への回答

スクリプトの概要を見てきたので、当ブログに寄せられた当ブログで作った機能への質問の回答を掲載していきます。

敵が追いかけてこない、敵に攻撃が当たらない

敵の検知範囲に主人公が侵入しても敵が追いかけてこなかったり、主人公が敵を攻撃したのに敵に攻撃が当たらないということがあります。

これはスクリプトで主人公が侵入してきた、敵に攻撃が当たったかどうか、をゲームオブジェクトのTagで判断していて、Tagが主人公や敵、敵の攻撃が当たる部位に設定されている必要があります。

敵が攻撃をした状態で止まる

敵の攻撃状態への遷移には敵のAnimatorControllerのアニメーションパラメータであるbool型のAttackをtrueにしてIdleやWalk状態からAttack状態へと遷移させています。

その為、どこかでこのAttackをfalseにしないとAttack→Idleへの遷移条件をAttackがfalseになった時にしている場合は、攻撃のアニメーションの最後で止まったまま他の状態へと遷移しなくなってしまいます。

そこでAttack状態で使用しているアニメーションクリップにアニメーションイベントStateEndをアニメーションの最後に設定しProcessEnemyAnimEventスクリプトでStateEndイベントを受け取りそこで敵の状態をフリーズ状態へと変更しEnemyスクリプトのSetStateメソッド内でアニメーションパラメータのAttackをfalseにしています。

アニメーションの遷移条件によってはStateEndイベントが発生する前に他の状態へと遷移してしまってアニメーションパラメータであるAttackがfalseにならなくなってしまうことがあります。

そんな時はビヘイビアを作成しその中でアニメーションパラメータのAttackをfalseにすると漏れを防ぐことが出来ます。

Unityでアニメーションを即時遷移させているとアニメーションイベントが実行されない時があります。そんな時にビヘイビアを設定しておくと確実に処理を実行する事が出来ます。

そもそもアニメーションパラメータのAttackをboolではなくTriggerに変更するとAttackをいちいちfalseにする必要がないのでこういったことを考慮する必要がないので楽かもしれません。

記事のスクリプトをそのまま設定したのにエラーが出る

当ブログのスクリプトを記事と同じように設定してもエラーが出る可能性はあります。

原因としてはいくつかあります。

  • わたくしが記事のスクリプトを書き直した時に間違って書き直した可能性
  • Unityのバージョン違いでうまくスクリプトが動作しなくなった
  • スクリプトを取り付けるゲームオブジェクトを間違えて別のゲームオブジェクトに設定し階層を辿ってコンポーネント等を取得している所でコンポーネントが取得出来ない
  • 取り付けたスクリプトのインスペクタで設定する項目が設定されていない
  • エラーが発生する理由は色々な事が絡み合っているのでまずはコンソールに表示されたエラー(赤い表示)部分をグーグルの翻訳機能を使って翻訳し、エラー部分をダブルクリックしVisual Stadioで該当箇所を調べてどこでエラーが出ているか?どういった内容のエラーなのかを判断し修正する必要があります。

    ここら辺は

    Unityのスクリプトを組んでいると必ず発生するのがコンパイルエラーです。このコンパイルエラーを修正する方法を実例とともに紹介したいと思います。

    を参照して頂くとエラーが出た時の対処の仕方が載っています。

    終わりに

    ブログに寄せられた質問には全てお答えしていきたいところですが、なかなか個別に対応するのは難しい為、2018年よりコメント欄への返信は行っておりません。

    質問が寄せられた記事中に分かり辛い部分などはその都度修正は入れています。

    その他ブログの機能を積み上げていた部分の質問に関してはこの記事にまとめて回答を残しておこうと思います。

    ほしい答えが載っていない可能性もあるとは思いますが、ご了承ください。(-_-)

    スポンサーリンク

    記事をシェアして頂ける方はこちら

    フォローして頂くとやる気が出ます