原カバンは鞄のお店ではありません。

Unityを使ったゲーム制作のあれこれを綴っていきます。

【Unity】【作業ログ】First Person Narrative Adventureでオリジナルのパズルを作る

PSVR

給付金でPSVRを購入し、ウキウキでSkyrimVRをPlayしてみたら開始5分でVR酔いして以後全く手を付けていない皆さんこんにちは。
走りながらジャンプしてドラゴンから逃げろとか無理ゲー、着地と同時に吐き気を催します。

 

脱出ゲーム

そんな訳でPSVRではもっぱらBeatSaberを楽しんでいるわけですが、そんなゲームの誘惑に惑わされながらも、夏に向けたゲーム制作のほうも(それなりに)進んで言います。

 

このブログでも記事にしていますが一人称視点で進む脱出ゲームになる予定です。

f:id:Karvan:20200609220240g:plain



このゲームは一から作っているわけでなく、フレームワーク的なアセットを購入してそれをベースに作成しています。
それが「First Person Narrative Adventure + Complete Puzzle Engine」(長いので以後、FAに略)
このアセットについても当ブログで数回にわたって記事にしています。

 

【Unity】アドベンチャーゲームできるかな - 原カバンは鞄のお店ではありません。

【Unity】アセット:First Person Narrative Adventure を使ってみよう(その1) - 原カバンは鞄のお店ではありません。

【Unity】アセット:First Person Narrative Adventure を使ってみよう(その2) - 原カバンは鞄のお店ではありません。

【Unity】アセット:First Person Narrative Adventure を使ってみよう(その3) - 原カバンは鞄のお店ではありません。

 

ざっくりというと一人称のAVGに必要な機能が殆どすべてそろったアセットなのですが、名前に「Complete Puzzle Engine」をあるように、AVGとしての機能だけでなく、ゲーム内で使用できるパズルゲームがPrefabとして提供されています。(40種類のバリエーション)

このパズルゲームはゲーム空間にDragするだけで直ちに使用できるようになっており、パズルを解き始めるときにカメラが寄ったり、パズルの解読と他のイベントとを連動させたりすることできる優れもの、これをステージ内の彼方此方に配置しておくだけでそれなりのAVGが作れちゃいます。

f:id:Karvan:20200707214224g:plain

アセットのデモシーンの一部

 

とは言え、一端のゲーム制作者としては提供されたPrefabをそのまま使うのは何となく気が引けて、少しはカスタマイズしたもの、できればオリジナルのものを使いたいと思うもの。
カメラが寄ったり、オブジェクトをピックアップしたり、他イベントと連動させたりする機能は実装が面倒くさいのでそのまま使って、パズル部分だけをオリジナルなものにしたい。

 

オリジナルのパズル

というわけで、今回はこのFAでオリジナルのパズルを作る手順の紹介。まぁ、このアセットを使っていない方には全然関係ない話だったりするのですが、私自身が後から手順を見返すために(よく忘れるので)この記事を書いています。

目標は下図のような、並んだ数字の空いている箇所に法則が合致する数字を埋める、というパズルを実装すること。

f:id:Karvan:20200707214603p:plain

 

最初にTools → AP → Object Creatorを選択してObjCreatorのウィンドウが開きます。
Selection Category欄で「01 Puzzles」を選択して作成するパズルの種類を選びます。

f:id:Karvan:20200707214656p:plain

 

選ぶことができるのは以下の7種類

  • Sliding:いわゆる15パズル、パネルをスライドさせて並べるパズル
  • Digicode:数値表などを使って導き出したパスワードを入力するパズル
  • Lever:レバーのON/OFFを切り替えて全てのランプを点灯するパズル
  • Cylinder:シリンダーを回転させるタイプのパズル、パズルというか鍵っぽい
  • Pipe:パーツを回転させて通り道を繋げていくパズル
  • Gear:ギアの組みあわせをつくるパズル
  • Logic:オブジェクトを正しいパターンに揃えるパズル

