Creator Guide
Korean
Korean
  • OVERDARE
    • ๐ŸšฉOVERDARE ์†Œ๊ฐœ
    • ๐Ÿค์‹œ์ž‘ํ•˜๊ธฐ
      • OVERDARE App
      • OVERDARE Studio
    • ๐Ÿ“Œ์šด์˜ ์ •์ฑ…
      • ์ปค๋ฎค๋‹ˆํ‹ฐ ๊ฐ€์ด๋“œ๋ผ์ธ
      • UGC ์ฝ˜ํ…์ธ  ์ œ์ž‘ ๊ฐ€์ด๋“œ๋ผ์ธ
      • UGC์˜ ์™ธ๋ถ€ ํ™œ์šฉ ๊ฐ€์ด๋“œ๋ผ์ธ
      • LOGO ํ™œ์šฉ ๊ฐ€์ด๋“œ๋ผ์ธ
      • ์ง€์‹ ์žฌ์‚ฐ๊ถŒ ์ •์ฑ…
      • ์‹ ๊ณ  ์•ˆ๋‚ด
      • ์ฝ˜ํ…์ธ  ์ œ์žฌ ์ด์˜ ์‹ ์ฒญ ์•ˆ๋‚ด
      • ํฌ๋ฆฌ์—์ดํ„ฐ ์ •์‚ฐ ์ •์ฑ…
      • OVERDARE ์ˆ˜์ตํ™” ๊ฐ€์ด๋“œ๋ผ์ธ
      • ํฌ๋Ÿผ ์‚ฌ์šฉ ๊ฐ€์ด๋“œ๋ผ์ธ
    • ๐Ÿ…ฐ๏ธOVERDARE Glossary
  • MANUAL
    • ๐Ÿฐ์ŠคํŠœ๋””์˜ค ๋ฉ”๋‰ด์–ผ
      • ์‹œ์ž‘ํ•˜๊ธฐ
        • ์ŠคํŠœ๋””์˜ค ์ธํ„ฐํŽ˜์ด์Šค
        • ์›”๋“œ ํ…œํ”Œ๋ฆฟ
        • ์ขŒํ‘œ๊ณ„
        • ์ŠคํŠœ๋””์˜ค ํ…Œ์ŠคํŠธ ํ”Œ๋ ˆ์ด
        • ์›”๋“œ ํผ๋ธ”๋ฆฌ์‹œ
        • Collaboration
      • ์—์…‹ & ๋ฆฌ์†Œ์Šค ์ œ์ž‘
        • ์—์…‹ ์ž„ํฌํŠธ
        • ์• ๋‹ˆ๋ฉ”์ด์…˜ ์—๋””ํ„ฐ
        • Shadow Detail ์„ค์ •
      • ๊ฒŒ์ž„ ์ œ์ž‘
        • ๊ฒŒ์ž„ ์„ค์ •
        • ์Šคํฌ๋ฆฝํŠธ ์—๋””ํ„ฐ
        • ์ •๋ ฌ
        • Material Manager
        • Collision Groups
        • Tag Editor
        • ํผํฌ๋จผ์Šค ๊ฐ€์ด๋“œ
        • ์›”๋“œ ์„ฑ๋Šฅ ๋ถ„์„
      • Object
        • ํŒŒํŠธ
        • ๋ชจ๋ธ
        • ์นด๋ฉ”๋ผ
        • ๋ฌผ๋ฆฌ
        • ์กฐ๋ช…
        • Tool
        • VFX
        • Sound
      • ์บ๋ฆญํ„ฐ
        • ์บ๋ฆญํ„ฐ ์• ๋‹ˆ๋ฉ”์ด์…˜
        • Humanoid Description
      • GUI
    • ๐Ÿ“์Šคํฌ๋ฆฝํŠธ ๋ฉ”๋‰ด์–ผ
      • ์‹œ์ž‘ํ•˜๊ธฐ
        • ์Šคํฌ๋ฆฝํŠธ ๊ฐœ์š”
        • ๋ฃจ์•„ ๊ธฐ์ดˆ ๊ฐ€์ด๋“œ
        • ์ฝ”๋”ฉ ์Šคํƒ€์ผ
        • ์˜ค๋ธŒ์ ํŠธ ์ฐธ์กฐ
        • ์œ ๋‹ˆํ‹ฐ ๊ฐœ๋ฐœ์ž์šฉ ๊ฐ€์ด๋“œ
      • ์ด๋ฒคํŠธ ๋ฐ ํ†ต์‹ 
        • ์ด๋ฒคํŠธ
        • ์„œ๋ฒ„-ํด๋ผ ํ†ต์‹ 
        • BindableEvent
        • Value Objects
      • ์ž…๋ ฅ ๋ฐ ์กฐ์ž‘
        • ๋ชจ๋ฐ”์ผ ์กฐ์ž‘ ์ฒ˜๋ฆฌ
        • TPS Strafing System
      • ๊ฒŒ์ž„ ๊ณ ๋„ํ™”
        • Saving & Loading Data
        • ํŠธ์œˆ
        • ๋ชจ๋“ˆ ์Šคํฌ๋ฆฝํŠธ
        • JSON๊ณผ HTTP ํ†ต์‹ 
      • ๋””๋ฒ„๊น… & ์ตœ์ ํ™”
        • ์ค‘๋‹จ์ 
        • ์Šคํฌ๋ฆฝํŠธ ์ตœ์ ํ™” ์‹ค์ „ ๊ฐ€์ด๋“œ
    • ๐Ÿ’กํฌ๋ฆฌ์—์ดํ„ฐ ์ฐธ๊ณ  ์ž๋ฃŒ
      • ํฌ๋ฆฌ์—์ดํ„ฐ๋ฅผ ์œ„ํ•œ ๊ฒŒ์ž„ ์šฉ์–ด ๋ฒˆ์—ญํ‘œ
    • ๐Ÿ’ธ์ˆ˜์ตํ™”
      • Payout Guideline
  • DEVELOPMENT
    • ๐Ÿ“šAPI Reference
      • Enums
        • ActuatorRelativeTo
        • AnimationPriority
        • AspectType
        • AssetTypeVerification
        • BorderMode
        • CameraMode
        • CameraType
        • ContextActionResult
        • CoreGuiType
        • DominantAxis
        • EasingDirection
        • EasingStyle
        • ForceLimitMode
        • HttpCompression
        • HttpContentType
        • HumanoidDisplayDistanceType
        • HumanoidStateType
        • KeyCode
        • Material
        • MaterialPattern
        • NormalId
        • ParticleEmitterShape
        • ParticleEmitterShapeInOut
        • ParticleEmitterShapeStyle
        • ParticleFlipbookLayout
        • ParticleFlipbookMode
        • ParticleOrientation
        • PartType
        • PlaybackState
        • RaycastFilterType
        • RollOffMode
        • RotationType
        • UserInputState
        • UserInputType
        • VelocityConstraintMode
      • DataTypes
        • BlendSpaceSampleSata
        • BrickColor
        • CFrame
        • Color3
        • ColorSequence
        • ColorSequenceKeypoint
        • Content
        • Enum
        • EnumItem
        • NumberRange
        • NumberSequence
        • NumberSequenceKeypoint
        • OverlapParams
        • PhysicalProperties
        • Ray
        • RaycastParams
        • RaycastResult
        • ScriptConnection
        • ScriptSignal
        • TweenInfo
        • Udim
        • Udim2
        • Vector2
        • Vector3
      • Classes
        • Animation
        • AngularVelocity
        • AnimationTrack
        • Animator
        • Atmosphere
        • Attachment
        • Backpack
        • BackpackItem
        • BasePart
        • BaseScript
        • Beam
        • BindableEvent
        • BlendSpace
        • BoolValue
        • Bone
        • Camera
        • CharacterMesh
        • CollectionService
        • Constraint
        • ContextActionService
        • CoreGui
        • DataStore
        • DataModel
        • DataStoreGetOptions
        • DataStoreIncrementOptions
        • DataStoreInfo
        • DataStoreKeyPages
        • DataStoreKeyInfo
        • DataStoreService
        • DataStoreListingPages
        • DataStoreSetOptions
        • FormFactorPart
        • Frame
        • Folder
        • GlobalDataStore
        • GuiBase2d
        • GuiButton
        • GuiObject
        • HttpService
        • Humanoid
        • HumanoidDescription
        • ImageButton
        • ImageLabel
        • InputObject
        • IntValue
        • LayerCollector
        • Instance
        • Light
        • Lighting
        • LinearVelocity
        • LocalScript
        • LuaSourceContainer
        • MaterialService
        • MaterialVariant
        • MeshPart
        • Model
        • ModuleScript
        • Mouse
        • NumberValue
        • OrderedDataStore
        • Pages
        • Part
        • ParticleEmitter
        • PhysicsService
        • Player
        • PlayerGui
        • Players
        • PlayerScripts
        • PointLight
        • PVInstance
        • ReplicatedStorage
        • RemoteEvent
        • ScreenGui
        • RunService
        • Script
        • ServerStorage
        • ServiceProvider
        • Skeleton
        • ServerScriptService
        • Sound
        • SoundService
        • SoundGroup
        • SpotLight
        • SpawnLocation
        • StarterCharacterScripts
        • StarterPack
        • StarterGui
        • StarterPlayer
        • StarterPlayerScripts
        • StringValue
        • SurfaceGui
        • SurfaceGuiBase
        • Team
        • Teams
        • TextLabel
        • TextButton
        • Tool
        • Trail
        • Tween
        • TweenService
        • TweenBase
        • UIAspectRatioConstraint
        • UserGameSettings
        • UserInputService
        • UserSettings
        • VectorForce
        • Workspace
        • WrapLayer
        • WorldRoot
        • WrapTarget
  • UPDATE
    • ๐Ÿ“ฐRelease Note
