Zapisz dane gracza za pomocą standardowych magazynów danych

*Ta zawartość została przetłumaczona przy użyciu narzędzi AI (w wersji beta) i może zawierać błędy. Aby wyświetlić tę stronę w języku angielskim, kliknij tutaj.

Magazyny danych to usługa, której możesz używać do zapisywania i ładowania trwałych danych gracza w różnych sesjach gry. Przechowują one ważne informacje, takie jak postęp gracza czy ekwipunek, i umożliwiają ich ponowne odzyskanie za każdym razem, gdy gracz dołącza do twojego doświadczenia. Bez magazynów danych gracz traciłby cały swój postęp za każdym razem, gdy opuszczał grę.

Istnieją dwa typy magazynów danych: standardowe i uporządkowane. W tym samouczku używamy standardowych magazynów danych, które przechowują dane, takie jak liczby, ciągi i tabele, które nie muszą być klasyfikowane ani sortowane.

Korzystając z pliku samouczka Gold Rush data store tutorial - Start .rbxl jako miejsca startowego i pliku samouczka Gold Rush data store tutorial - Complete .rbxl jako odniesienia, w tym samouczku zdobędziesz podstawy potrzebne do zapisywania postępów gracza i tworzenia bardziej spójnych doświadczeń, w tym wskazówki dotyczące:

  • Zapisywania i ładowania ilości złota, którą gracz zebrał.
  • Aktualizacji interfejsu użytkownika, aby wyświetlić ekwipunek złota gracza.
  • Automatycznego zapisywania ekwipunku złota gracza co 30 sekund.
  • Zapisywania pozycji gracza, gdy opuszcza doświadczenie.
  • Przywracania pozycji gracza, gdy znowu dołącza do doświadczenia.

Na koniec tego samouczka powinieneś mieć dwa skrypty z magazynami danych w ServerScriptService:

  1. Zaktualizowany skrypt GoldManager, który śledzi, ładuje i automatycznie zapisuje złoto gracza.
  2. Zaktualizowany skrypt PositionManager, który zapisuje pozycję gracza, gdy opuszcza doświadczenie i przywraca jego pozycję, gdy wraca do doświadczenia.

Włącz dostęp Studio do usług API

Magazyny danych nie są przechowywane lokalnie na twoim urządzeniu, więc twoje doświadczenie polega na komunikacji serwer-serwer z zapleczem Roblox, aby móc je używać. Domyślnie Studio ogranicza tę komunikację, aby zapobiec nadużyciom lub przypadkowemu użyciu. Dostęp do usług API w Studio jest wyłączony, dopóki nie włączysz go jawnie, aby mieć pewność, że tylko zaufane doświadczenia mogą odczytywać i zapisywać dane w serwerach zaplecza Roblox.

Aby włączyć dostęp Studio do usług API, abyś mógł korzystać z magazynów danych:

  1. Otwórz plik Gold Rush data store tutorial - Start .rbxl w Studio i utwórz lokalną kopię.
  2. Wróć do Studio, przejdź do PlikUstawienia gryBezpieczeństwo.
  3. Włącz Włącz dostęp Studio do usług API.
  4. Zapisz zmiany.

Utwórz standardowy magazyn danych

Podczas tworzenia magazynu danych należy zawsze wywoływać DataStoreService z serwerowego Script. Jest to ważne, ponieważ:

  • Roblox blokuje dostęp do wszystkich magazynów danych z klienta, aby tylko serwer miał uprawnienia do uzyskiwania dostępu i modyfikowania trwałych danych gracza.
  • Skrypty po stronie serwera działają w scentralizowanym środowisku, co zapewnia, że dane odczytywane i zapisywane do twojego magazynu danych są dokładne i ważne.
  • Ponieważ skrypty po stronie klienta działają na urządzeniu gracza, każdy gracz mógłby potencjalnie wykorzystać doświadczenie i ukraść lub nadpisać dane innych graczy, gdyby klient miał dostęp do twoich magazynów danych.

Powinieneś również nadać swojemu magazynowi danych unikalną nazwę, aby utrzymać porządek w danych i zapobiec ich pokrywaniu się lub konfliktom w różnych magazynach danych. W tym samouczku magazyn danych, który zapisuje i przechowuje ekwipunek złota gracza, nazywa się PlayerGold.