この中で「Logic」を選択してCreateボタンを押下します。

 

ロジックパズル

作成したロジックパズルとは上でも書いたように、配置されているオブジェクトから正しいパターンに合わせて揃えるパズルです。

このパズルは、まずロジックパズルには動かして並べる子オブジェクト(logicsxx)と、そのオブジェクトの配置場所を表す子オブジェクト(Axisxx)があり、logics側のオブジェクトをAxisオブジェクトの位置へ移動、その二つのオブジェクトの属性(Type)が一致した場合、正しいパターンだと認識させる仕組みです。

f:id:Karvan:20200707214931p:plain

 

この正解のパターンはLogicsPuzzleコンポーネントで設定することができます。
f:id:Karvan:20200707215027p:plain

 

色々とごちゃごちゃしていますが、色のついた四角形の部分が正解のパターンを示しています。
各四角形はロジックパズルで並べ替える各オブジェクトと関連付けられていて、図の場合だと左上から順にNo0からNo3の子オブジェクトを表しています。

 

f:id:Karvan:20200707215100p:plain

ロジックパズルの子オブジェクト(logics00~logics03,Axis00~Axis03)が各四角形と関連付けられている。

 

四角形の色は属性(Type)を示していて、四角の上方にあるtype欄から選択して設定します。

f:id:Karvan:20200707215132g:plain

 type欄でtypeを選択して、四角形をクリックすると選択したtypeが設定される。

 

オリジナルパズルに適用

ロジックパズルを作成して正解のパターンを設定したら、動かす各数字のオブジェクトを各logicオブジェクトの子オブジェクトとします。
そして、Axisオブジェクトを並べる場所に設定します。

 

f:id:Karvan:20200707215446p:plain

設置後の状態

 

今回の場合は、並べる候補は4つ(4,5,7,8)なのに正解は2つ(4,8)となっています。5と7の数字はフェイクです。
このようなときはLogicsPuzzleコンポーネントでFakeを設定することでパズル解読の成否判定から除外させることができます。

 

ここまでの設定が完了するとオリジナルパズルが出来上がります。
実際動かしてみるとこんな感じ

 

f:id:Karvan:20200707215737g:plain

パズル開始でカメラが寄って行ったり、オブジェクトを選択すると拡大されたり、配置場所にアイコンが表示されたり等の動作はFA側で実装されているのでこちら側では特に何もしていません。
設定が色々と面倒くさいですがコーディング不要なのは良いですね。あとはこの手順を忘れないように・・・
 

【Unity】CameraのパラメータをDotweenで変更する

特別給付金

ボーナス前に給付金が貰えたのでBeatSaber目的でPSVRのパックセットを購入したものの、BeatSaberのダウンロードコードが期限切れ(2020/6/18まで)で結局ストアで買う羽目になった皆さんこんにちは。
正に『安物買いの銭失い』ってやつですね。これからPSVRのパックセットの購入を検討されている方は注意が必要です。

 

CameraとDotween

一般的にDotweenはゲームオブジェクトを動かす(移動・回転される)際に用いられるかと思いますが、実はTransformコンポーネントだけでなく他のコンポーネントに対するTween(パラメータの変更)もそれなりに用意されています。


まぁ、Dotween.Toメソッドを使えば大抵のコンポーネント・パラメータをすることはできるのですが、専用のメソッドのほうが使い勝手が良いことは確かですし、特にCameraコンポーネントに対するTweenメソッドは覚えておいても損はないと思います。

 

DotweenでCameraコンポーネントに対して用意されているメソッドは以下の通り

  • DOAspect:アスペクト比を変更する
  • DOColor:背景色を変更する
  • DOFarClipPlane:FarClipPlaneのサイズを変更する
  • DOFieldOfView:カメラの視野角を変更する
  • DONearClipPlane:NearClipPlaneのサイズを変更する
  • DOOrthoSize:Orthographicサイズを変更する
  • DOPixelRect:表示画面に対する画素演算範囲を変更する
  • DORect:画面の表示範囲を変更する
  • DOShakePosition:手ぶれ効果(位置)
  • DOShakeRotation:手ぶれ効果(角度)

