How to use userinputservice in collectionservice?

So, I want to make a script using collection service that is a pickup script. C to pick up. But, how would I be able to incorporate userinputservice into the script without getting an error like indexing player a nil value?

Try it yourself first. There’s no evidence that you’ve attempted this problem yourself, plus this question was just recently asked. Please search first and attempt to work at a problem before posting a thread regarding it. The Scripting Support category is not a venue for you to drop in and ask for code to be supplied to you.

If you need guiding words; these two services are meant to operate separately. CollectionService is merely, as the name states, meant to create a collection of instances with a given tag. UserInputService is meant to, as the name states, handle user input.

Think about your requirements here. You need to have something happen when you press a button, so set up a check for the type of input passed and the key pressed. Is it C? Yes? Move on. How can we get the nearest object of a certain collection to us? Run through the list of objects you get after getting the collection of items with a certain tag. Which one’s nearest and within our grab range? If there’s one, we use that as the object to use our pickup function on.

Oh, sorry, I did it. But I forgot to say that I don’t want to use remote functions(because I’m using a local script) to increase a leaderstat. How else can I do it?
heres my script:

local CS = game:GetService("CollectionService")
local CollectionParts = CS:GetTagged("CollectionParts")
local UIS = game:GetService("UserInputService")

for _, Part in pairs(CollectionParts) do
	Part.ClickDetector.MouseHoverEnter:Connect(function()
		UIS.InputBegan:Connect(function(key)
			if key.KeyCode == Enum.KeyCode.C then
				Part:Destroy()
			end
		end)
	end)
	Part.ClickDetector.MouseHoverLeave:Connect(function()
		Part.Instructions.Enabled = false
	end)
end

In order to change a leaderstat and have it replicate, you are required to use a RemoteEvent. No workaround for that. Anything that can remain on the client-side can stay in the LocalScript, otherwise a remote will be required somewhere.

But then I would need a lot of them, because there are so many different items to pick up. Will that cause lag? Sorry I’m asking these questions, because I don’t want to post too many topics, and I am just new.

You don’t necessarily need a lot of them. One remote is sufficient enough. What do you have in mind that prompts the need to have lots of RemoteEvents: needing one per object? This is unnecessary. Make your code scalable to support an arbitrary number of collectibles.

I don’t really understand what you mean. Can you explain that arbitrary part?

Pretty much he means that you can use one remote event for multiple objects/functions/scripts etc

how would I be able to do that?

You can use arguments on the function of your remote event.

A remote event has multiple “inputs”

Lets say I have a remote event in my replicated storage

This is in a local script

local ARGUMENT_HERE = "TEST"
game.ReplicatedStorage.RemoteEvent:FireServer("ARGUMENT_HERE") --You can put arguments in the ()

On the server script

game.ReplicatedStorage.RemoteEvent.OnServerEvent:Connect(function(player, argument) --Player is always first when receiving a remote event
   print(player)
   print(argument)
end)

The output would be
kingerman88
TEST

1 Like

So in your case where you are trying to add to a leaderstat

local script

local RemoteEvent = game.ReplicatedStorage.RemoteEvent
local CS = game:GetService("CollectionService")
local CollectionParts = CS:GetTagged("CollectionParts")
local UIS = game:GetService("UserInputService")

for _, Part in pairs(CollectionParts) do
	Part.ClickDetector.MouseHoverEnter:Connect(function()
		UIS.InputBegan:Connect(function(key)
			if key.KeyCode == Enum.KeyCode.C then
                RemoteEvent:FireServer()
				Part:Destroy()
			end
		end)
	end)
	Part.ClickDetector.MouseHoverLeave:Connect(function()
		Part.Instructions.Enabled = false
	end)
end

Server script

local RemoteEvent = game.ReplicatedStorage.RemoteEvent

RemoteEvent.OnServerEvent:Connect(function(player)
    player.leaderstats.[leaderstat_name].Value = player.leaderstats.[leaderstat_name].Value + 1 --or any number
end)

Yes, I know how to do that, but pretend I want the argument to be the Name of any part and have that name used in WaitForChild and FindFirstChild functions. But, from my experience, you cannot just have an argument like so:

local name = script.Parent.Part.Name

game.ReplicatedStorage.RE:FireServer(name)

and then I want to make it so that I can use that to find leaderstats

game.ReplicatedStorage.RE.OnServerEvent:Connect(function(player, name)
    local Stats = player.Stats
    if Stats ~= nil then
        local currency = Stats:WaitForChild(name)

or maybe it does work, but I tried it and it doesn’t.
If it is possible can you help me?

Why are you using game.Players[player]?

player is the player object in game.Players

So you can do

player.leaderstats.[leaderstat_name].Value = player.leaderstats.[leaderstat_name].Value + 1 --or any number
1 Like

Good catch! Let me go edit that!

1 Like

So what you are doing in that script is changing the player’s leaderstats value to the name of the part, is that your goal?

yes, that is my goal. 30chars.

Ok, thanks for the clarification!

So lets talk about this script
it looks like the script is kind of cut, could you show a little bit more of the server side
I think I know what you are trying to do

game.ReplicatedStorage.RE.OnServerEvent:Connect(function(player, name)
    local Stats = player.Stats
    if Stats ~= nil then
        local currency = Stats:WaitForChild(name)
        if currency ~= nil then
            currency = currency + 1
and then a bunch of ends
for _, Part in pairs(CollectionParts) do
	Part.ClickDetector.MouseHoverEnter:Connect(function()
		UIS.InputBegan:Connect(function(key)
			if key.KeyCode == Enum.KeyCode.C then
                game.ReplicatedStorage.RE:FireServer(Part.Name) --This is how you send the name of a part
				Part:Destroy()
			end
		end)
	end)
	Part.ClickDetector.MouseHoverLeave:Connect(function()
		Part.Instructions.Enabled = false
	end)
end
game.ReplicatedStorage.RE.OnServerEvent:Connect(function(player, name)
    local Stats = player.Stats
    if Stats ~= nil then
        if Stats:FindFirstChild(name) then
            Stats:FindFirstChild(name).Value = Stats:FindFirstChild(name).Value + 1 --Remember to include Value
        end
    end
end)