Samouczki dla średnio zaawansowanych

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żyć do zapisywania i ładowania trwałych danych gracza w różnych sesjach gracza. Przechowują one ważne informacje, takie jak postęp gracza lub inwentarz, i pozwalają na ich odzyskanie, gdy gracz następnym razem dołączy do twojej gry. Bez magazynów danych gracz straciłby cały swój postęp za każdym razem, gdy opuściłby grę.

Istnieją dwa typy magazynów danych: standardowe i uporządkowane. Ten samouczek wykorzystuje standardowe magazyny danych, które przechowują dane, takie jak liczby, ciągi znaków i tabele, które nie muszą być klasyfikowane ani sortowane.

Używając pliku samouczek magazynów danych Gold Rush - Start .rbxl jako punktu wyjścia oraz pliku samouczek magazynów danych Gold Rush - Complete .rbxl jako odniesienia, ten samouczek daje ci podstawy potrzebne do zapisania postępu gracza i stworzenia bardziej spójnych gier, w tym wskazówki dotyczące:

  • Zapisywania i ładowania ilości złota, które gracz zebrał.
  • Aktualizacji interfejsu użytkownika, aby wyświetlić inwentarz złota gracza.
  • Automatycznego zapisywania inwentarza złota gracza co 30 sekund.
  • Zapisywania pozycji gracza, gdy opuszcza grę.
  • Przywracania pozycji gracza, gdy ponownie dołącza do gry.

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 grę i przywraca jego pozycję, gdy wraca do gry.

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

Magazyny danych nie są przechowywane lokalnie na twoim urządzeniu, więc twoja gra polega na komunikacji serwerowej z backendem Roblox w celu ich użycia. 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, aż wyraźnie go włączysz, aby upewnić się, że tylko zaufane gry mogą czytać i zapisywać na serwerach backendu Roblox.

Aby włączyć dostęp Studio do usług API, aby móc używać magazynów danych:

  1. Otwórz plik samouczek magazynów danych Gold Rush - Start .rbxl w Studio i stwórz lokalną kopię.
  2. Z powrotem w Studio, przejdź do PlikUstawienia doświadczeniaBezpieczeństwo.
  3. Włącz Włącz dostęp Studio do usług API.
  4. Zapisz swoje zmiany.

Utwórz standardowy magazyn danych

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

  • Roblox blokuje wszystkie dostęp do magazynów danych z klienta, aby tylko serwer miał pozwolenie na dostęp i modyfikowanie trwałych danych gracza.
  • Skrypty po stronie serwera działają w scentralizowanym środowisku, co zapewnia, że dane odczytywane i zapisywane w twoim magazynie 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ć grę i ukraść lub nadpisać dane innych graczy, jeśli klient miałby dostęp do twoich magazynów danych.

Należy również nadać swojemu magazynowi danych unikalną nazwę, aby uporządkować swoje dane i zapobiec ich zachodzeniu lub konfliktom w różnych magazynach danych. W tym samouczku magazyn danych, który zapisuje i przechowuje inwentarz złota gracza, nazywa się PlayerGold.

Aby utworzyć magazyn danych PlayerGold:

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

  2. Na górze skryptu, po innych usługach, zainicjalizuj DataStoreService i wywołaj GetDataStore z napisem "PlayerGold".


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

Zapisz i załaduj dane gracza

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

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

Klucze pozwalają ci uporządkować swoje dane, abyś mógł łatwo je zarządzać i debugować.
Wartość to faktyczne dane, które chcesz zapisać lub załadować, takie jak inwentarz gracza lub jego ustawienia.

Wartości pozwalają ci przechowywać postęp między sesjami, a także odzyskiwać dane gracza następnym razem, gdy dołączy do twojej gry.
Dozwolone formatyMogą być tylko ciągami znaków.Mogą być liczbami, ciągami znaków, wartościami logicznymi lub tabelami.
Przykłady"Player_A", "TopScore", "GameSetting"100, "Level_5", true, {gold = 100, level = 5}

W tym samouczku kluczem jest userId gracza, a wartością jest ilość złota, które 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. OPTIONAL
    Dodaj ostrzeżenie do saveGold, które wydrukuje identyfikator gracza i komunikat o błędzie. Choć nie jest to obowiązkowe, ten krok jest dobrą praktyką, aby łatwiej debugować, jeśli twoja funkcja nie powiedzie się.


    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 udało się zapisać złota dla", userId, ":", err)
    end
    end
  3. Zmodyfikuj zdarzenie onPlayerAdded, aby załadować złoto gracza, gdy ten po raz pierwszy dołączy do gry. Zaktualizowana funkcja onPlayerAdded:

    • Próbuje załadować zawartość wewnątrz 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 tę grę.
    • Dostarcza ci log debugowy, aby pomóc ci łatwiej debugować swój kod. Ten log debugowy zawiera zapisane złoto gracza, lub 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ą stworzyłeś wcześniej i zapisać złoto gracza, gdy opuszcza grę.


    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ą jego danych. Jeśli zapisujesz dane gracza tylko wtedy, gdy opuszcza grę za pomocą onPlayerRemoving, możesz stracić jego najnowszy postęp, gdy nieoczekiwanie rozłączy się z serwerem.

