CodeSmile AssetDatabase 1.9
Unity's AssetDatabase in enjoyable, consistent, concise, convenient, comprehensible, safe, documented form.
Loading...
Searching...
No Matches
Asset.Path.Static.cs
1// Copyright (C) 2021-2024 Steffen Itterheim
2// Refer to included LICENSE file for terms and conditions.
3
4using System;
5using System.Collections.Generic;
6using System.Diagnostics.CodeAnalysis;
7using System.IO;
8using System.Linq;
9using UnityEditor;
10using UnityEngine;
11using Object = UnityEngine.Object;
12
13namespace CodeSmileEditor
14{
15 public sealed partial class Asset
16 {
17 public partial class Path
18 {
19 // all lowercase
20 private static readonly String[] s_AllowedAssetSubfolders =
21 { "assets", "library", "logs", "packages", "projectsettings", "temp", "usersettings" };
22
29 public static String FullAssetsPath => Application.dataPath;
30
34 public static String FullPackagesPath => $"{FullProjectPath}/Packages";
35
39 [ExcludeFromCodeCoverage] // returns string interpolation
40 public static String FullLibraryPath => $"{FullProjectPath}/Library";
41
45 [ExcludeFromCodeCoverage] // returns string interpolation
46 public static String FullLogsPath => $"{FullProjectPath}/Logs";
47
51 [ExcludeFromCodeCoverage] // returns string interpolation
52 public static String FullProjectSettingsPath => $"{FullProjectPath}/ProjectSettings";
53
57 [ExcludeFromCodeCoverage] // returns string interpolation
58 public static String FullUserSettingsPath => $"{FullProjectPath}/UserSettings";
59
63 [ExcludeFromCodeCoverage] // returns string interpolation
64 public static String FullProjectTempPath => $"{FullProjectPath}/Temp";
65
69 public static String FullProjectPath => FullAssetsPath.Substring(0, Application.dataPath.Length - 6);
70
80 public static Path Get([NotNull] Object asset)
81 {
82 var path = AssetDatabase.GetAssetPath(asset);
83 return String.IsNullOrEmpty(path) ? null : (Path)path;
84 }
85
96 public static Path Get(GUID guid)
97 {
98 var path = AssetDatabase.GUIDToAssetPath(guid);
99 return String.IsNullOrEmpty(path) ? null : (Path)path;
100 }
101
114 public static String[] Get([NotNull] Object[] assets)
115 {
116 ThrowIf.ArgumentIsNull(assets, nameof(assets));
117
118 var objectCount = assets.Length;
119 var paths = new String[objectCount];
120 for (var i = 0; i < objectCount; i++)
121 paths[i] = Get(assets[i]);
122
123 return paths;
124 }
125
139 public static GUID GetGuid([NotNull] Path path,
140 AssetPathToGUIDOptions options = AssetPathToGUIDOptions.IncludeRecentlyDeletedAssets) =>
141 new(AssetDatabase.AssetPathToGUID(path, options));
142
153 [ExcludeFromCodeCoverage] // simple relay
154 public static Path ToMeta([NotNull] Path path) => AssetDatabase.GetTextMetaFilePathFromAssetPath(path);
155
166 [ExcludeFromCodeCoverage] // simple relay
167 public static Path FromMeta([NotNull] Path path) => AssetDatabase.GetAssetPathFromTextMetaFilePath(path);
168
178 public static Path GetScene([NotNull] Object instanceOrAsset) => AssetDatabase.GetAssetOrScenePath(instanceOrAsset);
179
194 public static Boolean IsValid([NotNull] String path)
195 {
196 var isValid = true;
197
198 try
199 {
200 // System.IO will throw for most illegal chars, plus some extra checks
201 var fileName = System.IO.Path.GetFileName(path);
202 var folderName = System.IO.Path.GetDirectoryName(path);
203
204 // check folder name for some chars that System.IO allows in GetDirectoryName
205 var testIllegalChars = new Func<Char, Boolean>(c => c == '*' || c == '?' || c == ':');
206 isValid = folderName.Any(testIllegalChars) == false;
207
208 if (isValid)
209 {
210 // check filename for some chars that System.IO allows in GetFileName
211 fileName = path.Substring(folderName.Length, path.Length - folderName.Length);
212 isValid = fileName.Any(testIllegalChars) == false;
213 }
214 }
215 catch (Exception ex)
216 {
217 SetLastErrorMessage($"{ex.Message} => \"{path}\"");
218 isValid = false;
219 }
220
221 return isValid;
222 }
223
232 public static Boolean FileExists([NotNull] Path path) => System.IO.File.Exists(path.m_RelativePath);
233
242 public static Boolean FolderExists([NotNull] Path path) => Directory.Exists(path.m_RelativePath);
243
254 public static GUID CreateFolders([NotNull] Path path)
255 {
256 ThrowIf.ArgumentIsNull(path, nameof(path));
257 ThrowIf.PathIsNotValid(path);
258
259 if (FileExists(path))
260 return path.FolderPath.Guid;
261
262 // if the last part has an extension we assume the path points to a file
263 var isPresumablyFilePath = String.IsNullOrEmpty(path.Extension) == false;
264 var folderPath = isPresumablyFilePath ? path.FolderPath : path;
265 if (FolderExists(folderPath))
266 return folderPath.Guid;
267
268 var folderNames = ((String)folderPath).Split(new[] { '/' });
269 var folderGuid = GuidForExistingPath(folderNames[0]); // first is "Assets"
270 var partialPath = folderNames[0];
271 for (var i = 1; i < folderNames.Length; i++)
272 {
273 partialPath += $"/{folderNames[i]}";
274 if (FolderExists(partialPath))
275 {
276 folderGuid = GuidForExistingPath(partialPath);
277 continue;
278 }
279
280 folderGuid = CreateSubFolder(Get(folderGuid), folderNames[i]);
281 }
282
283 return folderGuid;
284 }
285
295 [ExcludeFromCodeCoverage] // simple relay
296 public static String[] GetSubFolders([NotNull] Path path) => AssetDatabase.GetSubFolders(path);
297
314 public static Path UniquifyFileName([NotNull] Path path)
315 {
316 var uniquePath = AssetDatabase.GenerateUniqueAssetPath(path);
317 return String.IsNullOrEmpty(uniquePath) ? path : uniquePath;
318 }
319
325 public static String[] ToStrings([NotNull] IEnumerable<Path> paths) => paths.Select(path => (String)path).ToArray();
326
327 internal static Path UniquifyAsNeeded([NotNull] Path path, Boolean overwriteExisting) =>
328 overwriteExisting ? path : path.UniqueFilePath;
329
330 private static GUID CreateSubFolder([NotNull] Path parentFolder, [NotNull] String subFolderName) =>
331 new(AssetDatabase.CreateFolder(parentFolder, subFolderName));
332
333 private static String ToRelative([NotNull] String fullOrRelativePath)
334 {
335 var relativePath = fullOrRelativePath;
336 if (IsRelative(relativePath) == false)
337 {
338 ThrowIf.NotAProjectPath(fullOrRelativePath);
339 relativePath = MakeRelative(fullOrRelativePath);
340 }
341
342 relativePath = relativePath.Trim('/');
343
344 ThrowIf.PathIsNotValid(relativePath);
345 return relativePath;
346 }
347
348 private static Boolean IsRelative([NotNull] String path)
349 {
350 path = path.TrimStart('/').ToLower();
351
352 // path must start with given project root subfolder names (eg 'Assets', 'Packages', 'Library' ..)
353 // and bei either just the subfolder (length equals) or be followed by a path separator
354 foreach (var allowedSubfolder in s_AllowedAssetSubfolders)
355 {
356 var doesStartsWith = path.StartsWith(allowedSubfolder);
357 var subfolderLength = allowedSubfolder.Length;
358 var lengthMatches = path.Length == subfolderLength;
359 if (doesStartsWith && (lengthMatches || path[subfolderLength].Equals('/')))
360 return true;
361 }
362
363 return false;
364 }
365
366 private static String MakeRelative([NotNull] String fullOrRelativePath) =>
367 fullOrRelativePath.Substring(FullProjectPath.Length).Trim('/');
368
369 private static GUID GuidForExistingPath([NotNull] String path) =>
370 new(AssetDatabase.AssetPathToGUID(path, AssetPathToGUIDOptions.OnlyExistingAssets));
371 }
372 }
373}
static String FullLibraryPath
Returns the absolute path to the project's Library subfolder.
Path UniqueFilePath
Returns the path altered with a numbering if an asset already exists (and is imported) at the path.
Boolean Equals(Path other)
Tests another path for equality.
static Path FromMeta([NotNull] Path path)
Returns the asset's file path from a .meta file path.
static Boolean FolderExists([NotNull] Path path)
Tests if the given folder exists in the file system.
static String[] GetSubFolders([NotNull] Path path)
Returns the names of all subfolders in the path.
static String FullUserSettingsPath
Returns the absolute path to the project's UserSettings subfolder.
static String FullProjectPath
Returns the absolute path to the project's root folder.
static String FullLogsPath
Returns the absolute path to the project's Logs subfolder.
static String[] ToStrings([NotNull] IEnumerable< Path > paths)
Converts an IEnumerable collection of Path instances to a string array.
static String FullProjectTempPath
Returns the absolute path to the project's Temp subfolder.
static String[] Get([NotNull] Object[] assets)
Converts an array of asset instances to their asset paths.
static Path UniquifyFileName([NotNull] Path path)
Returns the path altered with a numbering if an asset already exists (and is imported) at the path.
static GUID GetGuid([NotNull] Path path, AssetPathToGUIDOptions options=AssetPathToGUIDOptions.IncludeRecentlyDeletedAssets)
Returns the GUID for an asset path.
static GUID CreateFolders([NotNull] Path path)
Creates any missing folders in the path.
static Path Get([NotNull] Object asset)
Gets the relative path of an asset.
static String FullAssetsPath
Returns the absolute path to the project's Assets subfolder.
static Path GetScene([NotNull] Object instanceOrAsset)
Returns the scene's path if the object is instantiated in a scene, otherwise returns the object's pat...
static String FullProjectSettingsPath
Returns the absolute path to the project's ProjectSettings subfolder.
static String FullPackagesPath
Returns the absolute path to the project's Packages subfolder.
static Boolean FileExists([NotNull] Path path)
Tests if the given file exists in the file system.
static Path ToMeta([NotNull] Path path)
Returns the .meta file path for an asset path.
static Path Get(GUID guid)
Gets the relative path of an asset.
static Boolean IsValid([NotNull] String path)
Returns true if the provided path is valid.
Represents a relative path to an asset file or folder, typically under 'Assets' or 'Packages'.
Definition Asset.Path.cs:25