Different Proximity Hold Durations For Different Players

I’m pretty sure it’s possible, directly or indirectly, as I’ve seen it in another game which inspired me to make my own.
It’s a system where, say, proficiency in doing things. The better you are at it, the faster you can finish it.
So if different players are interacting with the same prompt, the player with the faster hold duration would finish quicker.

Except, I’m not sure how it would be done, and I need help.

Use local script and change hold duration
too ez

2 Likes

Although the ui doesn’t go all the way through, you can just change the proximityprompts HoldDuration to something else on each client, Triggered event will still get called on the server after the user interacts (after the time set on the client), but the ui will still try to show the 5 second hold. In order to tackle that, i’m pretty sure you will have to use a custom ui, i doubt roblox gives any possibilities to change that.

@wiizzzzzzzaaaaard aren’t proximity prompts put into the server’s workspace? I understand that proxes are guis but as a server object how can I change each player’s interaction with it, with a local script nontheless?
Something of such ease must be easy to share, no? I apologize for my seven days of experience.
@lavasance same question for you, as the prox is litterally put in the workspace, and stays there, I’m not sure how each player would be able to interact with it differently, systematically or visually.

image

yes but, that is in the workspace, if I just change it, wouldn’t it change for every single player?

Change it locally on client side;
This way it will not replicate to other players.

Although it’s in the workspace, changes made on the client (e.g. from a LocalScript) will not replicate to other clients. You can test this out yourself by running a localscript on one client that creates a part and by not running it on another client. You’ll see that even though the part is in the workspace, it only exists on the first client’s device.

Here’s what I understand:
Local scripts are client, that’s why guis use them
Here’s what I don’t understand:
Proxes are inside the server, and that value called HoldDuration is inside the object which is inside the workspace which is in the server

Here’s what I now want to ask:
How do I get a prox locally, or alternatively, how do I get multiple proxes locally?
surely it’s not something as simple as
if prox.Name == “insert name here” then
prox.holdduration = insert number

have you even tried what others are saying?
please do :smiling_face_with_tear:

That a devforum moment
People literally have to be spoon fed here

that what you have to do :man_facepalming:

Summary

char limit

LocalScripts can do basically anything a Script can do. The difference is that a local script is purely local, meaning anything it does only affects the local player. This concept serves as a security measure of some sort. There’s a firewall between the actual server and each client. That’s why we have things like remote events so that clients and servers can talk to each other. Read this to get a better idea of how the relationship between server and clients works.

To answer your post question, all you need to do is change the HoldDuration value of the prompts from a local script, and that’ll change the time needed for each player. If I’m understanding what you’re wanting, as a player levels up in some areas, certain prompts become faster. What you should do is set the default speed for each prompt in the studio, and then in a server script, when you load players’ data, you fire a RemoteEvent to the client to change the speed of the prompts to the adjusted speed.
Here’s the server script, probably placed in ServerScriptService.

local event = game.ReplicatedStorage.RemoteEvent

game.Players.PlayerAdded:Connect(function(Player)
	-- Get Player Data
	if Player.Level == "2" then
		local PromptSpeed = 2
		event:FireClient(Player, PromptSpeed)
	end
end)

And then on a local script in StarterPlayerScripts or wherever you’d have.

local event = game.ReplicatedStorage.RemoteEvent

event.OnServerEvent:Connect(function(PromptSpeed)
	workspace.ProximityPrompt.HoldDuration = PromptSpeed
end)
1 Like

Modifications to the above example(thank you very much good ser, that’s not spoon feeding right?)
First off, hierarchy


Server Script

local event = game.ReplicatedStorage.RemoteEvent

game.Players.PlayerAdded:Connect(function(player)
	local part = workspace.Proxpart
	local PromptSpeed = 2
	event:FireAllClients(PromptSpeed, part)

	print("Server fired event to " .. player.Name .. " with speed " .. PromptSpeed .. " and part " .. part.Name)
end)

Client Script

local event = game.ReplicatedStorage.RemoteEvent

