I’m custom coding spectator camera controls (essentially noclip / freecam) in my game, but this allows players to use click detectors at any distance. Is there any easier way than looping through each click detector and disabling them? The reason I don’t like disabling and re-enabling them is because of shared control of one property by two scripts which can get messy and lead to unintentional behavior.
In your click event just check if the player’s distance is too far or not and if they are too far then cancel the event. You can also cancel the event if they are spectating as well.
When the player is in spectator mode, you can locally set the max activation distance to 0, but the server must check if the player is in spectator mode to prevent any exploiters from bypassing this on the standard level.
This would lead to the same problem as if I “disabled” them. Currently, I have an event for when spectator mode gets engaged and when it disengages. If I disabled all the click detectors when engaged and re enabled them on disengagement of the spectator system, that would work fine until another script which also has the role of disabling and enabling click detectors dynamically comes along and disables them during spectator mode. When spectator mode is disengaged, the value will be rewrote to something undesired in that instance. Same thing the other way around.
Example in an easier to read bullet point list:
Spectator mode is engaged disabling all click detectors
Another script makes the click detector disabled.
Spectator mode get disengaged, overriding the value set by the other script
Currently, the only way I can think of doing something like this is to create a brand new system similar to the way react handles state where upon the changing of listened values, it updates the properties on the object depending on user code. However, since I used click detectors in many different systems, this would be extremely difficult which was why I was asking if there wasn’t an easier way to just disable the client side ability to use click detectors without modifying actual click detector objects.
That would be an off-topic question but if you want, when we’re done, I could send you a link through a private chat or whatever the equivalent would be on the DevForums. It’s basically a game where two teams fight to destroy their user created space crafts.
The only real options you have to “disable” a ClickDetector is either to destroy it or make it inaccessible to the client, which in itself is not entirely possible since a client can restore controls. I would’ve also suggested throwing a Frame with its Active property set to true, but seeing as you’re making a freecam spectator system, probably not the best idea - it’ll catch right mouse as well. Such is the shortcoming of using objects interfaced on the backend.
Perhaps you may want to think about handling click detection through a custom implementation? It’s not too complicated - just have the mouse click, fire a RemoteEvent and the server receives that event. It voids the usage of ClickDetectors and gives you explicit control over the mouse behaviour.
The above is not a proper solution, but it’s an alternative. I know of no other way to disable ClickDetectors since you don’t have explicit control over its internal behaviour.
After reading through your post and the solutions that others have tried to come up with for you. It seems that your implementation of “Spectator Mode” is simply bad by design. Or in this case the way that you designed it causes collisions. This functionality that you want to disable click detectors would be better handled by default if you just redesigned your “Spectator Mode” just a tiny bit differently to accommodate it from the start.
@radbuglet If it makes you feel any better, I created this place with some scripts to help you with your game. Button Activation.rbxl (19.9 KB)
I hope this helps
There is a gui to change teams to see the results faster. Players on the “Playing” team are allowed to click the bricks on the baseplate. Players on the “Lobby” or “Spectating” team are not allowed to click the bricks. I also added minimal server security to prevent some exploits from occuring.
Apparently ClickDetectors already have a property to handle this for you: ClickDetector | Documentation - Roblox Creator Hub
Edit:
When in spectator mode set the property to 0 to disable the detector. On the server you’ll need to also check the distance since you’re only setting it on the client.
I don’t see how it is bad by design. I created a system to handle different camera states and have two methods to engage and disengage the system. Free cam locks the cursor in the middle of the screen and modifies pitch and yaw through the deltas of the mouse movement. All of this works fine except that cameras without an attached player can trigger click detectors at any distance. I was asking if there was a way to override the behavior of click detectors globally but it seems to me like I would have to modify each one manually so I’m probably going to use a react style listen and update workflow where the update logic can inherit the functionality of click detector disabling in spectate mode.
My issue isn’t that I can’t disable click detectors, it that multiple mechanics would have to share this one property. I didn’t want to code a system to allow for state based updating of an instance but I guess that would be the best way. I’m going to release the code I wrote soon after a bit of framework redesigning.
How have you implemented spectating? If you change the camera’s subject to a part the player can control without a Humanoid, or simply manipulate the camera’s position in the world, you shouldn’t be able to activate ClickDetectors.
Spectating is only possible when the player doesn’t have a character. When the player enters spectating mode, I bind Stepped and Input events to be able to look around and move the camera. To move the camera, I simply change the workspace.CurrentCamera.CFrame.