2

I imported a Unity package where several Editor scripts depend on a RootPath property from a static class:

public static class EditorUtils
{
    public static string RootPath => "Assets/HardcodedPath";
}

The problem is that this path is hardcoded, so that the package location can't be changed at all. I plan on changing the RootPath property so that it gets the current script location and searches for parent folder with a given pattern. That way, I would be able to use this package even inside a custom package of my own (inside a Packages folder instead of the Assets folder, that is).

The missing piece is that I can't find a way to get this static class folder location from code. Can anyone help me with this?

AustinWBryan
  • 3,249
  • 3
  • 24
  • 42
Alesqui
  • 6,417
  • 5
  • 39
  • 43
  • Not sure if things change with Unity, but in pure C# we can di System.IO.Path.GetFullPath(".") or System.IO.Directory.GetCurrentDirectory() - Look at : https://stackoverflow.com/questions/15653921/get-current-folder-path for better answers – Prateek Shrivastava Nov 25 '20 at 21:58
  • Would Application.dataPath be a start? I doubt u can get a path since the code is compiled to run and is no longer a text file at location. You could perform a search by file name starting from dataPath. – Everts Nov 25 '20 at 22:00
  • @PrateekShrivastava Unfortunately both methods returns the wrong path, so it does seem that there are peculiarities due to Unity. – Alesqui Nov 25 '20 at 22:01
  • Do they not return Executing folder path? I mean say if my app is C:\Level1\Code\bin\Debug\App.exe -- These 2 calls should return - path until Debug folder. What are you getting? – Prateek Shrivastava Nov 25 '20 at 22:04
  • @PrateekShrivastava it returns my project root path, but the file is three folder levels inside that. – Alesqui Nov 26 '20 at 12:11
  • @Everts Application.dataPath did the trick, thank you. I was expecting a more direct approach of getting the current file path though =( Directory.GetFiles (Application.dataPath, "file-name", SearchOption.AllDirectories); – Alesqui Nov 26 '20 at 12:19

1 Answers1

5

Dig around through the AssetDatabase and find a reference to your script. This should return what you're wanting.

public static class EditorUtils
{
    public static string RootPath
    {
        get
        {
            var g = AssetDatabase.FindAssets ( $"t:Script {nameof(EditorUtils)}" );
            return AssetDatabase.GUIDToAssetPath ( g [ 0 ] );
        }
    }
}

That will also hold true for scripts in Packages. Remember to change EditorUtils to your script name.

Here's the relevant Unity docs.

Milan Egon Votrubec
  • 3,696
  • 2
  • 10
  • 24
  • I have just tested your suggestion, but unfortunately `g.Length == 0`. I ended up following this approach for now: `var projectPath = Directory.GetParent(Application.dataPath); var res = System.IO.Directory.GetFiles (projectPath.FullName, "file_name", SearchOption.AllDirectories);` – Alesqui Nov 26 '20 at 17:50
  • 2
    Is "EditorUtils" in a script CALLED EditorUtils.cs? You'll simply have to change "t:Script EditorUtils" to reflect the actual name of the script. e.g. "t:Script Tools" if it's "Tools.cs". Can confirm this works, just tested it. – Milan Egon Votrubec Nov 27 '20 at 04:05
  • 1
    Thank you for the clarification @Milan ! It is indeed working. – Alesqui Nov 30 '20 at 13:56
  • I tried it for a file that exists inside a Package and unfortunately the path returned is something like `ProjectRoot/Packages/com.company.example/file`, but the real file resides somewhere inside `ProjectRoot/Library/PackageCache` – Zamaroht May 05 '21 at 23:46
  • Unity 2020.x all versions have broken the more correct approach - using MonoScript - which isn't fixed until 2021.2.0. Until someone at Unity fixes their bug this is the only workaround I've found that works correctly. I recommend: "t:Script "+typeof(MyClass).Name -- which automatically updates everytime you rename/refactor/etc your class. – Adam Jan 03 '22 at 23:38
  • @Adam good call. Updated the code, with `nameof()` instead. – Milan Egon Votrubec Apr 21 '22 at 04:44