ゲーム ボードのロジックを構築する最初のステップは、タイルをプログラム内でどのように表現するかを決定することです。
ボード タイルの表現方法を設計する際は、自身やプレイヤーがボード タイルをどのように使用するかについて考えます。 通常、ボード ゲームは、それぞれが区切られた個別の空間で構成されます。 これは UEFN のワールド空間と異なります。
ワールド空間では、座標は vector3 の位置で表現されます。これは、座標が浮動小数点数と同じくらい近くなることがあり、ワールド座標は個別ではなく連続しています。 さらに、同一のボード タイル上に多数の異なる vector3 の位置があります。 ここから、次のようないくつかのことをまとめることができます。
ボード タイルは個別であるため、個別データ (個別データは、整数値または整数値に対応する値範囲を取るデータ) 型を使用して位置を表現することができます。つまり、
intではなくfloat.type を使用します。ボードは 2 次元であるため、2 次元内の位置を保存する必要があるだけです。 ボードのタイル位置を格納するための 3 次元のデータ構造は必要ありません。
ボードのデータ型を定義する
tile_coordinate クラスは、ゲーム ボード上のどこにタイルがあるかを表します。 tile_coordinate クラスを作成するために、「utilities.verse」という名前の新しい Verse ファイルを作成します。 このファイル内で、DataTypes という名前の新しいモジュールを作成します。
DataTypes<public> := module:
このモジュールに新しい TileCoordinate クラスを追加し、クラスのコンポーネントを定義します。
using { /Verse.org/Simulation }
DataTypes<public> := module:
tile_coordinate<public> := class<concrete>:
@editable
Left<public>:int = 0
@editable
Forward<public>:int = 0
座標バトルでは、5 x 5 のボード グリッドを構築します。 つまり、ゲーム ボードの境界を定義する必要があります。 これを行うには、tile_coordinate の Left または Forward の値がどの程度小さいか、または大きいかに関する上限と上限を定義する新しいクラスバウンドを作成します。
using { /Verse.org/Simulation }
DataTypes<public> := module:
tile_coordinate<public> := class<concrete>:
@editable
Left<public>:int = 0
@editable
Forward<public>:int = 0
1 つのデータ構造で 1 つのゲーム ボードのバウンドを保持する構造体が必要です。 そのためには、tile_coordinate の各コンポーネントの下限と上限を定義する新しいクラス board_bounds を作成します。
using { /Verse.org/Simulation }
DataTypes<public> := module:
tile_coordinate<public> := class<concrete>:
@editable
Left<public>:int = 0
@editable
Forward<public>:int = 0
ゲーム ボードの定義
以下のための構造ができました。
ボード空間でのタイルの表現を定義します。
ボード領域の制限を定義します。
まだゲーム ボード自体という大きな要素がありません。 ゲーム ボードを定義するために、board.verse という名前の新しい Verse ファイルを作成します。「board」という名前の新しい Verse の仕掛けを追加します。
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }
using { /UnrealEngine.com/Temporary/SpatialMath }
using { /Verse.org/Assets }
using { DataTypes }
using { UtilityFunctions }
board<public> := class(creative_device):
ボードには以下の要素を含める必要があります。
ワールド空間のどこにボードが配置されているか
ボードのバウンドは何か
ボードのタイルのサイズをどれくらいにするか
最初の質問には新しい変数は必要ありません。仕掛け自体の組み込みトランスフォームを使用できます。 クリエイティブの仕掛けのトランスフォームは、GetTransform API 関数を使用して取得することができます。
2 つ目の質問は、board_bounds 変数で定義できます。
3 つ目の質問は、タイル サイズを追跡するために vector2 変数を定義することで解決できます。
最後の 2 つはボードの仕掛けのフィールドとして追加されます。
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }
using { /UnrealEngine.com/Temporary/SpatialMath }
using { /Verse.org/Assets }
using { DataTypes }
using { UtilityFunctions }
board<public> := class(creative_device):
ボード空間からワールド空間に変換
次に、タイルがワールド内のどこに配置されているかを vector3 として決定し、ゲーム ボード上の位置が tile_coordinate として与えられます。 この関数の名前を「ToVector3」にします ゲーム ボードの中心がどこにあるかを把握するために、ゲーム ボードの範囲内で行われる必要があります。
まず、特定の曖昧な点に対処する必要があります。 tile_coordinate を見ると、同じタイル上にさまざまな vector3 のワールド位置が多数あります。 数学の言語では、これは一対多の関数です。 理想的なのは、タイルがワールド空間での位置に存在するように、単一のワールド位置を選択することです。 自然な選択はタイルの中央です。
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }
using { /UnrealEngine.com/Temporary/SpatialMath }
using { /Verse.org/Assets }
using { DataTypes }
using { UtilityFunctions }
board<public> := class(creative_device):
この関数は、以下を実行します:
ワールド空間でのボードのトランスフォームを取得します。
トランスフォームからワールド空間でのボードの位置を取得します。
ボードの中心を基準にした入力タイルのオフセットを計算します。
ボード位置の中心にオフセットを追加して、ワールドの中心に対する位置を取得します。
ワールド空間からボード空間への変換
ワールド空間に位置が vector3 としてある場合は、それを tile_coordinate に変換する必要があります。
ToTileCoordinate という名前の関数を作成します。 この関数は引数として vector3 を受け取り、tile_coordinate を返します。 ワールド空間での位置が vector3 として与えられますが、ゲーム ボード上の位置を tile_coordinate として判断する場合は、少し複雑です。
これがさらに複雑になる主な理由は、ボードは離散的なグリッドであるため、ゲーム ボードに含まれていないワールド空間の多くの場所が存在するためです。 そのため、ワールド空間での位置を vector3 として指定すると、その位置がゲーム ボード上にない可能性があります。 これにより、ToTileCoordinate が <decides> 関数エフェクト指定子を持つ最適な候補になります。 これが最適な候補である理由は、ゲーム ワールドにはタイル座標上に存在しない場所が数多くあるためです。 この場合、データの変換は失敗します。 この変換が成功または失敗したタイミングを把握しておくことが重要です。 関数 ToTileCoordinate は、最初に位置がゲーム ボードの 1 かどうかを判断し、そうであればその tile_coordinate 位置を返します。
複雑度が増大するもう 1 つの理由は、1 つのタイルが多数の異なるワールド位置で構成されているためです。 数学演算では、これにより ToTileCoordinate 関数は多対一関数になります。
よりわかりやすくするために、ToTileCoordinate の失敗部分を別のものにし、関数 IsTileCoordinateOnBoard を別に定義して、ToTileCoordinate 内でそれを呼び出します。
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }
using { /UnrealEngine.com/Temporary/SpatialMath }
using { /Verse.org/Assets }
using { DataTypes }
using { UtilityFunctions }
board<public> := class(creative_device):
関数 IsTileCoordinateOnBoard は、以下を実行します。
入力タイル座標の左コンポーネントがボードのバウンド内にあるかどうかを決定します
入力タイルの座標前方コンポーネントがボードのバウンド内にあるかどうかを決定します
入力タイル座標がボード境界内にある場合、関数 IsTileCoordinateOnBoard は成功し、それ以外の場合は失敗します。
ToTileCoordinate 関数は、以下を実行します。
ボードのワールド空間トランスフォームを取得します
ワールド空間からボード位置の中心を取得します。
ボードの中心に対するワールド位置の相対位置を計算します。
相対的ワールド位置からタイル座標に変換します。
タイル座標がボード上にあるかどうかを判断します
タイル座標がボード上にあれば、その座標を返します。
関数 ToTileCoordinate は、IsTileCoordinateOnBoard が成功した場合にのみ成功します。
例
以下のセクションでは、「tile_coordinate」を取得して「vector3」に変換し、さらに同じ vector3 を取得して「tile_coordinate」に変換し直す例を確認できます。
タイル座標を Vector3 に設定
次のものが設定されているとします。
5 x 5 のタイルを持つゲーム ボード。
512.0 x 512.0 単位正方形のゲーム タイル。
ゲーム ボードの位置は X := 5000.0,ワールド空間で Y:= 0.0, Z := 1000.0 に設定します。
以下は、タイル座標が Left := -1, Forward := 2.0 であるタイルをワールド空間に変換する手順です。
ToVector3(tile_coordinate{Left := -1, Forward := 2.0})
BoardTransform:transform = GetTransform()
# BoardTransform := transform{Translation := vector3{X := 5000.0, Y := 0.0, Z := 1000.0}, ...}
CenterOfBoard:vector3 = BoardTransform.Translation
# CenterOfBoard := vector3{X := 5000.0, Y := 0.0, Z := 1000.0}
TileOffsetFromCenter:vector3 = vector3:
X := (TileLocation.Forward * TileSize.X)
次は ToTileCoordinate 関数で変換し直す手順です。
ToTileCoordinate(vector3{X := 6024.0, Y := 512.0, Z := 1000.0}):
BoardTransform:transform = GetTransform()
# BoardTransform := transform{Translation := vector3{X := 5000.0, Y := 0.0, Z := 1000.0}, ...}
CenterOfBoard:vector3 = BoardTransform.Translation
# CenterOfBoard := vector3{X := 5000.0, Y := 0.0, Z := 1000.0}
ShiftedWorldLocation:vector3 = WorldLocation - CenterOfBoard
# ShiftedWorldLocation := vector3{X := 6024.0, Y := 512.0, Z := 1000.0} - vector3{X := 5000.0, Y := 0.0, Z := 1000.0}
この最後の tile_coordinate は初期値とまったく同じであり、全てが想定どおりに機能していることを意味しています。
概要
要約すると、このページでは、次の手順を実行しました。
ボード空間でのタイルの表現を定義します。
ボード領域の制限を定義します。
ワールド空間内でボード空間を配置する場所を定義します。
ボード空間とワールド空間の間を変換します。
ファイル
using { /Verse.org/Simulation }
DataTypes<public> := module:
tile_coordinate<public> := class<concrete>:
Left<public>:int = 0
Forward<public>:int = 0
bounds<public> := class<concrete>:
@editable
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }
using { /UnrealEngine.com/Temporary/SpatialMath }
using { /Verse.org/Assets }
using { DataTypes }
using { UtilityFunctions }
board<public> := class(creative_device):
type