字符串在存储中是否一定小于 Vector3 ?

Is a string necessarily smaller than a Vector3 in storage?

我正在 Core 中开发一个系统来保存家具的变换,特别是位置和旋转,它们都是 Vector3 的。我在玩家存储中有这些,所以在某些时候为了保存所有玩家的家具,我想我最终会最大化玩家存储。所以我将所有 Vector3 转换为字符串,使用我发现的 Roblox 脚本的修改版本:

local API = {}

API.VectorToString = function(vec)
    return math.floor(vec.x*100)/100 ..' '.. math.floor(vec.y*100)/100 ..' '.. math.floor(vec.z*100)/100
end

API.StringToVector = function(str)
    local tab = {}
    for a in string.gmatch(str,"(%-?%d*%.?%d+)") do
        table.insert(tab,a)
    end
    return Vector3.New(tab[1],tab[2],tab[3])
end

return API

所以问题是,将所有这些 Vector 转换为字符串是否真的会 space 保存在我的播放器数据存储中?

Vector3 格式很可能比存储的字符串转换更有效。 Vector3 中的每个数字都需要存储 4 个字节,因为每个数字都是 16 位浮点数。通过将 Vector3 值转换为字符串,需要额外的字节(您添加的每个数字都需要一个字节,因为一个字符需要一个字节)。如果您需要将 Vector3 存储为字符串,我建议您使用以下方法。

对于任何想了解计算机如何仅用四个字节存储如此广泛的数字的人,我强烈建议研究 IEEE 754 格式。

Video that explains the IEEE754 Format

您可以使用 string.packstring.unpack 函数将浮点数转换为字节数组作为字符串发送。该方法在发送数据时总共只需要 12 个字节(12 个字符),并且具有大约 5 到 6 个小数点的精度。虽然此方法可能只节省几个字节,但它可以让您 send/save 更精确 numbers/positions.

local API = {}

API.VectorToString = function(vec) 
    --Convert the x,y,z positions to bytes 
    local byteXValue = string.pack('f', vec.x, 0) 
    local byteYValue = string.pack('f', vec.y, 0) 
    local byteZValue = string.pack('f', vec.z, 0) 
    --Combine the floats bytes into one string
    local combinedBytes = byteXValue + byteYValue + byteZValue
    return combinedBytes 
end

API.StringToVector = function(str) 
    --Convert the x,y,z positions from bytes to float values
    --Every 4th byte represents a new float value
    local byteXValue = string.unpack('f', string.sub(1, 4)) 
    local byteYValue = string.unpack('f', string.sub(5, 8)) 
    local byteZValue = string.unpack('f', string.sub(9, 12)) 
    --Combine the x,y,z values into one Vector3 object
    return Vector3.New(byteXValue, byteYValue, byteZValue) 
end

return API

String pack function documentation

它可以写得更短一些,内存分配更少

    local v3 = Vector3.New(111, 222, 333)
    local v3str = string.pack("fff", v3.x, v3.y, v3.z)
    local x, y, z = string.unpack("fff", v3str)
    local v31 = Vector3.New(x, y, z)
    assert(v3 == v31)

但你需要记住,大多数核心 API 函数不允许字符串中出现零字节,如果你想将这些字符串存储在 Storage 中或将它们用作事件参数 - 你应该发短信 -对它们进行编码(Base64 是常见选项)。