0
votes

I'm trying to make it so that when you touch a brick, It'll freeze your character then run a function in a ModuleScript that makes an ImageLabel slowly appear then disappear when your character has been teleported inside/outside of that building. So far, I've managed to make it freeze your character and call the function, but the code to make the Image appear and disappear isn't working. This is the code:

_G.BeginFade = {}

_G.BeginFade.GlobalFunction = function()

`local Image = game.StarterGui.Fade.FadeImage`
Image.Visible = true
repeat
    Image.ImageTransparency = Image.ImageTransparency - 0.1
    wait(0.2)
until
    Image.ImageTransparency == 0
wait(2)
repeat
    Image.ImageTransparency = Image.ImageTransparency + 0.1
until
    Image.ImageTransparency == 1

end

I use _G.BeginFade.GlobalFunction() to call the function, and I call it from a different script. The ModuleScript containing the function is in the StarterGui. It returns this error:

Workspace.Home Teleport.tele2.Teleport pad Script:47: attempt to index field 'BeginFade' (a nil value)

3

3 Answers

0
votes
local player = game.Players.LocalPlayer
local Image = player.StarterGui.Fade.FadeImage
local i = 0 --have i as a stopper for the repeat function, it tends to go over it.
script.Parent.Door1.Touched:connect(function(hit)
if hit.Humanoid ~= nil then
Image.Visible = true
repeat
Image.Transparency = Image.Transparency - 0.1
i = i + 1
wait(0.1)
until i == 10
end
end)

script.Parent.Door2.Touched:connect(function(hit)
if hit.Humanoid ~= nil then
Image.Visible = true
repeat
Image.Transparency = Image.Transparency - 0.1
i = i - 1
wait(0.1)
until i == 0 
end
end)
0
votes

Something you may want to look into is if the global is declared at the time of the function, since if you declare it in a separate thread there is the possibility of it still being nil.

In fact, the error code given has no relation to the code snippet you've given.

If you gave us the entirety of the module and your declarations, then we can give you the direct patch here... But until then just look on if your declarations are synced between threads.

0
votes

The way to correctly do this would be using Modules, because _G is only shared between a specific group / class of scripts.

For example:

In a Server Script:

_G.kek = true;
print(_G.topkek);

In a Client Script:

_G.topkek = false;
print(_G.kek);

Outcome:

server: attempt to index boolean 'topkek': a nil value
client: attempt to index boolean 'kek': a nil value

If you ran this, it would throw a error, because this is not shared between Server and Client boundary, though, it is shared between Client to Client, and Server to Server

For example:

In Server Script 1:

_G.kek = true;
wait(.1); -- add a bit of delay just in case
print(_G.topkek);

In Server Script 2:

_G.topkek = false;
wait(.1); -- same here
print(_G.kek);

Outcome:

server script 1: 'false'
server script 2: 'true'

It is not only this, it also is that you used game.StarterGui instead of using the Player's PlayerGui. And also, you used 'repeat', but witheout a wait(). Using any kind of loop (while true do, repeat until, for i in math.huge) witheout a wait() will cause your game to freeze and crash.

So, to clear everything else up, here is what you should of do:

In a ModuleScript called "fade", located in ReplicatedStorage:

local api = {};

api.BeginFade = function(image)
    local alpha = 30; -- Change this to the number of cycles before fully transparency. Higher = longer time that the image will take to fade in and out.
    image.Visible = true;
    image.ImageTransparency = 1;

    for i = 1, alpha do
        image.ImageTransparency = image.ImageTransparency - 1/alpha;
        wait(); -- We use 'wait()' here to prevent the loop from ending in 0 seconds.
    end;
    wait(0.7); -- I've worked with games that have screens like this, and I believe 0.7 time is better than 2 seconds. Trust me, I've got 200 places. lol
    for i = 1, alpha do
        image.ImageTransparency = image.ImageTransparency + 1/alpha;
        wait();
    end;
    image.ImageTransparency = 1; -- Not necessary too, but works as a 'extra check'.
    return image; -- We gotta return something, right? (not necessary)
end;

return api;

In the script inside the telport pad:

local pad = script.Parent;
local rep = game:service("ReplicatedStorage");
local fade = rep:WaitForChild("fade");
fade = require(fade); -- Extract the table of the Module which contains functions

pad.Touched:connect(function(ht)
    local hit = ht.Parent;
    if hit.ClassName == "Model" then
        if hit:FindFirstChildOfClass("Humanoid")then
            local name = hit.Name;
            local plr = nil;

            for _,v in pairs(game:service("Players"):GetPlayers())do
                if v.Name == name then
                    plr = v;
                end;
            end;
            if plr ~= nil then
                local img = plr.PlayerGui.Fade.FadeImage;
                fade.BeginFade(img);
                wait(0.1); -- Add a bit of cooldown
            end;
        end;
    end;
end);

That should do it in most cases. Though, a exploiter could be able to delete the Fade module, but fixing that requires RemoteEvents and a good amount of free time, and right now I'm running out of time, so I hope my answer helps you.