event.OnClientEvent:Connect(function(PromptSpeed, part)
	print("Client recieved event variable PromptSpeed: " .. PromptSpeed)
	print("Client recieved event variable part: " .. part)
	part.ProximityPrompt.HoldDuration = PromptSpeed
end)

Quick Note: FireAllClients does not need a player variable.
This would not work as the local script is unable to directly find the referenced part in the workspace, as stated in this error

  05:49:25.965  Server fired event to EeveePikachu54 with speed 2 and part Proxpart  -  Server - Script:8
  05:49:26.011  Client recieved event variable PromptSpeed: 2  -  Client - LocalScript:4
  05:49:26.011  Players.EeveePikachu54.PlayerScripts.LocalScript:5: attempt to concatenate string with nil  -  Client - LocalScript:5

You can see that the print statement in the Server Script ran as expected, whilst the Client Side was unable to read the referenced part, and returned as nil.
This makes spawning a part, then changing it’s duration for each player, much more complicated.

So how about sending the name of the part. This would be a bit strange, as, if you had multiple parts with the same name, the script may not be able to determine which part needs to be found.
But let’s try it anyway.
Server Script

local event = game.ReplicatedStorage.RemoteEvent

game.Players.PlayerAdded:Connect(function(player)
	local partName = workspace.Proxpart.Name
	local PromptSpeed = 2
	event:FireAllClients(PromptSpeed, partName)

	print("Server fired event to " .. player.Name .. " with speed " .. PromptSpeed .. " and part " .. partName)
end)

Client Script

local event = game.ReplicatedStorage.RemoteEvent

event.OnClientEvent:Connect(function(PromptSpeed, partName)
	print("Client recieved event variable PromptSpeed: " .. PromptSpeed)
	print("Client recieved event variable partName: " .. partName)
	local proxpart = workspace:WaitForChild(partName)
	proxpart.ProximityPrompt.HoldDuration = PromptSpeed
end)

This time, the local script succeeds in finding the part in the workspace, as shown below

  05:58:42.576  Server fired event to EeveePikachu54 with speed 2 and part Proxpart  -  Server - Script:8
  05:58:42.624  Client recieved event variable PromptSpeed: 2  -  Client - LocalScript:4
  05:58:42.624  Client recieved event variable partName: Proxpart  -  Client - LocalScript:5

After this, the proximity prompt’s duration was set from 10 to 2.
So how can we apply this in a real project, where there are multiple interactable things, with the same name, and use the same system of reducing proximity time.
Let’s move into one of my projects.



Now, the main point of focus would be in the last “segment” of the server script.

--Some Logic
if itemClone then
	itemClone.Parent = spawner -- Parent the item to the spawner
	itemClone.CFrame = spawner.CFrame
	hasItemValue.Value = true -- Set HasItem to true
				
	itemClone.Name =itemClone.Name .. "_Clone"
	setUpProxDuration:FireAllClients(itemClone.Name)
	print("setUpProxDuration event fired, cloneName variable is: "..cloneName)
	-- print(string.format("Spawned a %s in Spawner: %s", itemClone.Name, spawner.Name))
end
--End of Logic

A possible solution is to rename the item, then do something like, removing “_Clone”, the last 6 characters form the name aftawards.

It’s already solved but here is my solution cuz you said me explain it.


Server:

local A,B = workspace.A,workspace.B
local HoldDurationEvent = game.ReplicatedStorage.HoldDuration


A.Touched:Connect(function(Hit)
	local Player = game.Players:GetPlayerFromCharacter(Hit.Parent)
	HoldDurationEvent:FireClient(Player,"A")
end)

B.Touched:Connect(function(Hit)
	local Player = game.Players:GetPlayerFromCharacter(Hit.Parent)
	HoldDurationEvent:FireClient(Player,"B")
end)

Client:

local HoldDurationEvent = game.ReplicatedStorage.HoldDuration
local Prompt = workspace.Part.ProximityPrompt


HoldDurationEvent.OnClientEvent:Connect(function(Value)
	if Value == "A" then
		Prompt.HoldDuration = 0
		print("Duration = 0")
	elseif Value == "B" then
		Prompt.HoldDuration = 5
		print("Duration = 5")
	end
end)
1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.