元々CameraにはOrthographic(正投影)モードとPerspective(透視投影)モードがあるので、それぞれのモードでのみ使用できる(効果のある)メソッドがあります

 

Orthographicモードのみ

  •  DOOrthoSize

 

Perspectiveモードのみ

  • DOFieldOfView
  • DOFarClipPlane
  • DONearClipPlane

ここで、DOFieldOfViewとDOFarClipPlane,DONearClipPlaneはどれも視錐台のサイズに関する設定なので、それぞれを同時に使うと互いのTweenが干渉することになり注意が必要です。

 

実際に使ってみよう

まぁ文章で書いてもピンとこないと思うので幾つかのメソッドを使ってみましょう。
今回、カメラモードはPerspectiveモードとしています。

 

DOFieldOfView

ズームアップ等で使用します。

f:id:Karvan:20200630195411g:plain

 

DOShakePosition

DOShakePosition メソッドでは、duration(揺れる時間)以外のパラメーターはオプション扱いで、指定しなければデフォルト値が使用されます。

f:id:Karvan:20200630195456g:plain

 

DOColor

DOColorはSkyBoxを使用していない場合に使用します。

f:id:Karvan:20200630195529g:plain

 

ここで進捗報告

夏に向けて一人称視点のAVGを制作中ですが、そればっかりでは飽きるので他のゲーム開発にも手を出しています。

f:id:Karvan:20200630195810g:plain

 

まぁ、今年の初めに一週間ゲームジャムに投稿した「Helios Orbit」の焼き直しなのですが、頓挫している2.5D-STGの資産を使って規模を大きくしたいなぁ、と思っています。

完成するかどうかは・・・

 

【Unity】LOD Groupを使うと何ができるのか

最近の願い事

長く続くコロナ禍の中で唯一良かったことが会社の無駄な会議や飲み会が開催されないという事だったのに、ここ最近の社内で「Zoom飲み会」というワードが飛び交っていて戦々恐々としている皆さんこんにちは。IT系企業勤めの場合「家にPCがないので~」といった手口が使えないので逃げ場がない、上司が急に言い出さないことを願っています。

 

Level Of Detail

LODとはLevel Of Detailの略で、スマホゲーム等でパフォーマンスを改善する手法として用いられています。
カメラから遠く離れているオブジェクトは小さくて詳細は見にくいのでポリゴンを減らして表示させよう、という合理的な手法です。

 

Untiyでは距離によって表示させるオブジェクトをグループ化することで、カメラとの距離によって表示を自動で切り替える機能を備えています。
それがLOD Groupコンポーネントです。

 

導入は簡単

例えば下の図のようなポリゴン数の異なるオブジェクトを用意して、これを距離によって表示を切り替えるとします。

f:id:Karvan:20200623234232p:plain

 

まず、これらを束ねる空のオブジェクトを作成、3つのオブジェクトをすべて子要素にし、それらが同じ位置に重なるように配置します。

f:id:Karvan:20200623234613p:plain

 

次に親のオブジェクトにLOD Groupコンポーネントをアタッチ、LOD Groupコンポーネントでカメラがどのくらい離れたときに、どのオブジェクトを表示するかを設定します。

f:id:Karvan:20200623234809p:plain

LOD0がカメラがオブジェクトに最も近い距離、LOD2が最も遠い距離となっています。LOD2のエリアより遠くにカメラが移動した場合は非表示になります。

 

各LODをクリックすると、その下にRendersの欄が表示されるので、欄内の「Add」ボタンを押すとその距離で表示させれる子オブジェクトを選択できます。
LOD0,LOD1,LOD2で表示させるオブジェクトをそれぞれ選択すればLOD Groupの設定完了です。めっちゃ簡単

 

