讓你儲存需要在會話之間持續存在的資料,例如玩家庫存中的物品或技能點數。數據儲存在每個體驗上是一致的,因此體驗中的任何地方都可以存取和更改相同的數據,包括位於不同伺服器上的地方。
如果您想將粒度權限控制添加到數據儲存中,並在 Studio 或 Roblox 服務器之外存取它們,您可以使用 開啟雲端 API 對數據儲存進行操作。
若要通過創作者中心查看和監控體驗中的所有數據儲存,請使用 數據儲存管理器。
對於需要頻繁更新或訪問的暫時數據,請使用 記憶儲存 。
啟用工作室存使用權 通行權 存取
預設情況下,在工作室測試的體驗無法存取資料庫,因此您必須先啟用它們。在 Studio 存取資料儲存可能對實時體驗有風險,因為 Studio 使用與客戶應用程式相同的資料儲存。為了避免覆蓋生產資料,請勿為即時體驗啟用此設定。取而代之,為體驗的分離測試版啟用它。
要在發布的 體驗中啟用工作室存取:
- 開啟 遊戲設定。
- 導航到 安全 。
- 啟用 啟用 Studio 存取 API 服務 切換。
- 點擊 儲存 。
存取資料儲存
要存取體驗內的資料儲存:
- 向服務器側 DataStoreService 添加 Script。
- 使用 GetDataStore() 函數並指定要使用的資料儲存名稱。如果資料儲存不存在,當你第一次儲存體驗資料時,Studio 會在儲存資料時創建一個。
local DataStoreService = game:GetService("DataStoreService")local experienceStore = DataStoreService:GetDataStore("PlayerExperience")
創建資料
數據儲存本質上是一個字典,類似於 Luau 表。獨特的 鑰匙 索引每個值在數據存商店 商家中,像使用者的獨特 Player.UserId 或體驗促銷的命名字串一樣。
使用者資料鑰鍵 | 值 |
---|---|
31250608 | 50 |
351675979 | 20 |
505306092 | 78000 |
促銷資料鑰鍵 | 值 |
ActiveSpecialEvent | 夏季派對2 |
ActivePromoCode | 獎勵123 |
CanAccessPartyPlace | 真的 |
要創建新的記錄,請使用鑰匙名稱和值來呼叫 SetAsync() 。
local DataStoreService = game:GetService("DataStoreService")
local experienceStore = DataStoreService:GetDataStore("PlayerExperience")
local success, errorMessage = pcall(function()
experienceStore:SetAsync("User_1234", 50)
end)
if not success then
print(errorMessage)
end
更新資料
若要變更資料儲存商店 商家中的任何儲存值,請使用入口的鑰匙名稱和一個回呼函來定義您要如何更新入口的方式。UpdateAsync()此回呼會取得目前值並根據您定義的邏輯返回新值。如果回呼返回 nil,寫入操作將被取消,值不會更新。
local DataStoreService = game:GetService("DataStoreService")
local nicknameStore = DataStoreService:GetDataStore("Nicknames")
local function makeNameUpper(currentName)
local nameUpper = string.upper(currentName)
return nameUpper
end
local success, updatedName = pcall(function()
return nicknameStore:UpdateAsync("User_1234", makeNameUpper)
end)
if success then
print("Uppercase Name:", updatedName)
end
設定與更新
使用集來快速更新特定的鍵。SetAsync() 功能:
- 如果兩個伺服器嘗試在同一時間設置相同的鑰匙,可能會導致數據不一致
- 只計算對寫入限制
使用更新來處理多個伺服器的嘗試。UpdateAsync() 功能:
- 從伺服器閱讀最後更新它之前的當前鑰匙值,以便在進行任何變更之前保持一致
- 因為它在寫入之前閱讀,所以速度較慢
- 對閱讀和寫入限制進行計數
閱讀資料
要閱讀數據儲存入口的值,請使用入口的鑰匙名稱來呼叫 GetAsync() 。
local DataStoreService = game:GetService("DataStoreService")
local experienceStore = DataStoreService:GetDataStore("PlayerExperience")
local success, currentExperience = pcall(function()
return experienceStore:GetAsync("User_1234")
end)
if success then
print(currentExperience)
end
增量資料
若要在數據商店 商家存中增加整數,請使用入口的鑰匙名稱和要變更值的數量來呼叫 IncrementAsync() 。IncrementAsync() 是一個方便的功能,可以讓你避免呼叫 UpdateAsync() 並手動增加整數。
local DataStoreService = game:GetService("DataStoreService")
local experienceStore = DataStoreService:GetDataStore("PlayerExperience")
local success, newExperience = pcall(function()
return experienceStore:IncrementAsync("Player_1234", 1)
end)
if success then
print(newExperience)
end
移除資料
要移除一個記錄並返回與鍵匙相關的值,請呼叫 RemoveAsync() 。
local DataStoreService = game:GetService("DataStoreService")
local nicknameStore = DataStoreService:GetDataStore("Nicknames")
local success, removedValue = pcall(function()
return nicknameStore:RemoveAsync("User_1234")
end)
if success then
print(removedValue)
end
元資料
與鑰匙相關的 metadata 有兩種類型:
- 服務定義 : 最新更新時間和創建時間等預設閱讀僅限 metadata。每個對象都有服務定義的 metadata。
要管理元數據,擴展 SetAsync()、UpdateAsync()、GetAsync()、IncrementAsync() 和 RemoveAsync() 功能。
SetAsync() 接受可選的第三和第四個參數:
一個表的 UserIds 。這可以幫助內容版權和知識產權追蹤和移除。
一個 DataStoreSetOptions 對物件,您可以使用 SetMetadata() 函數定義自訂元數據。
local DataStoreService = game:GetService("DataStoreService")local experienceStore = DataStoreService:GetDataStore("PlayerExperience")local setOptions = Instance.new("DataStoreSetOptions")setOptions:SetMetadata({["ExperienceElement"] = "Fire"})local success, errorMessage = pcall(function()experienceStore:SetAsync("User_1234", 50, {1234}, setOptions)end)if not success thenprint(errorMessage)end
GetAsync() , IncrementAsync() , 及 RemoveAsync() 將在 DataStoreKeyInfo 對物件中返回第二值。這第二個值包含服務定義的屬性和功能以及用戶定義的元數據來獲取。
- Version 屬性擷取鑰鍵的版本。
- CreatedTime 屬性會擷取鑰匙創建的時間,格式為自史詩時間起的毫秒數。
- UpdatedTime 屬性會擷取鑰匙最後一次更新的時間,以秒數表示從史詩時代起的數量。
local DataStoreService = game:GetService("DataStoreService")local experienceStore = DataStoreService:GetDataStore("PlayerExperience")local success, currentExperience, keyInfo = pcall(function()return experienceStore:GetAsync("User_1234")end)if success thenprint(currentExperience)print(keyInfo.Version)print(keyInfo.CreatedTime)print(keyInfo.UpdatedTime)print(keyInfo:GetUserIds())print(keyInfo:GetMetadata())endUpdateAsync() 的回呼功能會在 DataStoreKeyInfo 對象中添加一個額外參數來描述當前鍵狀態。它返回修改的值、與 UserIds 相關的鑰匙,以及鑰匙的元數據。
local DataStoreService = game:GetService("DataStoreService")local nicknameStore = DataStoreService:GetDataStore("Nicknames")local function makeNameUpper(currentName, keyInfo)local nameUpper = string.upper(currentName)local userIDs = keyInfo:GetUserIds()local metadata = keyInfo:GetMetadata()return nameUpper, userIDs, metadataendlocal success, updatedName, keyInfo = pcall(function()return nicknameStore:UpdateAsync("User_1234", makeNameUpper)end)if success thenprint(updatedName)print(keyInfo.Version)print(keyInfo.CreatedTime)print(keyInfo.UpdatedTime)print(keyInfo:GetUserIds())print(keyInfo:GetMetadata())end
有關定義元數據時的限制,請參閱元數據限制。
已排序的資料儲存庫
預設情況下,數據儲存不會排序其內容。如果您需要按照排序方式獲得數據,例如在持久排行榜統計中,請使用 GetOrderedDataStore() 而不是 GetDataStore() 。
local DataStoreService = game:GetService("DataStoreService")local characterAgeStore = DataStoreService:GetOrderedDataStore("CharacterAges")
排序的數據儲存支持與預設數據儲存相同的基本功能,加上獨特的 GetSortedAsync() 功能。這會擷取 多個排序鑰匙 基於特定排序順序、頁面尺寸和最小/最大值來進行排序。
下面的例子將角色數據排序為包含三個入口的頁面,每個入口順序下降,然後循環通過頁面並輸出每個角色的名稱和年齡。
local DataStoreService = game:GetService("DataStoreService")
local characterAgeStore = DataStoreService:GetOrderedDataStore("CharacterAges")
-- 填充排序的資料儲存庫
local characters = {
Mars = 19,
Janus = 20,
Diana = 18,
Venus = 25,
Neptune = 62
}
for char, age in characters do
local success, errorMessage = pcall(function()
characterAgeStore:SetAsync(char, age)
end)
if not success then
print(errorMessage)
end
end
-- 依據下降順序將數據排序為每頁三個條目的頁面
local success, pages = pcall(function()
return characterAgeStore:GetSortedAsync(false, 3)
end)
if success then
while true do
-- 取得當前(第一)頁
local entries = pages:GetCurrentPage()
-- 在頁面上循環所有鑰匙值對雙方
for _, entry in entries do
print(entry.key .. " : " .. tostring(entry.value))
end
-- 檢查最後一頁已達到
if pages.IsFinished then
break
else
print("----------")
-- 前進到下一頁
pages:AdvanceToNextPageAsync()
end
end
end