Item System for game not fully working

So ive got this game in which you play as a robot with the ability to pickup objects and place them. Currently im using the CollectionService and using tags to handle it all. Everything seems to be working just fine, except for one issue:

Theres supposed to be an Item tag and an ItemHolder tag for things that can hold them. Currently the player character starts with the itemholder tag and it works right. However, thats without the clickdetector stuff (which i only want for non-character itemholders). When i try to place an item onto a model that i put the ItemHolder tag on, it doesn’t place. I checked and the values for the Item.Holder and ItemHolder.HeldItem is working. However, the Motor6D is never being attached. Also im realising now that i should probably use welds instead of Motor6Ds anyways but anyone know why this is? Heres the code:

ServerScriptService.TagScript

local CollectionService = game:GetService("CollectionService")

local GetChild = require(game.ReplicatedStorage.GetChild)

local Connections = {}



function ItemHolderChanged(Item, Value)
	local OldHolder = Item.OldHolder
	
	if OldHolder.Value ~= nil then
		OldHolder.Value.HeldItem.Value = nil
	end
	
	if Value == nil then
		Item.Motor.Part0 = nil
		
		if OldHolder.Value ~= nil then
			local Root = OldHolder.Value.PrimaryPart
			local LookVector = Root.CFrame.LookVector
			Item.PrimaryPart.CFrame = CFrame.new(Root.Position+LookVector*4, Root.Position+LookVector*8000)
		end
	else
		Item.Motor.C0 = Value.HoldCFrame.Value
		Item.Motor.Part0 = Value.PrimaryPart
	end
	
	OldHolder.Value = Value
end

function ItemClicked(Item, Player)
	local Character = Player.Character
	local HeldItem = Character.HeldItem
	
	print("Clicked!")
	
	if Item.Holder.Value == Character then
		Item.Holder.Value = nil
		HeldItem.Value = nil
		return
	end
	
	if (Item.Holder.Value == nil or Item.Holder.Value.CanTake.Value) and HeldItem.Value == nil then
		Item.Holder.Value = Character
		HeldItem.Value = Item
	end
end

function ItemAdded(Item)
	if not Item:IsA("Model") then return end
	
	local Holder = GetChild(Item, "Holder", "ObjectValue")
	local OldHolder = GetChild(Item, "OldHolder", "ObjectValue")
	local ItemId = GetChild(Item, "ItemId", "StringValue")
	local ClickDetector = GetChild(Item, "ClickDetector", "ClickDetector")
	ClickDetector.MaxActivationDistance = 8
	local Motor = GetChild(Item, "Motor", "Motor6D")
	Motor.Part1 = Item.PrimaryPart
	
	Connect(Item, "HolderChanged", Holder.Changed:Connect(function(Value)
		ItemHolderChanged(Item, Value)
	end))
	Connect(Item, "Clicked", ClickDetector.MouseClick:Connect(function(Player)
		ItemClicked(Item, Player)
	end))
end

function ItemRemoved(Item)	
	Disconnect(Item, "Item", "HolderChanged")
	Disconnect(Item, "Item", "Clicked")
end



function ItemHolderHeldItemChanged(ItemHolder, Value)
	
end

function ItemHolderClicked(ItemHolder, Player)
	local Character = Player.Character
	local HeldItem = Character.HeldItem
	
	if not (HeldItem.Value == nil) and ItemHolder.HeldItem.Value == nil then
		ItemHolder.HeldItem.Value = HeldItem.Value
		HeldItem.Value.Holder.Value = ItemHolder
	end
end

function ItemHolderAdded(ItemHolder)
	if not ItemHolder:IsA("Model") then return end
	
	local HeldItem = GetChild(ItemHolder, "HeldItem", "ObjectValue")
	local HoldCFrame = GetChild(ItemHolder, "HoldCFrame", "CFrameValue")
	local CanTake = GetChild(ItemHolder, "CanTake", "BoolValue")
	
	Connect(ItemHolder, "HeldItemChanged", HeldItem.Changed:Connect(function(Value)
		ItemHolderHeldItemChanged(ItemHolder, Value)
	end))
	if ItemHolder:FindFirstChild("Humanoid") == nil then
		local ClickDetector = GetChild(ItemHolder, "ClickDetector", "ClickDetector")
		ClickDetector.MaxActivationDistance = 8
		
		Connect(ItemHolder, "Clicked", ClickDetector.MouseClick:Connect(function(Player)
			ItemHolderClicked(ItemHolder, Player)
		end))
	end
end

function ItemHolderRemoved(ItemHolder)
	Disconnect(ItemHolder, "ItemHolder", "HeldItemChanged")
	Disconnect(ItemHolder, "ItemHolder", "Clicked")
end



function InitCollect(Tag, Added, Removed)
	CollectionService:GetInstanceAddedSignal(Tag):Connect(Added)
	CollectionService:GetInstanceRemovedSignal(Tag):Connect(Removed)
	
	for i, Inst in pairs(CollectionService:GetTagged(Tag)) do
		Added(Inst)
	end
end

function Connect(Inst, Tag, SubTag, Connection)
	if Connections[Tag] == nil then
		Connections[Tag] = {}
	end
	if Connections[Tag][SubTag] == nil then
		Connections[Tag][SubTag] = {}
	end
	Connections[Tag][SubTag][Inst] = Connection
end

function Disconnect(Inst, Tag, SubTag)
	Connections[Tag][SubTag][Inst]:Disconnect()
	Connections[Tag][SubTag][Inst] = nil
end

InitCollect("Item", ItemAdded, ItemRemoved)
InitCollect("ItemHolder", ItemHolderAdded, ItemHolderRemoved)

StarterCharacterScripts.ItemHandler

local GetChild = require(game.ReplicatedStorage.GetChild)

local HoldingAnim = script.HoldingAnimation

local Character = script.Parent
local HeldItem = GetChild(Character, "HeldItem", "ObjectValue")
local Root = Character.HumanoidRootPart
local Humanoid = Character.Humanoid
local Animator = Humanoid.Animator

local HoldingTrack= Animator:LoadAnimation(HoldingAnim)

local OldItem = nil

HeldItem.Changed:Connect(function(Value)
	if Value == nil then
		HoldingTrack:Stop()
	else
		HoldingTrack:Play()
	end
	
	OldItem = Value
end)

ReplicatedStorage.GetChild

return function(Inst, Name, Type)
	local ret = Inst:FindFirstChild(Name) or Instance.new(Type)
	ret.Name = Name
	ret.Parent = Inst
	return ret
end

Footage of it:

I fear i made this overlycomplex and that theres a way simpler way to make an item system that i dont know of

1 Like

If anyone has a solution please help me here. Or if you know a simpler way of going about an item system like this.

1 Like