Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
0

How can I make a GUI Image label change when a certain value is reached?

Asked by 2 years ago

I'm remaking a little temperature bar inside a Roblox place and need help figuring out how I can change a GUI Image Label when the bar reaches a certain value.

Heres what Ive got so far inside the script

local bar = script.Parent
local Meter = script.Parent.Parent.Meter

local barsize = bar.Size.Y.Offset

local Default = "rbxassetid://11946049186"
local Stage2 = "rbxassetid://11946059093"
local Stage3 = "rbxassetid://11946060289"



while barsize >= 0 do
    wait()
    local speed = script.Parent.Speed.Value
    bar.Size = bar.Size - UDim2.new(0,0,0,2)
    print("Bar Moved!")
    wait(speed)
end

I tried making it so that when the bar reaches a certain size it changes the image labels texture to no avail.

I can not figure out what I need to get it to change the image labels texture when reaching a certain value.

0
When you set `barsize` on line 4, that value is now a constant. It represents a snapshot of what bar.Size.Y.Offset was, but not what it is. You must continually update that variable if you want to record change. However, I would avoid using GUI state as a metric for detection as there are better alternatives. ScriptGuider 5640 — 2y

2 answers

Log in to vote
0
Answered by
Klui36 45
2 years ago

You could use something like Meter.Changed:Connect() that fires everytime your value gets changed and after that an if statement checking if your barsize value is the correct number. After that you just paste your stuff.

local bar = script.Parent
local Meter = script.Parent.Parent.Meter

local barsize = bar.Size.Y.Offset

local Default = "rbxassetid://11946049186"
local Stage2 = "rbxassetid://11946059093"
local Stage3 = "rbxassetid://11946060289"

Meter.Changed:Connect(function()
    if barsize >= 0 then
        -- do your stuff
    end
end)

Hope this helps!

Please not that I haven't checked if any of the scripts above are working correctly.

0
Thanks! This didnt work at first but I just had to change a few things and I got it working Creature_Horns 4 — 2y
Ad
Log in to vote
0
Answered by 2 years ago
Edited 2 years ago

So, a few things here:

  • On line 4 you set a variable for storing the Y-offset of your GUI. This variable is now a constant, and will not update as the state of your GUI changes.

    • If you wanted to go this route, you would need to re-assign that variable to the Y-offset continuously with a loop or event of some sort.
  • I notice you have a Meter variable declared at the top of your code, but it's not being used. I'm assuming this is a ValueObject that represents your temperature. If so, you should be using that!

    • (As an aside: 9 times out of 10 you shouldn't need to use ValueObjects for changing state. You can just create the variable in your code and use BindableEvents/Functions to update them across scripts!)

With these considerations in mind, let's break it down from the beginning:

Step 1): Create some state for your temperature bar

Let's start off by creating and grouping some data that is related to the temperature bar:

local meterState = {
    temperature = 0,
    maxTemperature = 120,
    minTemperature = -32,

    stages = {
        stage1 = "rbxassetid://11946049186",
        stage2 = "rbxassetid://11946059093",
        stage3 = "rbxassetid://11946060289"
    }
}

This way you can access all temperature-related data by doing things like meterState.temperature or meterState.stages. I also added a maxTemperature and minTemperature value, because your meter probably doesn't go from infinity to negative infinity.

Step 2): Create some way to update your temperature state

Obviously, you could just update your temperature value by doing something like meterState.temperature += 1, but that still leaves us with quite a few problems, such as updating the GUI.

A good solution to this would be to create a function that updates the temperature value and GUI at the same time!

local bar = script.Parent -- get the GUI bar

local updateTemperature = function(newTemp)
    meterState.temperature = newTemp;

    local min = meterState.minTemperature;
    local max = meterState.maxTemperature;

    bar.Size = UDim2.new(1, 0, 1/(max - min)*(newTemp - min), 0)
end

I'm also throwing a bit of math in there to compute the size of the temperature bar. The 1/(max - min)*(newTemp - min) is a common formula for computing the percentage of a number range when given a certain value in that number range.

I have a YouTube video on this that you can watch here.

Now you can update your temperature value and your GUI at the same time with one function call! For example, this will fill the bar up all the way vertically:

  • updateTemperature(120)

and this will completely shrink the bar vertically:

  • updateTemperature(-32)

Step 3): Apply different images based on temperature

I didn't see you setting any images in your code so I'm not sure where you would want to apply them, so I'm just going to psuedo-code that part: But first, let's add a bit more information to our meterState so we can update our image accordingly with our temperature:

local image = script.Parent.Parent -- wherever your image is

local meterState = {
    temperature = 0,
    maxTemperature = 120,
    minTemperature = -32,

    -- stages are now represented as an array.
    -- the 1st value in the array is the temperature 
    -- minimum needed to activate the image.
    -- the 2nd value is the image.
    stages = {
        { 0, "rbxassetid://11946049186" },
        { 60, "rbxassetid://11946059093" },
        { 100, "rbxassetid://11946060289" }
    }
}

Now, let's add the logic for changing our image once we update the temperature:

local bar = script.Parent -- get the GUI bar
local image = script.Parent.Parent -- wherever your image is

local meterState = {
    temperature = 0,
    maxTemperature = 120,
    minTemperature = -32,

    stages = {
        { 0, "rbxassetid://11946049186" },
        { 60, "rbxassetid://11946059093" },
        { 100, "rbxassetid://11946060289" }
    }
}

local updateTemperature = function(newTemp)
    meterState.temperature = newTemp;

    local min = meterState.minTemperature;
    local max = meterState.maxTemperature;

    bar.Size = UDim2.new(1, 0, 1/(max - min)*(newTemp - min), 0)

    -- get the stages from meterState
    local stages = meterState.stages;

    -- loop over all the stages
    for index = 1, #stages do
        local stage = stages[index];
        local stageMin, stageImg = unpack(stage);

        -- if the current temperature is less-than or equal to
        -- the stage we're checking, then update the image
        -- and break out of the loop.
        if (newTemp <= stageMin) then
            image.Image = stageImg -- update the image
            break;
        end
    end
end

And that's it! Now you can update your temperature through the updateTemperature function and it will handle all of your UI state changes.

If you need to update your temperature through a different script, I recommend looking into bindable events/functions like I mentioned above.

Hope this helps, good luck!

0
Klui36 answered my question but I will be changing my script to work more like the way you wrote it, Thanks for the help! Creature_Horns 4 — 2y

Answer this question