Are there any math equations that will give a negative number when outside of a range, and a positive number when inside?
For example, if the range is 0.5 - 0.75, and the input is 0.3 or 0.8, it should return negative. If the input is 0.6 or 0.7, it should return positive.
This is for a script that plays a music track depending on your distance to the target (similar to Forsaken, or Dead by Daylight). Each layer should smoothly blend into the next as you approach the music source.
I know I can do this with if-then logic, and I’ve already done that, but the code is pretty messy and I would like to do something more simple.
i just tried to understand this a second ago. super cool topic!! i may incorporate your idea somewhere down the line.
-- x = magnitude (distance from the music source.)
-- a = range start
-- b = range end
local function insideRangeValue(x, a, b)
local value = (x - a) * (b - x)
local inside = value >= 0 -- boolean. >= 0 means its inside, anything negative is outside
return value, inside
end
this helps a ton thank you ^^ it doesn’t really ease in/out evenly, but it cuts down on a ton of the code’s bulk.
i could probably modify the function to make the easing consistent but i’m not fully sure how to do that lol
yeah, it’ll definitely be a bit rough around the edges. if you’re open to using a function that returns the volume instead, i can write one that smooths out the edges real quick
the smoothing on it seems a lot better, but the output skyrockets a little bit after it leaves the range.
the way the music works right now is that i use this function
function percentage(input, min, max)
return ((input - min)) / (max - min)
end
to get the “closeness” of the player to the monster in the range of its music. if the outer layer starts at 100 studs and i’m 50 studs away, then it sets “closeness” to 0.5.
for example, if the player’s “closeness” is 0.1 and the monster’s first layer of music spans from 0-0.5, then the “layerCloseness” is set to 0.2.
percentage(0.1 0, 0.5) == 0.2
then i check if the the closeness is within the “blend amount”. if it is, i use the percentage function on the layerCloseness and the blend amount to get the final volume.
if layerCloseness is greater than the start of the layer + the blend amount, and less than the end of the layer - the blend amount, then it’s set to 1
this is the code for the blending, it’s just some light math and a ton of if-statements
layer.Percent is the final volume of the layer, and the volumes are set in the next line.
i’ve made it so that there can be any number of layers to a monster’s music, all at arbitrary intervals, just for maximum flexibility.
for i,layer in pairs(layers) do
local layerPercentage;
local firstLayer, lastLayer = i==1, i==#layers
local blendStart, blendEnd = (not firstLayer), (not lastLayer)
layer.Percent = 0
if (firstLayer and lastLayer) then
layerPercentage = eased_closeness
elseif (not lastLayer) then
layerPercentage = percentage(eased_closeness, layer.UnitRadius, layers[i+1].UnitRadius)
else
layerPercentage = percentage(eased_closeness, layer.UnitRadius, 1)
end
if layerPercentage ~= 0 then
if (not blendStart) and (layerPercentage < blendAmount) then
layer.Percent = percentage(layerPercentage, 0, blendAmount)
elseif blendStart and (layerPercentage < blendAmount) then
layer.Percent = percentage(layerPercentage, blendAmount*-1, blendAmount)
elseif blendEnd and (layerPercentage > 1 - blendAmount) then
layer.Percent = 1 - math.clamp(percentage(layerPercentage, 1 - blendAmount, 1 + blendAmount), 0, 1)
elseif (layerPercentage > blendAmount and layerPercentage < 1 - blendAmount) or not blendEnd then
layer.Percent = 1
end
else
layer.Percent = 0
end
layers[i] = layer
end
if there’s a function that can ease from 0-1 and 1-0 in the first/last % of a range, and then smooth back into 0 or a negative number as it goes away from both ends, that could possibly shrink this thing down to a few lines.