
みなみ
Tickモドキっぽいものの作り方を教えてください!

りゅう
こんなお悩みを解決します。
本記事の内容
本記事の信頼性
この記事を書いている僕は、クリエイター兼ブロガーです。実際にUEFNを使っており、現在進行形で学んでいます。
今回は、RPGゲームのような俯瞰視点の作り方についてスクショ画像を使って解説します。
なお、alwei様のブログを参考にさせていただきました。
私の解釈に誤りがありましたらその際はご了承ください。(o_ _)o))

あすか
VerseでTickモドキっぽいものを作る方法
※音量にご注意ください。
▼ まず、UEFNを開き、コンテンツドロワーをクリックします。
「prop chair」と入力し、椅子を選びましょう。
(propならなんでもOK)
※クリックすると拡大表示されます。
▼ propを追加したら、画面上にある「Verse」をクリックし、「Verse Explorer」を選択します。
▼ 画面右に「Verse Explorer」が表示されるので、Content下の「プロジェクト名」を右クリックし、「Add new Verse file to project」を選択します。
▼ 『rotate_device』と入力し、「作成」をクリック。
▼ 青枠部分の「Verse」をクリック。
▼ 以下のようにコードを入力します。
完全なスクリプト
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/SpatialMath }
rotate_device := class(creative_device):
@editable Prop:creative_prop = creative_prop{}
@editable Speed:float = 0.5
var Count:int = 0
Tick()<suspends>:void=
loop:
Print("Tick Execute Count : {Count}")
set Count = Count + 1
var t:transform = Prop.GetTransform()
if:
Prop.TeleportTo[t.Translation, t.Rotation.ApplyLocalRotationZ(Speed)]
Sleep(0.0)
OnBegin<override>()<suspends>:void=
spawn{Tick()}
引用:Let's Enjoy Unreal Engine
▼ コードを入力したらUEFNに戻り、コンテンツドロワー→コンテンツ→「Creatives Devices」をクリック。
▼ デバイスをシーン上に設置します。
▼ 設置したら、「Verse」→「Verseコードをビルド」をクリックします。
▼ ビルドしたら、デバイスを選択し「prop」に設定しましょう。
▼ 設定が完了したら、「セッションを開始」を押して実行できるか試してみましょう。
▼ 椅子が回転してればOKです。

あすか

みなみ

りゅう
alweiさんのTwitter account ⚡
My Twitter account 🍀
Verseコードの解説
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/SpatialMath }
rotate_device := class(creative_device):
@editable Prop:creative_prop = creative_prop{}
@editable Speed:float = 0.5
var Count:int = 0
Tick()<suspends>:void=
loop:
Print("Tick Execute Count : {Count}")
set Count = Count + 1
var t:transform = Prop.GetTransform()
if:
Prop.TeleportTo[t.Translation, t.Rotation.ApplyLocalRotationZ(Speed)]
Sleep(0.0)
OnBegin<override>()<suspends>:void=
spawn{Tick()}
注意:以下のコードの解説文はプログラミング初心者の主が解説したものです。

