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).
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")
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.
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.
-- '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.
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.
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.
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