Invisibility based off players stat

You can write your topic however you want, but you need to answer these questions:
Hello I am trying to create a script to where if the player has more psychic than you and the event is triggered to go invisible they can still see you at 0.6 transparency but if they have less psychic than u and it’s triggered then they cant see you at all

The issue is it’s only going based off the person in the server with the greatest psychic and least psychic so let’s say a player was in the middle and enabled the invisibility well they can still be seen by the player with the least psychic too because there’s someone in the server with more psychic than them

I’ve tried to get all players individually or update across all clients but haven’t found any help.

This is my server script

local ReplicatedStorage = game:GetService(“ReplicatedStorage”)
local Players = game:GetService(“Players”)

– RemoteEvents
local invisibilityEvent = ReplicatedStorage:WaitForChild(“InvisibilityToggle”)
local updateTransparencyEvent = ReplicatedStorage:WaitForChild(“UpdateTransparency”)

– Function to get the psychic stat of a player
local function getPsychicStat(player)
local physicalStats = player:FindFirstChild(“PhysicalStats”)
if physicalStats then
local psychicStat = physicalStats:FindFirstChild(“Psychic”)
if psychicStat then
return tonumber(psychicStat.Value) or 0
end
end
return 0
end

– Update the transparency of player character from the perspective of viewer
local function updateTransparencyForViewer(viewer, character, shouldBeInvisible, playerPsychic)
local viewerPsychic = getPsychicStat(viewer)

for _, part in pairs(character:GetDescendants()) do
	if part:IsA("BasePart") or part:IsA("Decal") then
		if part.Name ~= "HumanoidRootPart" then
			if playerPsychic > viewerPsychic then
				-- Fully invisible for viewers with a lower psychic stat
				part.Transparency = shouldBeInvisible and 1 or 0
			else
				-- Semi-transparent for viewers with a higher or equal psychic stat
				part.Transparency = shouldBeInvisible and 0.6 or 0
			end
		end
	elseif part:IsA("Accessory") then
		local handle = part:FindFirstChild("Handle")
		if handle and handle:IsA("BasePart") then
			if playerPsychic > viewerPsychic then
				handle.Transparency = shouldBeInvisible and 1 or 0
			else
				handle.Transparency = shouldBeInvisible and 0.6 or 0
			end
		end
	elseif part:IsA("BillboardGui") then
		if playerPsychic > viewerPsychic then
			part.Enabled = not shouldBeInvisible
		else
			part.Enabled = true -- Always visible for viewers with a higher or equal psychic stat
		end
	end
end

end

– Handle the event to toggle invisibility for others
invisibilityEvent.OnServerEvent:Connect(function(player, shouldBeInvisible)
local character = player.Character
if character then
local playerPsychic = getPsychicStat(player)

	-- Update all other players' perspectives of the player
	for _, otherPlayer in pairs(Players:GetPlayers()) do
		if otherPlayer ~= player then
			-- Update transparency for each player based on their psychic stat comparison
			updateTransparencyForViewer(otherPlayer, character, shouldBeInvisible, playerPsychic)
		end
	end

	-- Notify the client to update its own transparency (for the player who toggled invisibility)
	updateTransparencyEvent:FireClient(player, shouldBeInvisible)
end

end)

and this is my local script in startercharacterscripts

– Local Script (StarterPlayerScripts or similar)

local player = game.Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local invisibilityEvent = game.ReplicatedStorage:WaitForChild(“InvisibilityToggle”)
local updateTransparencyEvent = game.ReplicatedStorage:WaitForChild(“UpdateTransparency”)

local isInvisible = false
local localTransparency = 0.6 – Transparency for the local player when invisibility is active

– Function to set transparency locally for the local player
local function setTransparencyForSelf(transparency)
for _, part in pairs(character:GetDescendants()) do
if part:IsA(“BasePart”) or part:IsA(“Decal”) then
if part.Name ~= “HumanoidRootPart” then
part.Transparency = transparency
end
elseif part:IsA(“Accessory”) then
local handle = part:FindFirstChild(“Handle”)
if handle and handle:IsA(“BasePart”) then
handle.Transparency = transparency
end
elseif part:IsA(“BillboardGui”) then
part.Enabled = transparency == 0 – Visible only when transparency is 0
end
end
end

– Function to restore transparency for the local player
local function restoreTransparency()
setTransparencyForSelf(0) – Fully visible
end

– Function to check if Invisibility is equipped
local function isInvisibilityEquipped()
local abilities = player:FindFirstChild(“Abilities”)
local invisibilityEquipped = abilities and abilities:FindFirstChild(“Invisibility”)
return invisibilityEquipped and invisibilityEquipped.Value
end

– Listen for key press (T)
game:GetService(“UserInputService”).InputBegan:Connect(function(input)
if input.KeyCode == Enum.KeyCode.T then
if not isInvisibilityEquipped() then
print(“Invisibility is not equipped.”)
return
end

	isInvisible = not isInvisible

	if isInvisible then
		-- Notify the server to make them invisible to others
		invisibilityEvent:FireServer(true)
	else
		-- Notify the server to make them visible to others
		invisibilityEvent:FireServer(false)
	end
end

end)

– Handle transparency update from server
updateTransparencyEvent.OnClientEvent:Connect(function(shouldBeInvisible)
if isInvisible then
setTransparencyForSelf(localTransparency)
else
restoreTransparency()
end
end)

You can enclose code in three backticks to make it show up as code:
```
print(“hello world!”)
```

(Some formating going on to make that not code.)

print("hello world!")

As for your code, here is how I would structure it. There is no need to check on the server, since the effect is client sided and the instances inside Players are replicated.

Here is a pseudo code outline. This would go in a LocalScript

invisibilityEvent:Connect(function()
    local myStat = -- Get the Players.LocalPlayer's stat (by doing something like Players.LocalPlayer:WaitForChild("IntValue")
    for _, otherPlayer in ipairs(Players:GetChildren()) do
        task.spawn(function()
            -- TODO: Check if the otherPlayer has a valid character
            local otherCharacter = otherPlayer.Character
            local otherStat = -- Get the otherPlayer's stat
            if myStat < otherStat then
                makeCharacterInvisible(otherCharacter)
            else
                makeCharacterSemiInvisible(otherCharacter)
            end
        end
    end
end)

By having the effects on the client, each client can see their own view of the game based on their stats only.

For the transparency, you can also use BasePart.LocalTransparencyModifier, which plays nice with existing transparencies (it combines the Transparency and itself) and is easy to reset by just setting it to 0 in all cases (instead of needing to restore the values of semi-transparent stuff).

Thank you! But curious wouldn’t making the effect only client sided not allow you to be invisible to other players with a lower psychic than you?

The short answer is no. This can be very unintuitive.

Here is an explanation:

Say you had two players, yourself and a friend. Say you had a higher psychic.

When the signal fires on your client, the local script would run, see your friend had a lower psychic, and only make them semi transparent. This would result in you seeing yourself and your friend (but semi-transparent).

However, when the signal on your friend’s client, the local script would run, see you have a higher psychic, and make you invisible on their client. This would result in your friend seeing themselves only, and you would be invisible.


Different clients can be in different states at the same time, so it’s possible for a player to be invisible to some people but not to other by making them invisible on the client.


To answer this specifically, the trick is that while the effect is only client sided, it’s decided and done on every client.

Ah that makes a lot of sense I’ll remember this knowledge for further scripting thank you!

1 Like

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