遊戲經常需要在會話之間儲存 持久資料 ,例如玩家的等級、經驗點、金錢、庫存物品、位置等。
本教學顯示如何創建基本的 資料儲存庫 、儲存玩家資料,並將資料讀回遊戲會話。
啟用工作室存取權
預設情況下,在工作室測試的遊戲無法存取資料庫,因此您必須先啟用它們:
發布經驗。
選擇 檔案 和 遊戲設定 。
在 安全 部分,啟用 啟用 Studio 存取 API 服務 並點擊 儲存 。
創建資料儲存庫
數據存儲需要獨特的 名稱 。這個例子創建了一個名為 PlayerGold 的資料存儲,用於永久存儲每個玩家的黃金:
在 Script 內創建一個 ServerScriptService 稱為 GoldManager 的子程序。
數據存儲由 DataStoreService 管理,因此獲得服務:
local DataStoreService = game:GetService("DataStoreService")使用字串 DataStoreService:GetDataStore() 呼叫 "PlayerGold" 。這個方法會存取 PlayerGold 資料儲存庫,如果它已存在。如果不存在,方法會創建新的資料儲存並將其命名為 PlayerGold 。
local DataStoreService = game:GetService("DataStoreService")local goldStore = DataStoreService:GetDataStore("PlayerGold")
保存數據
數據存儲本質上是一個字典,像 Luau 表一樣。資料儲存中的每個值都由獨特的 鑰匙 索引,可能是玩家獨特的 UserId 或只是遊戲促銷的命名字串。
Key | Value |
---|---|
31250608 | 50 |
351675979 | 20 |
505306092 | 78000 |
要將玩家資料儲存在資料庫中:
創建名為 playerUserID 的變量來儲存數據存儲鍵。然後,使用 playerGold 來儲存玩家的初始黃金數量。
local DataStoreService = game:GetService("DataStoreService")local goldStore = DataStoreService:GetDataStore("PlayerGold")-- 數據儲存鍵和值local playerUserID = 505306092local playerGold = 250要將數據儲存到 PlayerGold 數據存儲中,請在保護呼叫中呼叫 SetAsync ,傳遞先前創建的鑰匙和值變量。
local DataStoreService = game:GetService("DataStoreService")local goldStore = DataStoreService:GetDataStore("PlayerGold")-- 數據儲存鍵和值local playerUserID = 505306092local playerGold = 250-- 設定數據儲存鍵local success, error = pcall(function()goldStore:SetAsync(playerUserID, playerGold)end)if not success thenwarn(error)end
像 SetAsync() 這樣的功能是可能會時不時失敗的網路呼叫。如上所示,pcall() 用於偵測和處理發生這種故障時。
在最基本的形式下, pcall() 接受一個函數並返回兩個值:
- 如果函數無錯誤地執行,狀態為 true ;否則為 false 。
- 函數或錯誤訊息的返回值。
上面的樣本在第 13 行檢查狀態。如果 SetAsync() 因任何原因失敗,樣本將在 輸出 窗口中顯示錯誤。
閱讀資料
要從數據存儲中閱讀數據,請使用所需的鑰匙名稱來呼叫 GetAsync()。
local DataStoreService = game:GetService("DataStoreService")
local goldStore = DataStoreService:GetDataStore("PlayerGold")
-- 數據儲存鍵和值
local playerUserID = 505306092
local playerGold = 250
-- 設定數據儲存鍵
local setSuccess, errorMessage = pcall(function()
goldStore:SetAsync(playerUserID, playerGold)
end)
if not setSuccess then
warn(errorMessage)
end
-- 閱讀數據儲存鍵
local getSuccess, currentGold = pcall(function()
return goldStore:GetAsync(playerUserID)
end)
if getSuccess then
print(currentGold)
end
要測試腳本,請點擊 執行 並注意輸出 currentGold 印出的值 **** 。請注意,這可能需要幾秒鐘,因為函數必須連接到數據儲存服務器。
自動閱讀和保存
以前的腳本工作,但有一個基本問題:它包含 playerUserID 和 playerGold 的硬碼值,因此無法支持多個玩家的不同數量的金幣。更接近現實的解決方案會在玩家連接到體驗時讀取金值,然後在玩家離開時儲存它。這種方法意味著將數據儲存調用連接到 事件 從 Players。
local DataStoreService = game:GetService("DataStoreService")
local Players = game:GetService("Players")
local goldStore = DataStoreService:GetDataStore("PlayerGold")
-- 將每位玩家的黃金值添加到本地表,以避免擊中數值
-- 重複儲存。
local playerGold = {}
local function incrementGold(player, amount)
playerGold[player.UserId] += amount
end
local function onPlayerAdded(player)
-- 閱讀數據儲存鍵
local success, storedGold = pcall(function()
return goldStore:GetAsync(player.UserId)
end)
if success then
local currentGold
if storedGold then
currentGold = storedGold
else
currentGold = 0
end
playerGold[player.UserId] = currentGold
print(currentGold)
end
-- 測試增量金幣
incrementGold(player, 5)
end
local function onPlayerRemoving(player)
-- 設定數據儲存鍵
local success, err = pcall(function()
goldStore:SetAsync(player.UserId, playerGold[player.UserId])
end)
if not success then
warn(err)
end
-- 清理入口,使表在服務器生命週期內不會增長
playerGold[player.UserId] = nil
end
Players.PlayerAdded:Connect(onPlayerAdded)
Players.PlayerRemoving:Connect(onPlayerRemoving)
閱讀和保存角色位置
為了保存玩家位置,您使用 Character 而不是 Player,但原理相同。這次,在 Script 內創建一個 ServerScriptService 稱為 位置管理器 的子程序:
local Players = game:GetService("Players")
local DataStoreService = game:GetService("DataStoreService")
local Workspace = game:GetService("Workspace")
local playerPositionStore = DataStoreService:GetDataStore("PlayerPositionStore")
local function positionHandler(player)
-- 在角色添加時載入位置
player.CharacterAdded:Connect(function(character)
local success, coords = pcall(function()
return playerPositionStore:GetAsync(player.UserId)
end)
local position = Vector3.new(coords[1], coords[2], coords[3])
if success and position then
character:PivotTo(CFrame.new(position))
print("Loaded player position!")
else
warn("Failed to load position for player " .. player.Name .. ". Placing in default position.")
end
-- 處理玩家死亡時重生
local humanoid = character:FindFirstChildOfClass("Humanoid")
humanoid.Died:Connect(function()
local spawnLocation = Workspace:FindFirstChild("SpawnLocation")
character:PivotTo(spawnLocation.CFrame)
end)
end)
-- 在角色移除時保存位置
player.CharacterRemoving:Connect(function(character)
local position = character:GetPivot().Position
local success, err = pcall(function()
playerPositionStore:SetAsync(player.UserId, {position.X, position.Y, position.Z})
print("Saved player position!")
end)
if not success then
warn("Failed to save position for player " .. player.Name .. ": " .. err)
end
end)
end
Players.PlayerAdded:Connect(positionHandler)
這個腳本添加了一個新的數據存儲,playerPositionStore。因為資料儲存只儲存基本類型而不是對象,因此您必須將 X、Y 和 Z 坐標存為單獨數值,而不是單一 Vector3 或 CFrame 值。當您測試您的體驗時,移動您的角色。注意你的角色下次測試體驗時會返回到相同位置。
示例項目
現在您已經理解了基本數據儲存使用,請在 黃金熱潮 樣本遊戲中進行測試您也可以在工作室編輯遊戲,並探索強化的 GoldManager 腳本,該腳本將黃金顯示為介面的一部分,並包括自動儲存。