Unityでワープ機能を作成する

記事内に広告が含まれています。

今回はUnityのゲームでワープポイントに接触したら他の場所にワープする機能を作成してみたいと思います。

今回作る機能としては、ワープするエリアに主人公が接触したらそのエリア内で所定の位置と角度に移動させ、そこでワープのパーティクルを表示します。

ワープするまでの時間を設定出来るようにし、時間が経過したら移動先にワープさせます。

移動先でもワープのパーティクルを表示する事にします。

ワープの簡易動画

完成させるサンプルは↑のような感じになります。

さっそく機能を作成していきましょう。

スポンサーリンク

ワープのパーティクルを用意する

まずはワープする時に表示するパーティクルを用意します。

アセットストアでteleporterで検索し出てくる無料のパーティクルをインポートします。

インポートしたパーティクルのプレハブはAssets→m31_teleporter_FX→04_FX_prefabの中にあります。

サンプルの為に設定を少し変更します。

teleporterプレハブのParticle SystemのDurationを3にし、Loopingのチェックを外します。

teleporterプレハブはワープする時にインスタンス化しますが、再生が止まったら削除したいので、teleporterプレハブに以下のスクリプトを設定します。

自身のゲームオブジェクトのParticleSystemコンポーネントを取得し、Updateメソッド内でisStoppedで止まったかどうかを判定し、止まっていたらゲームオブジェクトを削除します。

teleporterプレハブは以下のようになります。

teleporterのプレハブのインスペクタ

これでワープ用のパーティクルプレハブが出来上がりました。

ワープする場所、ワープする先を作成する

そのエリアに入ったらワープする場所とワープ先を作っていきます。

サンプルの舞台は適当に作って頂いて・・・、ワープ元とワープ先を作っていきます。

ワープ元とワープ先

↑のように緑の領域がワープ元で高い場所にある赤い領域がワープ先になります。

ワープ元の作成

ワープ元の領域を作っていきます。

サンプルの舞台を作成

まずはAssetsフォルダ内で右クリック→Create→Materialを選択し、名前をWarpとします。

WarpのAlbedoの右の色の選択部分をクリックし、色の調整とAを100にして不透明度を下げ領域が多少透けるようにします。

Warpの色と不透明度を設定

ヒエラルキー上にCubeを作成し名前をWarpにし、サイズの調整、向きの調整、Mesh RendererのMaterialsに作成したWarpを設定します。

またBox ColliderのIs Triggerにチェックを入れ物理的に当たらないようにしておきます。

ワープ元領域のマテリアルを変更する

ここで重要になるのがWarpゲームオブジェクトの位置と向きです。

今回はワープ元の領域に入ったらWarpの中心の位置と向きに向き直してからワープするようにする為、Warpゲームオブジェクトの中心が地面との接触点、向きがカメラの向きを向くようにしています。

これは領域に入ったら、カメラの方に向き直しながら中心位置に移動させるためです。

Warpゲームオブジェクトに取り付けるスクリプトの作成

次にWarpにWarpというスクリプトを作成し設定します。

publicでワープする先のゲームオブジェクトを指定出来るようにし、WarpにPlayerタグを持つキャラクターが入ってきたらキャラクターのWarpCharaスクリプトを取得し、

SetStateメソッドに、状態、WarpのTransform、ワープ先のTransformを渡して呼び出します。

WarpCharaスクリプトをまだ作成していないのでわかり辛いと思いますが、要はWarpの領域にキャラクターが入ったらキャラクターの状態を変更するメソッドを呼び出しているだけです。

ワープ先の作成

次はワープ先を作成していきます。

ワープ元と同じように新しくマテリアルを作成し、名前をWarpPointとします。

ヒエラルキー上にCubeを作成し名前をWarpAreaとし、先ほど作成したWarpPointマテリアルを設定します。

WarpAreaはワープ先なので特別な処理をせず、Box Colliderを使う必要がない為、右の歯車をクリックし、Remove Componentを選択します。

WarpAreaのインスペクタ

↑のような感じになります。

WarpAreaの中心はCubeの中心になっているのでWarpAreaをワープ先としてしまうとワープ先が少し地面から離れてしまいます。

そこでWarpAreaの子要素に空のゲームオブジェクトを作成し、名前をWarpPointとしてWarpAreaの地面部分に移動させます。

WarpPointを下に作成

↑のようになります。

このWarpPointを先ほど作ったワープ元のWarpスクリプトのインスペクタのWarpPointに設定します。

キャラクタースクリプトの作成

キャラクター用スクリプトを作成していきます。

CharacterControllerやAnimator、移動させるスクリプト等は

Unityでキャラクターの移動をプログラミングしてみる
Unityで3Dキャラクターモデルを配置し、キャラクターをCharacterControllerの機能を使って移動させるようなプログラミングをしてみます。

の辺りを参照してください。

AnimatorではIdle状態とWalk状態を作成し、アニメーションパラメータにFloat型のSpeedが0.1より上だったらWalk、それより下だったらIdleへと遷移するように作成します。

スクリプトが長いので分割して説明していきます。

スクリプトに追記していってください。

設定部分

まずはキャラクターの状態を表す列挙型を宣言し、通常の移動出来る状態とワープ処理をしている状態を作成します。

ワープ処理状態の時はキャラクターの操作を出来ないようにします。

waitPointはワープ元の領域に入った時にその領域内の指定したポイントを入れます。

これはワープ元の中心の位置と角度が入り、そこに自動で移動するようにします。

warpPointはワープ先のTransformが入ります。

instantiateParticleはワープのパーティクルをインスタンス化する為のスクリプトでキャラクター自身に設定し、パーティクルをインスタンス化します。

InstantiateParticleは後で作成します。

goToWaitPointSpeedはwaitPoint(ワープ元の中心)に移動や回転する時のスピードをインスペクタで設定出来るようにしています。

Startメソッド

Startメソッドではコンポーネントの取得等を行っています。

自身のCharacterController、Animator、InstantiateParticleを取得したり、キャラクターの状態変数をノーマル状態にしています。

Updateメソッド

Updateメソッドではキャラクターの状態に応じた処理を行っています。

キャラクターがノーマル状態の時はキャラクターの移動処理を行ってます。

キャラクターがワープ処理状態の時はGoToWarpWaitPointメソッドを呼び出しています。

GoToWarpWaitPointメソッド

GoToWarpWaitPointメソッドはwaitPointの位置と角度に徐々に移動させ、waitPointの位置と角度になったらパーティクルの表示と待機、ワープをさせます。

Vector3.DistanceでキャラクターとwaitPointの位置が0.1より大きい時、またはキャラクターの角度とwaitPointの角度が5度以上ある時は位置と角度をwaitPointに近づけます。

else ifでキャラクターの位置とwaitPointの位置が違う場合は目的地に到着したと見なし実際のワープ処理を行います。

まずはSpeedを0にしWalkからIdleへと状態を遷移させます。

その後、キャラクターの位置と角度をwaitPointに完全に合わせる為、代入します。

その後instantiateParticleスクリプトのInstantiateWarpParticleに自身の位置を引数として渡してパーティクルをインスタンス化します。

Invokeを使って3秒後に自身のスクリプトにあるWarpメソッドを実行します。

teleporterのDurationを3にしたのはこの秒数と合わせる為です。

キャラクターがwaitPointに移動してからワープするまでの待機時間を変えたい場合はpublicフィールドで秒数を指定出来るようにして、teleporterのDurationも調整します。

Warpメソッド

Warpメソッドでは実際のキャラクターの移動や移動先にパーティクルを表示する処理を行ってます。

キャラクターの位置をwarpPointの位置と角度にします。

移動先でもワープパーティクルを表示する為InstantiateWarpParticleメソッドにキャラクターの位置を引数として渡しインスタンス化しています。

それが終わったらワープ処理が終わったのでSetStateメソッドでキャラクターをノーマル状態に戻しています。

SetStateメソッド

SetStateメソッドはキャラクターの状態を変更するメソッドです。

Warpゲームオブジェクトに設定したWarpスクリプトから呼び出された場合はwaitPointとwarpPointが渡されてきます。

先ほどのWarpメソッドが呼び出した場合は状態しか渡されない為、waitPointとwarpPointが渡されてきません。

そういった場合はnullが指定されるように引数であらかじめ設定しておきます。

受け取った引数をフィールド値にそれぞれ入れた後、状態がワープ処理状態に遷移する時はvelocityの値を初期化しています。

またCharacterControllerコンポーネントが有効である状態で、キャラクターの位置を直接変更する場合はCharacterControllerコンポーネントが邪魔をして位置を変更出来ない場合があるので、一旦CharacterControllerコンポーネントを無効化し、移動が完了したら有効にします。

ここら辺は

UnityのCharacterControllerコンポーネントの落とし穴?
UnityのCharacterControllerコンポーネントを使ってキャラクターの衝突判定や移動機能を使うと非常に便利ですが、使い方を間違えると原因不明の不具合に悩まされるかもしれません。

も参照してみてください。

パーティクルをインスタンス化するスクリプトの作成

パーティクルをインスタンス化するスクリプトはキャラクター自身に取り付けた方が都合がいいのでキャラクターに取り付けます。

warpParticleに指定したゲームオブジェクトを受け取った引数の位置に作成します。

角度は全部0にしています。

WarpChara、InstantiateParticleスクリプトを取り付けたキャラクターのインスペクタは

ワープするキャラクターのインスペクタ

↑のようになります。

ワープ機能を確認する

これで全ての機能の作成が終わりました。

MainCameraにFollowTargetスクリプトを設定し、キャラクターを追従するようにして確認してみます。

↑のようになりました。

もっと演出を加えるならばワープまでの待機時間にキャラクター自身を少しづつ透明にし、ワープ先ではだんだんと見えるようにする。

といった事をすると近未来感がありますね(^_^)v

単純なワープ機能を作るだけなら

という記述だけで終わってしまいますが・・・(^_^;)

その周りを肉付けする事でワープしている感じが出てきますね(^_^)v

タイトルとURLをコピーしました