3D Percentage | calculate how much progress a part advanced

3D Percentage

Calculate how much progress a part advanced

Showcase

In this example, this resource calculates the progress of the player’s advancement in a 3D environment.

Code used
_3DPercentage:SetGroup("Way #1", {Priority = 1})
_3DPercentage:AddPartToGroup(workspace.Path1, "Way #1", {DominantAxis = Enum.Axis.Z})
_3DPercentage:AddPartToGroup(workspace.Path2, "Way #1")
_3DPercentage:AddPartToGroup(workspace.Path3, "Way #1", {DominantAxis = Enum.Axis.Z})
_3DPercentage:AddPartToGroup(workspace.Path4, "Way #1")
_3DPercentage:AddPartToGroup(workspace.Path5, "Way #1", {DominantAxis = Enum.Axis.Z})
_3DPercentage:AddPartToGroup(workspace.Path6, "Way #1")
_3DPercentage:SetGroup("Way #2")
_3DPercentage:AddPartToGroup(workspace.Path7, "Way #2", {DominantAxis = Enum.Axis.Y})

local event = game:GetService("ReplicatedStorage"):WaitForChild("Percentage")
while game:GetService("RunService").Stepped:Wait() do
	for _, player in pairs(game:GetService("Players"):GetPlayers()) do
		if player.Character then
			local progress = _3DPercentage:GetGlobalProgress(player.Character.PrimaryPart)
			progress = math.round(math.clamp(progress or 0, 0, 1) * 100) .. "%"
			event:FireClient(player, progress)
		end
	end
end

Usage

Installation:
In order to set up this resource, just download the model or use require(). You should put it like this:

local _3DPercentage = require(8207443586) -- Or the ModuleScript you have in your game
-- Start using it
_3DPercentage:SetGroup("Way #1")
_3DPercentage:AddPartToGroup(workspace.Path1, "Way #1")
_3DPercentage:AddPartToGroup(workspace.Path2, "Way #1")
while game:GetService("RunService").Stepped:Wait() do
	for _, player in pairs(game:GetService("Players"):GetPlayers()) do
		if player.Character then
			print(_3DPercentage:GetGlobalProgress(player.Character.PrimaryPart))
		end
	end
end

Groups:
To start using this resource, you have to put the parts in groups. They will be tracking the BaseParts that are within their boundaries. This is how this resource works. Example:

You can make and use more than 1 group. For example, if you want to track BaseParts Y position as well:

These are the options you can set for a group:

Key Datatype Default Description
OverlapParams OverlapParams OverlapParams{MaxParts=false, CollisionGroup=Default, FilterDescendantsInstances={}} Contains reusable portions of the spatial query parameters
Priority int 0 Indicates the priority if a place is touching two parts of differents groups at the same time

Parts:
The Instances which are going to track the BaseParts have to be Parts (it will error if you are trying to add another BasePart in a group). Put it them one in front of the other for better results, like this:

Key Datatype Default Description
DominantAxis Axis Enum.Axis.X Indicates how the Part should track BaseParts (for example, if Y then it will calculate from bottom to top).
Order int The order of the parts, following a way (please be careful since this setting can mess up the calculations).

Functions:
This resource includes 8 functions:

void _3DPercentage:AddPartToGroup (Part part, string group, Dictionary Settings)
Adds the given part to a group with the given Settings.

Variant, string _3DPercentage:GetGlobalProgress (Variant place, OverlapParams overlapParams)
Gets the progress of the given BasePart, Vector3 or CFrame considering all the groups in order of their Priority. Since this function ignores all groups’ OverlapParams, you can set it from this function instead (MaxParts property is ignored). It returns the percentage (number or nil) and the group of the touched part.

Dictionary _3DPercentage:GetGroup (string name)
Returns a dictionary with information about the given group.

Dictionary _3DPercentage:GetGroups ()
Returns a dictionary with information about all the groups.

Variant _3DPercentage:GetProgress (Variant place, string group)
Gets the progress of the given BasePart, Vector3 or CFrame if it’s touching a part of the given group (number or nil). It also consider all parts and group Settings.

void _3DPercentage:RemoveGroup (string name)
Removes the given group and all its references.

void _3DPercentage:RemovePartFromGroup (Variant reference, string group)
Removes with the given int or Part the part from the given group.

Dictionary _3DPercentage:SetGroup (string name, Dictionary Settings)
Creates or edits the given group with the given Settings.


Known bugs

  • For some reason, the percentage will be less than 0 or greater than 1 sometimes, to solve this use math.clamp(percentage, 0, 1).

Changelog

v1.0.1
  • This resource now counts the objects themselves of the passed array when using OverlapParams.FilterDescendantsInstances property.
v1.0.0
  • Released

Feel free to comment if you have any questions. :smiley:

11 Likes

Pretty cool module. Nice work, I might use this.

2 Likes

Here is the file of the place if you want to test this resource. (Updated to the newest version)

Test.rbxl (34.9 KB)

I published it because I couldn’t upload the video.

Poll

Requesting a change.

Should I keep _3DPercentage:GetGlobalProgress function?
  • Yes
  • No. Merge it with _3DPercentage:GetProgress function

0 voters


Thank you! The poll is closed.
Result: No changes were made.

v1.0.1 Released

Please update to the newest version.

Details:

Roblox Version 2
Uploaded 12/11/2021

Changes:

  • This resource now counts the objects themselves of the passed array when using OverlapParams.FilterDescendantsInstances property.

Feel free to comment if you have any questions. :smiley:

1 Like