Powered by GitBook
On this page
  • ๊ฐœ์š”
  • ์‚ฌ์šฉ ๋ฐฉ๋ฒ•
  • ์ง€์›๋˜๋Š” ๋ฐ์ดํ„ฐ ํƒ€์ž…
  • ๊ธฐ๋ณธ ๊ตฌ์กฐ
  • ๋ฐ์ดํ„ฐ ์Šคํ† ์–ด ๊ฐ€์ ธ์˜ค๊ธฐ
  • ์ €์žฅํ•˜๊ธฐ
  • ๋ถˆ๋Ÿฌ์˜ค๊ธฐ
  • ์—…๋ฐ์ดํŠธ ํ•˜๊ธฐ
  • ๋ฐ์ดํ„ฐ ์‚ญ์ œ ํ•˜๊ธฐ
  • ์ „์ฒด ์ฝ”๋“œ ์˜ˆ์‹œ
  • ํ™œ์šฉ ์˜ˆ์‹œ
  • ํผ๋ธ”๋ฆฌ์‹œ ๋ฐ ํ…Œ์ŠคํŠธ ํ™˜๊ฒฝ์˜ ๋™์ž‘ ์ฐจ์ด
  • ์ฃผ์˜ ์‚ฌํ•ญ
  1. MANUAL
  2. ์Šคํฌ๋ฆฝํŠธ ๋ฉ”๋‰ด์–ผ
  3. ๊ฒŒ์ž„ ๊ณ ๋„ํ™”

