As part of a utility I’m writing, I’ve cloned the “Add Component” button, and have it matching 1:1 with the Inspector’s Add Component button, thanks to help from the Unsupported.GetSubmenus and Unsupported.GetSubmenusCommands - which I believe Unity is using internally.
So visually, it looks great and is 1:1, but now I’m trying to figure out how to actually add the component to my selected object in my EditorWindow.
Is there a way to get a list of all the non-obsolete Components in the project? Unsupported.GetSubmenus(“Component”) gives me a nice list of the path’s, which was really handy for rebuilding the Add Component button functionality, and it doesn’t seem any of the components returned back are obsolete. Now I’m just trying to figure out how to get the actual components so I can add them with AddComponent.
Does any Unity Dev’s out there have any idea of how to be able to build up a list of the actual components or their path, and how I can accomplish the functionality I’m looking for?
Thanks in advance!
You should be able to just use reflection with the right filters / arguments to get what you need.
https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/reflection
You may need to separately query the attributes for each identifier to look for ObsoleteAttributes:
https://learn.microsoft.com/en-us/dotnet/api/system.obsoleteattribute?view=net-7.0
I think Kurts advice is sound. In all other cases, there’s a TypeCache helper you can use which is much faster.
I guess you could use TypeCache.GetTypesWithAttribute to find the ones that do have the Obsolete attribute and discard them in the rest of your code somehow. It’s a shame that there’s not a “GetTypesWithoutAttribute”.
3 Likes
Thank you both, that sounds like a solid plan. Do either of you have any tips on building out the namespace of the various components?
Unsupported.GetSubmenus is definitely returning only component’s that aren’t obsolete, so that’s helpful and has been great for building out the AdvancedDropDown. Just trying to figure out the best way to get the namespace so I can add the component with reflection.
Planning to do something like:
var type = Unsupported.GetTypeFromFullName($"{componentItem.NameSpace}.{componentItem.ComponentType}");
selected.gameObject.AddComponent(type);
Sorry to bump, but I think I have it sorted. I first built up a list of all of the namespace’s Unity uses (using some iteration magic on elements returned from System.AppDomain.CurrentDomain.GetAssemblies).
Then wrote a method that tests each component (not considered a ‘Script’) against all the namespaces. Then a dictionary with the component: namespace is copied to my clipboard to paste into a script, so I can just do a lookup that way.
Everything that isn’t a success, was printed to the console, so I could add them manually (mostly some TextMeshPro stuff that failed) That seems to be working okay so far, but if anyone has suggestions on a better way, please let me know.
Thanks again for your help and suggestions @Kurt-Dekker and @MelvMay - I appreciate you both!