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
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
Good catch! Let me go edit that!
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)