Get proper position between two bricks given a percentage

Hello there. I will try to make this as short as possible. Basically, I have this flag (FlagModel) and two extra bricks which indicate positions (UpPosition and DownPosition). I also have an IntValue which is called Percentage. This value holds numbers from 0 to 100.

What I am trying to do is whenever the Percentage value is changed, if the value is 50% or less, then it will position the flag where it should be positioned based on the percentage. Also, the flag is going from the UpPosition to the DownPosition. For example, if the percentage is 45%, then the flag should be 90% done reaching the DownPosition, so it would be close to the DownPosition. If the percentage is 10% on the other hand, the flag should be 20% done reaching the DownPosition, so it would be close to the UpPosition, and so on.

I can easily get that percentage (you can simply do Percentage.Value * 2), but I can’t get the overall math right in order to position it where it’s supposed to be. It seems to be somewhat working because it does go from the top to the bottom, it just does it the moment the percentage is 1%, so I am guessing something is wrong with the final CFrame value. Here is the code:

local Success4, ErrorMessage4 = coroutine.resume(coroutine.create(function()
	Percentage.Changed:connect(function(Change)
		if Percentage.Value =< 50 then
			local PercentageNumber = Percentage.Value
			local PercentageValue = ((PercentageNumber * 2) * 0.01)
			local A = (UpPosition.CFrame - DownPosition.Position)
			local B = Vector3.new(0, PercentageValue, 0)
			local C = (A * B)
			local NewCFrame = CFrame.new(UpPosition.Position - C)
			local Tween = TweenService:Create(FlagModel, TweenInfo.new((TimeToClaim / 100), Enum.EasingStyle.Linear, Enum.EasingDirection.InOut), {CFrame = NewCFrame})
			Tween:Play()
		end
	end)
end))

Also, here is footage of the code somewhat working:

Image from Gyazo

If you could help, that would be amazing. Thank you for your time.

3 Likes

1.
Maybe it would be good for you, to understand what usage that coroutine does for you - or actually “not do”.

local Success4, ErrorMessage4 = coroutine.resume(coroutine.create(function()
	Percentage.Changed:connect(function(Change)
		-- ...
	end)
end))

What reason do you have for using the coroutine.resume(coroutine.create(..) in this particular case?

There is nothing in that anonymous function you show, that even need being run inside a coroutine, so you could just remove that part, and only keep the Percentage.Changed:Connect(...) - it will do exactly the same.

2.
Are you absolutely sure you did a verbatim copy-paste of your code?

if Percentage.Value =< 50 then

That =< operator does not exist, so maybe you meant <= for equal-or-less-than?

3.
For the actual logic/math problem, where you want 50 to equal UpPosition.Position, and 0 to equal DownPosition.Position, your calculations looks almost correct.

Though I would urge you to use some more better names than A, B and C.

Lets see. Maybe it is your calculation ’ UpPosition.Position - C ’ that is wrong, due to you want ‘50’ (i.e. 100%) to be equal to the UpPosition, yet you subtract that 100% of C from UpPosition.Position.

So perhaps you should use DownPosition.Position as the “position of reference” for adding the position-offset (i.e. C) to?:

if (Percentage.Value <= 50) and (Percentage.Value >= 0) then
  -- Calculate the difference between the Up and the Down part's positions
  local UpDownDifferenceVector = (UpPosition.Position - DownPosition.Position)

  -- Due to '50' should equal 100% of the UpDownDifferenceVector (and '0' equals 0%),
  -- we calculate a position offset from the UpDownDifferenceVector.
  local PositionOffsetVector = UpDownDifferenceVector * (Percentage.Value / 50)

  -- As our 'position of reference' is the DownPosition.Position, we add the calculated
  -- position offset to that, which should result in the Position we want to Tween towards.
  local Goal = { Position = ( DownPosition.Position + PositionOffsetVector ) }
  -- ...
end
3 Likes

I don’t particularly understand your problem. but if i want to answer your title. i will tell you simply to use the Vector3 function called Lerp.
Position = StartPosition:Lerp(EndPosition, Percentage)
This function will return a position between the start and end position depending on the percentage. where 0 is the first position, and 1 is the end position, and 0.5, you guessed, it will be in the middle.

3 Likes

Thank you for the reply. Hopefully, I’ll answer some of your questions.

I was originally going to use a loop but quickly changed my mind and made it a change event. I will probably remove it since it isn’t needed.

In my normal script, I have it check for it is less than 50 instead of less than or equal to 50. Because I assumed that someone would say something like, "In order to be less than or equal to 50, you need to use the <= operator, so after making this topic, I edited the code and included the equal sign, which I placed in the wrong spot. That was my bad.[quote=“Decker004, post:2, topic:561337”]
For the actual logic/math problem, where you want 50 to equal UpPosition.Position , and 0 to equal DownPosition.Position , your calculations looks almost correct.

Actually, I want the exact reverse, but that’s alright. I want to so when it is at 0, it is on the top, and when it is at 50, it is at the bottom. I tried multiple ways, but all ended up just shooting the flag up/down whenever it reached 1% or more.

I hope I answered your questions. Thanks for the reply.

2 Likes

This works perfectly. I totally forgot Lerp existed. Thank you a lot for the help.

1 Like