【UEFN】フォートナイトクリエイティブで自作モデルをVerseから動的生成する (Verseの学習⑥)
フォートナイト24.30で自作モデルのスポーンが可能になった!
遂に、遂に、5月2日に更新された24.30で、Verseから自作モデルのスポーンが可能になりました!
といっても、
「はて、スポーンってなんじゃら?」
という方もいらっしゃるかと思いますので、簡単に説明しておきます。
今までのUEFNでは、コンテンツの作成時、レベルに必要なプロップ(小物、アイテム)を、コンテンツビューアーからレベル上にドラッグアンドドロップして、レベルを作成していきます。
100個、必要なプロップがあれば、100個ドラッグアンドドロップしてレベル上に配置することになります。
アーティスティックに作る場合はこの方法で問題ないのですが、レベルの進行状況に応じて表示するための小物などに関しても、同様な手段を取らねばならず、レベルが進行したら表示したいコインなどといったプロップに関しても、「最初は非表示にしておき、必要な時に表示する」、みたいな仕組みを入れていくことになります。
「め、めんどくさい・・・・」
ってなります・・・。
これをプログラム上から可能にする機能がスポーン(生成)です。
先ほどのドラッグアンドドロップのような操作が、Verseから可能になり、
ゲームの進行状況に合わせて、必要な時にスポーン、不要になったら削除、みたいなことが可能になります。
このスポーン機能、Fortnite専用プロップに対しての機能自体は当初からあったのですが、自作モデル(カスタムプロップ)はスポーンすることができていませんでした。
それが、なんと、24.30で可能になりました! ありがとうEpicさん!
今回は、その機能を用いて、プロップをスポーンするためのVerseプログラムを紹介していきます。
一つリンゴをゲーム開始時にSpawnするVerseプログラム
カスタムプロップをスポーンする簡単なプログラムは以下のような形になります。
using { /Fortnite.com/Devices } using { /Verse.org/Simulation } using { /UnrealEngine.com/Temporary/Diagnostics } using { /UnrealEngine.com/Temporary/SpatialMath } ### "Ringo" means "apple" in Japanese!!! #### ringo_spawner_device := class(creative_device): @editable RingoAsset : creative_prop_asset = DefaultCreativePropAsset # Runs when the device is started in a running game OnBegin<override>()<suspends>:void= SpawnPoint : vector3 = vector3 : X := 100.0 Y := 100.0 Z := 100.0 SpawnRotation : rotation = MakeRotationFromYawPitchRollDegrees(0.0, 0.0, 0.0) SpawnProp(RingoAsset, SpawnPoint, SpawnRotation) return
注目するのはまず以下の行です。
@editable RingoAsset : creative_prop_asset = DefaultCreativePropAsset
Verseの中では、コンテンツブラウザー上のプロップ素材が、creative_prop_asset、レベルに配置したプロップが、creative_propということになります。
このコードをコンパイルしてcreative_deviceを画面上に配置すると、creative_deviceの詳細パネルで、スポーンするためのアセットが選択できるようになります。そこにあらかじめ用意した自作のcreative_propを設定してやります。
自作のcreative_propの作り方は以下のページなどを参考にしてください。
OnBegin時、以下の部分でカスタムプロップが生成されます。
SpawnProp(RingoAsset, SpawnPoint, SpawnRotation)
これで、SpawnPointの位置に、SpawnRotationの角度でRingoが生成されます。
無限にリンゴを発生し続けるVerseプログラム
では、次に以下のようなプログラムを書いてみましょう
- 1秒ごとにリンゴを作成し続ける
- 作成したリンゴは、2秒間かけて上昇していく
- 上昇したリンゴは削除される
このコードは以下のようになります。
### "Ringo" means apple in Japanese!!! #### OnBegin<override>()<suspends>:void= loop: ## spawn RingoFunction spawn{SpawnAndMoveAndDisposeRingo()} Sleep(1.0) return SpawnAndMoveAndDisposeRingo()<suspends> : void = SpawnPoint : vector3 = vector3 : X := 100.0 Y := 100.0 Z := 100.0 EndPoint : vector3 = vector3 : X := 100.0 Y := 100.0 Z := 600.0 SpawnRotation : rotation = MakeRotationFromYawPitchRollDegrees(0.0, 0.0, 0.0) var SpawnedProp : ?creative_prop = SpawnProp(RingoAsset, SpawnPoint, SpawnRotation)(0) if: Ringo : creative_prop = SpawnedProp? then: Ringo.MoveTo(EndPoint, SpawnRotation, 2.0) Ringo.Dispose()
簡単に説明していきます。
1秒間隔のループを回し、その中で、並列処理の関数を駆動しています。
spawn{SpawnAndMoveAndDisposeRingo()}
紛らわしいですが、最初のspawnは並列処理を開始するためのspawn式(※関数ではない)、{}で囲まれた部分が、並列処理を行う関数部分になります。
次にこちらですが、
var SpawnedProp : ?creative_prop = SpawnProp(RingoAsset, SpawnPoint, SpawnRotation)(0)
SpawnProp関数の返り値は、タプル型で、(?creative_prop, spawn_prop_result)の2要素 となっています。 必要なものは、第1要素のcreative_propであるため、最初の要素にアクセスするために(0)を付けています。
ただ、SpawnProp関数は失敗する可能性もあるため、creative_prop型には「?」が付いており、オプション型という型で値を受け取らなくてはなりません。
この辺りは他の言語ではあまり見ないVerseの仕様のため、他のプログラム言語に慣れている方でも躓きやすいポイントではないでしょうか。
※SpawnProp関数は、生成しているprop数が多すぎる場合などに失敗する
if: Ringo : creative_prop = SpawnedProp? then: Ringo.MoveTo(EndPoint, SpawnRotation, 2.0) Ringo.Dispose()
オプション型で値を受け取っているため、失敗コンテキストのifを使用して値をセットしなおし、SpawnPropが成功している場合のみ、MoveTo(移動)とDispose(削除)を行うといった流れになります。
このコードがうまくいっていれば、以下のような結果となります。
まとめ
今回は24.30から可能になったカスタムプロップのVerseによる生成機能について説明しました。 現状では、Spawnしたプロップに対する処理がVerse上からあまり行えないため、できることがそれほど多くはありませんが、今後は、CreativeDeviceのVerse内での生成や、PropとDeviceとの関連付けなどがVerseから可能になると思われます。
こうした機能が実装されれば、UEFNでできることの幅は飛躍的に広がるはずです。
ますます今後のUEFNが楽しみになってきましたね。
RingoGamesではUEFNに関するさまざまな情報を発信していきます。Twitterでお知らせしていきますので、よろしければ、Twitterのフォローをしていただけると幸いです。
Twitterはこちら
基本的な検証が大枠できたので、自分もついにリリースするためのゲームを作り始めました:)
頑張って6月までにはリリースしたいです。