ken26uの日記

Blender, Excel, その他ソフトのメモを中心にしています

Unreal Engine 4 UE4学習 12日目 AEC 向けサンプルによるブループリント チュートリアルを見る 2/2

はじめに

  • なにか目的を持って作りたい為UE4を始める
  • UE4一ヶ月でどれくらいのレベルになるのか検証

猫でも分かるシリーズは次の回を待つとしてオンラインラーニングをやっていきます。

今回は前回に引き続きこちら

f:id:ken26u:20200627132359p:plain

実践3. アクターの正確な配置を容易にする

  • レベル作成時に多くの時間を節約する方法を学ぶ
  • ここでは柔軟性のためにコンストラクションスクリプトが使用できます
  • レベル内でのアクターのロケーションの保存と取得を知る必要があります。上軸も決定する必要があります
  • Line Trace を使用して一定の距離を上向きに測れるようになると便利です
    • 一定の距離内にあるメッシュにのみスナップするようにすることができます。
  • 最後に、アクターをライントレースのヒットポイントに移動させることも重要な要素となります。

  • ブループリントはビジュアライゼーションレベル自体の構築にも使える

アクタのロケーションを設定する

  • 原理はスイッチライトと非常によく似ていますのでこのレクチャーではコンストラクションスクリプトでライントレースノードをどのように使用してワールドでのアクタのいちを把握できるかを確認します。

  1. コンテンツブラウザでCeiling_Lightフォルダに移動する
  2. Ceiling_Lightをダブルクリックしてコンストラクションスクリプトを開く f:id:ken26u:20200627222424p:plain
    • このアクタ(Ceiling_Light)が3Dビューにドラッグされるたびに毎回スクリプトがアクタに影響を与えるようにするとのこと
    • コンストラクションスクリプトは実行時だけではなく3Dビューでアクタを使用する場合にも実行されるので理にかなっています
  3. Scene Rootをグラフにドラッグしてリファレンスを作成 f:id:ken26u:20200627222824p:plain
    • トランスフォーム情報はRootに格納されている f:id:ken26u:20200627223043p:plain
    • ビューポートを確認すると天井に配置するもののため (0, 0, 0)のいちよりも下にメッシュが配置されていることがわかる
    • シーンのルートは常にライトオブジェクトの上にあるようにする
  4. SceneRootにGetWorldLocationを接続する
  5. 空いているスペースに Get Actor Up Vector を追加
    • ライントレースを向ける方向が必要であり、今回のケースだと上方向にライントレースを向ける為このノードが必要
  6. Vector * Float ノードを追加し Get Actor Up Vector と接続 f:id:ken26u:20200627223641p:plain
    • スナップする範囲を定めるためのノード。 100をかけるようにする。
    • この100という数値をより大きくすれば上方向へのスナップする距離も大きくなる
      • 例えば地面あたりにあっても数値が大きければ天井にスナップする
      • この範囲を可視化できる方法はあるのだろうか??
  7. 最終的なスナップの最大位置を求めるために vector + vector ノードを配置し接続する f:id:ken26u:20200627224255p:plain
    • ライントレースは開始点と終了点の入力が必要なため、このような計算が必要となる
  8. ブランチノードを配置し接続しておけばいつ呼ばれたかが把握しやすくなる f:id:ken26u:20200627225428p:plain
    • False は何にもヒットしていないことを示す
      • つまり start から end の範囲内にはスナップできそうなものがないことを示す
  9. ライントレースが何にヒットしたかは Result Value に格納されているため、ブランチに接続する f:id:ken26u:20200627225628p:plain
    • こうしておけば、ライントレースがヒットを返した時にBranchのテストに渡される
    • 何にもヒットしなかった場合に誤ってBPが実行される事を防げる

コンストラクション スクリプトの基盤を作成する

  1. LineTraceByChannelを追加する f:id:ken26u:20200627224645p:plain
  2. 接続する
    f:id:ken26u:20200627225214p:plain

コンストラクション スクリプトをファイナライズする

  • ライントレースの生成は完了
  • これがどのように3Dワールドでの位置を上書きするか?
  • またその上部にあるシーリングメッシュにどのようにスナップするかを確認する

  1. Break Hit Result を配置し接続する
    f:id:ken26u:20200627230507p:plain
  2. Set world location(Default Scene Root)を配置し接続
    f:id:ken26u:20200627230744p:plain
  3. 接続する
    f:id:ken26u:20200627230946p:plain
    • ブランチは単純になにかにヒットしていることを返す
    • ヒットしている場合 Break Hit Result には何にヒットしているかの情報が格納されておりどこにヒットしているかの情報は Locationにある
    • Default Scene Rootの新しい位置を上記の Location に設定することでスナップが実現する
  4. Default Scene Rootは自動的に配置されているものであり、このグラフの先頭にも同じノードが配置されている。きれいに保つために自動で配置されたものは削除。先頭に配置されているものを接続 f:id:ken26u:20200627231321p:plain

コンストラクション ブループリントをテストする

  • 設定が終わったためちゃんと動作するかテストします

  • コンテンツブラウザに移動

  • Ceiling_Lightをコンテンツブラウザからレベルに配置
    • 地面付近で移動させても何も起こらないが天井付近だとスナップ(吸い付く)
    • しかし一旦スナップしたものは XYはずらせるもののZはずらせなくなる
      • ギズモではなく詳細パネルのTransformをいじればZも変えられる模様

実践4. オブジェクトのマテリアルの変更をユーザーから行えるようにする

  • チャレンジ1では事前に定義したリストに基づいてエンドユーザーがマテリアルを入れ替えられるようにすることです
  • トグルを利用することで単純にしています
  • トグルの利用できる範囲を制限する必要があります
  • 2つの異なるシステムを制御するために Line Traceを設定します。これは我々が克服する必要のあるものです
  • 最後に接近したらわかるような視覚的な手掛かりが必要です。これによってユーザーにマテリアルが変更可能であることを知らせます

アクタのインタラクティブ動作を作成する

  • ここではプレイヤーが近くにいるかどうかを判定する仕組みを実装

  1. SM_MatChange_Static_Meshアクタをダブルクリックして開く f:id:ken26u:20200629084244p:plain
  2. ActorBeginOverlap, ActorEndOverlapノードをイベントグラフに配置、 f:id:ken26u:20200629084756p:plain
  3. 変数を追加名前は CanUse 型は Boolean にする f:id:ken26u:20200629085016p:plain
  4. CanUseをSetで2つ配置して接続する f:id:ken26u:20200629094603p:plain
    • 椅子に近づいたらテキストが表示されるようにする
      f:id:ken26u:20200629095352p:plain
    • すでにテキストは追加してある模様
      f:id:ken26u:20200629095450p:plain
  5. interact , Set visibility x 2 を配置しそれぞれ接続 f:id:ken26u:20200629124001p:plain
    • これで近づくと表示され遠くなると消えるテキストが出来上がり。

マテリアルと通信する

  • BPでマテリアルの切り替えを行う

  1. Custom Event を配置し ChangeMat という名前にする
  2. ブランチノードを追加
  3. FlipFlopノードを配置接続 f:id:ken26u:20200629124217p:plain
  4. SM_Chair_LP のリファレンスを配置 f:id:ken26u:20200629124336p:plain
  5. Set Material x 2を配置し接続。 f:id:ken26u:20200629124920p:plain
  6. マテリアルは上を Fabric_White、下を Fabriic_Greenとする f:id:ken26u:20200629124812p:plain

これで椅子のBPは完了

  1. FirstPerson BPを開く
    f:id:ken26u:20200629125101p:plain
  2. Sequenceノードを配置し接続
    f:id:ken26u:20200629125249p:plain
    • これによって Then0 が終わったら Then1 を続けて実行できるようになる
  3. Cast To SM_MatChangeを配置し、ChangeMatを配置し接続
    f:id:ken26u:20200629125503p:plain

ブループリントをテストする

  • マテリアルの変更ができていること、連打して変わるかなどをテストする

最後に

まだ使ったことないコンストラクションスクリプトが登場しました。コンポーネントの使い方が繰り返しているうちにかなり理解できるようになってきました。

自分用メモ

実践2のまとめで使ったシーケンス図のメモ。 でたらめなシーケンス図なのでいつかちゃんと勉強しなければ

@startuml
User -> FirstPersonCharacter : マウスを押す
FirstPersonCharacter -> BP_Light_Switch : ライトスイッチイベント
BP_Light_Switch -> BP_Wall_Light : スイッチド
@enduml

メモ

  • AECとはArchitecture, Engineering , Constructionの頭文字らしい。建築、エンジニアリング、建設
  • Get Up Vector のドキュメント
  • カスタムイベントは他のBPから呼び出し可能で汎用的な用途が多い便利機能
    • コンパートメント化(小さく区切る?)は自身とプロジェクト両方にとって利益をもたらす

トレースについて

f:id:ken26u:20200628084944p:plain

これはなにか?