ちなみにカメラをドラッグして動かすことで、シーンビューにリアルタイムでLOD切り替えの距離が表示されます。
また、バーを動かすことで、シーンビューにリアルタイムでLOD切り替えの距離が表示されます。

 

実際にカメラを動かしてみると、カメラからの距離によってオブジェクトが切り替わっているのがわかると思います。

f:id:Karvan:20200623234953g:plain

 

他の使い方を考える

LODの使用例として挙げらるのは上記のように同じオブジェクトのハイポリゴンとローポリゴンを切り替える例ばかりですが、実は各LODで表示させる各オブジェクトは同じ形状である必要はありません。
つまり、まったく別のオブジェクトをLOD Groupに纏めてしまっても全然かまわない。

 

だったらちょっと面白い演出しても使えるのではないか、と思ったわけです。
こんな感じで

 

f:id:Karvan:20200623235159g:plain

パフォーマンス改善以外にもビックリ箱的な演出にも使えるかもしれません。

 

【Unity】DotweenのLoopとDelayとRotate

暑い

この暑さの中、マスクを着けて歩くなんて狂気の沙汰だと思う皆さんこんにちは。6月ってこんなに暑かったかな?

去年が冷夏だった分、その反動でこの夏は猛暑になりそうで凄く嫌。

 

Dotweenによる回転

例えば歯車のようなオブジェクトを回転させたい場合、DotweenだとDORotateを使います。

f:id:Karvan:20200616212735p:plain

 

そしてこの回転を延々と続けたい場合はLoopオプションに「-1」を設定します。

GearObj.transform.DOLocalRotate(new Vector3(0.0f, 0.0f, 360.0f), 2.0f)
                            .SetRelative(true)
                            .SetLoops(-1);

まぁ、このぐらいの動作なら簡単に実装できるのですが、これを「1秒待った後に10度回転する」動作を繰り返す、という処理を実装しようとした場合ちょっと頭を悩ませます、ってか、結構悩みました。今回はそのお話。

 

Delayの設定

当初は「1秒待った後に」とあるので、Delayオプションをつければ良かろう、と単純に考えていたのです

GearObj.transform.DOLocalRotate(new Vector3(0.0f, 0.0f, 10.0f), 0.7f)
                            .SetRelative(true)
                            .SetDelay(1.0f)
                            .SetLoops(-1);

実際に動かしてみると

 

f:id:Karvan:20200616213211g:plain

ん~・・普通に回転しとる

 

DORotateのDelayオプションはあくまで「回転動作開始の遅延」設定であるため、遅延が発生するのは最初の一回だけですのようです。Loopオプションで繰り返されるのは回転動作の部分のみ、なるほどね。

 

なので次はSequenceを使うことにしました。Sequenceに上のDORotateをAppendして、SequenceのLoopオプションに「-1」を設定。

Sequence GearSeq = DOTween.Sequence();

GearSeq.Append(
   GearObj.transform.DOLocalRotate(new Vector3(0.0f, 0.0f, 10.0f), 0.7f)
                               .SetRelative(true)
                               .SetDelay(1.0f)
   );
GearSeq.SetLoops(-1);

これでSequenceを繰り返す=「最初の遅延動作」+「回転動作」を繰り返す、となるはずなので「1秒待った後に10度回転する」動作が繰り返されるはずです。

 

f:id:Karvan:20200616213611g:plain

・・・なんだこれ?・・・

 

Loopの設定

なるほど、Sequenceを繰り返す、ということは指定のTweenを最初から実行する、となりますが、DORotateを最初から実行するということは「初期角度から指定角度まで回転する」という動作を繰り返すことになります。これでは上の動画みたいに壊れたレコードみたいな動作となるのは当然です。なるほど、なるほど

 

Loopオプションは第一引数でループ回数を指定出来ますが、第二引数にループの挙動も指定することができます。

  • Restart: 挙動が終了した時に値を始点に戻し、再度実行する
  • Yoyo: ヨーヨーのように行き戻りを繰り返す
  • Incremental: 挙動が終了した時に差分を endValue に追加しつつ再度Tweenを実行する

 

