Hello,
So, I basically know how to serialize objects, but this time, I wanted to save an object which is not found in the replicated storage, it is just created using Ray.new
and other stuff.
I tried looking for tutorials and I found nothing, so any help?
Local Script:
local UIS = game:GetService("UserInputService")
local RunService = game:GetService("RunService")
local Player = game.Players.LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()
local Mouse = Player:GetMouse()
local Counter = 1
local Grid = 4
local Toggle = false
local PointA = script.Point:Clone()
local PointB = script.Point:Clone()
local PosA
local PosB
local LRA
function Round(Num, To)
return math.floor(Num / To + 0.5) * To
end
RunService.RenderStepped:Connect(function()
if Mouse.Target then
if Mouse.Target.Name == Mouse.Target.Name ~= "Baseplate" and Mouse.Target.Name ~= "LargePlotBanBox" then
if Toggle then
if Counter == 1 then
PointA.Parent = workspace
PosA = Vector3.new(Round(Mouse.Hit.p.X, Grid), 0, Round(Mouse.Hit.p.Z, Grid))
PointA.CFrame = CFrame.new(PosA) + Vector3.new(0,4,0)
PointA.Orientation = Vector3.new(0, 90, -90)
elseif Counter == 2 then
PointB.Parent = workspace
PosB = Vector3.new(Round(Mouse.Hit.p.X, Grid), 0, Round(Mouse.Hit.p.Z, Grid))
PointB.CFrame = CFrame.new(PosB) + Vector3.new(0,4,0)
PointB.Orientation = Vector3.new(0, 90, -90)
if LRA then
LRA:Destroy()
LRA = nil
end
local Mag = (PosA - PosB).magnitude
local ray = Ray.new(PosA, (PosA - PosB).unit * Mag)
local part, position = workspace:FindPartOnRay(ray, workspace.BuildingPlace, false, false)
local beam = Instance.new("Part", workspace)
beam.Name = "WallPreview"
beam.BrickColor = BrickColor.new("Shamrock")
beam.FormFactor = "Custom"
beam.Material = "Neon"
beam.Transparency = 0.25
beam.Anchored = true
beam.Locked = true
beam.CanCollide = false
local distance = (PosA - position).magnitude
beam.Size = Vector3.new(0.3, 10, distance)
beam.CFrame = CFrame.new(PosA, position) * CFrame.new(0, 0, distance / 2) + Vector3.new(0,4,0)
LRA = beam
end
end
end
end
end)
Mouse.Button1Down:Connect(function()
if Toggle then
if Counter == 1 then
Counter = 2
elseif Counter == 2 then
Counter = 1
game.ReplicatedStorage.Events.GenerateObjectsEvents.generateWall:FireServer(PosA, PosB, game.ReplicatedStorage.PlotName.Value)
LRA:Destroy()
PointA:Destroy()
PointB:Destroy()
PointA = script.Point:Clone()
PointB = script.Point:Clone()
end
end
end)
script.Parent.MouseButton1Click:Connect(function()
Toggle = true
script.Parent.Parent.Parent.Parent.BuildButtons:TweenPosition(UDim2.new(0, 0,1, 0), "In", "Sine", 0.3)
script.Parent.Parent.Parent.Parent.OBJButtons:TweenPosition(UDim2.new(0, 0,0.838, 0), "In", "Sine", 0.3)
script.Parent.Parent.Parent.Parent.ObjHelp.Visible = true
script.Parent.Parent.Parent.Parent.Collisions.Visible = true
script.Parent.Parent.Parent.Parent.PaintButton.Visible = false
script.Parent.Parent.Parent.Parent.DeleteButton.Visible = false
script.Parent.Parent.Parent.Parent.ShowOBJMoney.Visible = true
end)
UIS.InputBegan:Connect(function(Input)
if Input.KeyCode == Enum.KeyCode.X and Toggle then
script.Parent.Parent.Parent.Parent.BuildButtons:TweenPosition(UDim2.new(0, 0,0.838, 0), "In", "Sine", 0.3)
script.Parent.Parent.Parent.Parent.OBJButtons:TweenPosition(UDim2.new(0, 0,1, 0), "In", "Sine", 0.3)
script.Parent.Parent.Parent.Parent.ObjHelp.Visible = false
script.Parent.Parent.Parent.Parent.Collisions.Visible = false
script.Parent.Parent.Parent.Parent.PaintButton.Visible = true
script.Parent.Parent.Parent.Parent.DeleteButton.Visible = true
script.Parent.Parent.Parent.Parent.ShowOBJMoney.Visible = false
if LRA then
LRA:Destroy()
end
PointA:Destroy()
PointB:Destroy()
PointA = script.Point:Clone()
PointB = script.Point:Clone()
Toggle = false
Counter = 1
end
end)
Script:
game.ReplicatedStorage.Events.GenerateObjectsEvents.generateWall.OnServerEvent:Connect(function(player, PosA, PosB, plot)
local Mag = (PosA - PosB).magnitude
local ray = Ray.new(PosA, (PosA - PosB).unit * Mag)
local part, position = workspace:FindPartOnRay(ray, workspace.BuildingPlace, false, false)
local beam = Instance.new("Part", plot.placedObjects)
beam.Name = "RegularWall"
beam.BrickColor = BrickColor.new("Medium stone grey")
beam.FormFactor = "Custom"
beam.Material = Enum.Material.SmoothPlastic
beam.Transparency = 0
beam.Anchored = true
beam.Locked = false
beam.CanCollide = true
local distance = (PosA - position).magnitude
beam.Size = Vector3.new(0.3, 10, distance) + Vector3.new(0,0,.25)
beam.CFrame = CFrame.new(PosA, position) * CFrame.new(0, 0, distance / 2) + Vector3.new(0,4,0)
end)
Serializing script:
-- 1. Data Save
-- 1.1 Get Plot
local players = game:GetService("Players")
local replicatedStorage = game:GetService("ReplicatedStorage")
local argument = "Data"
local argument2 = "ReadData"
local plotHandler = require(script.Parent.Parent.ServerModules.PlotHandler)
local remoteRF = replicatedStorage.Events.requestPlot
local function assignPlot(plr)
plotHandler.assignPlot(workspace.Plots, plr)
end
local function requestPlot(plr)
return plotHandler.returnPlot(workspace.Plots, plr)
end
remoteRF.OnServerInvoke = requestPlot
players.PlayerAdded:Connect(assignPlot)
-- 1.2 DataStore
local dataStoreService = game:GetService("DataStoreService")
local dataStore = dataStoreService:GetDataStore("DataSave1")
local tries = 3
local dataloaded = nil
local function serialize(plr)
if dataloaded then
local plot = plotHandler.returnPlot(workspace.Plots, plr)
local key = plr.UserId
local count = 0
local data = {}
for i, obj in ipairs(plot.placedObjects:GetChildren()) do
table.insert(data, {
["name"] = obj.Name,
["transform"] = {
["x"] = obj.PrimaryPart.CFrame.X;
["y"] = obj.PrimaryPart.CFrame.Y;
["z"] = obj.PrimaryPart.CFrame.Z;
["r"] = obj.PrimaryPart.Orientation.Y;
["r2"] = obj.PrimaryPart.Orientation.X;
["paintableR"] = obj:WaitForChild("Paintable1").Color.R;
["paintableG"] = obj:WaitForChild("Paintable1").Color.G;
["paintableB"] = obj:WaitForChild("Paintable1").Color.B
}
})
end
local success, err
repeat
success, err = pcall(function()
dataStore:SetAsync(key, data)
end)
count = count + 1
until count >= tries or success
if not success then
warn("Data could not be set." .. tostring(err))
return
end
else
game.ReplicatedStorage.Events.DataGUI:FireClient(plr, argument)
return
end
end
local function deserialize(plr)
local plot = plotHandler.returnPlot(workspace.Plots, plr)
local key = plr.UserId
local count = 0
local data
local success, err
repeat
success, err = pcall(function()
data = dataStore:GetAsync(key)
end)
count = count + 1
until count >= tries or success
if not success then
warn("Failed to read data." .. tostring(err))
game.ReplicatedStorage.Events.DataGUI:FireClient(plr, argument2)
wait(17)
plr:Kick("Failed to read data. Please rejoin the game.")
return
end
if data then
local plot = plotHandler.returnPlot(workspace.Plots, plr)
for i, saved in ipairs(data) do
local loadedModel = replicatedStorage.Objects:FindFirstChild(saved.name):Clone()
if loadedModel then
loadedModel:SetPrimaryPartCFrame(CFrame.new(saved.transform.x, saved.transform.y, saved.transform.z)*CFrame.Angles(0, math.rad(saved.transform.r), 0))
loadedModel.Paintable1.BrickColor = BrickColor.new(saved.transform.paintableR, saved.transform.paintableG, saved.transform.paintableB)
loadedModel.Parent = plot.placedObjects
else
return
end
end
dataloaded = true
else
dataloaded = true
end
end
-- 1.3 Remove objects and set values to nil
local function unloadTycoonData(plr)
local plot = plotHandler.returnPlot(workspace.Plots, plr)
serialize(plr)
for _, obj in ipairs(plot.placedObjects:GetChildren()) do
obj:Destroy()
end
plot.Owner.Value = nil
plot.OwnerName.Value = ""
plot.Plot.Size = Vector3.new(450,0.1,450)
for i, parts in pairs(plot.Banbox:GetChildren()) do
if parts:IsA("BasePart") then
parts.Transparency = 0
parts.CanCollide = true
end
end
-- Remove banboxes
for i, parts in pairs(plot.LargePlotBanbox:GetChildren()) do
if parts:IsA("BasePart") then
parts.Transparency = 1
parts.CanCollide = false
end
end
for i, parts in pairs(plot.Banbox:GetChildren()) do
if parts:IsA("BasePart") then
parts.Transparency = 1
parts.CanCollide = false
end
end
end
-- 1.4 Connect functions
-- On player added, load data and assign player's plot.
players.PlayerAdded:Connect(deserialize)
-- Player removing, save data.
players.PlayerRemoving:Connect(unloadTycoonData)
-- When servers are shut down.
game:BindToClose(function()
for i, plr in ipairs(players:GetPlayers()) do
serialize(plr)
end
end)
Thank you.