HOME

HoudiniEngineを使ってUnrealEngine上でコリジョンを更新する(HoudiniEngine 20.5.522)

過去にも試したことがあるが、記事を作成しようとした際に不具合でうまくいかなかったことがあった。 現環境で不具合が直っていたので改めて確認

環境

Houdini Indie 20.5.522
Houdini Engine 20.5.522
UnrealEngine5.5.3

補足:Houdini20.5.278で発生したHoudiniEngineの不具合について

Houdini20.0で過去に試したことがあり、20.5にアップデートした初期の頃に記事化しようとしたら不具合でリソースの上書きができない時期があった。
(その折はサポートに報告させていただきました。)

[移行記事]HoudiniEngine20.5.278でベイクフォルダ指定できない不具合
https://www.procedural.jp/articles/doekagcs3

現環境で試したところ直っていたので改めて流れを確認した。

スタティックメッシュを読み込む

※この工程は最終的なノードの構成には不要な手順です

デバッグやテストを行うためのスタティックメッシュをキャッシュ化する。
HoudiniEngineのSyncを使うなら不要。
(僕はUEのクラッシュが嫌で極力UE側を触りたくないのでこの手順でHoudini内のみで作業しています)

file cacheのみを作成したhdaを用意し、

UnrealEngineからキャッシュを保存する用のhdaを作成

HoudiniEngineを読み込んだUnrealEngine上で、このhdaから絶対パスなどでキャッシュとして保存

UnrealEngineのHoudiniEngineからhdaを介してスタティックメッシュをキャッシュ化

Houdini上でキャッシュを読み込み

UnrealEngineから出力されたスタティックメッシュをHoudiniで読み込み

これでUEのコンポーネントからメッシュを入力した場合の情報が参照できるのでノードの検証やデバックに利用できる。

上書きのためのアトリビュートを作成

上書き用のパス設定などを行うためのアトリビュートを設定する。
文字列の処理が楽なので以降、自分はPythonで行う。

unreal_input_mesh_name
入力されたメッシュの 各Primにunreal_input_mesh_nameというアトリビュートがあり、入力したスタティックメッシュのパスが格納されている。

UnrealEngine上で参照されている情報がアトリビュートにある

以下のようなPythonで参照できる。

check_prim = geo.prim(0)
source_mesh = check_prim.attribValue("unreal_input_mesh_name")
source_folder_path = os.path.dirname(source_mesh)
source_mesh_name = os.path.basename(source_mesh)

※Pythonを使う場合の注意点があり、Pythonだとvexに比べて非常に遅いのでコンポーネント単位の処理を行おうとするとボトルネックになりがち。geo.prims()でprimすべてが入ったタプルを取得できるが、今回のようにprimすべてに同じアトリビュートが入っていることが明確ならgeo.prim(index)で取得した方が良いと思う

unreal_bake_name
この名称のDetail、ないしPrimアトリビュートがhdaの出力にあった場合、HoudiniEngineからこの名称でデータが作成される。
入力メッシュから参照した値を設定する。

out_mesh_name = source_mesh_name.split(".")[-1]
# アトリビュートの作成
geo.addAttrib(hou.attribType.Global, "unreal_output_name", "")
# アトリビュートの設定
geo.setGlobalAttribValue("unreal_output_name", out_mesh_name)

unreal_bake_folder
この名称のDetail、ないしPrimアトリビュートがhdaの出力にあった場合、HoudiniEngineからこのパスの階層にデータが作成される。
入力メッシュから参照した値を設定する。

source_folder_path = os.path.dirname(source_mesh)
# アトリビュートの作成
geo.addAttrib(hou.attribType.Global, "unreal_bake_folder", "")
# アトリビュートの設定
geo.setGlobalAttribValue("unreal_bake_folder", source_folder_path)

スタティックメッシュの更新
以上の、入力パスから出力パスを作成する手順を実行することで既存のスタティックメッシュを入力し、処理した結果でデータの上書きまでができるようになる。
以下の画像は入力メッシュを更新するhdaを作成したテスト。

UnrealEngine上でコンテンツの上書きができるかのテストのため、入力メッシュを変形し出力するhdaを作成
UnrealEngine上で実行
ベイクすると入力に利用したコンテンツを上書き保存できる

コリジョンを更新する

本題。入力メッシュのコリジョンを更新できるようなhdaを作成する。
コリジョンを設定するにはcollision_geo、ないし、単純なコリジョンが必要ならcollision_geo_simpleというグループ名を設定したメッシュをmargeしてhdaの出力に指定するとコリジョンが設定された状態でメッシュが作成される。

collision_geoとcollision_geo_simpleをマージして出力

「上書きのためのアトリビュートを作成」の項で作成したhdaの出力にmargeして、UnrealEngine上でhdaにコンテンツを設定するとコリジョンを設定した状態で保存ができる。

ベイクするとコリジョンが更新される

HDA全体と入出力用のPython

最終的なhdaの構成
import os

node = hou.pwd()
geo = node.geometry()

source_unreal_mesh_attr_name = "unreal_input_mesh_name"
export_file_name_attr_name = "unreal_output_name"
bake_folder_path_attr_name = "unreal_bake_folder"

# プリムアトリビュートの値の設定
check_prim = geo.prim(0)
source_mesh = check_prim.attribValue(source_unreal_mesh_attr_name)
source_folder_path = os.path.dirname(source_mesh)
source_mesh_name = os.path.basename(source_mesh)

out_mesh_name = source_mesh_name.split(".")[-1]


# detailアトリビュートの作成
geo.addAttrib(hou.attribType.Global, export_file_name_attr_name, "")
geo.addAttrib(hou.attribType.Global, bake_folder_path_attr_name, "")

# detailアトリビュートの設定
geo.setGlobalAttribValue(export_file_name_attr_name, out_mesh_name)
geo.setGlobalAttribValue(bake_folder_path_attr_name, source_folder_path)

この後の調整

入出力とコリジョン作成の仕組みができたのであとは入力に合わせて形状を作成し、作成条件などの分岐を用意すればUnrealEngine上のHoudiniEngineで動作するコリジョン作成用のHDAが作成できる。


過去に報告した内容を確認したら直してくれていました。
ありがとう、SideFX。ちゃんと更新してくれる開発元なので信頼しています。

fish_ball

プロシージャル魚類