今回の場合はLoopTypeにIncrementalを指定する必要があったみたいです。

GearSeq.SetLoops(-1, LoopType.Incremental);

さっそく追加して実行

 

f:id:Karvan:20200616213911g:plain

・・・なんだこれ?(二度目)・・・

 

暫定対応

f:id:Karvan:20200616214516p:plain

よく見ると回転動作の最終位置は加算されているようで、じわじわ回転しているのはわかります。が、何故か動作開始位置が前回動作時のendValueとなっていないようで先ほどの動作と大して変わらない挙動となってしまいます。

 

 色々と調べましたがお手上げとなってしまったので暫定的な対応としてDelayオプションによる遅延動作をあきらめ、Sequenceに遅延時間分ダミーオブジェクトを動作させるTweenを追加、これを繰り返すことにしました。

 

f:id:Karvan:20200616214615g:plain

左の歯車がダミーオブジェクト
本命オブジェクトのDORotate前に左のダミーオブジェクトを遅延時間分回転させています。

 

GearSeq = DOTween.Sequence();

  GearSeq.Append(
   DummyObj.transform.DOLocalRotate(new Vector3(0.0f, 0.0f, 360.0f), 1.0f)
                               .SetRelative(true)
   );

GearSeq.Append(
   GearObj.transform.DOLocalRotate(new Vector3(0.0f, 0.0f, 10.0f), 0.7f)
                               .SetRelative(true)
   );

GearSeq.SetLoops(-1, LoopType.Incremental);

一応これで想定する動作を実現することができましたが、何かほかに良い方法があればだれか教えてください。


ちなみに、どうしてこんな動作を作る必要があったのかと言えば、現在作成中のゲーム内で使用するためです。
こんな場面で使っています。

f:id:Karvan:20200616215101g:plain

 

【Unity】【進捗報告】脱出ゲームを作ろう

今ここにある危機

コロナ騒動の中、日々黒人差別と闘っている意識高い皆さんこんにちは。意識の低い私にはこの日本の中で一体どこに向かって石を投げているのか、なぜ今なのか、ちっとも分かないのですが、とりあえず直近の危機回避としてクラスターが発生しないことを祈るばかりです。

 

そんなわけで井上陽水の「傘がない」よろしく、大局よりも目の前の問題解決に奔走するしがない小市民として、この週末は部屋に閉じこもってゲームを作っていました。

というのも、以前ブログで取り上げた"Portal"のアセットが非常に優秀だったので、これを有効活用するようなゲームをお試しで作っているといつの間にか時間が過ぎてた。

 

ここ2週間の成果がコレ

f:id:Karvan:20200609220240g:plain

 

上ってきた階段を戻って降りると違う部屋に繋がっていて、仕掛けを解除するまで同じ部屋をグルグル回り続けるという、ちょっと不思議な感覚が味わえる脱出ゲームとなっています。

 

一体どうなっている

簡単に言うと階段の途中にポータルが設置されていて、ポータル自身の姿は見えないのでプレイヤーが気づかない間に上ってきた階段の元の位置へ飛ばれされているだけです。

このステージはSceneビューで見るとこんな構造をしています。

f:id:Karvan:20200609220613p:plain

 

分かりづらいので簡略化するとこんな感じ

f:id:Karvan:20200609220732p:plain


1Fから2Fへ上る途中にA、3Fから出口に上る途中にBのポータルがあり、Aが上る方向を、Bが降りる方向を向いています。

これにより3Fのフロアから上に上る階段を見ると、途中から1Fから2Fへ上る階段が見えることになりますが、階段の形状、色、大きさを同じものにそろえているため、プレイヤー側は3Fの階段がそのまま上の階に続いているように見えます。

2Fのフロアから1Fに下りる階段(ポータルA)を見た時も同じです。

 

f:id:Karvan:20200609220719p:plain

一度このエリアに入るとプレイヤーは階段を上り続けても3Fの途中でB→Aに飛ばされ、2Fのフロアにたどり着くことになります。