Aby automatycznie zapisać dane gracza:

  1. Utwórz nową stałą, aby określić, jak często chcesz, aby twoja gra automatycznie zapisywała dane gracza. Stała jest zmienną, której wartość nie zmienia się podczas działania gry. Możesz użyć tej stałej, aby odwołać się do interwału autosave w całym swoim skrypcie i łatwo dostosować frekwencję autosavingu.


    -- Ta liczba jest w sekundach
    local AUTOSAVE_INTERVAL = 30
  2. Dodaj coroutine autosave do istniejącej funkcji onPlayerAdded, aby utworzyć pętlę w tle, która działa, gdy gracz jest w grze. Coroutine to funkcja, która działa asynchronicznie; może wstrzymać się w pewnych punktach, wznowić tam, gdzie skończyła, i działać równolegle z innymi częściami twojego skryptu, nie blokując ich.

    W tym skrypcie tło autosave coroutine czeka na liczbę sekund w twojej stałej AUTOSAVE_INTERVAL, a następnie wywołuje funkcję saveGold, którą stworzyłeś wcześniej.


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

Zapisz i załaduj pozycję gracza

Aby zapisać pozycję gracza, należy pracować z jego Character, a nie z obiektem Player. Character gracza reprezentuje jego fizyczny model w świecie 3D i ma współrzędne dla swojej obecnej pozycji i orientacji, podczas gdy obiekt Player reprezentuje tylko konto użytkownika.

Ponieważ magazyny danych mogą przechowywać tylko podstawowe typy danych, takie jak liczby, ciągi znaków i tabele, nie możesz bezpośrednio przechować 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 górze skryptu zainicjalizuj DataStoreService i wywołaj GetDataStore z napisem "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 bezpośrednio zapisać wartości Vector3, skonwertuj pozycję na 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. OPTIONAL
    Dodaj ostrzeżenie do savePosition, które wydrukuje komunikat o błędzie i nazwę gracza, dla którego nie udało się zapisać pozycji. Choć nie jest to obowiązkowe, ten krok jest dobrą praktyką, aby łatwiej debugować, jeśli twoja funkcja nie powiedzie się.


    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 zwracane jest jako tabela, musisz odbudować Vector3, a następnie przekształcić go w 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 zainicjować logikę pozycji dla każdego gracza, który dołącza do twojej gry. W zaktualizowanej funkcji onPlayerAdded:

    • CharacterAdded wywołuje loadPosition, aby przywrócić ostatnią znaną lokalizację postaci, gdy postać gracza się pojawia.
    • CharacterRemoving wywołuje savePosition, aby zapisać bieżącą pozycję postaci gracza, jeśli zostanie usunięta z gry.
    • GetPivot uzyskuje dokładną lokalizację postaci w świecie w momencie jej usunięcia.

    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)

Końcowy kod

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

GoldManager


-- Pobierz usługi
-- 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łotych kawałków gracza
local goldStore = DataStoreService:GetDataStore("PlayerGold")
-- Tabela do przechowywania kawałków złota gracza w jednej sesji
local playerGold = {}
-- Stałe
local GOLD_VALUE = 10 -- Ile wart jest każdy kawałek złota
local GOLD_REGEN_DELAY = 2 -- Opóźnienie przed respawnowaniem kawałka (w sekundach)
local AUTOSAVE_INTERVAL = 30 -- Jak często kawałki gracza są zapisywane (w sekundach)
-- Funkcja do obsługi zbierania kawałka złota przez gracza
local function processGoldTouch(chunk, player)
-- Ukryj kawałek, gdy gracz go zbierze
chunk.Parent = nil
-- Dodaj kawałek do sesyjnego wyniku złota gracza
local userId = player.UserId
playerGold[userId] = (playerGold[userId] or 0) + GOLD_VALUE
print(player.Name, "ma teraz", playerGold[userId], "złota")
-- Aktualizuj 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 respawnuj kawałek złota, który został właśnie zebrany
task.delay(GOLD_REGEN_DELAY, function()
chunk.Parent = workspace.GoldChunks
end)
end
-- Przejdź 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 zapisywania 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 do obsługi przyłączania gracza do gry
local function onPlayerAdded(player)
local userId = player.UserId
print(player.Name, "dołączył do gry")
-- Spróbuj załadować złoto gracza z magazynu danych
local success, storedGold = pcall(function()
return goldStore:GetAsync(userId)
end)
if success then
-- Ustaw obecny wynik złota sesji, korzystając z wartości magazynu danych dla gracza
local currentGold = storedGold or 0
playerGold[userId] = currentGold
-- Zaktualizuj interfejs użytkownika za pomocą wartości 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ę autosave, 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("Autosave", playerGold[userId], "złota dla", player.Name)
end
end
end)()
end
-- Funkcja do obsługi opuszczania gry przez gracza
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 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 przyłączania gracza do gry
local function onPlayerAdded(player)
local userId = player.UserId
-- Spróbuj załadować pozycję 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)
©2026 Roblox Corporation. Nazwa Roblox, logo Roblox oraz hasło „Powering Imagination” należą do naszych zarejestrowanych i niezarejestrowanych znaków towarowych na terenie Stanów Zjednoczonych oraz w innych krajach.