Saving & Loading Data

๊ฐœ์š”

DataStore๋ฅผ ํ™œ์šฉํ•˜๋ฉด ํ”Œ๋ ˆ์ด์–ด์˜ ๋ ˆ๋ฒจ, ๊ฒฝํ—˜์น˜, ๋ณด์œ  ๊ณจ๋“œ ๋“ฑ ํ•ต์‹ฌ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๊ณ  ๋ถˆ๋Ÿฌ์˜ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ํ”Œ๋ ˆ์ด์–ด์˜ ์ง„ํ–‰ ์ƒํƒœ๋ฅผ ์ง€์†์ ์œผ๋กœ ์œ ์ง€ํ•˜๋ฉฐ, RPG์™€ ๊ฐ™์€ ์œก์„ฑ ์š”์†Œ๊ฐ€ ํฌํ•จ๋œ ๊ฒŒ์ž„์„ ์ œ์ž‘ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์‚ฌ์šฉ ๋ฐฉ๋ฒ•

์ง€์›๋˜๋Š” ๋ฐ์ดํ„ฐ ํƒ€์ž…

๋ฐ์ดํ„ฐ ํƒ€์ž…
์ง€์› ์—ฌ๋ถ€

number

O

string

O

bool

O

table

O

object

์ง€์›๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

ํ•จ์ˆ˜

์ง€์›๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๊ธฐ๋ณธ ๊ตฌ์กฐ

DataStoreService์˜ GetDataStore์„ ์‚ฌ์šฉํ•˜์—ฌ ์ง€์ •๋œ ์ด๋ฆ„์˜ DataStore ๊ฐ์ฒด๋ฅผ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ์œผ๋ฉฐ, DataStore ๊ฐ์ฒด์— ํ‚ค-๊ฐ’(Key-Value) ํ˜•์‹์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๊ฑฐ๋‚˜ ๋ถˆ๋Ÿฌ์˜ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • Key (ํ‚ค): ๋ฐ์ดํ„ฐ๋ฅผ ์‹๋ณ„ํ•˜๋Š” ๊ณ ์œ ํ•œ ์ด๋ฆ„ (์˜ˆ: PlayerGold)

  • Value (๊ฐ’): ์ €์žฅํ•  ๋ฐ์ดํ„ฐ (์˜ˆ: 1000)

์ถ”๊ฐ€์ ์œผ๋กœ ํ•ด๋‹น ํ‚ค์— ๋ถ€๊ฐ€์ ์ธ ์ •๋ณด๋ฅผ ์ €์žฅํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

  • UserIds (๋ฐฐ์—ด): ๋ฐ์ดํ„ฐ์™€ ๊ด€๋ จํ•œ UserId ๋ฆฌ์ŠคํŠธ

  • Metadata (ํ…Œ์ด๋ธ”) : ๋ถ€๊ฐ€์ ์œผ๋กœ ์ €์žฅํ•  ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ ์ •๋ณด

์œ„ ๋‘ ๋ถ€๊ฐ€์ •๋ณด๋Š” DataStoreKeyInfo๋ฅผ ํ†ตํ•ด ์ฝ์–ด์˜ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

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

local function LoadMetadata(player)
    local success, errorMessageOrLoadValue, keyInfo = pcall(function()
       -- Key : PlayerName
        return GoldStore:GetAsync(player.UserId)
    end)

    if not success then
        print("errorMessage : ", errorMessageOrLoadValue)
    else
        local loadValue = errorMessageOrLoadValue
        local userIds = keyInfo:GetUserIds()
        local metadata = keyInfo:GetMetadata()
        print(player.Name, "Load PlayerGold : ", loadValue)
        print(" - UserIds : ", table.concat(userIds, ", "))
        print(" - Metadata: ", metadata)
    end
end

๊ธฐ๋Šฅ
์„ค๋ช…

GetDataStore(name)

์ด๋ฆ„์— ํ•ด๋‹นํ•˜๋Š” Datastore ๊ฐ์ฒด๋ฅผ ๊ฐ€์ ธ์˜ค๊ธฐ

GetAsync(key)

Datastore ๊ฐ์ฒด์—์„œ ํ‚ค์— ํ•ด๋‹นํ•˜๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ

SetAsync(key, value, userIds(*optional), datastoreSetOption(*optional) )

