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

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

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

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

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

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

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

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

SetPositionスクリプトの作成


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

スポンサーリンク

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

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

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

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

関数の戻り値の指定は

function 関数名 : 戻り値の型 {
return 戻り値;
}

↑のように関数名の後にコロン(:)を付けその後に戻り値の型を記述します。

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

次にMoveEnemyの修正をします。

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

private var setPos : SetPosition;

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

setPos = GetComponent(SetPosition);

start関数内でGetComponentでスクリプトを取得し変数に入れておきます。

これでsetPosを介してSetPositionスクリプト内の関数が使用出来るようになります。

setPos.SetDestination(); // 目的地の設定
destination = setPos.GetDestination(); // 目的地の取得

setPos.SetDestination関数で目的地を設定し、setPos.GetDestination関数で目的地を取得します。

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

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

まずは待機時間の設定と待機してから何秒たったかを記憶する変数を宣言します。

private var waitTime : float;
private var currentTime : float;

start関数内で初期値を設定します。

waitTime = 5.0f;
currentTime = 0.0f;

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

上記のようにTime.deltaTimeを足していきます。
Time.deltaTimeは1フレームの時間を取得出来ます。

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

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

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

以下全文

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

戻り値を使わない時は関数実行命令だけ送る事も可能

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

SendMessage(“関数名”)

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

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

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

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

修正箇所があったので追記します。

SetPositionスクリプトをMoveEnemyスクリプトから独立した影響でSetPositionスクリプトのSetDestination関数内で取得しているcurrentのVector3の値が常に(0.0, 0.0, 0.0)となっていました。

これではランダム値の所に移動してしまいます。

この原因はスクリプトの動作順序にありました。

SetPostionスクリプトのStart関数内でcurrentに現在の位置を入れて、SetDestinationで現在の位置+ランダム値で次の目的地を設定していますが、MoveEnemy関数内のStart関数内でSetPositionのスクリプトを使用しているので、スクリプトの実行順序によってはcurrentに値が入っていない事があります。(どんな動作をするかは不明)

その為SetPositionスクリプトはMoveEnemyスクリプトより後に実行されるように変更します。

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

を選択します。

Update関数の実行順を変更する

+をクリックしSetPositionを選択します。
SetPositionがDefault Timeより前に実行するように移動します。
これで設置位置+ランダム値がちゃんと機能するようになります。

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