【Roblox】チュートリアルでよく見る「あの矢印」 ~Beamオブジェクト~
1.はじめに
Robloxで新しいゲームをプレイした時、チュートリアルで、こんな感じのプレイヤーを誘導する矢印を見たことはないでしょうか?

これ、薄いパーツを配置して毎フレーム位置を調整してテクスチャをスクロールして……なんて自分で細かくコーディングする必要はなく、Robloxに用意されているオブジェクトで簡単に作る事ができます。
それがBeamです。
Beamは、二つのAttachmentに対して、それらの間をつなぐようにテクスチャを描画するオブジェクトです。
チュートリアルでよく見る矢印は、これでPlayerCharacterと目標地点をつないで表現されているわけですね。
今回は、このBeamオブジェクトについてご紹介します。
バージョン:0.672.0.6720706
2. 「あの矢印」を作ってみる
とりあえず、チュートリアルのあの矢印を作ってみましょう。
確認しながら調整できないと不便なので、まずは確認用のオブジェクトを配置します。
WorkspaceにPartを置き、その子にBeamとAttachment2つを追加してください。
Attachmentの名前はわかりやすいよう「Attachment0」と「Attachment1」としておきます。

PartはTransparencyを1にして、適当な場所に置いてください。
これで最初の準備はOKです。
Attachment0, Attachment1
まず、BeamのプロパティのBeam.Attachment0に先ほど作ったAttachment0を、Beam.Attachment1にAttachment1を設定してください。
Attachment0がBeamの始点、Attachment1が終点になります。

この状態でAttachment1の座標を適当に動かしてみると、こんな感じで二つのAttachmentを繋ぐ白い板が描画されたはずです。

これがBeamです。
Texture
次にTextureを設定します。
サンプル用に新しく作るのは大変なので、今回はRobloxに元から用意されている画像を使用します。
Robloxに元から用意されている画像とその参照方法については以下の記事で解説していますので、詳しく知りたい方はこちらをご覧ください!
今回は、「rbxasset://textures/StudioToolbox/ArrowDownIconWhite.png」に設定してください。

こんな感じ画像 背景は透過されている
するとなにやら矢印っぽいものが流れるようになりました。

テクスチャ画像の上側が始点側、画像の下側が終点側に向いて表示されています。
この向きは変更できないので、自分でテクスチャを作成する場合は画像の向きに注意してください!
さて、とりあえず流れる矢印にはなっていますが、色々調整が必要そうです。
まず、矢印が伸びてしまっているのが気になります。
これは、TextureLength及びTextureModeによって設定できます。
TextureLength, TextureMode
TextureLengthは、テクスチャの長さを設定するためのプロパティで、TextureModeの設定によって挙動が異なります。
TextureModeは、Beamに付けたテクスチャがどのように貼り付けられるかを設定します。
選択肢としてはStretch、Warp、Staticの3つがあるのですが、Beamの場合はStaticには対応していないため、Warpと同じ挙動になります。
Stretchは、Beam全体にTextureLengthの値の数分テクスチャが入るようにテクスチャを伸縮させます。
デフォルトではStretchでTextureLengthが1になっているため、テクスチャ1枚がBeam全体の長さになるように引き延ばしているわけですね。
Beamの長さが変われば、テクスチャの長さも変わります。

Beam | Documentation - Roblox Creator Hubより引用
Warp、Staticは、Beamの全体の長さをTextureLengthで割った値の分、テクスチャが表示されます。
と言うとなんだかピンと来ませんが、要はPartなどのSizeと同様、スタッド単位でテクスチャの長さを指定できるということです。
こちらは、Beamの長さが変わってもテクスチャの長さは影響を受けません。

Beam | Documentation - Roblox Creator Hubより引用
というわけで、今回はTextureModeをWarpにしてみましょう。

テクスチャが引き延ばされなくなりました。
Width0, Width1
このままだとPlayerCharacterに対して細すぎるので、Beamの太さを調整しましょう。
Width0はAttachment0(始点)側、Width1はAttachment1(終点)側の太さをスタッド単位で設定できます。
Width1だけ値を小さくすることで、終点に向かってだんだん細くなる、といったことも可能ですが、今回はとりあえず両方5にしておきましょう。

おっと、太さは良さそうですが、テクスチャが横に引き延ばされてしまいました。
TextureLengthの方を調整して、こちらは3くらいにしておきましょう。

ちなみに、比率を維持したい場合、今回は元のテクスチャが正方形なので、TextureLengthをWidthと同じ値にすればOKです。
TextureSpeed
TextureSpeedはテクスチャの流れる速さを設定できます。
正の値だとAttachment0からAttachment1に向かって流れていきますが、負の値を設定すると逆に向かって流れます。
あんまり遅いと違和感があるので、今はとりあえず3にしておきましょう。
最終的には実際に動かした時に調整すればよいと思います。
さて、大分それっぽくなってきましたが、Beamは厚みの無い板なので、面が見えている時はいいのですが、見る角度によっては完全に見えなくなってしまいます。
この問題は、プロパティ一つで対応できます。
FaceCamera
それがFaceCameraです。
このプロパティをtrueにすると、常に面をカメラの方に向けて描画されるようになります。

横から見た時

上から見た時
ParticleEmitterやBillboardGuiっぽいですね。
ただし、Beamが二点を繋いでいるものである以上、完全にカメラの方に向けることはできない点には注意してください。
あくまで、その二点を繋いだ線を軸に回転する形になります。
実際につないでみる
ここらで実際にPlayerCharacterと接続してみたいと思います。
まず、作成したBeamだけをStarterCharacterScriptsに移動し、Beamの子にLocalScriptを追加してください。
名前は「SetBeam」としておきます。