Datastore ๊ฐ์ฒด์—์„œ ํ‚ค์— ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅ (๋ฎ์–ด์“ฐ๊ธฐ)

IncrementAsync(key, delta, userIds(*optional), datastoreSetOption(*optional))

Datastore ๊ฐ์ฒด์—์„œ ํ‚ค์— ํ•ด๋‹นํ•˜๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์ฆ๊ฐ (number ํƒ€์ž…์— ๋Œ€ํ•ด์„œ๋งŒ ๋™์ž‘)

UpdateAsync(key, callback)

Datastore ๊ฐ์ฒด์—์„œ ํ‚ค์— ํ•ด๋‹นํ•˜๋Š” ๋ฐ์ดํ„ฐ๋ฅผ callback์„ ํ†ตํ•ด ์—…๋ฐ์ดํŠธ

RemoveAsync(key)

Datastore ๊ฐ์ฒด์—์„œ ํ‚ค์— ํ•ด๋‹นํ•˜๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์‚ญ์ œ

๋ฐ์ดํ„ฐ ์Šคํ† ์–ด ๊ฐ€์ ธ์˜ค๊ธฐ

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

์ €์žฅํ•˜๊ธฐ

local function SaveData(player)
    local success, errorMessageOrLoadValue = pcall(function()
        local saveValue = 1 
        
        -- Key : PlayerName / Value : SaveValue
        GoldStore:SetAsync(player.UserId, saveValue) 
    end)

    if not success then
        print("errorMessage : ", errorMessageOrLoadValue)
    end
end

๋ถˆ๋Ÿฌ์˜ค๊ธฐ

local function LoadData(player)
    local success, errorMessageOrLoadValue = pcall(function()
       -- Key : PlayerName
        return GoldStore:GetAsync(player.UserId)
    end)

    if not success then
        print("errorMessage : ", errorMessageOrLoadValue)
    else
        local loadValue = errorMessageOrLoadValue
        print(player.Name, "Load PlayerGold : ", loadValue)
    end
end

์—…๋ฐ์ดํŠธ ํ•˜๊ธฐ

DataStore๋ฅผ ์ด์šฉํ•ด ํ”Œ๋ ˆ์ด์–ด ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•  ๋•Œ, ๋‹จ์ˆœํžˆ GetAsync์™€ SetAsync๋งŒ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ ์—ฌ๋Ÿฌ ์‚ฌ์šฉ์ž๊ฐ€ ๋™์‹œ์— ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ๊ณ  ์“ธ ๋•Œ ๊ฒฝ์Ÿ ์ƒํƒœ(race condition)๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋กœ ์ธํ•ด ํ•œ ์‚ฌ์šฉ์ž๊ฐ€ ์ €์žฅํ•œ ๊ฐ’์ด ๋‹ค๋ฅธ ์‚ฌ์šฉ์ž์˜ ์ €์žฅ ์š”์ฒญ์— ์˜ํ•ด ๋ฎ์–ด์จ์ง€๊ฑฐ๋‚˜, ์ผ๋ถ€ ๋ฐ์ดํ„ฐ๊ฐ€ ์†์‹ค๋˜๋Š” ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด GetAsync๋กœ ๊ฐ’์„ ๊ฐ€์ ธ์™€ ์ฒ˜๋ฆฌํ•˜๋Š” ๋„์ค‘, ๋‹ค๋ฅธ ์ด๋ฒคํŠธ๋‚˜ ์„œ๋ฒ„์—์„œ SetAsync๊ฐ€ ํ˜ธ์ถœ๋˜์–ด ๊ฐ’์ด ์—…๋ฐ์ดํŠธ ๋˜๋Š” ๊ฒฝ์šฐ, ์ฒ˜๋ฆฌ์ค‘์— ์—…๋ฐ์ดํŠธ ๋˜์—ˆ๋Š”์ง€ ์—ฌ๋ถ€๋ฅผ ํ™•์ธ ํ•  ์ˆ˜ ์—†์–ด ๊ณผ๊ฑฐ ๊ฐ’์„ ๊ธฐ์ค€์œผ๋กœ ํ•˜์—ฌ ๊ณ„์‚ฐ๋œ ๊ฐ’์ด ๋ฎ์–ด์จ์ง€๋ฉด์„œ ์ง์ „์— ์—…๋ฐ์ดํŠธ ๋œ ๋‚ด์šฉ์ด ๋‚ ๋ผ๊ฐ€๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

์ด๋Ÿฌํ•œ ๊ฒฝ์Ÿ ์ƒํƒœ๋ฅผ ๋ฐฉ์ง€ํ•˜๊ณ  ๋ฐ์ดํ„ฐ ๋ฌด๊ฒฐ์„ฑ์„ ๋ณด์žฅํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋ณด๋‹ค ์•ˆ์ „ํ•œ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ ๋ฐฉ์‹์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

IncrementAsync

