Get the location of a part in the explorer [closed]

So I’m trying to find the location (not the X,Y,Z) of a part thats stored within the explorer, Without
assigning a variable for it.

To do this, you’d need a way to identify the part you’re looking for in the explorer. Whether this be by a unique property compared to other parts in your game, to even a structured system (such as looping through every part instance in a dictionary, with the key being the part and the value being the parent etc).

1 Like

These are probably poor implementations, but both solutions require you to know what you’re looking for (whether you have direct access to the part or a parts attribute).

First off is the dictionary way that I mentioned:

--[[ THE DICTIONARY WAY ]]--
local PartsInGameDictionary = {}

-- Loop through every object in the workspace, including objects within objects.
for _, object in ipairs(workspace:GetDescendants()) do

	--[[ We'll check if object is of type BasePart (Part is an inherited class 
    of BasePart, same with MeshPart and UnionOperation etc) so these will 
    be included too.]]
	if object:IsA("BasePart") then
		PartsInGameDictionary[object] = object.Parent
	end
end

--[[ Then to see if a part exists (assuming you have a reference to the part), 
you could create a function like so.]]
function GetPartLocation(BasePart: part)
	return PartsInGameDictionary[object]
end

-- Passing through a part into this function will return its parent.
GetPartLocation(part)

And the second method is creating a unique identifier (doesn’t necessarily have to be a GUID, it could be a string, or a number. GUID’s however are unique so it’s pretty much impossible to create a duplicate GUID, ever):

--[[ THE UNIQUE IDENTIFIER WAY ]]--
local HttpService = game:GetService("HttpService")

--[[ Loop through every object in the workspace, 
including objects within objects. But this time, we're going to give 
each part an attribute "UniqueIdentifier" and make it a GUID. ]]
for _, object in ipairs(workspace:GetDescendants()) do

	--[[ We'll check if object is of type BasePart (Part is an inherited 
    class of BasePart, same with MeshPart and UnionOperation etc) so these
	will be included too. ]]
	if object:IsA("BasePart") then
		object:SetAttribute("UniqueIdentifier", HttpService:GenerateGUID(false))
	end
end

--[[ Now, assuming you know the GUID ("UniqueIdentifier") you're looking for, 
you can create a function that takes the GUID as a parameter 
and find your part. ]]
function GetPartLocation(string: uniqueIdentifier)
	for _, object in ipairs(workspace:GetDescendants()) do
		if object:GetAttribute("UniqueIdentifier") == uniqueIdentifier then
			return object.Parent
		end
	end
end

-- And passing through the GUID will return the parts parent.
GetPartLocation("acdd78e8-4a07-4edb-9e75-03533bcaea8f")
1 Like

https://developer.roblox.com/en-us/api-reference/function/Instance/GetFullName

1 Like

I +1 this as the route to go down. Although this will return the path hierarchy in a string only, you could use something like this post suggests to get the part as an instance, then do .Parent to get the parent object itself. :slight_smile:

1 Like

Oh sweet that works, But getting it from string to instance has been quite a pain

I’ll implement a function for you (based on that topic) and add comments to explain every step as much as I can. :slight_smile:

-- 'partDirectory' will be the path of your part (aka, PART.GetFullName).
function GetPartLocation(partDirectory: string)
	
	--[[ We're splitting off the string into separate array/table 
	entries. For example:
	
	partDirectory = "game.Workspace.Part"
	
	And using :split(".") on this, we're splitting 
	the string with the . being the splitter, so now partDirectory 
	would now become:
	
	{
		[1] = "game",
		[2] = "Workspace",
		[3] = "Part"
	}
	]]
	local partDirectoryLocations = partDirectory:split(".")
	
	--[[ Store a current location, the root of where all instances in our
	place start. ]]
	local currentLocation = game
	
	--[[ Now what we're doing here is, we're looping through 
	our partDirectoryLocations table, and we're 
	essentially indexing to the next child when we go
	down the explorer.
	
	--For example, this is how this example will work (currentLocation == game right now):
	
	--1st Iteration (partDirectoryLocations[i] is game):
	--[[ You can't index game with game, since game["game"] (game.game) isn't
	a thing, so we just skip to the next iteration.]]
	
	--2nd Iteration (partDirectoryLocations[i] is Workspace):
	--	currentLocation = currentLocation[partDirectoryLocations[i]]
	-- Which can also be written as.
	-- currentLocation = game.Workspace
	
	--3rd Iteration (currentLocation is now game.Workspace, partDirectoryLocations[i] is Part):
	--	currentLocation = currentLocation[partDirectoryLocations[i]]
	-- Which can also be written as.
	-- currentLocation = game.Workspace.Part
	
	--[[ And at the end of the loop, you'll have your Part instance, so to get its location
	we just return the parent, it's as simple as that. ]]
	for i = 1, #partDirectoryLocations, 1 do
		--[[ We can ignore game, as currentLocation is equal to game,
		so essentially doing game.game doesn't make sense as game
		isn't a child of game. ]]
		if partDirectoryLocations[i] == "game" then
			continue
		end
		
		--[[ Here, we set the current location equal to the child
		of the currentLocation that we're currently on in the
		partDirectoryLocations table. For example, if game was
		the currentLocation and partDirectoryLocations[i] was 
		Workspace, what we're doing is setting the new
		currentLocation to game.Workspace, since indexing game
		with ["Workspace"] is the same as doing game.Workspace.
		
		As a rule of thumb, game.Workspace is the 
		same as game["Workspace"].]]
		currentLocation = currentLocation[partDirectoryLocations[i]]
	end
	
	--[[ Once we have our part (currentLocation) we can just return
	the parent. :)]]
	return currentLocation.Parent
end

--[[ And printing this out will print out the parent,
assuming you had a part in the workspace called 'APart' :)]]
print(GetPartLocation(game.Workspace.APart:GetFullName()))

Hope this explains it well. :slight_smile:

1 Like

OH thank you so much for your help, Sorry if it made me look like I was trying to get you to do all the work. But this really does help me alot thanks.

Not a problem. :slight_smile:

I don’t mind writing a script, but I want people to read the comments so they actually understand what the code’s doing, and for good reason.

Lets say you add code into a game, but you just copy and paste it without actually understanding it. What if the time comes at some point where you need to maintain/adjust your code due to deprecation of functions etc? You wouldn’t know what to do. I don’t completely oppose finding solutions and using them online, but please know what you’re using before you use it.

1 Like

with your explanations it was crystal clear. I’ve been able to implement that into my original code and it works flawlessly only some tinkering and I got it working. thanks alot

1 Like