さらに、Workspaceに目標地点となるPartを作ります。さっきまでBeamの確認用に使っていたPartの流用で構いません。
名前を「TargetPart」に変更し、Transparencyは0に戻します。
Attachmentは一つで構わないので、Attachment0は削除し、Attachment1のPositionは全て0にしてください。


そして、SetBeamに以下のコードを追加してください。
--!strict
local beam = script.Parent
local target = workspace:WaitForChild("TargetPart")
-- Attachment0はCharacterの構成に存在する物を使う.
beam.Attachment0 = script:FindFirstAncestorOfClass("Model"):WaitForChild("HumanoidRootPart"):WaitForChild("RootAttachment")
beam.Attachment1 = target:FindFirstChildWhichIsA("Attachment")
Attachment0には、HumanoidRootPart下にRootAttachmentというAttachmentがあるのでそれを使用しています。
それではさっそく実行して確認してみましょう。

これで、チュートリアルの矢印ができました!
実際に使用する場合は、ゲームに合わせて色などを調整した上で、サーバー側でセーブデータから矢印を出すかどうかを判定して処理を行う感じになるかと思います。
3. 他にBeamにできること
さて、ここまでは矢印を題材にBeamの基本を紹介してきましたが、Beam自体は他にもできることがあるので、Beam特有の要素に関わる他のプロパティも紹介していきます。
Color, Transparency
それぞれ、色と透明度を指定するColorSequence、NumberSequenceのプロパティです。
Sequenceとは、複数の値を設定し、その間を線形補間することで遷移を表現できる型で、一つ一つの個別の値はKeyPointと呼びます。
ColorSequenceはColor3の遷移を、NumberSequenceはnumberの遷移を表現するためのもので、Beamの場合は始点から終点にかけて徐々に色や透明度が変わっていくようにすることができます。
Beamをエフェクトのように使う場合などには、始点付近と終点付近だけ透明にしたりすると、突然途切れているような印象を抑えることができたりします。

四つのKeyPointを使って、始点付近と終点付近だけ透明に

文字通り "ビーム" を撃たせてみたり
CurveSize0, CurveSize1
実は、Beamは直線で結ぶだけではなく、曲げることができます。
いわゆる三次ベジェ曲線と呼ばれるもので、四つの制御点から曲線を作る仕組みとなっているため、Attachmentの二か所に加えてもう二か所、制御点が必要になります。
CurveSize0とCurveSize1は、そのBeamを曲げるための二つの制御点の位置をnumberで指定します。
CurveSize0はAttachment0から正のX方向にズラした位置、CurveSize1はAttachment1から負のX方向にズラした位置に制御点が配置され、負の値を設定すればその逆になります。
Attachmentのローカル空間で指定されるので、Attachmentの向きを変えるとそれに合わせて制御点の位置も変わります。


Beam | Documentation - Roblox Creator Hubより引用
Segments
Beamの分割数を指定します。
Beamは板ポリゴンで構成されているため、曲げた場合には分割数が多いほどより綺麗な曲線に近づきます。

Segmentsが5の場合

Segmentsが20の場合
そしてさらに、先述のColorとTransparencyにも関係しています。
Beamは、一つのSegmentsつき一つの遷移しか表現できません。
よって、最低でもSequenceのKeyPointsの数-1個のSegmentsが無ければ、全ての遷移を表現することができなくなります。
これもやはり分割数が多いほど、より正確に遷移を表現できます。

赤、青、緑、赤、青、緑と、6つのKeyPointが設定されている

Segmentsが3の場合 分割数が足りず、色の遷移が表現できなくなっている

Segmentsが10の場合 分割数が十分にあるため、Colorに設定した通りになっている
もちろん、Segmentsが多いほど処理負荷も増えるので、無駄に増やしすぎないように注意してください。
上記の例の場合、KeyPointsを等間隔に配置しており、Segmentsが5の場合にちょうどSegmentsの分割点とKeyPointの位置が一致するため、色の遷移を表現することができる最低のSegments数は5になります。
しかし、等間隔でない場合は適切に表現するにはある程度の数のSegmentsが必要になるので、やはり単純にKeyPointsの数-1にするというよりは、実際の表現を見ながら調整するのが良いかと思います。
4. まとめ
- Beamは、二つのAttachment間を繋いでテクスチャを表示するオブジェクト
- Attachment0が始点、Attachment1が終点
- 貼られるテクスチャの向きは、上部が始点側、下部が終点側になる
- TextureLengthは、テクスチャの長さを設定するためのプロパティで、TextureModeによって挙動が異なる
- TextureSpeedはテクスチャの流れる速度を指定でき、正の値なら始点から終点へ、負の値ならその逆に流れる
- FaceCameraをtrueにすると、常にカメラの方に面を向けて描画される
- Color, TransparencyはSequenceで指定でき、始点から終点にかけての遷移を表現できる
- CurveSize0, CurveSize1は、Beamを曲げる場合の制御点を指定できる
- SegmentsはBeamの分割数を指定でき、Beamを曲げた場合の形状や、Sequenceを適切に表現できるかどうかに関わる
他にもプロパティはあるのですが、今回はここまでにしたいと思います。
Beamはアイデア次第で色々な表現に使えるオブジェクトだと思いますので、ぜひ自分なりに使い方を考え、利用してみてください!
最後までお読みいただき、ありがとうございました!
5. 参考
当社ではRobloxを活用したゲームの開発、 また企業の商品やサービスの認知度拡大に寄与する3Dワールドの制作など、 Robloxにおける様々な活用支援を行っております。 Robloxのコンテンツ開発をご検討されている企業様は、お気軽にご相談ください。 landho.co.jp/
Discussion