Aby utworzyć magazyn danych PlayerGold:

  1. Otwórz istniejący skrypt GoldManager w ServerScriptService.

  2. Pod innymi usługami na górze skryptu, zainicjalizuj DataStoreService i wywołaj GetDataStore z ciągiem "PlayerGold".


    local DataStoreService = game:GetService("DataStoreService")
    local goldStore = DataStoreService:GetDataStore("PlayerGold")

Zapisz i ładuj dane gracza

Magazyny danych składają się z kluczy, które identyfikują dane, i wartości, które przechowują dane.

KluczWartość
OpisKlucz to unikalny identyfikator, którego można użyć do uzyskania dostępu do konkretnego fragmentu danych.

Klucze pozwalają zorganizować dane, dzięki czemu można nimi łatwo zarządzać i debugować je.
Wartość to rzeczywiste dane, które chcesz zapisać lub załadować, takie jak ekwipunek gracza lub jego ustawienia.

Wartości pozwalają na przechowywanie postępu między sesjami oraz odzyskiwanie danych gracza, gdy następnym razem dołącza do twojego doświadczenia.
Dozwolone formatyMogą to być tylko ciągi.Mogą to być liczby, ciągi, wartości logiczne lub tabele.
Przykłady"Player_A", "TopScore", "ExperienceSetting"100, "Level_5", true, {gold = 100, level = 5}

W tym samouczku kluczem jest userId gracza, a wartością jest ilość złota, którą zebrał. Aby użyć tego klucza i wartości do zapisywania i ładowania danych gracza:

  1. W skrypcie GoldManager dodaj funkcję pomocniczą o nazwie saveGold, aby zapisać złoto gracza w magazynie danych PlayerGold.


    local function saveGold(userId, value)
    local success, err = pcall(function()
    -- `userId` to unikalny identyfikator gracza
    -- `value` to ilość złota do zapisania dla tego gracza
    goldStore:SetAsync(userId, value)
    end)
    end
  2. OPCjonalne
    Dodaj ostrzeżenie do saveGold, które wyświetli identyfikator gracza oraz komunikat o błędzie. Choć nie jest to obowiązkowe, ten krok jest dobrą praktyką ułatwiającą debugowanie w przypadku, gdy twoja funkcja zawiedzie.


    local function saveGold(userId, value)
    local success, err = pcall(function()
    -- `userId` to unikalny identyfikator gracza
    -- `value` to ilość złota do zapisania dla tego gracza
    goldStore:SetAsync(userId, value)
    end)
    if not success then
    warn("[BŁĄD ZAPISU] Nie można zapisać złota dla", userId, ":", err)
    end
    end
  3. Zmodyfikuj zdarzenie onPlayerAdded, aby załadować złoto gracza, gdy po raz pierwszy dołącza do doświadczenia. Zaktualizowana funkcja onPlayerAdded:

    • Próbuje załadować zawartość magazynu danych PlayerGold. Zwraca albo zapisane złoto gracza, albo wartość 0, jeśli gracz nie ma żadnego złota lub nie grał wcześniej w doświadczenie.
    • Dostarcza log debugowy, aby pomóc w łatwiejszym debugowaniu twojego kodu. Ten log debugowy zawiera zapisane złoto przychodzącego gracza albo komunikat o błędzie, jeśli onPlayerAdded nie może uzyskać dostępu do magazynu danych.
    • Aktualizuje interfejs użytkownika, aby wyświetlić zapisane złoto gracza na jego ekranie.

    local function onPlayerAdded(player)
    local userId = player.UserId
    local success, storedGold = pcall(function()
    return goldStore:GetAsync(userId)
    end)
    if success then
    local currentGold = storedGold or 0
    playerGold[userId] = currentGold
    uiEvent:FireClient(player, {
    gold = currentGold,
    doTween = false,
    showAlert = not success
    })
    else
    uiEvent:FireClient(player, { showAlert = true })
    warn("Nie można załadować złota dla", player.Name)
    end
    end
  4. Zmodyfikuj zdarzenie onPlayerRemoving, aby wywołać funkcję saveGold, którą utworzyłeś wcześniej, i zapisać złoto gracza, gdy opuszcza doświadczenie.


    local function onPlayerRemoving(player)
    local userId = player.UserId
    if playerGold[userId] then
    saveGold(userId, playerGold[userId])
    end
    end

Automatyczne zapisywanie danych gracza

Automatyczne zapisywanie danych gracza to dobra praktyka, ponieważ chroni gracza przed utratą danych. Jeśli tylko zapiszesz dane gracza, gdy opuszcza doświadczenie za pomocą onPlayerRemoving, możesz stracić jego ostatni postęp, jeśli niespodziewanie rozłączy się z serwerem.

Aby automatycznie zapisywać dane gracza:

  1. Utwórz nową stałą, aby określić, jak często chcesz, aby twoje doświadczenie automatycznie zapisywało dane gracza. Stała to zmienna, której wartość nie zmienia się podczas uruchamiania gry. Możesz użyć tej stałej do odwoływania się do interwału automatycznego zapisu w całym swoim skrypcie i łatwo dostosować częstotliwość automatycznego zapisu.


    -- Ta liczba jest w sekundach
    local AUTOSAVE_INTERVAL = 30
  2. Dodaj korutynę automatycznego zapisu do istniejącej funkcji onPlayerAdded, aby utworzyć pętlę w tle, która działa, podczas gdy gracz jest w doświadczeniu. Korutyna to funkcja, która działa asynchronicznie; może zatrzymywać się w określonych punktach, wznawiać skąd przerwała, i działa równolegle z innymi częściami twojego skryptu, nie blokując ich.

    W tym skrypcie pętla korutyny automatycznego zapisu czeka na liczbę sekund określoną w twojej stałej AUTOSAVE_INTERVAL, a następnie wywołuje funkcję saveGold, którą utworzyłeś wcześniej.


    coroutine.wrap(function()
    while player.Parent do
    task.wait(AUTOSAVE_INTERVAL)
    if playerGold[userId] then
    print("[AUTOMATYCZNY ZAPIS] Zapisuję", playerGold[userId], "złota dla", player.Name)
    saveGold(userId, playerGold[userId])
    end
    end
    end)()

Zapisz i ładuj pozycję gracza

Aby zapisać pozycję gracza, pracuj z jego Character, a nie z obiektem Player. Character gracza reprezentuje jego fizyczny model w świecie gry i ma współrzędne jego aktualnej pozycji oraz orientacji, podczas gdy obiekt Player reprezentuje tylko konto użytkownika.

Ponieważ magazyny danych mogą zapisywać tylko podstawowe typy danych, takie jak liczby, ciągi i tabele, nie możesz bezpośrednio przechowywać złożonych obiektów, takich jak wartości Vector3 lub CFrame. Aby zapisać pozycję gracza, musisz podzielić ją na trzy oddzielne liczby (współrzędne X, Y i Z) i zapisać je osobno. Podczas ładowania pozycji później możesz odbudować Vector3 za pomocą zapisanych współrzędnych.

