Now you’re asking for a completely different system (where each player has their own part), the script I provided works with a global part (shared by everyone), when that part is touched its properties change and those changes are saved each time a player leaves the server, fortunately for you, I decided to write an alternate system which creates, saves and loads a unique part for each player, you’ll need to randomize the location of the part by changing this line here.
part.CFrame = CFrame.new(0, 0, 0)
As an added bonus the part’s material is randomised and its color is randomised too, with a fading animation effect between color changes.
Here are the scripts.
--SERVER
local players = game:GetService("Players")
local dataStores = game:GetService("DataStoreService")
local partStore = dataStores:GetDataStore("PartStore")
local replicated = game:GetService("ReplicatedStorage")
local partRemote = replicated.PartRemote
local function loadData(player)
local success, result = pcall(function()
return partStore:GetAsync(player.UserId)
end)
if success then
if result then
if type(result) == "table" then
return result
end
end
else
warn(result)
end
end
local function saveData(player)
local data = partRemote:InvokeClient(player)
local success, result = pcall(function()
return partStore:SetAsync(player.UserId, data)
end)
if success then
if result then
print(result)
return result
end
else
warn(result)
end
end
local function onServerShutdown(player)
for _, player in ipairs(players:GetPlayers()) do
partRemote:InvokeClient(player)
end
end
local function onRemoteInvoked(player, boolean)
if boolean then
return loadData(player)
elseif not boolean then
return saveData(player)
end
end
partRemote.OnServerInvoke = onRemoteInvoked
game:BindToClose(onServerShutdown)
--CLIENT
local players = game:GetService("Players")
local localPlayer = players.LocalPlayer
local tweens = game:GetService("TweenService")
local replicated = game:GetService("ReplicatedStorage")
local partRemote = replicated:WaitForChild("PartRemote")
local materials = {256, 272, 288, 512, 528, 784, 788, 800, 804, 816, 820, 832, 836, 848, 864, 880, 896, 912, 1040, 1056, 1072, 1088, 1280, 1284, 1296, 1312, 1328, 1344, 1360, 1376, 1392, 1536, 1552, 1568, 1584, 1792, 2048}
local debounce = false
local part = Instance.new("Part")
part.Anchored = true
part.Size = Vector3.new(3, 3, 3)
part.CFrame = CFrame.new(0, 0, 0)
part.Parent = workspace
local randomObject = Random.new(tick())
local function onPlayerRemoving(player)
if player == localPlayer then
local partData = partRemote:InvokeServer(false)
end
end
local function onPartTouched(hit)
if debounce then
return
end
local hitModel = hit:FindFirstAncestorOfClass("Model")
if hitModel then
local hitPlayer = players:GetPlayerFromCharacter(hitModel)
if hitPlayer then
if hitPlayer == localPlayer then
debounce = true
part.Material = materials[randomObject:NextInteger(1, #materials)]
local tween = tweens:Create(part, TweenInfo.new(1), {Color = Color3.new(randomObject:NextNumber(), randomObject:NextNumber(), randomObject:NextNumber())})
tween:Play()
local partData = partRemote:InvokeServer(false)
task.wait(10)
debounce = false
end
end
end
end
local function onRemoteInvoked()
local data = {}
data["Color"] = {part.Color.R, part.Color.G, part.Color.B}
data["Material"] = part.Material.Name
return data
end
players.PlayerRemoving:Connect(onPlayerRemoving)
partRemote.OnClientInvoke = onRemoteInvoked
part.Touched:Connect(onPartTouched)
local partData = partRemote:InvokeServer(true)
local color = partData["Color"]
local success, result = pcall(function()
return Color3.new(color[1], color[2], color[3])
end)
if success then
part.Color = result
end
local material = partData["Material"]
local success, result = pcall(function()
return Enum.Material[material]
end)
if success then
part.Material = result
end
This server script goes inside ServerScriptService and the local script goes inside StarterPlayerScripts. This implementation makes use of a a RemoteFunction in order to facilitate back and forth communication between both scripts (between the server and the client). This RemoteFunction instance is named “PartRemote” and should be placed inside the ReplicatedStorage folder.
Here’s a screenshot how everything should be organised.
Finally, here’s the model file for reproduction purposes.
repro.rbxm (3.5 KB)