How to make an image appear as a player gets closer to it

Hey there,

I’m trying to make an image/decal become less transparent as a player gets closer to it - thus being visible - using the player’s magnitude in relation to the parented part (transparent).

I’ve used and applied the script by D0RYU and made some adjustments here and there, but to no avail due to receiving an error: ‘Position is not a valid member of Decal “Workspace.Model.Part.Decal”’

Below is my script:

local player = game.Players.LocalPlayer
local LastPosition = nil
local debounce = false

local MinDistance = 0
local MaxDistance = 50
local Image = workspace.Model.Part.Decal

game:GetService("RunService").Heartbeat:Connect(function()
	local character = player.Character or player.CharacterAdded:Wait()
	if character.PrimaryPart == nil then return end
	local humanoidP = character.PrimaryPart
	if humanoidP.Position ~= LastPosition and debounce == false then
		debounce = true
		LastPosition = humanoidP.Position
		if Image then
			local distance = (humanoidP.Position - Image.Position).Magnitude
			Image.Transparency = math.clamp(distance, MinDistance, MaxDistance) / MaxDistance
		end
		debounce = false
	end
end)

This is especially helpful to gradually display an image to indicate the edges of a map’s boundaries without placing a haphazard “invisible barrier”, and I’m sure this topic will be helpful to any developer out there wanting the same thing.

Using decals are not my expertise, nor changing their properties. So I’m really rooting for someone out there to help!

1 Like
local player = game.Players.LocalPlayer
local LastPosition = nil
local debounce = false

local MinDistance = 0
local MaxDistance = 50
local Image = workspace.Model.Part.Decal

game:GetService("RunService").Heartbeat:Connect(function()
	local character = player.Character or player.CharacterAdded:Wait()
	if character.PrimaryPart == nil then return end
	local humanoidP = character.PrimaryPart
	if humanoidP.Position ~= LastPosition and debounce == false then
		debounce = true
		LastPosition = humanoidP.Position
		if Image then
			local distance = (humanoidP.Position - Image.Parent.Position).Magnitude -- Images don't have the position property, closest to it is 2d position relative to container it is in
			Image.Transparency = math.clamp(distance, MinDistance, MaxDistance) / MaxDistance
		end
		debounce = false
	end
end)

That should solve your problem unless the code has other issues in it

2 Likes

Thought I would revive this topic as the current solution does not work. I have had other things prioritised in the past, and this problem was at the bottom of my list.

A player’s capacity to see the image boundaries is entirely luck-dependent, by which a player may see some images, whereas another player cannot see the exact same image in the same place. They may also not be able to see the images entirely.

In the attached videos below, you can clearly see that one player is capable of seeing the images as intended, but the second player cannot:

What is going on?

[Edit: forgot to add my script, which is different from the proposed one above]

local RunService = game:GetService("RunService")
local Character = script.Parent
local Decals = {}
local MaxDistance = 60

local Connection

local function AddMainFrameDecal(MainFrame)
	local OutOfBounds = MainFrame:WaitForChild("OutOfBounds")
	local WarningBarriers = OutOfBounds:WaitForChild("WarningBarriers")
	for i, barrier in ipairs(WarningBarriers:GetChildren()) do
		Decals[barrier] = barrier:WaitForChild("Part"):WaitForChild("Decal")
	end
	WarningBarriers.ChildAdded:Connect(function(barrier)
		Decals[barrier] = barrier:WaitForChild("Part"):WaitForChild("Decal")
	end)
end

for i, Child in ipairs(game.Workspace.Map:GetChildren()) do
	if Child.Name ~= "MAINFRAME" then continue end
	AddMainFrameDecal(Child)
end

game.Workspace.Map.ChildAdded:Connect(function(Child)
	if Child.Name ~= "MAINFRAME" then return end
	AddMainFrameDecal(Child)
end)

Connection = RunService.Heartbeat:Connect(function(deltaTime)
	for MainFrame, decal in pairs(Decals) do
		local magnitude = (decal.Parent.Position - Character.PrimaryPart.Position).Magnitude
		decal.Transparency = math.min(magnitude / MaxDistance, 1)
	end
end)