| using System; |
| using System.IO; |
| using UnityEngine; |
|
|
| namespace OnDeviceAgent.Inference |
| { |
| |
| |
| |
| |
| public static class ModelPathResolver |
| { |
| public static string GetModelFilePath(string relativePath) |
| { |
| var rel = (relativePath ?? string.Empty).Replace('\\', '/').TrimStart('/'); |
| #if UNITY_EDITOR |
| var packagePath = TryResolveInPackage(rel); |
| if (packagePath != null) |
| return packagePath; |
| #endif |
| return Path.Combine(Application.streamingAssetsPath, rel.Replace('/', Path.DirectorySeparatorChar)); |
| } |
|
|
| #if UNITY_EDITOR |
| |
| public static readonly (string streamingAssetsSubdir, string packageName)[] PackageMap = |
| { |
| ("Model/E5", "com.sky.sentis.e5"), |
| ("Model/OpenWakeWord", "com.sky.sentis.openwakeword"), |
| ("Model/SileroVad", "com.sky.sentis.silero-vad"), |
| ("Model/Supertonic", "com.sky.sentis.supertonic"), |
| ("Model/Whisper", "com.sky.sentis.whisper"), |
| ("Model/YOLO", "com.sky.sentis.yolox"), |
| }; |
|
|
| |
| |
| |
| static string ResolvePackageRoot(string pkg) |
| { |
| var info = UnityEditor.PackageManager.PackageInfo.FindForAssetPath("Packages/" + pkg); |
| if (info != null && !string.IsNullOrEmpty(info.resolvedPath)) |
| return info.resolvedPath; |
| return Path.GetFullPath(Path.Combine("Packages", pkg)); |
| } |
|
|
| static string TryResolveInPackage(string rel) |
| { |
| foreach (var (sub, pkg) in PackageMap) |
| { |
| if (rel != sub && !rel.StartsWith(sub + "/", StringComparison.Ordinal)) |
| continue; |
|
|
| var tail = rel.Substring(sub.Length).TrimStart('/'); |
| var full = Path.Combine(ResolvePackageRoot(pkg), "Models~", tail.Replace('/', Path.DirectorySeparatorChar)); |
| if (File.Exists(full) || Directory.Exists(full)) |
| return full; |
| return null; |
| } |
| return null; |
| } |
|
|
| |
| |
| public static void ProvisionToStreamingAssets() |
| { |
| foreach (var (sub, pkg) in PackageMap) |
| { |
| var src = Path.Combine(ResolvePackageRoot(pkg), "Models~"); |
| if (!Directory.Exists(src)) |
| continue; |
| var dst = Path.Combine(Application.streamingAssetsPath, sub.Replace('/', Path.DirectorySeparatorChar)); |
| CopyDir(src, dst); |
| WriteFilesManifest(dst); |
| } |
| } |
|
|
| |
| |
| const string FilesManifestFile = "files_manifest.txt"; |
|
|
| static void WriteFilesManifest(string dst) |
| { |
| if (!Directory.Exists(dst)) |
| return; |
|
|
| var entries = new System.Collections.Generic.List<string>(); |
| foreach (var file in Directory.GetFiles(dst, "*", SearchOption.AllDirectories)) |
| { |
| if (file.EndsWith(".meta", StringComparison.Ordinal)) |
| continue; |
| var rel = file.Substring(dst.Length).TrimStart(Path.DirectorySeparatorChar, '/').Replace('\\', '/'); |
| if (rel == FilesManifestFile) |
| continue; |
| entries.Add(rel); |
| } |
| entries.Sort(StringComparer.Ordinal); |
| File.WriteAllText(Path.Combine(dst, FilesManifestFile), string.Join("\n", entries) + "\n"); |
| } |
|
|
| |
| public static void RemoveFromStreamingAssets() |
| { |
| var modelRoot = Path.Combine(Application.streamingAssetsPath, "Model"); |
| if (Directory.Exists(modelRoot)) |
| Directory.Delete(modelRoot, true); |
| var meta = modelRoot + ".meta"; |
| if (File.Exists(meta)) |
| File.Delete(meta); |
| } |
|
|
| static void CopyDir(string src, string dst) |
| { |
| Directory.CreateDirectory(dst); |
| foreach (var file in Directory.GetFiles(src)) |
| { |
| if (file.EndsWith(".meta", StringComparison.Ordinal)) |
| continue; |
| File.Copy(file, Path.Combine(dst, Path.GetFileName(file)), true); |
| } |
| foreach (var dir in Directory.GetDirectories(src)) |
| CopyDir(dir, Path.Combine(dst, Path.GetFileName(dir))); |
| } |
| #endif |
| } |
| } |
|
|