-
What do you want to achieve?
In my game, players can add furniture inside their ships. The ships move with the furniture inside them smoothly (without any performance issues) -
What is the issue?
The Issue comes in saving a furniture’s Y-axis. The Y axis is either a few studs bellow what is should be, or a few studs above. Each furniture piece has a (0.1, 0.1, 0.1) sized invisible part at the very lowest part of the furniture piece. It is the Primary part of all furniture models. This part is used to gather the X, Y, Z, and Y rotation of the furniture. This goes well, except for the Y-axis positioning. -
What solutions have you tried so far?
- I tried saving the positions with the ship’s Orientation being
0,0,0
with no difference - I tried using
Ship.Hull:ToObjectSpace(CFrame.new(Furniture.PrimaryPart.Position)))
instead ofShip.Hull:ToObjectSpace(CFrame.new(Furniture.PrimaryPart.CFrame)))
with again, no solution. - Furniture is loaded in by cloning a furniture item with the same name in ReplicatedStorage, and adding the saved positions with the ship’s Hull
Things to note:
- the furniture is not in the workspace if the player is not inside the ship
- The Furniture is welded to the ship
- The ship’s network owner is the server unless if someone is driving the ship (still happens no matter what the network owner is)
here is a chunk of code on the server side, which saves furniture positions. Again, this saves the X and Z axis normally. But has issues with saving the Y axis
game.ReplicatedStorage.Remotes.Functions.PlaceFurniture.OnServerEvent:Connect(function(player, name, pos, oren, furnCFrame)
if player.DataStoreFolder.InteriorCheck.Value == true and player.DataStoreFolder.PlayerFurniture:FindFirstChild(player.DataStoreFolder.PlayerInfoFolder.ShipSpawned.Value.ShipClass.Value).SlotAt.Value < 60 then
local Hull = player.DataStoreFolder.PlayerInfoFolder.ShipSpawned.Value.Hull
if player.DataStoreFolder.PlayerFurniture:FindFirstChild(Hull.Parent.ShipClass.Value).SlotAt.Value <= 60 then -- checks if a player has an open slot value (max 60 furniture per ship) and if the player is inside their ship (so they cant place items outside their ships)
player.DataStoreFolder.PlayerFurniture:FindFirstChild(name).Value = player.DataStoreFolder.PlayerFurniture:FindFirstChild(name).Value -1
local furniture = game.ReplicatedStorage.Furniture:FindFirstChild(name):Clone()
furniture.Parent = player.DataStoreFolder.PlayerInfoFolder.ShipSpawned.Value.FurnitureValue.Value
furniture.Highlight:Destroy()
print(furniture.Name)
furniture.rot.Parent = workspace
workspace.rot.Orientation = oren
furniture:SetPrimaryPartCFrame(workspace.rot.CFrame)
furniture:SetPrimaryPartCFrame(CFrame.new(pos))
local found = false
local Saved = player.DataStoreFolder.PlayerFurniture:FindFirstChildWhichIsA("StringValue")
local weld = Instance.new("Weld")
weld.Part0 = player.DataStoreFolder.PlayerInfoFolder.ShipSpawned.Value.Hull
weld.Part1 = furniture:FindFirstChild(name)
weld.Parent = furniture:FindFirstChild(name)
weld.C0 = Hull.CFrame:toObjectSpace(furniture:FindFirstChild(name).CFrame) * CFrame.Angles(0,0,0)
weld.C1 = CFrame.new()
Hull.Anchored = false
player.DataStoreFolder.PlayerFurniture:FindFirstChild(player.DataStoreFolder.PlayerInfoFolder.ShipSpawned.Value.ShipClass.Value).SlotAt.Value = player.DataStoreFolder.PlayerFurniture:FindFirstChild(player.DataStoreFolder.PlayerInfoFolder.ShipSpawned.Value.ShipClass.Value).SlotAt.Value+1
local Serial = Instance.new("ObjectValue") -- has an object value representing the slot it takes, so when the furniture is deleted, it can be referenced from the furniture
Serial.Name = "SerialInstance"
Serial.Parent = furniture
Serial.Value = player.DataStoreFolder.PlayerFurniture:FindFirstChild(player.DataStoreFolder.PlayerInfoFolder.ShipSpawned.Value.ShipClass.Value):FindFirstChild("Slot"..player.DataStoreFolder.PlayerFurniture:FindFirstChild(player.DataStoreFolder.PlayerInfoFolder.ShipSpawned.Value.ShipClass.Value).SlotAt.Value)
for i, V in pairs(furniture:GetChildren()) do
if V:IsA("MeshPart") or V:IsA("Part") or V:IsA("WedgePart") or V:IsA("UnionOperation") then
V.Anchored = false
end
end
local org
org = Hull.Orientation
Hull.Orientation = Vector3.new(0,180,0) -- saves furniture with this orientation
for i, V in pairs(player.DataStoreFolder.PlayerFurniture:FindFirstChild(Hull.Parent.ShipClass.Value):GetChildren()) do -- finds an open slot in the player's furniture folder to save data
if V:IsA("StringValue") then
if V.Value == "" and found == false then
found = true
local Saved = V -- Saved is the stringvalue which is a furniture slot. PositionX, PositionY, PositionZ are it's children and are what the positions are relative to the ship
local g = Hull.CFrame:ToObjectSpace(CFrame.new(furniture.pos.Position))
Saved.PositionX.Value = -g.X
Saved.PositionY.Value = g.Y
Saved.PositionZ.Value = g.Z
Saved.Rotation.Value = workspace.rot.Orientation.Y
Saved.Value = name
Saved.Parent = player.DataStoreFolder.PlayerFurniture:FindFirstChild(Hull.Parent.ShipClass.Value)
end
end
end
Hull.Orientation = org
end
workspace.rot:Destroy()
end
end)
here is some footage: https://youtu.be/wPyoD4G8zLc