Does anyone know what I can use to load parts from the original base to another? When you save your base and parts on it in a specific place and then load them on another base with different coordinates, how can I make the parts teleport to that new base’s coordinates with accuracy since they don’t seem to do that?
Can you be more specific about what you mean by base? From what I understood you are trying to make some kind of level editors or tycoon. For that you’ll need to use functions such as Model:PivotTo() to be able to move and place models instead of moving one by one every parts. The PivotTo() functions takes in a CFrame value. CFrame is a bit like Vector3 but it’s more relative to the part itself. It uses the same concept as Vector3 aka x, y, and z values. Note that the PivotTo() function will most likely take the PrimaryPart to decide the position of the model (if there is one). If you would like to rotate the model at the same time too you could add another parameter which is CFrame.Angles. Here for example my base is called “Base” the syntax to achieve a positioning and rotation of that base would be like this:
Base:PivotTo(CFrame.new(x, y, z) * CFrame.Angles(x, y, z)).
In the CFrame.Angles, the parameters are just offsets from the original rotation of the model. Also the values given in CFrame.Angles are in radians so if you would prefer to use degrees, you could put your rotation values enclosed into this math function: math.rad(value in degrees goes here). I hope this helps! If you have any other questions please feel free to ask.
What I exactly mean is, when you save a part on a base and then load that part on a different base that has a different position, you can’t get the part to load on that base rather than it goes on the old base.
I may be able to provide a video if you need.
I would really like to get a video to have a better understanding. When you say changing base do you mean closing the game and then loading in a new base or still have it in the same game session? Also moving the parts accurately would require having the same sizes from base to another to be able to set a “reference” point from which the parts will be moved and rotated.
I think the issue here is you might have accidently set an offset from the original position of where you want to make the parts appear. Could you provide me the code you’re using to place the parts in the workspace?
I do not have any offset, I only save the position and size. As you saw in the video the part loads to the previous base.
Could I see your code to try to figure out the issue?
In the code I noticed that you saved the positions in the local storage but as I mentionned earlier the problem is since the base position is relative, you might have to get a certain reference point in the base from where the parts are placed. For example you could decide to chose the middle of the base as a reference point and then calculate the distance of each part from the middle and then store that value inside the storage instead of the actual position of the part. When the data is retrieved again the program will use the middle as a reference point and place every parts from the saved distances in each one.
So basically something like a temporary offset that does not save? And also I tried doing something similar to that but I failed could you show me how can I attach them to my script?
Sure I’ll try to make a little demo in a video with a few explanations and I’ll post it here soon.
You could’ve just put them in the code, I know it may sound a little off but that way I can see what you mean quicker and easier for you but I think it might be okay to send a video too, although most of the times I prefer them in the code directly.
Alright if you just want it in code I could just update your code as follow. I added comments of where I did some modifications. I don’t know what’s the structure of your workspace and models and elements but I made a few assumptions. Feel free to modify the code to how you would prefer it.
local DataStoreS = game:GetService("DataStoreService")
local datastore = DataStoreS:GetDataStore("TestSave1")
local players = game:GetService("Players")
local oldReferencePoint = workspace.BaseInfo.Base1.ReferencePart.Position
local newReferencePoint
--[[
Here you create a part and put it in the middle for example. We will use this part
as a reference point to then place all the other parts. We also create a newReferencePoint
which is undefined
]]--
local function save(player: Player)
print("Saving")
local key = player.UserId
local tableToSave = {}
local success, results = pcall(function()
for i,obj: BasePart in ipairs(game.Workspace.BaseInfo.Base1:GetChildren()) do
if obj:IsA("BasePart") then
table.insert(tableToSave, {
obj.Name,
obj.Size.Y,
obj.Size.X,
obj.Size.Z,
oldReferencePoint.X - obj.CFrame.Position.X,
oldReferencePoint.Y - obj.CFrame.Position.Y,
oldReferencePoint.Z - obj.CFrame.Position.Z
})
--[[
In this table instead of actually saving the part's coordinates we will use
the part's distance from the referencePoint
]]--
datastore:SetAsync(key,tableToSave)
print(1)
local LastSavedBase = player.LastBase.Value
local HasBase = player.HasBase.Value
local PlayerInfo = {}
table.insert(PlayerInfo,{
LastSavedBase,
HasBase
})
datastore:SetAsync(key.."Values",PlayerInfo)
local lol = datastore:GetAsync(key.."Values")
print(lol)
end
end
end)
if success then
print("success")
else
print("no" ,results)
end
end
--[[
Assign a value to your newReferencePoint somewhere in this function based on how your
procedure works
]]--
local function load(player: Player)
local key = player.UserId
local success, err
local data
repeat
success, err = pcall(function()
data = datastore:GetAsync(key)
end)
until success or not players:FindFirstChild(player.Name)
if not data then return end
if success then
for i, obj in ipairs(data) do
local newPart = Instance.new("Part")
newPart.Name = obj[1]
newPart.Size = Vector3.new(obj[2],obj[3],obj[4])
newPart.Parent = workspace.BaseInfo.Base1
newPart.CFrame = CFrame.new(newReferencePoint.X - obj[5], newReferencePoint.Y - obj[6], newReferencePoint.Z - obj[7])
--[[
Here you assign the new coordinate values of each object based on your newReferencePoint which
is the middle of the new base
]]--
end
else
print("fail", err)
end
end
game.Players.PlayerRemoving:Connect(save)
--game.Players.PlayerAdded:Connect(load)
--game:BindToClose(function()
-- for i, plr: Player in ipairs(players:GetPlayers()) do
-- save(plr)
-- end
--end)
I also didn’t define newReferencePoint in your code but I left a comment to tell you to decide where to put it. If you don’t put it. The code won’t work.
Do I put the new part in the middle of the base that is the new reference point?
Yes. Like I said the reference point could be anywhere as long as it’s relative position from the base is always the same from one base to another. So if you put the point in the top right corner in the next base it’ll have to be in top right corner.
Can’t I just set it with the same position as the base? Even increasing the Y axis a bit.
Every base-plate should have a partwith a name like “Base_Root” so when you load all the parts, before you actually make them create an attachment with the offset position you saved you can get the EXACT WorldPosition of all the parts. Altough this is probably inefficient it should work.
Yes you can do that. I just though that you had a bunch of part but now that you tell me that the base is a part, yes you can do that. But remember to use the distance thing I used. So you could declare oldReferencePoint as follow:
local oldReferencePoint = (Path to your base).Position
For the newReferencePoint you can use the same thing but for the new base.
It’s actually called PrimaryPart and yes it does work. It’s pretty much the equivalent of what I did but simpler. I didn’t want to give the PrimaryPart idea because I didn’t know the base was actually a part, I though it was just a model so I just told him to assign the coordinates with a part he wants to add himself to the base.
im kinda confused, i hope this is correct: