Better way for checking Object types

Hi!

With me coming close to completing my building system, I only have a few more issues as I code.

Now, I need to complete server placement, but I cant find a way ot check the object types, besides IsA, and that wont work in my situation, Roblox should probably add IsA globals support.

Here’s the code:
If I do IsA, I get “attempt to index nil with IsA” and if i do Object[1], I get attempt to index nil with number.

local ReplicatedStorage = game:GetService("ReplicatedStorage")

local Remotes = ReplicatedStorage:WaitForChild("PlotStorage"):WaitForChild("Remotes")
local PlaceItemServer = Instance.new("RemoteEvent")
PlaceItemServer.Parent = Remotes
PlaceItemServer.Name = "PlaceItem"


local ItemsFolder = ReplicatedStorage.Assets.Data.Furniture

PlaceItemServer.OnServerEvent:Connect(function(player, Object)	
	--[[
	Object 1 is the type of part
	Object 2 is the parts name
	Object 3 is the parts CFrame
	Object 4 is the parts size
	]]
	if Object:IsA("Part") then
		local Part = Instance.new("Part")
		Part.Shape = "Block"
		Part.Name = Object.Name
		Part.CFrame = Object.CFrame
		Part.Size = Object.Size
	elseif Object:IsA("WedgePart") then
		local Part = Instance.new("WedgePart")
		Part.Name = Object.Name
		Part.CFrame = Object.CFrame
		Part.Size = Object.Size
	elseif Object:IsA("MeshPart") then
		local Part = Instance.new("MeshPart")
		Part.Name = Object.Name
		Part.CFrame = Object.CFrame
		Part.Size = Object.Size
		Part.MeshId = Object.MeshId
	elseif Object:IsA("UnionOperation") then
		local Part = Instance.new("UnionOperation")
		Part.Name = Object.Name
		Part.CFrame = Object.CFrame
		Part.Size = Object.Size
	end
end)

Thanks for any help!

1 Like

Why don’t you make separate remotes? Why are you using the PlaceItem remote event for something other than placing items?

Use a for loop. Like so:

PlaceItemServer.OnServerEvent:Connect(function(player,Object)
for i,v in pairs(Object) do
   if v:IsA("Part") then
      -function
   elseif v:IsA("WedgePart") then
      -Next function
   end
end

So on and so forth.

1 Like

That’s only what I’m using this remote for.

Object is a single part, unless it’s a model.

? I’m having a hard time understanding what PlaceItemServer is actually for. Why would you pass an object instead of the name of it? Why would you pass a CFrame?

I’m not passing any of that. If you read the code wou would have seen I’m passing the player, and object placed on the localplayer’s plot

Then what’s this? By the looks of it, you’re firing the remote 4 times, each time giving a different type.

1 Like

That was an idea, I’m not actually passing that stuff through.

Can you show the bit of the local script firing the remote event?

1 Like

image

Well, anyway, you shouldn’t be passing objects through remotes. You should be passing an identifier, for example

--Localscript
PlaceItem:FireServer("Door")

--Regular script
PlaceItem.OnServerEvent:Connect(function(Player, Item)
    if Item == "Door" then
        --Place door
    end
end)
1 Like

                           SendToServer(Part)
1 Like

Probably use ipairs instead

But now that I read the script a little more. Make a the script fire a different identifier for each type of block.

The only thing I can think of is that you aren’t actually passing the part to the function. Try printing the Item on the client in that function. Also, the player argument in fire server is unnecessary.

Edit: Did you create the part on the client?

If you create a part on the client and try pass it to the server, the server won’t know about your part. You must have the server create the instance instead of the client.

It may not be faster, but it is shorter.

local ReplicatedStorage = game:GetService("ReplicatedStorage")

local Remotes = ReplicatedStorage:WaitForChild("PlotStorage"):WaitForChild("Remotes")
local PlaceItemServer = Instance.new("RemoteEvent")
PlaceItemServer.Parent = Remotes
PlaceItemServer.Name = "PlaceItem"


local ItemsFolder = ReplicatedStorage.Assets.Data.Furniture
local ACCEPTED_CLASSES = {
	"Part",
	"WedgePart",
	"MeshPart",
	"UnionOperation"
}

local SPEICAL_ADJUSTMENTS = {
	["Part"] = function(Part)
		Part.Shape = "Block"
	end,
	
	["MeshPart"] = function(Part, Object)
		Part.MeshId = Object.MeshId
	end,
}

local function CREATE_PART(Object, OBJECT_CLASS)
	local Part = Instance.new(OBJECT_CLASS)
	Part.Name = Object.Name
	Part.CFrame = Object.CFrame
	Part.Size = Object.Size
	
	if SPEICAL_ADJUSTMENTS[OBJECT_CLASS] then
		SPEICAL_ADJUSTMENTS[OBJECT_CLASS](Part, Object)
	end
	
	return Part
end

PlaceItemServer.OnServerEvent:Connect(function(player, Object)	
	local CLASS_NAME = Object.ClassName
	if table.find(ACCEPTED_CLASSES, CLASS_NAME) then
		CREATE_PART(Object, CLASS_NAME)
	end
end)

Based on this I’m assuming your not firing the right information over to the server from the client. Show the RemoteEvent:FireServer() if you can.

You don’t need to pass the Player over the remote event. The .OnServerEvent automatically takes the player who fired the remote as the first argument:

someRemoteEvent.OnServerEvent:Connect(function(playerWhoSent)
    print(playerWhoSent.Name)
end)
1 Like

I’m going to try @deafaultyboii1324 's solution right now.

image