I want to script something like this but dont know where to start

I want to create a script whereas there is a part, (we can call this part1) typically at the place the player spawns at and there would be another part (we can call this part2) a certain distance away from the part at the players spawn, and the player has a intvalue inserted inside them and so the intvalue increases when going closer to part2, and when they go closer to part1 their intvalue decreases. If they are standing directly on part1 their value would be 0 but if they are standing directly on part2 their intvalue should be the full distance part1 is away from part2. i want this script to only work when the player is between the positions of part1 and part2, i already know how to make the parts and the intvalue inside the player but how would i be able to create a script like this?

2 Likes

something like this, the player starts at part1 and then when it gets closer to part2 their intvalue should increase and going backwards to part1 decreases their intvalue
Screenshot 2024-08-25 204453
Screenshot 2024-08-25 204503

5 Likes

I’m not the best with CFrames, but you could try subtracting the character’s CFRame from the second part and get the intvalue relative to that.

4 Likes

Magnitude

3 Likes

what does the magnitude mean? sorry if i sound dumb im still fairly new to scripting on roblox

1 Like

It’s when you subtract 2 different positions and get the distance between them as a number

2 Likes

Magnitude is the distance between two parts in the workspace. Lets say part1 is 5 studs above part2. Then (part1.Position - part2.Position).Magnitude = 5 but the Vector would be Vector3.new(0,5,0)

2 Likes

Now as for this type of script, I would do this, it’s quite simple

game.Players.PlayerAdded:Connect(function(plr)
   local distance = Instance.new('NumberValue',plr)
   distance.Name = 'Distance'
end)
   for i, Player in ipairs(game.Players:GetPlayers()) do
    RunService.Heartbeat:Connect(function(_: number): ()
        distance.Value = (Player.Character.HumanoidRootPart.Position - part1.Position).Magnitude
    end);
end;

So every frame we’re basically changing the distance value to the distance between the player and the part. You could store the distance between part2 and part1 in a variable and do stuff depending on the distance value and that variable

3 Likes

Make sure to use NumberValue instead of IntValue, as the distance between the player and the part may not always be a whole number.
Another quick add-on is that if you ever require the direction from the part to the player, use (Target - Origin).Unit, in this case being (Player - Part).Unit

2 Likes

Yeah I did the second one, but the first one is a good tip. Thanks for the feedback :+1:

3 Likes

Using a for loop inside a function which gets called every Heartbeat is not ideal, as it impacts performance.
You can spawn a thread for each player or just invert the logic.

for i: number, Player: Player in ipairs(game.Players:GetPlayers()) do
    RunService.Heartbeat:Connect(function(_: number): ()
        distance.Value = (Player.Character.HumanoidRootPart.Position - part1.Position).Magnitude
    end);
end;

Erratum: fixed a typo

2 Likes

Lol. Quite easy to find out unoptimized parts in my code since Im bad at it :fire:

2 Likes

It’s alright lol, you’ll learn how to spot performance blocks in your code eventually.

2 Likes

How can i make it so the value doesnt decrease when the player goes backwards so instead its only able to increase?

1 Like

Then we would simply have to add the distance they moved

game.Players.PlayerAdded:Connect(function(plr)
   local distance = Instance.new('NumberValue',plr)
   distance.Name = 'Distance'
end)
   for i, Player in ipairs(game.Players:GetPlayers()) do
    RunService.Heartbeat:Connect(function(_: number): ()
        distance.Value +=  (Player.Character.HumanoidRootPart.Position - part1.Position).Magnitude - distance.Value
    end);
end;
3 Likes

Ok, i implented it and it works so thank you for the help :+1:

Hi there, if the post works for you mark it as the solution to close the topic, thank you :+1:

2 Likes

also, one more part, when the player dies how can i make it so the value of the distance the player had gets added on when they die? like for example the player has 1000 distance then they die meaning theyd go back to the spawn point which is 0 distance, i want them to keep their 1000 distance and when they go again their new distances gets added on to that 1000, like if the player starts moving away from the distance again after they die then they would have something like 1200 or 1050 distane since its added on from their last death

For this we need one more value called ‘TotalDistance’ which you will not touch in the heartbeat function. Then just a small fix to the run service connection

game.Players.PlayerAdded:Connect(function(plr)
   local basedistance = Instance.new('NumberValue',plr)
  basedistance.Name = 'BaseDistance'
   local totaldistance = Instance.new('NumberValue',plr)
   totaldistance.Name = 'TotalDistance'
end)
   for i, player in ipairs(game.Players:GetPlayers()) do
    RunService.Heartbeat:Connect(function(_: number): ()
        player.BaseDistance.Value +=  (player.Character.HumanoidRootPart.Position - part1.Position).Magnitude - player.BaseDistance.Value
        player.TotalDistance.Value += player.BaseDistance.Value
    end);
end;

So if you want the total distance the player travelled just reference the total distance

I tried the script, but when i implented it the total distance value just kept increasing infinitely without stopping for some reason when the character wasnt even moving
Screenshot 2024-08-27 063650
Screenshot 2024-08-27 063655
Screenshot 2024-08-27 063702