各横列に並んでいるいくつかのプラットフォームにのみジャンプ可能である、プラットフォームのユニークなグリッド シーケンスを生成することは、プラットフォーム ゲーム モードではよくあります。 その場合、プレイヤーは速度を落として、シーケンスを見つけ出す必要があります。
このチュートリアルでは、プラットフォームのグリッドを生成する方法を示します。このとき、各列にあるプラットフォームはランダムに選択され、コリジョンおよびライト カラーを持たせて、選択されなかったプラットフォームと区別します。
プラットフォームのプレハブを作成する
以下の手順に従って、Verse からスポーンするプラットフォームのプレハブを作成します。
新規エンティティを配置し、それを choose_one_platform_prefab というプレハブに昇格させます。 手順については、「プレハブとプレハブ インスタンス」を参照してください。
プレハブ エディタで、以下のコンポーネントをエンティティに追加します。
transform_component:プラットフォームの位置を決めるトランスフォーム コンポーネント。
mesh_component:プラットフォームのスタティックメッシュを設定するメッシュ コンポーネント。 この例では、Fab マーケットプレイスにある Stylized Egyptian World Pack アセットの SM_block_02 メッシュを使用します。
collision_component:プラットフォームでのコリジョンを有効および無効にするためのコリジョン コンポーネント。
parent_constraint_component:Verse を使用してこのプレハブをワールドにスポーンする際に、親エンティティを基準としたトランスフォームを設定しやすくするための、親コンストレイント コンポーネント。
子エンティティを追加し、「Light」という名前にします。
以下のコンポーネントを子エンティティ Light に追加します。
transform_component:プラットフォームの上でのエンティティの位置を決めるトランスフォーム コンポーネント。
point_light_component:プラットフォームにコリジョンがあるかどうかに応じて色を変える光源に追加する、ポイント ライト コンポーネント。
parent_constraint_component:親エンティティを基準としてこのエンティティのトランスフォームを制約する、親コンストレイント コンポーネント。
プレハブを保存します。
これで、プレハブは、「Assets.digest.verse」ファイルに、プレハブと同じ名前 (choose_one_platform_prefab) のクラスとして表示されます。
プラットフォームのグリッドをスポーンする
以下の手順に従って、プラットフォームのプレハブから作成されたグリッドをスポーンします。
choose_one_component という Verse コンポーネントを作成します。 Verse コンポーネントを作成する手順については、「Verse を使用して独自のコンポーネントを作成する」を参照してください。
以下の編集可能なプロパティを追加します。
グリッド内のプラットフォームの数を定義する、
GridSizeという整数 2D ベクターvector2iフィールド。 X はグリッド内の横列の数であり、Y は縦列の数です。横列と縦列の全体でのプラットフォーム間の間隔を指定する、
PlatformSpacingという浮動小数点 2D ベクターvector2フィールド。~~~(verse) GridSizeTip<localizes>:message = "グリッドのサイズであり、グリッドは X 単位の幅で、Y 単位の深さです" PlatformSpacingTip<localizes>:message = "グリッド上の各プラットフォーム間の距離"
choose_one_component<public> := class(component):
# グリッドのサイズであり、グリッドは X 単位の幅で、Y 単位の深さです。 @editable_vector_number(int): ToolTip := GridSizeTip MinComponentValue := option{0} GridSize:vector2i = vector2i{X := 3, Y := 10}
# グリッド上の各プラットフォーム間の距離。 @editable_vector_number(float): ToolTip := PlatformSpacingTip MinComponentValue := option{0.0} PlatformSpacing:vector2 = vector2{X := 256.0, Y := 256.0} ~~~
OnSimulate関数内で、GridSizeベクターをイテレートして、スポーンするプラットフォームの数を把握します。 そのループ内で、プレハブ クラスのインスタンスを作成し、この Verse コンポーネントのアタッチ先であるエンティティにそれを追加すると、プレハブがワールド内にスポーンされます。~~~(verse) GridSizeTip<localizes>:message = "グリッドのサイズであり、グリッドは X 単位の幅で、Y 単位の深さです" PlatformSpacingTip<localizes>:message = "グリッド上の各プラットフォーム間の距離"
choose_one_component<public> := class(component):
# グリッドのサイズであり、グリッドは X 単位の幅で、Y 単位の深さです。 @editable_vector_number(int): ToolTip := GridSizeTip MinComponentValue := option{0} GridSize:vector2i = vector2i{X := 3, Y := 10}
# グリッド上の各プラットフォーム間の距離。 @editable_vector_number(float): ToolTip := PlatformSpacingTip MinComponentValue := option{0.0} PlatformSpacing:vector2 = vector2{X := 256.0, Y := 256.0}
OnSimulate<override>()<suspends>:void= # プラットフォームをスポーンして、グリッドを作成します。 for (Column := 0..GridSize.Y - 1): for (Row := 0..GridSize.X - 1): # プレハブのインスタンスを作成し、それを既存のエンティティに追加すると、プレハブがワールド内にスポーンされます。 ChooseOnePlatform := choose_one_platform_prefab{} Entity.AddEntities(array{ChooseOnePlatform}) ~~~
この時点でコードを実行すると、すべてのプラットフォームが同じ位置にスポーンされます。 プレハブにはトランスフォーム コンポーネントと親コンストレイント コンポーネントがあるため、そのトランスフォーム コンポーネントの InitialRelativeTransform プロパティを設定すると、プレハブの追加先のエンティティの位置を基準としたオフセットでプレハブをスポーンできます。 スポーンするエンティティに親コンストレイント コンポーネントがなかったとしたら、(ルート エンティティに対する相対位置ではなく) ワールド空間での位置を指定する必要がありました。
VerseGridSizeTip<localizes>:message = "Size of the grid, where the grid is X units wide by Y units deep." PlatformSpacingTip<localizes>:message = "The distance between each platform on the grid." choose_one_component<public> := class(component): # Size of the grid, where the grid is X units wide by Y units deep. @editable_vector_number(int): ToolTip := GridSizeTip MinComponentValue := option{0} GridSize:vector2i = vector2i{X := 3, Y := 10}コードを保存してコンパイルします。
この Verse コンポーネントをエンティティにアタッチし、セッションを起動すると、プラットフォームのグリッドがそのエンティティの位置に現れます。
有効なプラットフォームをランダムに選択する
プラットフォームのグリッドをワールドにスポーンしたので、それらに機能を追加できます。 以下の手順では、プレイヤーがジャンプして渡ることができる、ユニークで順序が変わるプラットフォームを生成するために、コリジョンがあるプラットフォームをランダムに選択する方法を示しています。
以下の手順に従って、グリッドの中で有効なプラットフォームをランダムに選択します。
以下の編集可能なプロパティを Verse コンポーネントに追加します。
コリジョンがあるプラットフォームの最小数を指定する、
MinCorrectPlatformsPerRowという整数変数。コリジョンがあるプラットフォームの最大数を指定する、
MaxCorrectPlatformsPerRowという整数変数。コリジョンが有効になっている場合のプラットフォームのカラーを設定する、
ChosenColorという color 変数。コリジョンが有効になっていない場合のプラットフォームのカラーを設定する、
NotChosenColorという color 変数。Verseusing { /UnrealEngine.com/Temporary/SceneGraph } using { /UnrealEngine.com/Temporary/SpatialMath } using { /Verse.org } using { /Verse.org/Colors } using { /Verse.org/Native } using { /Verse.org/Random } using { /Verse.org/Simulation } GridSizeTip<localizes>:message = "Size of the grid, where the grid is X units wide by Y units deep." PlatformSpacingTip<localizes>:message = "The distance between each platform on the grid."
for式の結果は、各イテレーションの配列です。 1 つの横列に対してスポーンされたすべてのプラットフォームを 1 つの配列に格納し、その配列を、プラットフォームをランダムに選択するRandomizeCollidablePlatformsPerRow()という関数に渡します。VerseOnSimulate<override>()<suspends>:void= # For each row, spawn multiple platforms and pick a number of them to have collision while the others don't. # The platforms with collision will have the Chosen color for their light component. # The platforms without collision will have the NotChosen color for their light component. for (Row := 0..GridSize.Y - 1): EntitiesInRow := for (Column := 0..GridSize.X - 1): # The prefab has a parent constraint component so set the InitialRelative Transform # on the transform component to offset each platform relative to this entity. # This means the platform prefabs will spawn same distance from each other # but moving the root entity will change where the platforms originate.コリジョンがあるエンティティをランダムに選択する
RandomizeCollidablePlatformsPerRowという関数を作成し、すべてのエンティティでコリジョンを無効にします。 ポイント ライト コンポーネントはプレハブの子エンティティ上にあるため、FindComponentsを使用して、そのエンティティの子の中から、ポイント ライトの色を変える子エンティティを見つけることができます。Verse# Randomly choose platforms to have collision in the row. RandomizeCollidablePlatformsPerRow(Entities:[]entity):void= # Disable all the entities before choosing which ones to enable. # It disables an entity by disabling the collision on the entity, # and finding a point light in its child entities to change its color. for: EntityPlatform : Entities Collision := EntityPlatform.GetComponents(collision_component)[0] Light := EntityPlatform.FindComponents(point_light_component)[0] do:配列からランダムに要素を選択する、
ChooseOneという、配列用の拡張メソッドを作成します。 その結果は、選択された要素と、選択されていない他のすべての要素の配列の両方が入っているタプルです。Verse# An extension method for an array to get a randomly selected element from the array. (Input:[]t where t:subtype(comparable)).ChooseOne()<decides><transacts>:tuple(t, []t)= ChosenElement := Input[GetRandomInt(0, Input.Length - 1)] NotChosenElements := Input.RemoveFirstElement[ChosenElement] (ChosenElement, NotChosenElements)RandomizeCollidablePlatformsPerRowからChooseOneを呼び出して、コリジョンがあるエンティティを選択し、その色を変えます。Verse# Randomly choose platforms to have collision in the row. RandomizeCollidablePlatformsPerRow(Entities:[]entity):void= # Disable all the entities before choosing which ones to enable. # It disables an entity by disabling the collision on the entity, # and finding a point light in its child entities to change its color. for: EntityPlatform : Entities Collision := EntityPlatform.GetComponents(collision_component)[0] Light := EntityPlatform.FindComponents(point_light_component)[0] do:編集可能なプロパティに基づいて、コリジョンがある複数のエンティティを選択するように、
RandomizeCollidablePlatformsPerRowを更新します。 まず、横列あたりの正しいプラットフォームの最小数と最大数の間のランダムな値を取得し、その回数だけエンティティを選択して、選択されたエンティティを次回の選択候補のリストから取り除きます。Verse# Randomly choose platforms to have collision in the row. RandomizeCollidablePlatformsPerRow(Entities:[]entity):void= # Disable all the entities before choosing which ones to enable. # It disables an entity by disabling the collision on the entity, # and finding a point light in its child entities to change its color. for: EntityPlatform : Entities Collision := EntityPlatform.GetComponents(collision_component)[0] Light := EntityPlatform.FindComponents(point_light_component)[0] do:コードを保存してコンパイルします。
この時点でセッションを起動すると、プラットフォームのグリッドがワールドにスポーンされ、コリジョンと ChosenColor がユニークな順序で適用されるプラットフォームになります。
完全なスクリプト
using { /UnrealEngine.com/Temporary/SceneGraph }
using { /UnrealEngine.com/Temporary/SpatialMath }
using { /Verse.org }
using { /Verse.org/Colors }
using { /Verse.org/Native }
using { /Verse.org/Random }
using { /Verse.org/Simulation }
GridSizeTip<localizes>:message = "Size of the grid, where the grid is X units wide by Y units deep."
PlatformSpacingTip<localizes>:message = "The distance between each platform on the grid."