🙆‍♀️

【Roblox】動的リストに作成に強いFusion Fusion編 #7

2024/08/29に公開

はじめに

今回は動的に表示内容が変わるListUIをFusionを使い簡単に実装する方法を共有します。

Fusion記事まとめ

https://zenn.dev/keisuke114/scraps/f33cd9b23b6e29

公式Reference

https://elttob.uk/Fusion/0.2/tutorials/lists-and-tables/forvalues/

https://elttob.uk/Fusion/0.2/tutorials/instances/new-instances/

https://elttob.uk/Fusion/0.2/tutorials/components/children/

実装

local Fusion = require(ReplicatedStorage.Fusion)
local Value = Fusion.Value
local New = Fusion.New
local Children = Fusion.Children
local ForValues = Fusion.ForValues

local playerNames = Value({"Player1", "Player2", "Player3", "Player4"})

local textLabels = ForValues(playerNames, function(playerName)
	return New "TextLabel" {
		Name = playerName,
		Size = UDim2.new(1, 0, 0, 50),
		TextScaled = true,
		Text = playerName
	}
end, Fusion.cleanup)

local ui = New "ScreenGui" {
	Parent = playerGui,

	[Children] = New "Frame" {
		Name = "PlayerList",

		Position = UDim2.new(0.5,0,0.5,0),
		AnchorPoint = Vector2.new(0.5,0.5),
		Size = UDim2.new(0.5, 0, 0.5, 0),

		[Children] = {
			New "UIListLayout" {
				SortOrder = "Name"
			},
			textLabels
		}
	}
}

コード解説

  • FusionのValueオブジェクトplayerNamesに、プレイヤーの名前を格納するテーブルを初期値として設定しています。このValueオブジェクトの値を後で変更することで、生成されるTextLabelの数が動的に変化します。
  • ForValues関数を使用して、playerNamesの値のそれぞれに対して、TextLabelを生成し、textLabelsに格納しています。
  • cleanup引数を指定することで、不要になったTextLabelを自動的に破棄します。
  • local ui = New "ScreenGui"...でUIのベースを作成し[Children]を利用してその子要素にFrameと先ほどのtextLabelsを追加します。

実行結果

playerNames内の要素を変更すると、、、

--local playerNames = Value({"Player1", "Player2", "Player3", "Player4"})

task.wait(2.0)

playerNames:set({"Player1", "Player2", "Player3", "Player4", "Player5"})

task.wait(2.0)

playerNames:set({"Player1", "Player2", "Player3"})

増えた要素、減った要素が何か判別し個別に追加したり減らしたりさせることができます。何かの要素の増減があるたびに全削除して一から生成するようなことをしていないので処理が軽いみたいです!


https://elttob.uk/Fusion/0.2/tutorials/lists-and-tables/forvalues/

全体コード

local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Fusion = require(ReplicatedStorage.Fusion)
local Value = Fusion.Value
local New = Fusion.New
local Children = Fusion.Children
local ForValues = Fusion.ForValues

local player = Players.LocalPlayer
local playerGui = player:WaitForChild("PlayerGui")
local gui = playerGui:WaitForChild("MainGui")

local playerNames = Value({"Player1", "Player2", "Player3", "Player4"})

local textLabels = ForValues(playerNames, function(playerName)
	return New "TextLabel" {
		Name = playerName,
		Size = UDim2.new(1, 0, 0, 50),
		TextScaled = true,
		Text = playerName
	}
end, Fusion.cleanup)

local ui = New "ScreenGui" {
	Parent = playerGui,

	[Children] = New "Frame" {
		Name = "PlayerList",

		Position = UDim2.new(0.5,0,0.5,0),
		AnchorPoint = Vector2.new(0.5,0.5),
		Size = UDim2.new(0.5, 0, 0.5, 0),

		[Children] = {
			New "UIListLayout" {
				SortOrder = "Name"
			},
			textLabels
		}
	}
}

task.wait(2.0)

playerNames:set({"Player1", "Player2", "Player3", "Player4", "Player5"})

task.wait(2.0)

playerNames:set({"Player1", "Player2", "Player3"})

実行

https://youtu.be/cFWma2AKY7A

Landelテックブログ

Discussion