前回の続きです。
前編ではカメラを切り替えるUIをWidgetで作って、レベルにオブジェクトと切り替えるためのカメラを設置しました。
後編は実際のカメラ制御の部分を作ります。
Blueprint Interface
まず、Widgetからメインカメラ用のブループリントにアクセスするためのインターフェイスを用意します。
コンテンツブラウザから右クリックで、Blueprints > Blueprint Interface を選択。
このブループリントインターフェイスの中身は 関数名 とその 入出力ピン の設定のみで構成されています。
今回の関数名 SwitchCamera を作成して、Inputs に Integer型のピンを1つだけ追加したらコンパイルして保存します。
メインカメラ用Actor
次に、メインカメラ用のブループリントを用意します。
今度は Blueprints > Blueprint Class を選択。
ダイアログから、Actor を選択します。
さっそく編集していきます。その前にさっき作ったブループリントインターフェイスをセットします。
できたブループリントを開いて、ツールバーの Class Settings をクリック。
Details(詳細)パネルから Interface の項目を探してセットします。
ブループリントインターフェイスがセットできたら、次はメインのカメラを追加します。
まずは左上の Componentタブから、+Add Componentボタンを押して Camera を選択します。
次は変数を用意します。
一番上の CameraActor型の配列変数は、 レベルに設置したカメラにアクセスするためのものです。これだけ目玉のアイコンが付いているのは、以下のチェックボックスにチェックを付けているからです。
この2つにチェックを付けると、このブループリントを Spawnする際に値を受け取れるようになります。(Expose on Spawn だけだと 警告が出る)
変数が用意できたら次は関数を2つほど用意します。
配列に格納されたカメラの情報を取り出すのと、メインカメラにパラメータをセットする関数です。
まずは情報を取り出す方。getCameraPosition と命名。
中央下のノードは、ちょっと見つけにくいです。
get ノードからドラッグして、 get comp あたりで検索をかけて下の方。
カメラのアイコン付きを選択。
あとは、get Field Of View ノードと、 getActorTransform ノードです。
その二つを、Returnノードの Outputsピンから出します。
また、このGetCameraPosition関数は Pure型にした状態で作っていきます。
次は情報をセットする方。setCameraPosition と命名。
Transform と FOVを setするだけです。セットする先は別になります。
変数と関数が用意できたので、次はイベント。
Event BeginPlay
まずカメラを乗っ取ります。
※GetCameraPosition関数は Pure型で利用しています。
Set View Target with Blend ノードに Self ノードをつないでいます。このSet View Target with Blendノードは、先に get Player Controller を取り出してからだとすぐに見つかります。
あとは、用意した関数をつないで、開始時のカメラ位置をセット。
Event Switch Camera
ブループリントインターフェイスに仕込んでおいた名前だけの関数みたいなやつを、イベントとして利用します。
グラフで右クリックして SwitchCamera を探すと見つかります。
これはイベントとしておくことで呼び出してもらうかたちとなります。
右上にブループリントインターフェイスのアイコンが付いたノードが出てきます。
ここにカメラ切り替えの処理をつないでいきます。
まずは前半部分。あらかじめ用意した変数と関数を並べるだけ。
※GetCameraPosition関数は Pure型で利用しています。
今のカメラ位置(Old)から、新しいカメラ位置(New)へ移動させるために、それぞれの値を一旦変数に取り置きします。
常に最新のカメラ番号を保持させる Current Index 変数ですが、更新するタイミングがとても重要。つなぐ順番によって結果が変わるからです。
残りの後半部分。
いよいよタイムラインノード登場です。
タイムラインノードのトラックは Floatタイプ が一つだけ。
これでメインカメラActorの完成です。
ボタンWidgetを並べるWidgetの再編集
メインカメラのActorも用意できたので、Widgetの方からアクセスする仕組みを作ります。ボタンWidgetを並べるためのWidgetを編集します。
カメラにアクセスするために、Actor型の変数を新しく追加します。
Instance Editable と Expose on Spawn にチェックを付けておきます。
この段階ではまだどんな Blueprint Actor が入るか判りません。ただのActor型です。
あたりまえですが、中身にアクセスしたり関数を呼び出したりはできません。
さてこれを、放っておいたバインドからのカスタムイベントにつなぎます。
この空っぽのActor型のオブジェクトに対して、SwitchCamera の関数を取り出してつなぎます。右上に手紙のアイコンが付いたノードが取り出せます。
これは、プロジェクト内にブループリントインターフェイスが存在すると、見つけることができるというちょっと特殊な関係性によるもの。
その対象がなんであるかも構わず、中に関数を持ってるかどうかも関係なくつなぐことができます。
こんな状態でコンパイルが通ってしまうのです。
試しに適当なオブジェクトにつないでみてもコンパイルは正常です。
再生してもエラーは出ません。
ブループリントインターフェイスにはこんな便利な仕組みが備わっているのです。
Widgetの再編集はこれだけです。
では最後の仕上げとまいりましょう。
Level Blueprint
レベルブループリントを編集します。
まず Spawn Actor From Classノードを取り出してEvent BeginPlay につなぎます。
Class のところに、用意しておいた BP_MainCamera をセットします。
すると Expose on Spawn にチェックをつけておいた配列が入力ピンとなって現れます。
ここにカメラを配列にしてつなぎます。
最近知ったのですが公式に便利な操作方法が載ってました。
まず、レベルに置いたカメラたちを全部、複数選択状態にします。
そしてレベルブループリントのグラフ上で右クリックして、
Create References to X selected Actors を探します。
結構紛れて探しにくいのですが、 cr ref で検索するとすぐ出てきます。
これを選択すると・・・
結構便利かも。
このうちの一つから、Make Array ノードを取り出してつなぎます。
これで配列化できました。
これをさっきのSpawn ノードにつなぎます。
Spawn Transform ピンに何もつながれていないとコンパイルした時にエラーがでます。
これはTransformについて適当な初期値を渡してやれば消えてくれます。
オレンジ色のピンからドラッグして、Make Transform を選択します。
こうなります。
これで、再生したときにメインカメラのブループリントがワールドに誕生します。
あとはWidgetをViewportに描けば完成です。
Widget を表示するのは、おなじみ Create Widget ノードと Add to Viewport ノードのコンボです。
Create Widgetノードも Class を変えると入力ピンが増えます。
ここと、先ほどの Spawn Actor from Class の Return Value とをつなぎます。
ようやく完成です。
再生してみます。
静止画だとタイムラインの動作が伝わらないので動画にしました。
使っているタイムラインは1つです。
ブループリントを触らなくても、カメラのアングルやFOVはワールドに置いてあるカメラを直接触ればすぐに反映してくれます。気に入ったアングルはレベルを保存するだけです。
いかがでしょうか?
キャラクリエイションとかで使えそうな気がします。
例えばキャラの身長に合わせてカメラの距離を調整したりとかも、今回の方法ならタイムラインノードをいじらずに臨機応変に補正ができます。
結構長くなりましたが、今回はここまで
ではでは
ステキなカメラ切り替えライフを!