Aby zapisać i załadować pozycję postaci:

  1. Otwórz istniejący skrypt PositionManager w ServerScriptService.

  2. Na początku skryptu zainicjalizuj DataStoreService i wywołaj GetDataStore z ciągiem "PlayerPosition".


    local DataStoreService = game:GetService("DataStoreService")
    local positionStore = DataStoreService:GetDataStore("PlayerPosition")
  3. Dodaj funkcję pomocniczą o nazwie savePosition, która przyjmuje userId gracza i pozycję Vector3. Ponieważ nie możesz zapisywać wartości Vector3 bezpośrednio, przekształć pozycję w tabelę z liczbami X, Y, Z.


    local function savePosition(player, position)
    local userId = player.UserId
    local success, err = pcall(function()
    positionStore:SetAsync(userId, {position.X, position.Y, position.Z})
    end)
    end
  4. OPCjonalne
    Dodaj ostrzeżenie do savePosition, które wydrukuje komunikat o błędzie i imię gracza, dla którego nie udało się zapisać pozycji. Choć nie jest to obowiązkowe, ten krok jest dobrą praktyką ułatwiającą debugowanie w przypadku, gdy twoja funkcja zawiedzie.


    local function savePosition(player, position)
    local userId = player.UserId
    local success, err = pcall(function()
    positionStore:SetAsync(userId, {position.X, position.Y, position.Z})
    end)
    if not success then
    warn("Nie można zapisać pozycji dla", player.Name, ":", err)
    end
    end
  5. Dodaj kolejną funkcję pomocniczą o nazwie loadPosition, aby załadować zapisane współrzędne dla gracza w magazynie danych PlayerPosition. Użyj PivotTo, aby przywrócić pozycję postaci w świecie. Ponieważ zapisane położenie gracza jest zwracane jako tabela, musisz odbudować Vector3 i przekształcić go na CFrame, aby przenieść postać.


    local function loadPosition(userId, character)
    local userId = player.UserId
    local success, savedCoords = pcall(function()
    return positionStore:GetAsync(userId)
    end)
    if success and savedCoords then
    local pos = Vector3.new(savedCoords[1], savedCoords[2], savedCoords[3])
    print("Przywrócono pozycję dla", player.Name)
    character:PivotTo(CFrame.new(pos))
    elseif not success then
    warn("Nie można załadować pozycji dla", player.Name)
    end
    end
  6. Zmodyfikuj zdarzenie onPlayerAdded, aby skonfigurować logikę pozycji dla każdego gracza, który dołącza do twojego doświadczenia. W ramach zaktualizowanej funkcji onPlayerAdded:

    • CharacterAdded wywołuje loadPosition, aby przywrócić ostatnią znaną lokalizację postaci, gdy postać gracza pojawia się na świecie.
    • CharacterRemoving wywołuje savePosition, aby zapisać aktualną pozycję postaci gracza, jeśli zostanie usunięta z doświadczenia.
    • GetPivot uzyskuje dokładną lokalizację postaci w świecie w momencie, gdy jest usuwana.

    local function onPlayerAdded(player)
    local userId = player.UserId
    player.CharacterAdded:Connect(function(character)
    loadPosition(player, character)
    end)
    player.CharacterRemoving:Connect(function(character)
    local pos = character:GetPivot().Position
    savePosition(player, pos)
    end)
    end
    Player.PlayerAdded:Connect(onPlayerAdded)

Ostateczny kod

Zobacz poniższe fragmenty kodu dla kompletnych skryptów GoldManager i PositionManager. Możesz wkleić je i uruchomić bezpośrednio w pliku Gold Rush save data tutorial - Start .rbxl w Studio.

GoldManager