์ˆซ์ž ๊ฐ’์„ ๋‹จ์ˆœํžˆ ์ฆ๊ฐ€(ํ˜น์€ ๊ฐ์†Œ)์‹œํ‚ค๋Š” ๊ฒฝ์šฐ์—๋Š” IncrementAsync๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. IncrementAsync๋Š” ๋‚ด๋ถ€์ ์œผ๋กœ ์›์ž์  ์—ฐ์‚ฐ์„ ์ง€์›ํ•˜์—ฌ, ์—ฌ๋Ÿฌ ์‚ฌ์šฉ์ž๊ฐ€ ๋™์‹œ์— ๊ฐ’์„ ์ฆ๊ฐ€์‹œ์ผœ๋„ ๋ฐ์ดํ„ฐ ์ถฉ๋Œ ์—†์ด ์•ˆ์ „ํ•˜๊ฒŒ ๋ˆ„์ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ฝ”์ธ, ๊ฒฝํ—˜์น˜, ์ ์ˆ˜ ๋“ฑ ๋‹จ์ˆœ ๋ˆ„์ ์ด ํ•„์š”ํ•œ number ๋ฐ์ดํ„ฐ์—๋Š” IncrementAsync๊ฐ€ ๊ฐ€์žฅ ๊ฐ„๋‹จํ•˜๊ณ  ํšจ์œจ์ ์ธ ์„ ํƒ์ž…๋‹ˆ๋‹ค.

local function IncrementGold(player, delta)
    local success, errorMessageOrLoadValue = pcall(function()
        return GoldStore:IncrementAsync(player.UserId, delta)
    end)
    
    if not success then
        print("errorMessage : ", errorMessageOrLoadValue)
    else
        local loadValue = errorMessageOrLoadValue
        print(player.Name, "Load PlayerGold : ", loadValue)
    end
end

UpdateAsync

ํ•˜์ง€๋งŒ IncrementAsync๋Š” number ํ˜•ํƒœ ๋ฐ์ดํ„ฐ์—๋งŒ ์œ ํšจํ•˜๊ณ  ๋‹จ์ˆœํ•œ ์ฆ๊ฐ ์—ฐ์‚ฐ์™ธ์— ๊ณฑ์…‰, ๋‚˜๋ˆ—์…ˆ, ๊ธฐํƒ€ ๋ถ„๊ธฐ ์ฒ˜๋ฆฌ๋“ฑ ๋ณต์žกํ•œ ํ˜•ํƒœ์˜ ๋ฐ์ดํ„ฐ ์—…๋ฐ์ดํŠธ๋ฅผ ์ œ๊ณตํ•˜์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค.

UpdateAsync ํ•จ์ˆ˜๋Š” ๋ฐ์ดํ„ฐ์Šคํ† ์–ด์—์„œ ๊ฐ’์„ ์ฝ๊ณ , ๋ณ€๊ฒฝํ•˜๊ณ , ๋‹ค์‹œ ์ €์žฅํ•˜๋Š” ๊ณผ์ •์„ ์›์ž์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋„๋ก ์„ค๊ณ„๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ๋™์‹œ ์ ‘๊ทผ ์ƒํ™ฉ์—์„œ๋„ ๋ฐ์ดํ„ฐ ์†์‹ค ์—†์ด ์•ˆ์ •์ ์œผ๋กœ ๊ฐ’์„ ๊ฐฑ์‹ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

UpdateAsync๋Š” ์ฝœ๋ฐฑ(callback) ํ•จ์ˆ˜๋ฅผ ์ธ์ž๋กœ ๋ฐ›์•„, ํ˜„์žฌ ์ €์žฅ๋œ ๊ฐ’์„ ์ฝœ๋ฐฑ์— ์ „๋‹ฌํ•œ ํ›„ ์ฝœ๋ฐฑ์ด ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฐ’์„ ๋ฐ์ดํ„ฐ์Šคํ† ์–ด์— ์ €์žฅํ•ฉ๋‹ˆ๋‹ค. ๋งŒ์•ฝ ๋™์‹œ์— ์—ฌ๋Ÿฌ ์š”์ฒญ์ด ๋“ค์–ด์™€ ๋ฐ์ดํ„ฐ ์ถฉ๋Œ์ด ๋ฐœ์ƒํ•˜๋ฉด, UpdateAsync๋Š” ์ž๋™์œผ๋กœ ์ตœ์‹  ๊ฐ’์„ ๋‹ค์‹œ ๋ถˆ๋Ÿฌ์™€ ์ฝœ๋ฐฑ์„ ์žฌ์‹คํ–‰ํ•˜์—ฌ ์ถฉ๋Œ์„ ํ•ด๊ฒฐํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ณผ์ •์€ ๋ฐ์ดํ„ฐ๊ฐ€ ์•ˆ์ „ํ•˜๊ฒŒ ๊ฐฑ์‹ ๋  ๋•Œ๊นŒ์ง€ ๋ฐ˜๋ณต๋ฉ๋‹ˆ๋‹ค.

์ฝœ๋ฐฑ ํ•จ์ˆ˜๋Š” ๋ฐ์ดํ„ฐ ํŠธ๋žœ์žญ์…˜์˜ ์•ˆ์ •์„ฑ๊ณผ ๋ฌด๊ฒฐ์„ฑ์„ ๋ณด์žฅํ•˜๋Š” ACID(Aromicity, Consistency, Isolation, Duration) ์ฒ˜๋ฆฌ๋ฅผ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•˜๋ฉฐ, ๋ฐ˜ํ™˜๊ฐ’์— ๋”ฐ๋ผ ์—…๋ฐ์ดํŠธ์˜ ์‹ค์ œ ์ ์šฉ ์—ฌ๋ถ€๋ฅผ ๊ฒฐ์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์ฝœ๋ฐฑ ํ•จ์ˆ˜์—์„œ nil์„ ๋ฐ˜ํ™˜ํ•˜๋ฉด ํ•ด๋‹น ์—…๋ฐ์ดํŠธ๋Š” ์ทจ์†Œ๋ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ™œ์šฉํ•ด ์กฐ๊ฑด๋ถ€ ๋ฐ์ดํ„ฐ ์—…๋ฐ์ดํŠธ, ๋ฌด๊ฒฐ์„ฑ ๊ฒ€์‚ฌ ๋“ฑ ๋‹ค์–‘ํ•œ ๋กœ์ง์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

local function UpdateGold(player, delta)
    local success, errorMessageOrLoadValue, keyInfo = pcall(function()
        return GoldStore:UpdateAsync(player.UserId, function(currentGold, keyInfo)
            local newGold = (currentGold or 0) + delta		
            return { newGold, keyInfo:GetUserIds(), keyInfo:GetMetadata() }
        end)
    end)
    
    if not success then
        print("errorMessage : ", errorMessageOrLoadValue)
    else
        local loadValue = errorMessageOrLoadValue
        print(player.Name, "Load PlayerGold : ", loadValue)
    end
end

๋ฐ์ดํ„ฐ ์‚ญ์ œ ํ•˜๊ธฐ

RemoveAsync๋ฅผ ์ด์šฉํ•˜๋ฉด DataStore์— ์ €์žฅ๋œ ๊ฐ’์„ ์‚ญ์ œ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

local function RemoveData(player)
    local success, errorMessageOrLoadValue = pcall(function()
        return GoldStore:RemoveAsync(player.UserId)
    end)
    
    if not success then
        print("errorMessage : ", errorMessageOrLoadValue)
    end
end

์ „์ฒด ์ฝ”๋“œ ์˜ˆ์‹œ

๋‹ค์Œ ์ฝ”๋“œ๋Š” ํ”Œ๋ ˆ์ด์–ด๊ฐ€ ๊ฒŒ์ž„์— ์ž…์žฅํ•  ๋•Œ, ์„œ๋ฒ„์— ์ €์žฅ๋œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๊ณ , ์ €์žฅ๋œ ๊ฐ’์ด ์—†์œผ๋ฉด ์ดˆ๊ธฐ๊ฐ’์„ ์„ค์ •ํ•œ ํ›„, ํ•ด๋‹น ๊ฐ’์„ ํ”Œ๋ ˆ์ด์–ด์˜ Attribute๋กœ ํ• ๋‹นํ•ฉ๋‹ˆ๋‹ค.

์ดํ›„, ์ €์žฅ ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋˜๋ฉด, Attribute์— ์„ค์ •๋œ ํ˜„์žฌ ๊ฐ’์„ ์„œ๋ฒ„์— ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.

DataManager = {}

local Players = game:GetService("Players") 
local DataStoreService = game:GetService("DataStoreService") 

-- ์ €์žฅํ•˜๊ฑฐ๋‚˜ ๋ถˆ๋Ÿฌ์˜ฌ ๋‹ค์–‘ํ•œ ๋ฐ์ดํ„ฐ ํƒ€์ž… ์ •์˜
local PlayerData =
{
    { Name = "PlayerGold", InitValue = 0, Store = nil },
}

for i = 1, #PlayerData do
    PlayerData[i].Store = DataStoreService:GetDataStore(PlayerData[i].Name) 
end

--------------------------------------------------------
-- ํ˜„์žฌ ๊ฐ’์„ ์„œ๋ฒ„์—์ €์žฅํ•ฉ๋‹ˆ๋‹ค.
function DataManager:SavePlayerData(player)
    repeat wait() until player:GetAttribute("IsDataLoaded")    
    
    print(player, "> SavePlayerData")        
    
    local text = ">>>> Save : "
    
    for i = 1, #PlayerData do
        local playerData = PlayerData[i]
        local store = playerData.Store        
        
        local success, errorMessageOrLoadValue = pcall(function()
            -- ํ”Œ๋ ˆ์ด์–ด์˜ Attribute ๊ฐ’์„ ์ฝ๊ณ  ์„œ๋ฒ„์— ์ €์žฅ
            local currentValue = player:GetAttribute(playerData.Name)
            
            store:SetAsync(player.UserId, currentValue) 
            
            return currentValue
        end)
    
        if not success then
            text = text .. "errorMessage : " .. errorMessageOrLoadValue
        else
            local loadValue = errorMessageOrLoadValue
            
            if i > 1 then
                text = text .. ", "
            end
            text = text .. player.Name .. " / Save " .. playerData.Name .. " : " .. tostring(loadValue)
        end
    end
            
    print(player, text)
end
-- ํ”Œ๋ ˆ์ด์–ด๊ฐ€ ๊ฒŒ์ž„์„ ๋– ๋‚  ๋•Œ ์ž๋™ ์ €์žฅ ์ฒ˜๋ฆฌ
Players.PlayerRemoving:Connect(function(player) DataManager:SavePlayerData(player) end)

--------------------------------------------------------
-- ์„œ๋ฒ„์— ์ €์žฅ๋œ ๊ฐ’์„ ๋ถˆ๋Ÿฌ์˜ต๋‹ˆ๋‹ค.
function DataManager:LoadPlayerData(player)
    print(player, "> LoadPlayerData")    
    
    local text = ">>>> Load : "    
    
    for i = 1, #PlayerData do
        local playerData = PlayerData[i]
        local store = playerData.Store        
        
        local success, errorMessageOrLoadValue = pcall(function()            
            return store:GetAsync(player.UserId)
        end)
    
        if not success then
            text = text .. "errorMessage : " .. errorMessageOrLoadValue
        else
            local loadValue = errorMessageOrLoadValue
            
            -- ์ €์žฅ๋œ ๊ฐ’์ด ์—†์œผ๋ฉด ์ดˆ๊ธฐ๊ฐ’(InitValue)์„ ์„ค์ • ํ›„ ์„œ๋ฒ„์— ์ €์žฅ
            if loadValue == nil then      
                loadValue = playerData.InitValue    
                            
                store:SetAsync(player.UserId, loadValue) 
            end    
            
            -- ๋ถˆ๋Ÿฌ์˜จ ๊ฐ’์„ ํ”Œ๋ ˆ์ด์–ด์˜ Attribute๋กœ ์„ค์ •
            player:SetAttribute(playerData.Name, loadValue)
            
            if i > 1 then
                text = text .. ", "
            end
            text = text .. player.Name .. " / Load " .. playerData.Name .. " : " .. tostring(loadValue)
        end
    end
    
    player:SetAttribute("IsDataLoaded", true)
    
    print(player, text)
end

--------------------------------------------------------
-- ํ”Œ๋ ˆ์ด์–ด๊ฐ€ ๊ฒŒ์ž„์— ์ž…์žฅ์‹œ, ๋ฐ์ดํ„ฐ๋ฅผ ๋ถˆ๋Ÿฌ์˜ต๋‹ˆ๋‹ค.
local function LoadPlayerDataWhenEnter(player)
    local function onAddCharacter(character)
        print(player.Name ..  " LoadPlayerDataWhenEnter")    
        
        DataManager:LoadPlayerData(player)    
    end
    player.CharacterAdded:Connect(onAddCharacter)    
end
Players.PlayerAdded:Connect(LoadPlayerDataWhenEnter)

--------------------------------------------------------
-- ๋ฐ์ดํ„ฐ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ ์˜ˆ์ œ
local function LoadExample(player)
    DataManager:LoadPlayerData(player)
end

-- ๋ฐ์ดํ„ฐ ์ €์žฅํ•˜๊ธฐ ์˜ˆ์ œ
local function SaveExample(player)        
    -- ์ €์žฅ ์ „์— ๊ฐ’ ๋ณ€๊ฒฝํ•˜๋Š” ์˜ˆ์ œ ์ฝ”๋“œ
    for i = 1, #PlayerData do
        local playerData = PlayerData[i]
        
        local currentValue = player:GetAttribute(playerData.Name)         
        
        if currentValue ~= nil then
            local newValue = currentValue + 1
            
            player:SetAttribute(playerData.Name, newValue) 
        end
    end        
    
    DataManager:SavePlayerData(player)
end

  • LoadPlayerDataWhenEnter(player)

    • ํ”Œ๋ ˆ์ด์–ด๊ฐ€ ๊ฒŒ์ž„์— ์ ‘์†ํ•˜๋ฉด ํ˜ธ์ถœ\

  • DataManager:LoadPlayerData(player)

    • ์„œ๋ฒ„์—์„œ ์ €์žฅ๋œ ํ”Œ๋ ˆ์ด์–ด ๋ฐ์ดํ„ฐ๋ฅผ ๋ถˆ๋Ÿฌ์˜ด(GetAsync)

      • ์ €์žฅ๋œ ๊ฐ’์ด ์—†์œผ๋ฉด ์ดˆ๊ธฐ๊ฐ’(InitValue)์„ ์„ค์ • ํ›„ ์„œ๋ฒ„์— ์ €์žฅ

      • ๋ถˆ๋Ÿฌ์˜จ ๊ฐ’์„ ํ”Œ๋ ˆ์ด์–ด์˜ Attribute๋กœ ์„ค์ •\

  • DataManager:SavePlayerData(player)

    • ํ”Œ๋ ˆ์ด์–ด์˜ Attribute ๊ฐ’์„ ์ฝ๊ณ  ์„œ๋ฒ„์— ์ €์žฅ(SetAsync)

    • PlayerRemoving ์ด๋ฒคํŠธ๋ฅผ ํ†ตํ•ด ํ”Œ๋ ˆ์ด์–ด๊ฐ€ ๊ฒŒ์ž„์„ ๋– ๋‚  ๋•Œ ์ž๋™ ์ €์žฅ ์ฒ˜๋ฆฌ

ํ™œ์šฉ ์˜ˆ์‹œ

DataStore์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๊ฑฐ๋‚˜ ๋ถˆ๋Ÿฌ์˜ฌ ๋•Œ Key ๊ฐ’์„ ์–ด๋–ป๊ฒŒ ์„ค์ •ํ•˜๋А๋ƒ์— ๋”ฐ๋ผ ๊ฐœ๋ณ„ ์œ ์ € ๋ฐ์ดํ„ฐ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๊ฒŒ์ž„ ์ „์ฒด ๋ฐ์ดํ„ฐ๋ฅผ ๊ด€๋ฆฌํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด, Key ๊ฐ’์„ Player.Name ๋Œ€์‹  RaceGameLeaderBoard์™€ ๊ฐ™์€ ํ˜•์‹์œผ๋กœ ์„ค์ •ํ•˜๋ฉด, ํŠน์ • ํ”Œ๋ ˆ์ด์–ด์˜ ๋ฐ์ดํ„ฐ๊ฐ€ ์•„๋‹Œ ์„œ๋ฒ„์— ์ €์žฅ๋œ ๋žญํ‚น ์ •๋ณด๋ฅผ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด๋Ÿฌํ•œ ๋ฐฉ์‹์œผ๋กœ, ๋ฆฌ๋”๋ณด๋“œ, ์ด๋ฒคํŠธ ์ง„ํ–‰ ์ƒํƒœ, ์„œ๋ฒ„ ์„ค์ • ๋“ฑ๊ณผ ๊ฐ™์€ ๊ฒŒ์ž„ ์ „์—ญ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๊ณ  ๋ถˆ๋Ÿฌ์˜ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํผ๋ธ”๋ฆฌ์‹œ ๋ฐ ํ…Œ์ŠคํŠธ ํ™˜๊ฒฝ์˜ ๋™์ž‘ ์ฐจ์ด

ํผ๋ธ”๋ฆฌ์‹œ ํ›„ ๋ชจ๋ฐ”์ผ ํ™˜๊ฒฝ์—์„œ๋Š” ์‹ค์ œ ์„œ๋ฒ„์— ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๊ณ  ๋ถˆ๋Ÿฌ์˜ต๋‹ˆ๋‹ค. ๋ฐ˜๋ฉด, ์ŠคํŠœ๋””์˜ค ํ…Œ์ŠคํŠธ ํ™˜๊ฒฝ์—์„œ๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ๋กœ์ปฌ์— ์ž„์‹œ ์ €์žฅํ•˜๋ฉฐ, ์ŠคํŠœ๋””์˜ค ์ข…๋ฃŒ ์‹œ ํ•ด๋‹น ๋ฐ์ดํ„ฐ๋Š” ์ž๋™์œผ๋กœ ์‚ญ์ œ๋ฉ๋‹ˆ๋‹ค.

์ฃผ์˜ ์‚ฌํ•ญ

  • ๋ฐ์ดํ„ฐ ๋กœ๋”ฉ์ด ์™„๋ฃŒ๋˜๊ธฐ ์ „์— ํ”Œ๋ ˆ์ด์–ด๊ฐ€ ๊ฒŒ์ž„์„ ์ง„ํ–‰ํ•˜๋ฉด ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ, ๋กœ๋”ฉ์ด ์™„๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ๋กœ๋”ฉ UI๋ฅผ ํ‘œ์‹œํ•˜์„ธ์š”.

  • ์ €์žฅํ•  ๋ฐ์ดํ„ฐ๋Š” ๊ฐ€๊ธ‰์  ์ž‘๊ณ  ๋‹จ์ˆœํ•œ ๊ตฌ์กฐ๋กœ ์„ค๊ณ„ํ•˜์„ธ์š”.

  • ๊ณผ๋„ํ•œ ์š”์ฒญ์€ ๋ฐ์ดํ„ฐ ์ €์žฅ ์‹คํŒจ๋ฅผ ์œ ๋ฐœํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ, ์งง์€ ์‹œ๊ฐ„ ๋‚ด ๋ฐ˜๋ณต ์ €์žฅ์„ ๋ฐฉ์ง€ํ•˜์„ธ์š”.

    • API ํ˜ธ์ถœ์€ ๋ถ„๋‹น 150ํšŒ๋ฅผ ์ดˆ๊ณผํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์ดˆ๊ณผ ์š”์ฒญ์‹œ ์„œ๋ฒ„์— ์ œํ•œ์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ๊ฐ‘์ž‘์Šค๋Ÿฌ์šด ๊ฒŒ์ž„ ์ข…๋ฃŒ๋‚˜ ์„œ๋ฒ„ ์ถฉ๋Œ๋กœ ์ธํ•ด ๋ฐ์ดํ„ฐ๊ฐ€ ์†์‹ค๋  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ์ฃผ๊ธฐ์ ์œผ๋กœ ๋ฐ์ดํ„ฐ๊ฐ€ ์ €์žฅ๋˜๋„๋ก ๊ตฌํ˜„ํ•˜์„ธ์š”.

  • ์ €์žฅ ๋˜๋Š” ๋ถˆ๋Ÿฌ์˜ค๊ธฐ๊ฐ€ ์‹คํŒจํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ, pcall์„ ์‚ฌ์šฉํ•˜์—ฌ ์˜ค๋ฅ˜๋ฅผ ๋ฐฉ์ง€ํ•˜๊ณ  ์žฌ์‹œ๋„ ๋กœ์ง์„ ์ถ”๊ฐ€ํ•˜์„ธ์š”.

Previous๊ฒŒ์ž„ ๊ณ ๋„ํ™”NextํŠธ์œˆ

Last updated 26 days ago

๐Ÿ“