f:id:ken26u:20200628085358p:plain

  • トレースはレベル上でラインセグメントに沿って何が存在するかのフィードバックを集める。
  • ラインセグメントにヒットしたアクタがあればレポートする
    • トレースは基本的に他のソフトウェアパッケージの例キャストやレイトレースと同様
  • トレースでは物理システムを使用する
    • このためトレース対象を定義する事ができる
      • 主にChannelsとObject Typesの2種類のカテゴリがある
      • Channels は可視性とカメラのようなものに対して使用される
        • LineTraceByChannel ノード
        • MultiTraceByChannel ノード
        • MultiCapsuleTraceByChannel ノード
          • LineTraceは線。こちらはカプセル。線では不十分なときに使用する
          • Box や Sphereもある
      • Object Types はシーン内でコリジョンを持つ芥の物理の種類
        • LineTraceByObject ノード
        • MultiTraceByObject ノード
        • MultiCapsuleTraceByObject ノード
          • LineTraceは線。こちらはカプセル。線では不十分なときに使用する
          • Box や Sphereもある
        • ボーン、ビークル(乗り物?)、被破壊アクタなどがある
  • トレースは信頼性が高く、演算処理的に負荷が低い
  • カスタムイベントを呼び出す場合、カスタムイベントノードに必要な情報は呼び出し対象のリファレンス
    f:id:ken26u:20200628102447p:plain

使い方

ラインセグメントを定義するため2つのエンドポイント(始点終点)を指定して使用する。

戻り値

  • シングルまたはマルチヒットを返す
  • Hit Result 何がヒットしたかが格納されている

実践1のまとめ 自動ドア

  • コンストラクションスクリプト f:id:ken26u:20200628094737p:plain

    • 自動ドアの初期位置Yを取得して変数に格納しておく
  • イベントグラフ f:id:ken26u:20200628094717p:plain

    • 自動ドアに設定されているBOXコリジョンで重なり始めと重なり終わりを検出
    • 検出したらタイムラインを再生。重なり始め時は順再生、重なり終わりは逆再生
    • タイムラインは0.0 ~ 1.0 という浮動小数を2秒の時間をかけて推移する
      • 推移する方法は線形ではなくユーザー定義(曲線)としており扉はゆっくり開き始め徐々にスピードを上げてゆっくりと停止するアニメーションを実現
    • Lerpは0 ~ 1 を実際のLocationYの値 閉じてるとき to 開いている時の値へマッピングしている
    • Lerp の結果を左右の自動ドアに適用することで自動で開くドアが出来上がっている

実践2のまとめ ONOFF可能な壁ライト

f:id:ken26u:20200628093603p:plain

  • 出てくるBPは3つ
    • FirstPersonCharacter (キャラクター) f:id:ken26u:20200628093745p:plain
      • ライントレースを行いライトにヒットしていたら Light_Switchイベントを呼び出す
      • ライントレースでヒット検知後のCastの意味がわからなかった(ライトスイッチ以外の場合もあるけど大丈夫?と思ってた)がテストしてみると、ライトスイッチ以外をCastしようとすると Cast Filed となる様子。なるほどすっきり。 f:id:ken26u:20200628102029p:plain
    • BP_Light_Switch (スイッチ) f:id:ken26u:20200628093807p:plain
      • どのライトに対してスイッチを作用させるかを選定
        • どのライトをスイッチから作用させるか決めるためパブリックでライト配列を持っている
        • ライト配列はレベル上で手動で事前定義している
      • 選定したライトに対し Switched イベントを送出
    • BP_Wall_Light (壁ライト) f:id:ken26u:20200628093706p:plain
      • Switchされたライトに対して強さを設定

実践 3のまとめ レベル編集時に機能するスナップを実装

  • コンストラクションスクリプト(のみ。BPなし) f:id:ken26u:20200628095641p:plain

  • レベル編集時に作用するBP。

  • 天井付近に天井ライトを配置しようとしたときに付近に天井があったらスナップする
  • 実現方法
    • Default Scene Root ( アクタが持つトランスフォーム情報) + 上方向に 100 の距離のライントレースを作成
    • なにかにヒットしたらヒットした対象のロケーションを取得
    • 取得したロケーションをDefault Scene Root のロケーションに設定する

実践 4のまとめ マテリアルの変更をエンドユーザーから行うことを可能とした

f:id:ken26u:20200629130547p:plain - SM_MatChange - 上段: BOXコリジョンに近づいたら表示・離れたら非表示になるテキスト - 下段: カスタムイベントが実行されるたびにマテリアルを切り替える

  • FirstPersonCharacter f:id:ken26u:20200629130916p:plain
    • Sequenceを追加し2つのタスクを順番に実行する用に設定
    • Cast To SM_MatChangeからはChangeMatカスタムイベントを呼び出す