-- Pobierz usługi
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local CollectionService = game:GetService("CollectionService")
local DataStoreService = game:GetService("DataStoreService")
-- Zdalne zdarzenie do aktualizacji interfejsu użytkownika
local uiEvent = ReplicatedStorage:WaitForChild("UIEvent")
-- Magazyn danych do zapisywania złota gracza
local goldStore = DataStoreService:GetDataStore("PlayerGold")
-- Tabela do przechowywania złota gracza dla jednej sesji gry
local playerGold = {}
-- Stałe
local GOLD_VALUE = 10 -- Ile warte jest każde kawałek złota
local GOLD_REGEN_DELAY = 2 -- Opóźnienie przed ponownym pojawieniem się kawałka (w sekundach)
local AUTOSAVE_INTERVAL = 30 -- Jak często zapisywane są kawałki złota gracza (w sekundach)
-- Funkcja obsługująca zbieranie kawałka złota przez gracza
local function processGoldTouch(chunk, player)
-- Ukryj kawałek, gdy gracz go zbiera
chunk.Parent = nil
-- Dodaj kawałek do wyniku złota gracza w sesji
local userId = player.UserId
playerGold[userId] = (playerGold[userId] or 0) + GOLD_VALUE
print(player.Name, "ma teraz", playerGold[userId], "złota")
-- Zaktualizuj interfejs użytkownika, aby odzwierciedlić nowy wynik złota w tej sesji
uiEvent:FireClient(player, {
gold = playerGold[userId],
doTween = true,
showAlert = false
})
-- Poczekaj chwilę, a następnie ponownie pojawi się kawałek złota, który został właśnie zebrany
task.delay(GOLD_REGEN_DELAY, function()
chunk.Parent = workspace.GoldChunks
end)
end
-- Pętla przez wszystkie części oznaczone jako "Gold" i połącz je z wykrywaniem dotyku
for _, chunk in ipairs(CollectionService:GetTagged("Gold")) do
chunk.Touched:Connect(function(otherPart)
local player = Players:GetPlayerFromCharacter(otherPart.Parent)
if player then
processGoldTouch(chunk, player)
end
end)
end
-- Funkcja do zapisania złota gracza w magazynie danych
local function saveGold(player, value)
local userId = player.UserId
local success, err = pcall(function()
goldStore:SetAsync(userId, value)
end)
if not success then
warn("Nie można zapisać złota dla", player.Name, ":", err)
end
end
-- Funkcja obsługująca gracza dołączającego do gry
local function onPlayerAdded(player)
local userId = player.UserId
print(player.Name, "dołączył do gry")
-- Próba załadowania złota gracza z magazynu danych
local success, storedGold = pcall(function()
return goldStore:GetAsync(userId)
end)
if success then
-- Ustaw aktualny wynik złota w sesji na podstawie wartości z magazynu danych dla gracza
local currentGold = storedGold or 0
playerGold[userId] = currentGold
-- Zaktualizuj interfejs użytkownika na podstawie wartości z magazynu danych dla gracza
uiEvent:FireClient(player, {
gold = currentGold,
doTween = false,
showAlert = false
})
print("Załadowano", currentGold, "złota dla", player.Name)
else
-- Powiadom gracza, że jego złoto nie mogło zostać załadowane
uiEvent:FireClient(player, { showAlert = true })
warn("Nie można załadować złota dla", player.Name)
end
-- Rozpocznij korutynę automatycznego zapisu, aby zapisywać złoto gracza co 30 sekund
coroutine.wrap(function()
while player.Parent do
task.wait(AUTOSAVE_INTERVAL)
if playerGold[userId] then
saveGold(player, playerGold[userId])
print("Automatyczne zapisywanie", playerGold[userId], "złota dla", player.Name)
end
end
end)()
end
-- Funkcja obsługująca gracza opuszczającego grę
local function onPlayerRemoving(player)
local userId = player.UserId
print(player.Name, "opuścił grę")
-- Sprawdź, czy złoto gracza było śledzone
if playerGold[userId] then
-- Zapisz złoto gracza w magazynie danych przed jego opuszczeniem
saveGold(player, playerGold[userId])
end
end
-- Połącz zdarzenia dołączania i opuszczania gracza
Players.PlayerAdded:Connect(onPlayerAdded)
Players.PlayerRemoving:Connect(onPlayerRemoving)

PositionManager


-- Pobierz usługi
local Players = game:GetService("Players")
local DataStoreService = game:GetService("DataStoreService")
-- Magazyn danych do zapisywania pozycji gracza
local positionStore = DataStoreService:GetDataStore("PlayerPosition")
-- Funkcja do zapisywania pozycji gracza jako tabeli {X, Y, Z}
local function savePosition(player, position)
local userId = player.UserId
local success, err = pcall(function()
positionStore:SetAsync(userId, {position.X, position.Y, position.Z})
end)
if not success then
warn("Nie można zapisać pozycji dla", player.Name, ":", err)
end
end
-- Funkcja do ładowania ostatniej zapisanej pozycji gracza i przenoszenia jego postaci
local function loadPosition(player, character)
local userId = player.UserId
local success, savedCoords = pcall(function()
return positionStore:GetAsync(userId)
end)
if success and savedCoords then
local pos = Vector3.new(savedCoords[1], savedCoords[2], savedCoords[3])
print("Przywrócono pozycję dla", player.Name)
character:PivotTo(CFrame.new(pos))
elseif not success then
warn("Nie można załadować pozycji dla", player.Name)
end
end
-- Funkcja do obsługi gracza dołączającego do gry
local function onPlayerAdded(player)
local userId = player.UserId
-- Próba załadowania pozycji gracza, gdy jego postać się pojawi
player.CharacterAdded:Connect(function(character)
loadPosition(player, character)
end)
-- Zapisz pozycję gracza, gdy jego postać zostanie usunięta
player.CharacterRemoving:Connect(function(character)
local pos = character:GetPivot().Position
savePosition(player, pos)
end)
end
Players.PlayerAdded:Connect(onPlayerAdded)

Na tej stronie