私たちは、宇宙ステーション内での情報をユーザーが消費できるように、世界に生きているように感じられるインタラクティブなマップ UI を追加したいと考えました。体験の上にオーバーレイされる画面ではなく、3D 空間の中にマップを構築することに決めました。このようなダイジェティックな視覚化は、完全に別の体験のように感じるのではなく、世界との没入感を高めることができます。
マップのデザイン
マップをデザインするには:
外部アプリケーションで UI をモックアップし、どのように見せたいかの粗いアイデアを考えました。

マップの個々の部分を .png としてエクスポートし、スタジオにインポートしました。

マップの構築
スタジオ内でのマップの構築には Parts と SurfaceGuis を使用しました。
非インタラクティブな要素については、パーツに SurfaceGui オブジェクトを追加するだけで済みました。
インタラクティブな要素には、SurfaceGui が StarterGui コンテナ内にあり、Adornee プロパティが 3D ワークスペース内の適切なパーツにリンクされている必要があります。これにより、ボタンイベントを追加できます。
パララックス効果を実現するために、異なる X 値を持つ 3 つのユニークな Parts に割り当てられた 3 つの別々の ScreenGui インスタンスを使用しました。

次に、SurfaceGui.LightInfluence プロパティを使用してグロー効果を追加しました。プロパティ値を 1 未満に設定すると、SurfaceGui.Brightness プロパティが有効になります。明るさを調整することで、画像から放出されるグローを増加させることができます。
ユーザーがマップの表示を切り替えられるように、3D モデルにアタッチした ProximityPrompt を使用しました。これは、ユーザーが環境要素とインタラクトできる簡単な方法です。

最後に、ReplicatedStorage 内の UITweenModule ModuleScript を使用して、TweenService と状態を判断する簡単なロジックで UI の非表示と表示をアニメーション化しました。ユーザーがクリックしたものを追跡することで、不透明度、位置、サイズなどのさまざまなプロパティをトゥイーンすることで要素を隠したり表示したりできました。
UITweenModule ModuleScriptlocal TweenService = game:GetService("TweenService")local UITween = {}-- 画像をフェードインさせるための関数function UITween.fadePart(object, amount, time, delay)local tweenAlpha = TweenInfo.new(time, --時間Enum.EasingStyle.Quad, --イージングスタイルEnum.EasingDirection.Out, --イージング方向0, --繰り返し回数false, --true の場合は逆再生delay --遅延時間)local tween = TweenService:Create(object, tweenAlpha, {Transparency = amount})tween:Play()endfunction UITween.fade(object, amount, time, delay)local tweenAlpha = TweenInfo.new(time, --時間Enum.EasingStyle.Quad, --イージングスタイルEnum.EasingDirection.Out, --イージング方向0, --繰り返し回数false, --true の場合は逆再生delay --遅延時間)local tween = TweenService:Create(object, tweenAlpha, {ImageTransparency = amount})tween:Play()end-- 画像をフェードインさせるための関数function UITween.fadeBackground(object, amount, time, delay)local tweenAlpha = TweenInfo.new(time, --時間Enum.EasingStyle.Quad, --イージングスタイルEnum.EasingDirection.Out, --イージング方向0, --繰り返し回数false, --true の場合は逆再生delay --遅延時間)local tween = TweenService:Create(object, tweenAlpha, {BackgroundTransparency = amount})tween:Play()end-- テキストをフェードインさせるための関数function UITween.fadeText(object, amount, time, delay)local tweenAlpha = TweenInfo.new(time, --時間Enum.EasingStyle.Quad, --イージングスタイルEnum.EasingDirection.Out, --イージング方向0, --繰り返し回数false, --true の場合は逆再生delay --遅延時間)local tween1 = TweenService:Create(object, tweenAlpha, {TextTransparency = amount})tween1:Play()end-- テキストと画像を移動させるための関数function UITween.move(object, position, time, delay)task.wait(delay)object:TweenPosition(position, Enum.EasingDirection.Out, Enum.EasingStyle.Quint, time)end-- サイズを変更するための関数function UITween.size(object, size, time, delay, override, callback)local tweenSize = TweenInfo.new(time, --時間Enum.EasingStyle.Quint, --イージングスタイルEnum.EasingDirection.Out, --イージング方向0, --繰り返し回数false, --true の場合は逆再生delay, --遅延時間override,callback)local tween = TweenService:Create(object, tweenSize, {Size = size})tween:Play()endfunction UITween.rotate(object, rotation, time, delay, override, callback)local tweenSize = TweenInfo.new(time, --時間Enum.EasingStyle.Quint, --イージングスタイルEnum.EasingDirection.Out, --イージング方向0, --繰り返し回数false, --true の場合は逆再生delay, --遅延時間override,callback)local tween = TweenService:Create(object, tweenSize, {Rotation = rotation})tween:Play()end-- ゲームカメラをぼかすための関数function UITween.blur(object, amount, time)local tweenInfo = TweenInfo.new(time, Enum.EasingStyle.Linear, Enum.EasingDirection.Out, 0, false, 0)local tween = TweenService:Create(object, tweenInfo, {Size = amount})tween:Play()end-- ゲームカメラをぼかすための関数function UITween.turnOn(object, amount, time)local tweenInfo = TweenInfo.new(time, Enum.EasingStyle.Linear, Enum.EasingDirection.Out, 0, false, 0)local tween = TweenService:Create(object, tweenInfo, {Brightness = amount})tween:Play()endreturn UITweenオブジェクトへの UI トゥイーンの適用local ReplicatedStorage = game:GetService("ReplicatedStorage")-- UITween モジュールを追加local UITween = require(ReplicatedStorage.UITweenModule)-- プレイヤーの Guis と UI オブジェクトを見つけるlocal playerGui = game:GetService('Players').LocalPlayer:WaitForChild('PlayerGui')local screenGuiMapUIFrame = playerGui:WaitForChild("ScreenGuiMapUIFrame").SurfaceGuilocal mapUIFrameStroke = screenGuiMapUIFrame.FrameStrokelocal mapUIFrameFill = screenGuiMapUIFrame.FrameFill-- トゥイーンに使用するサイズlocal frameSizeStart = UDim2.new(0, 0, 0, 0)local frameSizeMid = UDim2.new(1, 0, 0.05, 0)local frameSizeEnd = UDim2.new(1, 0, 1, 0)-- トゥイーンの例UITween.fade(mapUIFrameStroke, 0, 2, 0)UITween.size(mapUIFrameStroke, frameSizeMid, 0.4, 0)UITween.fade(mapUIFrameFill, 0, 2, 0.5)UITween.size(mapUIFrameFill, frameSizeEnd, 0.4, 0.25)task.wait(0.25)UITween.size(mapUIFrameStroke, frameSizeMid, 0.4, 0)UITween.size(mapUIFrameFill, frameSizeMid, 0.4, 0.25)task.wait(0.25)UITween.size(mapUIFrameStroke, frameSizeEnd, 0.4, 0)UITween.size(mapUIFrameFill, frameSizeEnd, 0.4, 0.25)
インタラクティブマップの最終結果は次のとおりです: