Roblox-如何在roblox数据存储中存储大型阵列

时间:2018-09-24 19:19:45

标签: roblox

我正在尝试制作一个游戏,让玩家创建自己的建筑物,然后可以将其保存以供其他玩家观看和玩。但是,roblox不允许我存储整个创作所需的所有数据(每个积木有多个属性) 我得到的只是这个错误代码: 104:无法在DataStore中存储数组

任何帮助将不胜感激!

3 个答案:

答案 0 :(得分:0)

我不确定这是否是最好的方法,但这是我的尝试。下面是一个表的示例,您可以使用表存储多个值。我认为您可以使用HttpService的JSONEncode函数将表转换为字符串(希望可以更有效地保存它们)

JSONEncode(将砖块的数据放入字符串中,您可以将其保存到数据存储区中

local HttpService = game:GetService("HttpService")

-- this is an example of what we'll convert into a json string
local exampleBrick = {
    ["Size"] = Vector3.new(3,3,3),
    ["Position"] = Vector3.new(0,1.5,0),
    ["BrickColor"] = BrickColor.new("White")
    ["Material"] = "Concrete"
}

local brickJSON = HttpService:JSONEncode(exampleBrick)
print(brickJSON)

-- when printed, you'll get something like
-- { "Size": Vector3.new(3,3,3), "Position": Vector3.new(0,1.5,0), "BrickColor": BrickColor.new("White"), "Material": "Concrete"}
-- if you want to refer to this string in a script, surround it with two square brackets ([[) e.g. [[{"Size": Vector3.new(3,3,3)... }]]

JSONDecode(读取字符串并将其转换回砖块)

local HttpService = game:GetService("HttpService")
local brickJSON = [[ {"Size": Vector3.new(3,3,3), "Position": Vector3.new(0,1.5,0), "BrickColor": BrickColor.new("White"), "Material": "Concrete"} ]]

function createBrick(tab)
    local brick = Instance.new("Part")
    brick.Parent = <insert parent here>
    brick.Size = tab[1]
    brick.Position= tab[2]
    brick.BrickColor= tab[3]
    brick.Material= tab[4]
end

local brickData = HttpService:JSONDecode(brickJSON)
createBrick(brickData) --this line actually spawns the brick

如果要考虑任何可能的数据存储错误,也可以将该函数包装在pcall中。

将整个模型编码为字符串

假设玩家的“建筑物”是模型,则可以使用上述编码脚本将模型中的所有部分转换为json字符串进行保存。

local HttpService = game:GetService("HttpService")
local StuffWeWantToSave = {}

function getPartData(part)
    return( {part.Size,part.Position,part.BrickColor,part.Material} )
end

local model = workspace.Building --change this to what the model is
local modelTable = model:Descendants()
for i,v in pairs(modelTable) do
    if v:IsA("Part") or v:IsA("WedgePart") then
        table.insert(StuffWeWantToSave, HttpService:JSONEncode(getPartData(modelTable[v])))
    end
end

将字符串解码为整个模型

这可能在服务器加载播放器的数据时发生。

local HttpService = game:GetService("HttpService")
local SavedStuff = game:GetService("DataStoreService"):GetDataStore("blabla") --I don't know how you save your data, so you'll need to adjust this and the rest of the scripts (as long as you've saved the string somewhere in the player's DataStore)

function createBrick(tab)
    local brick = Instance.new("Part")
    brick.Parent = <insert parent here>
    brick.Size = tab[1]
    brick.Position= tab[2]
    brick.BrickColor= tab[3]
    brick.Material= tab[4]
end

local model = Instance.new("Model") --if you already have 'bases' for the players to load their stuff in, remove this instance.new
model.Parent = workspace

for i,v in pairs(SavedStuff) do
    if v[1] ~= nil then
        CreateBrick(v)
    end
end

FilteringEnabled

如果您的游戏使用了启用过滤功能,请确保只有服务器才能处理保存和加载数据! (您可能已经知道)如果您想让播放器通过单击gui按钮保存,请使gui按钮触发一个RemoteFunction,将其基础数据发送到服务器以将其转换为字符串。

顺便说一句,我不太擅长编写脚本,所以我可能在某些地方犯了一个错误。.祝你好运

答案 1 :(得分:0)

Crabway的答案是正确的,因为HttpService的{​​{1}}和JSONEncode方法是解决此问题的方法。正如在JSONDecodeDataStoreServicehttps://developer.roblox.com/articles/Datastore-Errors的开发人员参考页上所说的那样。)这说明了您收到的错误,因为您不能简单地将表推入数据存储中。相反,您必须首先使用Data is ... saved as a string in data stores, regardless of its initial type.将表的数据编码为字符串。

尽管我同意Crabway的大部分回答,但我相信函数JSONEncode的行为可能不符合预期。考虑下面的简单示例:

createBrick

如您所见,httpService = game:GetService("HttpService") t = { hello = 1, goodbye = 2 } s = httpService:JSONEncode(t) print(s) > {"goodbye":2,"hello":1} u = httpService:JSONDecode(s) for k, v in pairs(u) do print(k, v) end > hello 1 > goodbye 2 返回的表与原始表一样,使用字符串作为键而不是数字索引。因此,JSONDecode应该这样写:

createBrick

对于编码模型,调用function createBrick(t) local brick = Instance.new("Part") brick.Size = t.Size brick.Position = t.Position brick.BrickColor = t.BrickColor brick.Material = t.Material -- FIXME: set any other necessary properties. -- NOTE: try to set parent last for optimization reasons. brick.Parent = t.Parent return brick end 会产生一个模型子表,然后您可以循环浏览并编码其中的所有属性。请注意,在Crabway的答案中,他仅占GetChildrenPart的部分。您应该使用WedgePart来说明所有零件,还应该使用object:IsA("BasePart")检查并集。以下是一个非常基本的示例,其中我不存储编码的数据;相反,我只是试图显示如何检查必要的情况。

object:IsA("UnionOperation")

对于function encodeModel(model) local children = model:GetChildren() for _, child in ipairs(children) do if ((child:IsA("BasePart")) or (child:IsA("UnionOperation"))) then -- FIXME: encode child else if (child:IsA("Model")) then -- FIXME: using recursion, loop through the sub-model's children. end end return end ,例如userdataVector3,当您使用BrickColor对其进行编码时,您可能希望将它们转换为字符串。

JSONEncode

答案 2 :(得分:0)

我建议@Crabway说什么,使用HttpService。

local httpService = game:GetService("HttpService")
print(httpService:JSONEncode({a = "b", b = "c"}) -- {"a":"b","b":"c"}

但是,如果您有任何UserData值,例如Vector3CFramesColor3BrickColorEnum个项目,请使用此{ {3}}。真的很好。

local library = require(workspace:WaitForChild("JSONWithUserdata"))
library:Encode({Vector3.new(0, 0, 0)})

如果您需要一些文档,请查看脚本中的第一个注释:

-- Defaultio

--[[

    This module adds support for encoding userdata values to JSON strings.
    It also supports lists which skip indices, such as {[1] = "a", [2] = "b", [4] = "c"}

    Userdata support is implemented by replacing userdata types with a new table, with keys _T and _V:
        _T = userdata type enum (index in the supportedUserdataTypes list)
        _V = a value or table representing the value

    Follow the examples bellow to add suppport for additional userdata types.

    ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ 

    Usage example:

        local myTable = {CFrame.new(), BrickColor.Random(), 4, "String", Enum.Material.CorrodedMetal}

        local jsonModule = require(PATH_TO_MODULE)

        local jsonString = jsonModule:Encode(myTable)

        local decodedTable = jsonModule:Decode(jsonString)

--]]