Unityで敵キャラが見回りをするように動き回るプログラム

前回までで敵キャラが自動で設定された目的地に移動するところまで作成出来ました。

敵キャラクターをシーンに配置し、動かす為のコンポーネントであるキャラクターコントローラーを取りつけ、目的地に向かって移動するようなスクリプトを作成して動かします

今回は敵キャラクターが目的地に到着したら数秒の待機をした後、別の目的地を設定し、そこに移動する機能を作ります。

まず初めに前回までに作ったスクリプトを分割してみます。

移動のスクリプトと目的地の設定スクリプトが混在していたので、目的地の設定スクリプトを取り出して別の名前にします。

こうすることでスクリプトを機能毎に分ける事が出来、処理の把握がしやすくなると思います。

目的地設定はMoveEnemyと機能を共有しているので、特別分ける必要もなくMoveEnemyメソッドにSetPositionというメソッドを追加して対応した方がいいです。

があえて他のスクリプトを取得するという事を勉強する為にやってみます・・・・(^_^;)

名前は安易にSetPostionという名前にしました。

SetPositionスクリプトの作成

忘れずにゾンビ(敵キャラ)にSetPositionを設定しておきます。

スポンサーリンク

ゾンビの位置を設定するスクリプトSetPosition

CreateRandomPositionメソッドが呼ばれるとランダム値を加えた目的地が設定され、このスクリプトで値を保持します。

設定された目的地destinationはprivateで宣言されていますので、外部のスクリプトからは値の取得が出来ません。

その為Getter(privateで宣言されている変数の値を取得するだけのメソッド)を用意し、GetDestinationメソッドが呼ばれたら値を取得出来るようにしておきます。

メソッドの戻り値の指定は

↑のようにメソッド名の前に戻り値の型を書きます。

敵キャラ移動スクリプトMoveEnemyの修正

次にMoveEnemyの修正をします。

目的地の設定をしていた個所を修正する必要があります。スクリプトもコンポーネントなので取得はGetComponentで出来ます。

上記のようにスクリプト名型の変数を宣言します。

Startメソッド内でGetComponentでスクリプトを取得しフィールドに入れておきます。

これでsetPositionを介してSetPositionスクリプト内のメソッドを使用出来ます。

setPosition.CreateRandomPositionでランダム位置の作成と設定をし、setPosition.GetDestinationで目的地を取得します。

あとは目的地に到着した後に待機して新たな目的地を設定、到着フラグをoffにするという処理を加えるだけです。

敵キャラが見回りをするスクリプト

MoveEnemyスクリプトに待機時間の設定と待機してから何秒たったかを記憶するフィールドを宣言します。

Startメソッド内で初期値を設定します。

到着したと判定された時に待っていた時間(elapsedTime)を増やしていきたいので、

上記のようにTime.deltaTimeを足していきます。
Time.deltaTimeは1フレームの時間を取得出来ます(厳密には前回Updateメソッドを実行してから現在のUpdateメソッドを実行するまでの時間)。

つまりelapsedTimeに1フレーム毎に時間を足していき、

それが待機時間を超えた時に、新しい目的地の設定、取得、到着フラグのoffをし、経過時間を0にリセットします。

到着フラグがリセットされたので、また新しい目的地へと移動を開始するはずです。

以下MoveEnemyの全文です。

これで敵キャラが見回りをするような動きを表現できました。
スクリプトが長くなってきたので、全文を載せるのはそろそろやめようかな・・・。

戻り値を使わない時はメソッド実行命令だけ送る事も可能

今回はGetComponentでスクリプトを取得し、setとgetのメソッドを呼び出して使用しました。
しかし戻り値を使わない場合は別の方法もあります。

SendMessage(“メソッド名”)

とします。同じオブジェクトに設定されたスクリプトであれば上記のように記述し、メソッド名を指定するだけでメソッドを実行してくれます。

第2引数(引数はメソッドに渡す値の事)に値を設定する事は出来ますが、値を複数渡したい時、第3引数以降は使えないので、第2引数に配列として渡すなどをすれば複数の値の引き渡しが出来ます。

メソッドを実行してくれ!というメッセージを送るだけなので、戻り値は取れません。

スクリプトの実行順序で不具合!?

以下Updateメソッドの実行順を変更する方法が載っていますが、不具合の原因は単純にキャラクターの位置と目的地のどれだけ近づいたか?の距離が短すぎた事が原因でした。

↑の部分ですね。

0.3fのところの数値を多少大きくすれば問題ありません。

その為、以下の内容はUpdateメソッドの順序をスクリプト毎でどうしても変えたい時のTipsとして使い、安易に変更しない方がいいです。

またUpdateメソッドの後に実行したい時はLateUpdateメソッドを使うとUpdateと同じように毎フレーム呼ばれるのでこちらを使うといいです。

-- 以下Updateメソッドの実行順序を変えるTips--

Updateメソッドの実行順序をスクリプト毎に変更したい時もあります。

そんな時は、

Editメニュー→Project Setting→Script Exection Order

を選択します。

Updateメソッドの実行順を変更する

+をクリックしSetPositionを選択します。

SetPositionがDefault Timeより前に実行するように移動します。

するとSetPositionスクリプトのUpdateメソッドの方が他のスクリプトのUpdateメソッドよりも早く実行されます。

次回は主人公キャラが敵キャラに接近したら近づいてくるというようなことをやってみたいと思います。

スポンサーリンク

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

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

コメント

  1. 未来 より:

    ゾンビを削除して
    再度、配置したらランダムに移動するようになりました。

  2. 未来 より:

    最初に実行すると、必ずゾンビが
    X座標[0~2]付近に移動してしまいます。

    スクリプトに問題があるんでしょうか?

    • どのようなスクリプトを組んでいるかわからないのでなんとも言えませんが、

      この記事ですとMoveEnemyスクリプトのStartメソッドでCreateRandomPositionメソッドを呼び出した後にdestinationにsetPosition.GetDestination()を入れて目的地を取得すると最初からランダムな位置に移動出来ると思います。

      それでもX座標でしか移動出来ないとすると目的地を設定した時にZ座標の値が入っていない可能性があるので、そちらをDebug.Log等で確認してみてください。