あすか
参考程度にどうぞ。
▼ この行では、Prop
という名前のプロパティ(属性)を宣言しています。
@editable Prop:creative_prop = creative_prop{}
@editable Speed:float = 0.5
var Count:int = 0
クリックすると開きます。
@editable Prop:creative_prop = creative_prop{}
この行では、Prop
という名前のプロパティ(属性)を宣言しています。
このプロパティの型はcreative_prop
であり、初期値はcreative_prop{}
となっています。
@editable
は、このプロパティが編集可能であることを示しています。
@editable Speed:float = 0.5
この行では、Speed
という名前のプロパティを宣言しています。
このプロパティの型はfloat
(浮動小数点数)であり、初期値は0.5
となっています。
var Count:int = 0
この行では、Count
という名前の変数を宣言しています。
この変数の型はint
(整数)であり、初期値は0
となっています。
Countについて
クリックすると開きます。
var Count:int = 0
は、Count
という名前の変数を定義しています。
この変数は整数の値を格納するためのものであり、初期値は0
です。
この変数は、Tick
メソッド内で使用されています。
Tick
メソッドはループ内で実行され、回転処理を行うたびにCount
の値が1ずつ増加します。
これにより、回転が何回実行されたかをカウントするための変数として使用されます。
具体的には、Tick
メソッド内で以下のようなコードがあります。
set Count = Count + 1
このコードによって、現在のCount
の値に1を加えて新しい値をCount
に代入しています。
つまり、回転が1回実行されるたびにCount
の値が1ずつ増加します。
このように、Count
変数は回転が何回実行されたかを追跡するためのものであり、回転のカウントや制御に使用されます。
▼ この部分のコードは、Tick
というメソッドの定義です。
Tick()<suspends>:void=
loop:
Print("Tick Execute Count : {Count}")
set Count = Count + 1
var t:transform = Prop.GetTransform()
if:
Prop.TeleportTo[t.Translation, t.Rotation.ApplyLocalRotationZ(Speed)]
Sleep(0.0)
クリックすると開きます。
Tick()<suspends>:void=
この行は、Tick
というメソッド(関数)を定義しています。
<suspends>
は、このメソッドが一時停止可能であることを示しています。
また、void
はメソッドが値を返さないことを示しています。
loop:
この行は、無限ループを表しています。
loop
キーワードを使うことで、Tick
メソッドがずっと繰り返し実行されるようになります。
Print("Tick Execute Count : {Count}")
この行は、テキストを表示するための命令です。
Print
関数を使って、"Tick Execute Count : {Count}"
というテキストを表示しています。
{Count}
は、Count
変数の値を埋め込んだものです。
set Count = Count + 1
この行は、Count
変数の値を1増やしています。
Count
には回転が実行された回数が格納されており、この行によって回転が1回実行されるたびにカウントが増えます。
var t:transform = Prop.GetTransform()
この行では、Prop
の位置と回転情報を取得しています。
Prop.GetTransform()
は、Prop
の変換情報を取得するためのメソッドです。
取得した情報は、t
という変数に格納されます。
if:
Prop.TeleportTo[t.Translation, t.Rotation.ApplyLocalRotationZ(Speed)]
この行では、条件文(if
文)があります。
if
の後には条件式が続き、条件式が真の場合に実行される処理が行われます。
ここでは、条件式が省略されているため、条件は常に真となります。
Prop.TeleportTo[t.Translation, t.Rotation.ApplyLocalRotationZ(Speed)]
は、Prop
の位置と回転情報を指定された値で更新するためのメソッドです。
具体的には、t.Translation
は位置を表し、t.Rotation.ApplyLocalRotationZ(Speed)
は回転を表します。
これにより、Prop
が指定された速度(Speed
)でZ軸周りに回転します。
Sleep(0.0)
この行は、一定時間待機するための命令です。
Sleep
関数を使って、指定した時間(ここでは0.0
秒)だけ待続きです。
この場合、0.0
秒の待機となるため、ほとんど待機せずに次のループがすぐに始まります。
Sleep(0.0)
このように、Tick
メソッドは以下のような処理を行います。
- メッセージを表示して回転が実行された回数を表示する。
Count
変数の値を1増やす。Prop
の位置と回転情報を取得する。Prop
の位置と回転を更新し、回転処理を実行する。- ほんのわずかな時間待機する。(しないと同然)
- 上記の処理を無限ループする。
このコードは、rotate_device
クラスのTick
メソッドがデバイスの回転を制御するためのコードです。
Count
変数を使って回転のカウントを行い、Prop
の位置と回転を更新してデバイスを回転させます。
また、一定時間の待機を挟むことで、一定の速度で回転させることができます。
var t:transform = Prop.GetTransform()
クリックすると開きます。
var t:transform = Prop.GetTransform()
このコードは、変数 t
を宣言し、その型を transform
と指定しています。
また、Prop.GetTransform()
を使って Prop
の変換情報を取得し、それを変数 t
に代入しています。
ここで使われている transform
は、おそらくデバイスやオブジェクトの位置と回転情報を表すデータ型であると推測されます。
Prop.GetTransform()
は、Prop
オブジェクトの現在の位置と回転情報を返すためのメソッドでしょう。
つまり、この行のコードでは、Prop
の現在の位置と回転情報を取得し、それを変数 t
に格納しています。
t
変数には、デバイスやオブジェクトの位置情報や回転情報が含まれることになります。
これにより、後続のコードで t
変数を使用して、デバイスやオブジェクトの位置や回転に関する情報を取得することができます。
例えば、t.Translation
は位置情報を表し、t.Rotation
は回転情報を表します。
このようにして、Prop.GetTransform()
を使って Prop
オブジェクトから位置と回転情報を取得し、それを t
変数に代入することで、後続の処理でその情報を利用できるようにしています。
Translationについて
クリックして下さい
t.Translation
は、変数t
に格納されたトランスフォーム情報から位置情報を取得するための部分です。
デバイスの現在の位置を表しています。
トランスフォーム情報は、オブジェクトの位置、回転、スケールなどを包括的に表現するためのものです。
デバイスの位置情報はその中の一部であり、位置は通常3D空間内の座標で表されます。
具体的には、t.Translation
は、デバイスがX軸、Y軸、Z軸のそれぞれの方向にどれだけ移動しているかを表します。
たとえば、(0, 0, 0)は原点を表し、(1, 0, 0)はX軸方向に1単位移動した位置を表します。
デバイスの位置情報を取得することで、デバイスがどの位置に存在しているかを把握することができます。
そして、この位置情報を基にデバイスの挙動や表示を制御することができます。
なお、デバイスの位置情報は、通常トランスフォーム情報内の他の要素(回転やスケール)と組み合わせて使用されます。
デバイスを回転させたり、サイズを変更したりする場合には、位置情報も変化する可能性があります。
したがって、t.Translation
はデバイスの現在の位置を表し、その位置情報を活用してデバイスの挙動や表示を制御することができます。
Rotationについて
クリックして下さい
t.Rotation.ApplyLocalRotationZ(Speed)
は、回転を適用するための式です。
t.Rotation
は、変数t
に格納されたトランスフォーム情報から回転情報を取得するための部分です。
t.Rotation
は、デバイスの現在の回転を表しています。
.ApplyLocalRotationZ(Speed)
は、回転を適用する操作を行うためのメソッドです。
>> 公式ドキュメントを見る
具体的には、デバイスを現在の回転に対してSpeed
の値だけZ軸周りに回転させることを意味します。
ここで、Z軸とは、直感的には奥行き方向を表す軸です。
デバイスを回転させるときに、どの軸周りに回転を適用するかを指定することができます。
この場合、ApplyLocalRotationZ
メソッドはZ軸周りに回転を適用するため、デバイスが奥行き方向に対して回転することになります。
Speed
は、回転の速度を表す変数です。この値によって回転の速さが変わります。
具体的な値はコード内でSpeed:float = 0.5
と指定されているように、0.5となっています。この値を変更することで回転の速さを調整することができます。
したがって、t.Rotation.ApplyLocalRotationZ(Speed)
は、デバイスの現在の回転に対してZ軸周りに指定した速度で回転を適用する操作を表しています。
デバイスはこの回転操作によって奥行き方向に回転し、デバイスの見た目や挙動が変化します。
breakに関して
クリックすると開きます。
ループを終了させるために一般的に使われるコードは、break
文です。
break
文は、ループ内で条件が満たされた場合にループを即座に終了させるために使用されます。
上述のコードの場合、Tick()
メソッド内のループは無限ループとなっていますが、終了条件が不足しているため、永遠にループし続けます。
以下にbreak
文の使用例を示します。
while True:
# ループの処理
if some_condition:
break # 条件が満たされたらループを終了
上記の例では、while
ループが無限に継続されますが、some_condition
が満たされた場合にbreak
文が実行され、ループが終了します。
同様に、for
ループでもbreak
文を使用することができます。
for i in range(10):
# ループの処理
if some_condition:
break # 条件が満たされたらループを終了
上記の例では、for
ループが10回繰り返されますが、some_condition
が満たされた場合にbreak
文が実行され、ループが終了します。
break
文はループ内のどの位置でも使用することができますが、条件判定の後に配置することが一般的です。
条件が満たされた時点で直ちにループを終了したい場合に有効な手段です。
Transform型とVector3型の違いについて
クリックすると開きます。
Transform 型と Vector3 型にはいくつかの違いがあります。
- Transform 型は、3D オブジェクトの位置、回転、スケールの情報を表す型であるのに対し、Vector3 型は 3 次元ベクトルを表す型です。
- Transform 型には Position、Rotation、Scale というプロパティが存在するのに対し、Vector3 型には X、Y、Z というプロパティが存在します。
Transform 型と Vector3 型は、どちらも 3 次元の位置を表す型ですが、使用される場面や持っているプロパティが異なります。
さらに詳しく解説すると・・・
- Transform 型は、オブジェクトのローカル座標を表します。
- ローカル座標とは、オブジェクトの原点を基準とした座標です。
- Vector3 型は、ワールド座標を表します。
- ワールド座標とは、ゲーム世界の原点を基準とした座標です。
たとえば、オブジェクトを回転させたときに、Transform 型の位置は変わりません。
しかし、Vector3 型の位置は変わります。これは、Vector3 型はワールド座標を表しているためです。
Transform 型は、オブジェクトの位置や回転を制御するために使用されます。
Vector3 型は、オブジェクトの位置や回転を計算するために使用されます。
プログラミング初心者向けにわかりやすく解説すると、Transform 型は、オブジェクトの位置や回転をオブジェクト自体の基準で表します。Vector3 型は、オブジェクトの位置や回転をゲーム世界の基準で表します。
オブジェクトを回転させた場合、Transform 型の位置は変わりませんが、Vector3 型の位置は変わります。
これは、Transform 型はオブジェクト自体の基準で位置を表しているため、オブジェクトを回転してもオブジェクト自体の位置は変わりません。
しかし、Vector3 型はゲーム世界の基準で位置を表しているため、オブジェクトを回転するとゲーム世界の中の位置が変わります。
▼ OnBegin<override>()<suspends>:void=
は、デバイスが開始されたときに実行されるメソッドを定義しています。
OnBegin<override>()<suspends>:void=
spawn{Tick()}
クリックすると開きます。
OnBegin<override>()<suspends>:void=
は、デバイスが開始されたときに実行されるメソッドを定義しています。
override
修飾子がついているため、親クラスで定義された同名のメソッドを上書きしています。
OnBegin
メソッドは、デバイスの初期化や準備などの処理を行うためのメソッドです。
ゲーム内のイベントやアクションに応じて呼び出されることがあります。
<suspends>
は非同期処理の指示であり、このメソッドが非同期で実行されることを示しています。
非同期処理は、複数の処理が同時に実行されるため、待ち時間が発生しても他の処理がブロックされません。
void
は、このメソッドが値を返さないことを示しています。
つまり、メソッドが呼び出された後は何も返さずに終了します。
spawn{Tick()}
は、Tick()
メソッドを非同期で実行するためのコードです。
spawn
ブロック内の処理は並列して実行されます。
Tick()
メソッドは、デバイスの回転を実行するためのメソッドです。
このメソッドはループ処理を行い、定期的に実行されます。
つまり、OnBegin()
メソッドが呼び出されると、非同期でTick()
メソッドが実行されます。
これにより、デバイスの回転が開始されます。
このように、OnBegin<override>()<suspends>:void=
とspawn{Tick()}
の組み合わせは、デバイスの初期化と回転処理の開始を行うためのコードです。
デバイスが開始されたときに自動的に回転が開始されるように設定されています。
spawnが使われている理由
クリックすると開きます。
spawn
は非同期処理を実行するためのキーワードです。
非同期処理とは、複数の処理が同時に実行されることを意味し、一つの処理が終わるまで待つ必要がないため、他の処理をブロックすることなくプログラムが進行します。
spawn{}
ブロック内のコードは、非同期に実行されます。
つまり、spawn
ブロック内の処理が実行された後、その結果を待つことなく次の行に進むことができます。
この例では、spawn{Tick()}
というコードが使われています。
これにより、Tick()
メソッドが非同期に実行されます。
つまり、OnBegin()
メソッドが呼び出された後、Tick()
メソッドがバックグラウンドで実行され、他の処理と同時に進行します。
このようにすることで、デバイスの初期化処理と回転処理が同時に行われます。
OnBegin()
メソッドは初期化処理を担当し、Tick()
メソッドは回転処理を担当します。
非同期処理を使用することで、デバイスの初期化が遅延することなく、回転処理が開始されることが保証されます。
また、spawn
キーワードは並列処理を表すだけでなく、非同期処理が終了するまで待つこともできます。
例えば、spawn{Tick()}
の行の後に別の処理を追加していた場合、その処理はTick()
メソッドの実行が終了するまで待機します。
ただし、この例では待機処理がないため、spawn
キーワードの効果は非同期実行のみです。
総括すると、spawn
キーワードは非同期処理を実行するために使用されており、複数の処理を同時に実行することができるため、他の処理をブロックせずにプログラムが進行します。
MoveToとTeleportToの違い
クリックすると開きます。
TeleportTo と MoveTo は、どちらもオブジェクトの位置を変更するメソッドです。
ただ、TeleportTo はオブジェクトを瞬時に目的の位置に移動させるのに対し、MoveTo はオブジェクトを目的の位置に移動させるまでの間、滑らかに移動させます。
TeleportTo は、オブジェクトを瞬時に移動させたい場合に使用されます。
たとえば、オブジェクトを敵の近くに移動させたい場合や、オブジェクトをステージの別の場所に移動させたい場合に使用されます。
MoveTo は、オブジェクトを滑らかに移動させたい場合に使用されます。
たとえば、オブジェクトを敵の近くに移動させたいが、敵に攻撃されたくない場合に使用されます。
また、オブジェクトをステージの別の場所に移動させたいが、オブジェクトが途中で止まってしまったり、逆走したりするのを防ぎたい場合に使用されます。
TeleportTo と MoveTo のどちらを使用するかは、シチュエーションによって異なります。
以上、このコードは、Fortniteのデバイスを制御するためのスクリプトであり、Tick()
メソッドをループ内で実行してデバイスの動作を定期的に更新し、OnBegin()
メソッドでTick()
メソッドを非同期に実行しています。
まとめ
今回は、VerseでTickモドキっぽいものを作る方法について解説しました。
完全なスクリプト
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/SpatialMath }
rotate_device := class(creative_device):
@editable Prop:creative_prop = creative_prop{}
@editable Speed:float = 0.5
var Count:int = 0
Tick()<suspends>:void=
loop:
Print("Tick Execute Count : {Count}")
set Count = Count + 1
var t:transform = Prop.GetTransform()
if:
Prop.TeleportTo[t.Translation, t.Rotation.ApplyLocalRotationZ(Speed)]
Sleep(0.0)
OnBegin<override>()<suspends>:void=
spawn{Tick()}
今回もお疲れさまでした。
コツコツとがんばっていきましょう🔥