逆に降り続けても1Fに向かう途中でA→Bに飛ばされて3Fに到着、延々と同じフロアを歩くことになります。ようは無限回廊の出来上がり。

 

ポータルの裏側

先程の動画ではドアを開けて最初の階段を上るとポータルで飛ばれされず1Fのフロアにそのままたどり着きます。

これはポータルには向きがあり、裏から通り抜けた場合は特に何の処理(移動)も発生しないからです。

そして、ポータルを裏側から覗くと透明なので何事もなく1Fのフロアに続く階段がそのまま見えています。

 

f:id:Karvan:20200525002318g:plain

ポータルのデモシーン、裏側から見たときは特に何もないように見え、そのまま通り抜ける。

 

仕掛けを解除して無限回廊を終える場合はポータルのオブジェクトを非活性化します。

ここら辺はスクリプトを組む必要がありますが、ただ該当のGameObjectにsetActive(false)を設定するだけなので苦労することはないと思います。

 

f:id:Karvan:20200609221859p:plain

ポータルを非活性化して3Fのフロアから階段を見上げた場面、本来の3Fの階段と出口のドアが見える。

 

今回はポータルの境目が分からないように壁の色を白一色で統一させています。少し見づらい感じもしますが、これはこれでおしゃれかなぁ、と(言い聞かせ)

後は完成するかどうかが心配・・・

 

使用アセット:Fluid Portals System & Non-euclidian Tunnels

assetstore.unity.com

 

【Unity】シンプルな物理ツールキット-磁力・水・風-VR対応

一段落

全国的に緊急事態宣言が解除されプロ野球やJリーグも再開が決まって、長く続いたコロナ禍が一段落したのと呼応したわけではないのですが、個人的に仕事の面でも一段落がつき、プライベート面はとっくに波が停止しているので、ここ最近は何事もない平穏な日々が続いております。

その所為かゲーム制作の方はGameJamに参加するも箸にも棒にも掛からぬような感じだったこともあり、全くモチベーションが上がらない状態で、1年掛けた2.5DSTGも進捗が進まないどころか大きく作り変える事にしたり、今年中にゲームアプリをリリースできるのか不透明な情勢です。

 

そんな訳でブログネタにするようなUnityの技術的な知見も広がっていないので、今回もアセット紹介となります。

 

物理ツールキット

『切磋琢磨するしかない!』を制作する際に物理演算に沿ったギミックを作れないか考えていたのですが、コガネブログさんの以下の記事を見つけて、ギミックとして使えそうだったので購入しました。

 

baba-s.hatenablog.com

その名の通り"磁力・水・風"の物理の挙動を再現できるアセットとなっています。

"Simple"とあるようにパラメータ等はシンプルで特に難しい設定無く導入することができます。

 

磁力

磁力を使う場合は磁力の影響を受ける全てのオブジェクトにRigidbodyとこのアセットの「Magnet」コンポーネントを設定します

f:id:Karvan:20200602214716p:plain
磁石が引き付けられる範囲を"OuterRadius"、引き付けれて停止する(オブジェクトがくっつく)範囲を"InnerRaius"で指定します。

 

挙動はこんな感じ

f:id:Karvan:20200602214808g:plain

 

浮力

浮力は浮力が発生するオブジェクト(水となるオブジェクト)にRigidbodyと「Water」コンポーネントを設定します

f:id:Karvan:20200602214922p:plain

この「Water」が設定されたオブジェクトに接触したRigidbody全てに対して「浮力」の効果を加えます

 

f:id:Karvan:20200602214949g:plain

キャラクターのお尻が浮いてるのは重心設定の関係です。

 

風力

風力の場合はまず空のオブジェクトにBoxCollider等のColliderを設定します。これが風力を受ける範囲になります

そして「Wind」コンポーネントを設定します。

f:id:Karvan:20200602215136p:plain

 

風の方向はSceneビュー内にて水色の線で表示されるので、それを見ながらオブジェクトを回転させて風向きを設定します。

f:id:Karvan:20200602215206p:plain

浮力と同様、この「Wind」が設定されたオブジェクトのCollider内にある全てのRigidbodyに対して「風力」の効果を加えます

 

f:id:Karvan:20200602215241g:plain

分かりやすいように風の範囲にパーティクルを表示しています

 

 簡単に導入できる

前述のように"磁力・水・風"の物理効果を簡単にゲーム内に導入することができます。

『切磋琢磨するしかない!』では風力だけ使用しましたが、アイデア次第で多種多様なギミックを作ることができるかと思います。

 

assetstore.unity.com

【Unity】流体ポータルシステム と 非ユークリッドトンネル

 

f:id:Karvan:20200525002153g:plain

 

猿か

成功体験に味を占めたのか毎日のように扇動的なハッシュタグがTwitterのトレンド入りしてくることにウンザリしている皆さんこんにちは。よっぽど「~に抗議ます」って言葉が好きなんでしょうね。無駄に吠える猿。

 

さて、まるで数学の問題のようなタイトルですが、これは最近購入したUnityアセットの名前です。Google先生に日本語訳をお願いするとこんな感じの名前になる。

"Fluid Portals System & Non-euclidian Tunnels"

assetstore.unity.com

 "Portal"とついていることから察しの言い方は気づくかもしれませんが、これはPortalシステムを簡単に導入できるアセットで、今回はこのアセットについて紹介したいと思います。

 

Portal的システム

特に説明する必要もないぐらい「Portal」というギミックは同名のゲームの存在で有名かと思いますが、その仕様を一言で説明すると「どこでもドア」的なもの、と言えます。

「Portal」は二つの空間を繋ぐゲートとなり、Portal越しに互いの世界を覗き見ることができるし、Portalをくぐり抜けることで両空間を行き来することができるシステムです。

 

この「Portal」をUnityで実現する手法については色々なブログで取り上げられていますが、大抵は同じ手法で説明されています。

曰く、Portal的システムを構築するには以下の3つの処理が必要らしい。

 

  1. 相手側の世界を表示する
  2. こちら側の視点と相手側の視点を連動させて動かす
  3. 相手側の世界へ移動させる

 

例えばAとBの二つの空間があったとして、AのエリアにPlayerがいるとします。そして、Player側の映像はMainCameraで撮影されているとします。

一方、BのエリアにもCameraを設置します。しかし、こちらの映像はゲーム画面に直接映すのではなくA側のPortalに設定されているRenderTextureに表示させます。

f:id:Karvan:20200526215508p:plain二つのCameraは連動しておりPlayerに合わせてMainCamraが動くと、BエリアのCameraも同じように動きます。

MainCameraが上を向くとBエリアのCameraも上を向き、Playerが前後左右に移動するとそれに合わせてどちらのCameraも動きます。

 

そして、PlayerがPortalに接触(Collider内に侵入)するとPlayerをMainCamraと共にBエリアのPortal位置へ移動させます。

f:id:Karvan:20200526215615p:plain

この時、B側のCameraは無効化され、逆にA側にMainCameraと連動したCameraが設置されます。

 

手法だけ聞くと簡単そうに思えますが、いざ実装しようとすると意外と面倒くさいです。

 というのも、カメラの動きを連動させるにも互いのPortalの向き(方向)を考慮しないといけないし、Playerを相手世界へ移動させるにも違和感のないスムーズな移動をさせるにはPortalに対する進入角度と退出角度を合わせる必要がでてきます。

そこで今回紹介するアセット「Fluid Portals System & Non-euclidian Tunnels」の登場です。

 

Fluid Portals System & Non-euclidian Tunnels

前置きを長々と説明しましたが、それもこのアセットではセットアップ等の作業が殆どいらずに済む為、特に書くことがないからです。

 Fluid Portals Systemを使ってPortalシステムを実現する手順は以下の3つ

 

