I have a weapon in replicated storage that is cloned to every player. I have a .Activated listener for the weapon, to detect if its been activated, however, the listener won’t work with all my players. It dosn’t even throw and error in the dev console. Script:
local replicated_storage = game.ReplicatedStorage
local plr = game.Players.LocalPlayer
local combat_remote = replicated_storage:WaitForChild("RemoteEvents"):WaitForChild("Combat")
local debounce = false
local weapon = script.Parent
local function animate(humanoid)
local animations = replicated_storage:WaitForChild("Animations"):GetChildren()
local animation_to_play = animations[math.random(1,#animations)]
humanoid:LoadAnimation(animation_to_play):Play()
end
local function fire_ray(character,distance)
local humanoid_root_part = character:WaitForChild("HumanoidRootPart")
local ray_from_char = Ray.new(humanoid_root_part.Position,(humanoid_root_part.CFrame.LookVector).Unit*distance)
local hit = workspace:FindPartOnRay(ray_from_char,character)
if hit then
if hit.Parent.Name == "Crystal" then
return hit.Parent
elseif hit.Parent.Parent.Name == "Crystal" then
return hit.Parent.Parent
else
return nil
end
end
end
script.Parent.Activated:Connect(function()
print("Activated")
if not debounce then
debounce = true
local humanoid = plr.Character:WaitForChild("Humanoid")
animate(humanoid)
local find_object = fire_ray(plr.Character,3)
if find_object ~= nil then
combat_remote:FireServer(find_object)
end
wait(0.4)
debounce = false
end
end)
If this is a local script, enable it after it has been patented, and disable it before then. Local scripts will only run under a descendant of the player or it’s character, so this is most likely the problem (the script is not running in the first place)
That’s strange. If your weapon is in ReplicatedStorage, then the code shouldn’t be executing period - it’s a storage service, scripts are static. Execution of code is held off until the code enters an appropriate executing environment.
I don’t typically recommend solutions like @REALTimothy0812’s because realistically you shouldn’t be touching the Disabled property. It sounds more like the code isn’t in an expected location or the code isn’t registering something properly.
I’ve previously tried detecting clicks with the script being in starterplayer scripts, that had the same issue of not working for all players aswell.
local replicated_storage = game.ReplicatedStorage
local plr = game.Players.LocalPlayer
local combat_remote = replicated_storage:WaitForChild("RemoteEvents"):WaitForChild("Combat")
local debounce = false
local weapon
local char
local mouse = plr:GetMouse()
if not plr.Character then
repeat wait()
until plr.Character
char = plr.Character
end
char = plr.Character
weapon = char:WaitForChild("Weapon")
local function animate(humanoid)
local animations = replicated_storage:WaitForChild("Animations"):GetChildren()
local animation_to_play = animations[math.random(1,#animations)]
humanoid:LoadAnimation(animation_to_play):Play()
end
local function fire_ray(character,distance)
local humanoid_root_part = character:WaitForChild("HumanoidRootPart")
local ray_from_char = Ray.new(humanoid_root_part.Position,(humanoid_root_part.CFrame.LookVector).Unit*distance)
local hit = workspace:FindPartOnRay(ray_from_char,character)
if hit then
if hit.Parent.Name == "Crystal" then
return hit.Parent
elseif hit.Parent.Parent.Name == "Crystal" then
return hit.Parent.Parent
else
return nil
end
end
end
mouse.Button1Down:Connect(function()
print("Ahhh")
if not debounce then
debounce = true
local humanoid = char:WaitForChild("Humanoid")
animate(humanoid)
local find_object = fire_ray(char,3)
if find_object ~= nil then
combat_remote:FireServer(find_object)
end
wait(0.35)
debounce = false
end
end)
plr.Character.ChildRemoved:Connect(function(z)
if z.Name == "Weapon" then
char = plr.Character
weapon = char:WaitForChild("Weapon")
end
end)
I find that strange. I made a mockup of your StarterPlayerScripts code and it doesn’t seem as though I’ve received any issues. I kept your naming convention for my repro.
local players = game:GetService("Players")
local replicated_storage = game:GetService("ReplicatedStorage")
local player = players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local mouse = player:GetMouse()
local combat_remote = replicated_storage.RemoteEvents.Combat
local debounce = false
local weapon = character:WaitForChild("Weapon")
local function animate(humanoid)
print("animated", humanoid)
end
local function fire_ray(character, distance)
warn("ray fired at", distance, "studs by", character)
end
mouse.Button1Down:Connect(function ()
print("registering mouse click")
if not debounce then
debounce = true
print("beginning combat")
local humanoid = character:WaitForChild("Humanoid")
animate(humanoid)
wait(0.35)
print("ending combat")
debounce = false
end
end)
player.CharacterAdded:Connect(function (new_character)
character = new_character
weapon = character:WaitForChild("Weapon") -- Added this after, forgot it
end)
Did you ever check your console when the code wasn’t working for errors? Did you also try debugging? I can guarantee you that unnecessarily flipping the disabled property of scripts is not a wise solution, especially if you’re just moving something out of a storage service.
The issue comes when multiple people play in an actual roblox server, while some people’s weapon seemed to function perfectly fine, other people’s did not. The weird thing is that there was no errors relating to the weapon, not even any warnings in the dev console when a screenshot was sent to me. I’ve tried a version that dosn’t change any of the disabled properties and the same problem seems to persist. Some people’s work, while others do not.
The weird thing is; If disabling and re-enabling fixes it; Then the local script somehow ran in the first place. This might be another case of studio inconsistencies.
Out of curiosity, what are you doing when you parent? Do you move the tools directly to the player’s backpacks or do you have another in-between amount of code that’s running? I feel like there is something here that is being missed, which is what is causing that to happen.
@REALTimothy0812 The execution doesn’t happen until the LocalScript is in an appropriate container. The tool is initially kept in ReplicatedStorage. Unless the tool visits another place before entering the player’s backpack, not possible.
Alright, to clarify, I’ve did a few changes within this hour. Heres how it functions as of now: There is a script in starter players, which is replicated to every client. When it first runs, it waits for the character, then waits for a tool instance named “weapon”. It then connects a .Activated listener to detect the clicks from the clients. I have a print statement which is meant to print when the weapon is activated. Some people can see that the print statement appears in the dev console, some do not.
That’s really weird. If you add a print at the beginning of the script, does it print? Is the local script itself even running? If you directly parent it, it should be. I’ve never seen this behavior before.
The thing is it seems to be running for some players but not for others. The script isn’t parented to the weapon itself now, it now gets the path to the weapon.
Is there a specific reason why you’re setting up your tools the way you are? I created another repro based off your information and I was just thinking about the oddity of the way the tools are scripted. That aside, again I do not receive any problems and the script functions as expected.
local players = game:GetService("Players")
local player = players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local function on_tool_activated()
print("activated")
end
local function register_tool(character)
local weapon = character:WaitForChild("Weapon")
weapon.Activated:Connect(on_tool_activated)
end
player.CharacterAdded:Connect(function (new_character)
register_tool(new_character)
end)
register_tool(character)
My reasoning for not directly parenting the script to the weapon itself was that it would make and changes to the script hard, as I have multiple weapon I would need to change the script in. By having one script that gets the path of the weapon, its much easier to change it.
Ooh, I think I found it. Borderline XY problem. There’s definitely not an issue in creating tool behaviour like this, but there are many ways (potentially even better ways) to create and consolidate behaviour for tools like this without sacrificing much. I think your specific iteration of it might be hitting an edge case.
Pseudoclass: Create a pseudoclass (OOP in Lua) ModuleScript that handles your tool code. When a tool needs to be registered, make a new object from that class and hook it up to your tool.
Packages: If you have little to no explicit dependencies in your script, packages would do you well to keep the same code across tools and only having the need to update a script once in order for everything else to be updated. You can also use them cross-place and cross-game.
1 Code sample for CollectionService:
local collection_service = game:GetService("CollectionService")
local tool_tag = "Weapon"
local function on_tool_activated()
print("activated")
end
collection_service:GetInstanceAddedSignal(tool_tag):Connect(function (tagged)
if tagged:IsA("Tool") and tagged.Name:lower() == "weapon" then
tagged.Activated:Connect(on_tool_activated)
end
end)
-- Elsewhere
local weapon = character:WaitForChild("Weapon")
collection_service:AddTag(weapon, tool_tag)
Two caveats I can think of with the above code: it isn’t a full repro so filling in the blanks is largely on your part and the code doesn’t account for tools already registered. All in all though, it would be the closest to your conventions without needing to delve into changing your structure majorly, a special demand from using pseudoclasses.
Oh damn. I do not understand any of that at all, oof. I don’t know anything about half the terms that you’ve just stated. I’ve only been coding for around 4 months now you see. Looks like it’ll be a while before I can complete my game project…