【バグ?】Verseで2つの配列を使うと1つ目の配列の出力がおかしくなる

TeleportTo関数を使用して複数の小道具をシャッフル移動させたいときに生じる問題についてです

下記のコード(レベル上の小道具の配列と、同じ小道具配列をシャッフル関数で別の並び順にしたものを組み合わせてTeleportTo関数を使用する)を実行し、小道具をシャッフルすると、ログ表示のように位置情報の重複が生じてしまい、複数の小道具が同じ位置になってしまいます。


using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }
using { /UnrealEngine.com/Temporary/SpatialMath }
using { /Verse.org/Random }
using { /Verse.org/Verse }

#ゲーム開始時、レベル上のカードアクタをシャッフル移動するクラス
prop_teleport := class(creative_device):

    #UEFNレベル上のアクタを格納する配列
    @editable
    var Props: []creative_prop = array{}

    OnBegin<override>()<suspends>:void=
        Sleep(3.0)
        #カードアクタの配列変数Propをシャッフルし、ランダムに並べ替える新しい配列Cards
        var Positions :[]creative_prop = array{}
        set Positions = Shuffle(Props)
        for(Index := 0..Positions.Length-1):
            if (Position := Positions[Index]):
                Transform := Position.GetTransform()
                PositionX := Transform.Translation.X
                PositionY := Transform.Translation.Y
                PositionZ := Transform.Translation.Z
                Rotation := Transform.Rotation
                NewPosition := vector3{X := PositionX, Y :=PositionY, Z :=PositionZ}
                Print("Index: {Index}")
                Print("Teleport NewPosition: {NewPosition}") 
                TereportProp(Index, PositionX, PositionY, PositionZ, Rotation)

    TereportProp(Index:int, PositionX:float, PositionY:float, PositionZ:float, Rotation:rotation): void=
            NewRotation := Rotation.ApplyYaw(0.0)
            NewPosition := vector3{X := PositionX, Y :=PositionY, Z :=PositionZ}
            if (Props[Index].TeleportTo[NewPosition, NewRotation]):
                Print("Teleport NewPosition: {NewPosition}")

ところが、下記のように、↑のプログラムのうち「 if (Props[Index].TeleportTo[NewPosition, NewRotation]):」の部分(つまり小道具の配列を使用したTeleportTo関数の箇所)を削除して再度実行すると位置情報の重複は生じなくなります。

片方の配列にもう片方の配列の出力が影響されるというのがプログラムとして理解できないところですが、これはVerse言語のバグか、あるいは作成した上記プログラムに何か欠けているところがありますでしょうか?

バグではないです

小道具の配列、というのは小道具を指すラベルデータが入っているものと考えてください
Shuffleではその順番を入れ替えているだけです

具体例で説明します
シャッフル後の配列はこうなっていることでしょう

Props: [ A, B, C ]
Positions: [ B, C, A ]

ここからPositionsの位置をPropsに反映(Teleport)していくようですが

1. B -> A
2. C -> B
3. A -> B

と操作したときに、1の時点でBの位置をAの位置に書き換えているので、3の開始時点時点でAの位置はBの位置と同じになっています
これが被っている理由になります

Propsそのものではなく、PropsのTransformの配列を扱うようにすれば、問題は解決すると思います
(下記はそれっぽいコードなので、考え方だけ拾って使ってください)


var Positions  :[]transform = array{}
for (Index := 0..Props.Length - 1):
    Positions[Index] = Props[Index].GetTransform()

Positions := Shuffle(Positions)

# このあとは従来通りTeleportに使う
...

回答ありがとうございます。

そういう仕様なのですね。いただいた考え方の認識が合っているかどうか確認させていただきたいのですが、コードの該当部分を書き直すとこのようになりますでしょうか?

OnBegin<override>()<suspends>:void=
        Sleep(3.0)
        # 位置情報のみをシャッフルし格納する配列
        var Positions :[]transform = array{}
        # Prop配列から位置情報のみを抽出しPositions配列に格納するFor文を追加
        for(Index := 0..Props.Length-1):
            if (Position := Positions[Index], Element := Props[Index]):
                Position = Element.GetTransform()

        Positions = Shuffle(Positions)

        for(Index := 0..Positions.Length-1):
            if (Position := Positions[Index], Element := Props[Index]):
                Transform := Position.GetTransform()
                PositionX := Transform.Translation.X
                PositionY := Transform.Translation.Y
                PositionZ := Transform.Translation.Z
                Rotation := Transform.Rotation
                NewPosition := vector3{X := PositionX, Y :=PositionY, Z :=PositionZ}
                TereportProp(Index, PositionX, PositionY, PositionZ, Rotation)

新しく追加したFor文内の

Position = Element.GetTransform()

の箇所ですが、これはフィールドとして定義しているProp変数配列の要素(位置情報)を、新しく準備したtransform型配列Positionsに要素を追加している、という理解でよろしいでしょうか?

よろしくお願いします。b

考え方はあってます

Verseは基本殆どの変数がconstの扱い、かつ配列も可変ではないので、配列の初期化に関しては下記のようにする必要があるかと思います

var Positions : []transform = 
    for(n := 0..Props.Length - 1):
        if (Prop := Props[n]):
            Prop.GetTransform()
        else:
            # こちらは配列の中身がおかしいとき以外流れない
            transform{}

set Positions = Shuffle(Positions)

...

おそらく下記コードではAssignできずエラーになります

if (Position := Positions[Index], Element := Props[Index]):
   Position = Element.GetTransform()

ありがとうございます!

完全に解決できました。