1.Prefabs配下にある「portals_back_and_forth」をシーン内に配置

f:id:Karvan:20200526220004p:plain

 

2.子オブジェクトのportal_one, portal_twoを双方向で移動させたい位置に置く

f:id:Karvan:20200526220037p:plain

 

3.Prefabs配下の「Player(dg_simpleFirstPersonController)」をシーンに配置

 

以上になります。各Prefabをシーンに配置するだけ。もし、導入するシーンにCameraが既に設置されている場合は3.の工程は不要です。その代わり

  • Cameraに"MainCamera"のtagを設定する
  • Portalで移動させるPlayerのオブジェクトに"Player"のtagを設定する

上記二つの設定を行う必要があります。

また、CameraはPlayerオブジェクトの子オブジェクトであることが望ましいみたいです。(そうでないとPortal移動時に変な回転が起きる)

 

前置きの中で説明したMainCameraと連動させるCamera等はゲームPlay時に自動的に生成される為、こちら側での設定は不要です。

ただ、Portalを同じシーン内に複数個設置する場合はPortalSetupコンポーネントのGroupID欄にIDを設定する必要があります

f:id:Karvan:20200526220354p:plain

 

試しにA,Bの部屋を作ってそれぞれにPortalを設定しました。

f:id:Karvan:20200526220427p:plain

オレンジの部屋(Room-A)にある青いポールはPlayerです。

 

この状態で動かしてみるとこんな感じ、奇麗にPortalシステムが実現されていることが分かります。

f:id:Karvan:20200525002318g:plain

 

実はこのアセットの導入から上の動画を撮るまで一時間もかかっていません。

ドキュメントが全て英語で簡単な説明しかない、かつ設定手順はYoutubeを見ないけない、と不親切な点もありますが、先程も紹介したように殆ど設定不要で導入できるし、何よりPortal間の移動、表示がスムーズで違和感のないPortalシステムを作ることができます。

 

製作中のゲームでPortalシステムを使う事を考えている方はこのアセットの導入を検討されてはどうでしょうか。

◇プライバシーポリシー

●個人情報の利用目的

当ブログでは、メールでのお問い合わせ、メールマガジンへの登録などの際に、名前(ハンドルネーム)、メールアドレス等の個人情報をご登録いただく場合がございます。

これらの個人情報は質問に対する回答や必要な情報を電子メールなどをでご連絡する場合に利用させていただくものであり、個人情報をご提供いただく際の目的以外では利用いたしません。

●個人情報の第三者への開示

当サイトでは、個人情報は適切に管理し、以下に該当する場合を除いて第三者に開示することはありません。

・本人のご了解がある場合
・法令等への協力のため、開示が必要となる場合

個人情報の開示、訂正、追加、削除、利用停止
ご本人からの個人データの開示、訂正、追加、削除、利用停止のご希望の場合には、ご本人であることを確認させていただいた上、速やかに対応させていただきます。

アクセス解析ツールについて

当サイトでは、Googleによるアクセス解析ツール「Googleアナリティクス」を利用しています。

このGoogleアナリティクスはトラフィックデータの収集のためにCookieを使用しています。このトラフィックデータは匿名で収集されており、個人を特定するものではありません。
この機能はCookieを無効にすることで収集を拒否することが出来ますので、お使いのブラウザの設定をご確認ください。

●免責事項

当サイトからリンクやバナーなどによって他のサイトに移動された場合、移動先サイトで提供される情報、サービス等について一切の責任を負いません。

当サイトのコンテンツ・情報につきまして、可能な限り正確な情報を掲載するよう努めておりますが、誤情報が入り込んだり、情報が古くなっていることもございます。

当サイトに掲載された内容によって生じた損害等の一切の責任を負いかねますのでご了承ください。

●プライバシーポリシーの変更について

当サイトは、個人情報に関して適用される日本の法令を遵守するとともに、本ポリシーの内容を適宜見直しその改善に努めます。

修正された最新のプライバシーポリシーは常に本ページにて開示されます。