Compare commits
10 Commits
073dd25857
...
main
Author | SHA1 | Date | |
---|---|---|---|
64e0bf2282 | |||
41d502b239 | |||
6271171ab4 | |||
7906203f84 | |||
dfa00340f5 | |||
9b9264a6cc | |||
3c962267ab | |||
344260266c | |||
040f167b6d | |||
7887695a67 |
@@ -1,7 +1,4 @@
|
|||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using Convention.SO;
|
|
||||||
using UnityEditor;
|
using UnityEditor;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
@@ -12,7 +9,7 @@ namespace Convention
|
|||||||
[MenuItem("Convention/AssetBundle/Create for Android")]
|
[MenuItem("Convention/AssetBundle/Create for Android")]
|
||||||
static void CreatAssetBundle()
|
static void CreatAssetBundle()
|
||||||
{
|
{
|
||||||
string path = Path.Combine(Application.streamingAssetsPath, "AssetBundle", "Android");
|
string path = Path.Combine(Application.dataPath, "../", "AssetBundle", "Android");
|
||||||
if (!Directory.Exists(path))
|
if (!Directory.Exists(path))
|
||||||
{
|
{
|
||||||
Directory.CreateDirectory(path);
|
Directory.CreateDirectory(path);
|
||||||
@@ -24,7 +21,7 @@ namespace Convention
|
|||||||
[MenuItem("Convention/AssetBundle/Create for IOS")]
|
[MenuItem("Convention/AssetBundle/Create for IOS")]
|
||||||
static void BuildAllAssetBundlesForIOS()
|
static void BuildAllAssetBundlesForIOS()
|
||||||
{
|
{
|
||||||
string dirName = "AssetBundles/IOS/IOS";
|
string dirName = "AssetBundles/IOS/";
|
||||||
if (!Directory.Exists(dirName))
|
if (!Directory.Exists(dirName))
|
||||||
{
|
{
|
||||||
Directory.CreateDirectory(dirName);
|
Directory.CreateDirectory(dirName);
|
||||||
@@ -37,7 +34,7 @@ namespace Convention
|
|||||||
[MenuItem("Convention/AssetBundle/Create for Windows")]
|
[MenuItem("Convention/AssetBundle/Create for Windows")]
|
||||||
static void CreatPCAssetBundleForwINDOWS()
|
static void CreatPCAssetBundleForwINDOWS()
|
||||||
{
|
{
|
||||||
string path = Path.Combine(Application.streamingAssetsPath, "AssetBundle", "Windows");
|
string path = Path.Combine(Application.dataPath, "../", "AssetBundle", "Windows");
|
||||||
if (!Directory.Exists(path))
|
if (!Directory.Exists(path))
|
||||||
{
|
{
|
||||||
Directory.CreateDirectory(path);
|
Directory.CreateDirectory(path);
|
||||||
@@ -49,7 +46,7 @@ namespace Convention
|
|||||||
[MenuItem("Convention/AssetBundle/Create for Mac")]
|
[MenuItem("Convention/AssetBundle/Create for Mac")]
|
||||||
static void CreatPCAssetBundleForMac()
|
static void CreatPCAssetBundleForMac()
|
||||||
{
|
{
|
||||||
string path = Path.Combine(Application.streamingAssetsPath, "AssetBundle", "Mac");
|
string path = Path.Combine(Application.dataPath, "../", "AssetBundle", "Mac");
|
||||||
if (!Directory.Exists(path))
|
if (!Directory.Exists(path))
|
||||||
{
|
{
|
||||||
Directory.CreateDirectory(path);
|
Directory.CreateDirectory(path);
|
||||||
|
@@ -96,8 +96,10 @@ MonoBehaviour:
|
|||||||
m_Name:
|
m_Name:
|
||||||
m_EditorClassIdentifier:
|
m_EditorClassIdentifier:
|
||||||
m_CurrentContextKey: 0
|
m_CurrentContextKey: 0
|
||||||
m_AllContextPlane: []
|
m_AllContextPlane:
|
||||||
WindowPlane: {fileID: 6262932319296346077}
|
- plane: {fileID: 1743752460056994028}
|
||||||
|
root: {fileID: 6898088878883608404}
|
||||||
|
WindowPlane: {fileID: 2851218872878303137}
|
||||||
WindowBar: {fileID: 5431686027440357681}
|
WindowBar: {fileID: 5431686027440357681}
|
||||||
--- !u!114 &8120993653923732271
|
--- !u!114 &8120993653923732271
|
||||||
MonoBehaviour:
|
MonoBehaviour:
|
||||||
@@ -350,6 +352,7 @@ MonoBehaviour:
|
|||||||
anchorMin: {x: 0, y: 0}
|
anchorMin: {x: 0, y: 0}
|
||||||
pivot: {x: 0, y: 0}
|
pivot: {x: 0, y: 0}
|
||||||
BeforeMaximizeWindowBackgroundColorA: 1
|
BeforeMaximizeWindowBackgroundColorA: 1
|
||||||
|
IsMaximizeWindowMode: 0
|
||||||
AdjustSizeToContainsRect: {fileID: 0}
|
AdjustSizeToContainsRect: {fileID: 0}
|
||||||
--- !u!114 &6852005934204649840
|
--- !u!114 &6852005934204649840
|
||||||
MonoBehaviour:
|
MonoBehaviour:
|
||||||
@@ -707,6 +710,17 @@ PrefabInstance:
|
|||||||
addedObject: {fileID: 1225826108170619254}
|
addedObject: {fileID: 1225826108170619254}
|
||||||
m_AddedComponents: []
|
m_AddedComponents: []
|
||||||
m_SourcePrefab: {fileID: 100100000, guid: 9f83398a7d855e44493acb9b240c01ca, type: 3}
|
m_SourcePrefab: {fileID: 100100000, guid: 9f83398a7d855e44493acb9b240c01ca, type: 3}
|
||||||
|
--- !u!114 &2851218872878303137 stripped
|
||||||
|
MonoBehaviour:
|
||||||
|
m_CorrespondingSourceObject: {fileID: 6525725186002079832, guid: 9f83398a7d855e44493acb9b240c01ca, type: 3}
|
||||||
|
m_PrefabInstance: {fileID: 9007647915676817401}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 0}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 999be728ad5e8324baf45ccaf0f9c3d2, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
--- !u!224 &6898088878883608404 stripped
|
--- !u!224 &6898088878883608404 stripped
|
||||||
RectTransform:
|
RectTransform:
|
||||||
m_CorrespondingSourceObject: {fileID: 2502725167534981293, guid: 9f83398a7d855e44493acb9b240c01ca, type: 3}
|
m_CorrespondingSourceObject: {fileID: 2502725167534981293, guid: 9f83398a7d855e44493acb9b240c01ca, type: 3}
|
||||||
|
@@ -1085,6 +1085,7 @@ MonoBehaviour:
|
|||||||
anchorMin: {x: 0, y: 0}
|
anchorMin: {x: 0, y: 0}
|
||||||
pivot: {x: 0, y: 0}
|
pivot: {x: 0, y: 0}
|
||||||
BeforeMaximizeWindowBackgroundColorA: 1
|
BeforeMaximizeWindowBackgroundColorA: 1
|
||||||
|
IsMaximizeWindowMode: 0
|
||||||
AdjustSizeToContainsRect: {fileID: 0}
|
AdjustSizeToContainsRect: {fileID: 0}
|
||||||
--- !u!114 &3897188892033144510
|
--- !u!114 &3897188892033144510
|
||||||
MonoBehaviour:
|
MonoBehaviour:
|
||||||
|
@@ -1459,6 +1459,7 @@ MonoBehaviour:
|
|||||||
anchorMin: {x: 0, y: 0}
|
anchorMin: {x: 0, y: 0}
|
||||||
pivot: {x: 0, y: 0}
|
pivot: {x: 0, y: 0}
|
||||||
BeforeMaximizeWindowBackgroundColorA: 1
|
BeforeMaximizeWindowBackgroundColorA: 1
|
||||||
|
IsMaximizeWindowMode: 0
|
||||||
AdjustSizeToContainsRect: {fileID: 0}
|
AdjustSizeToContainsRect: {fileID: 0}
|
||||||
--- !u!114 &682559958368963457
|
--- !u!114 &682559958368963457
|
||||||
MonoBehaviour:
|
MonoBehaviour:
|
||||||
|
@@ -22,7 +22,7 @@ namespace ES3Internal
|
|||||||
|
|
||||||
public StreamReader baseReader;
|
public StreamReader baseReader;
|
||||||
|
|
||||||
internal ES3JSONReader(Stream stream, ES3Settings settings, bool readHeaderAndFooter = true) : base(settings, readHeaderAndFooter)
|
public ES3JSONReader(Stream stream, ES3Settings settings, bool readHeaderAndFooter = true) : base(settings, readHeaderAndFooter)
|
||||||
{
|
{
|
||||||
this.baseReader = new StreamReader(stream);
|
this.baseReader = new StreamReader(stream);
|
||||||
|
|
||||||
|
@@ -13,6 +13,7 @@ using UnityEditor;
|
|||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.Events;
|
using UnityEngine.Events;
|
||||||
using UnityEngine.SceneManagement;
|
using UnityEngine.SceneManagement;
|
||||||
|
using UnityEngine.Scripting;
|
||||||
using UnityEngine.UI;
|
using UnityEngine.UI;
|
||||||
|
|
||||||
namespace UnityEditor
|
namespace UnityEditor
|
||||||
@@ -56,6 +57,19 @@ namespace Convention
|
|||||||
public static string PersistentDataPath => Application.persistentDataPath;
|
public static string PersistentDataPath => Application.persistentDataPath;
|
||||||
|
|
||||||
public static string DataPath => Application.dataPath;
|
public static string DataPath => Application.dataPath;
|
||||||
|
|
||||||
|
public static string CurrentWorkPath => Environment.CurrentDirectory;
|
||||||
|
|
||||||
|
public static string Combine(string a, string b) => Path.Combine(a, b);
|
||||||
|
public static string CombineAsDir(string a, string b)
|
||||||
|
{
|
||||||
|
string name = b.Replace("\\", "/");
|
||||||
|
if (name.EndsWith("/") == false)
|
||||||
|
{
|
||||||
|
name += "/";
|
||||||
|
}
|
||||||
|
return Path.Combine(a, name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static partial class Utility
|
public static partial class Utility
|
||||||
@@ -425,7 +439,7 @@ namespace Convention
|
|||||||
public static _T convert_xvalue<_T>([In] string str)
|
public static _T convert_xvalue<_T>([In] string str)
|
||||||
{
|
{
|
||||||
Type type = typeof(_T);
|
Type type = typeof(_T);
|
||||||
var parse_method = type.GetMethod("Parse");
|
var parse_method = type.GetMethod(nameof(int.Parse), BindingFlags.Static | BindingFlags.Public, null, new Type[] { typeof(string) }, null);
|
||||||
if (parse_method != null &&
|
if (parse_method != null &&
|
||||||
(parse_method.ReturnType.IsSubclassOf(type) || parse_method.ReturnType == type) &&
|
(parse_method.ReturnType.IsSubclassOf(type) || parse_method.ReturnType == type) &&
|
||||||
parse_method.GetParameters().Length == 1 &&
|
parse_method.GetParameters().Length == 1 &&
|
||||||
@@ -2192,3 +2206,29 @@ namespace Convention
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace Convention
|
||||||
|
{
|
||||||
|
public static partial class ConventionUtility
|
||||||
|
{
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Unity engine function to disable the GC
|
||||||
|
/// </summary>
|
||||||
|
public static void GC_disable()
|
||||||
|
{
|
||||||
|
#if !UNITY_EDITOR
|
||||||
|
GarbageCollector.GCMode = GarbageCollector.Mode.Disabled;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Unity engine function to enable the GC
|
||||||
|
/// </summary>
|
||||||
|
public static void GC_enable()
|
||||||
|
{
|
||||||
|
#if !UNITY_EDITOR
|
||||||
|
GarbageCollector.GCMode = GarbageCollector.Mode.Enabled;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -4,7 +4,6 @@ using System.Collections.Generic;
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.IO.Compression;
|
using System.IO.Compression;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
@@ -58,24 +57,28 @@ namespace Convention
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private string FullPath;
|
private string OriginPath;
|
||||||
private FileSystemInfo OriginInfo;
|
private FileSystemInfo OriginInfo;
|
||||||
public ToolFile(string path)
|
public ToolFile(string path)
|
||||||
{
|
{
|
||||||
FullPath = Path.GetFullPath(Environment.ExpandEnvironmentVariables(path));
|
OriginPath = Environment.ExpandEnvironmentVariables(path).Replace('\\', '/');
|
||||||
Refresh();
|
Refresh();
|
||||||
}
|
}
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
return this.FullPath;
|
return this.OriginPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Path
|
#region Path
|
||||||
|
|
||||||
public static implicit operator string(ToolFile data) => data.FullPath;
|
public static implicit operator string(ToolFile data) => data.OriginPath;
|
||||||
|
public string GetAbsPath()
|
||||||
|
{
|
||||||
|
return Path.GetFullPath(OriginPath);
|
||||||
|
}
|
||||||
public string GetFullPath()
|
public string GetFullPath()
|
||||||
{
|
{
|
||||||
return this.FullPath;
|
return this.OriginPath;
|
||||||
}
|
}
|
||||||
public string GetName(bool is_ignore_extension = false)
|
public string GetName(bool is_ignore_extension = false)
|
||||||
{
|
{
|
||||||
@@ -86,13 +89,13 @@ namespace Convention
|
|||||||
else if (OriginInfo is DirectoryInfo dinfo)
|
else if (OriginInfo is DirectoryInfo dinfo)
|
||||||
return dinfo.Name;
|
return dinfo.Name;
|
||||||
}
|
}
|
||||||
var result = this.FullPath[..(
|
var result = this.OriginPath[..(
|
||||||
(this.FullPath.Contains('.') && is_ignore_extension)
|
(this.OriginPath.Contains('.') && is_ignore_extension)
|
||||||
? this.FullPath.LastIndexOf('.')
|
? this.OriginPath.LastIndexOf('.')
|
||||||
: ^0
|
: ^0
|
||||||
)]
|
)]
|
||||||
[..(
|
[..(
|
||||||
(this.FullPath[^1] == '/' || this.FullPath[^1] == '\\')
|
(this.OriginPath[^1] == '/' || this.OriginPath[^1] == '\\')
|
||||||
? ^1
|
? ^1
|
||||||
: ^0
|
: ^0
|
||||||
)];
|
)];
|
||||||
@@ -103,32 +106,32 @@ namespace Convention
|
|||||||
{
|
{
|
||||||
if (IsDir())
|
if (IsDir())
|
||||||
return "";
|
return "";
|
||||||
return this.FullPath[(
|
return this.OriginPath[(
|
||||||
(this.FullPath.Contains('.'))
|
(this.OriginPath.Contains('.'))
|
||||||
? this.FullPath.LastIndexOf('.')
|
? this.OriginPath.LastIndexOf('.')
|
||||||
: ^0
|
: ^0
|
||||||
)..];
|
)..];
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetFilename(bool is_without_extension = false)
|
public string GetFilename(bool is_without_extension = false)
|
||||||
{
|
{
|
||||||
if (is_without_extension && Path.HasExtension(FullPath))
|
if (is_without_extension && Path.HasExtension(OriginPath))
|
||||||
{
|
{
|
||||||
return Path.GetFileNameWithoutExtension(FullPath);
|
return Path.GetFileNameWithoutExtension(OriginPath);
|
||||||
}
|
}
|
||||||
else if (FullPath.EndsWith(Path.DirectorySeparatorChar.ToString()) || FullPath.EndsWith(Path.AltDirectorySeparatorChar.ToString()))
|
else if (OriginPath.EndsWith(Path.DirectorySeparatorChar.ToString()) || OriginPath.EndsWith(Path.AltDirectorySeparatorChar.ToString()))
|
||||||
{
|
{
|
||||||
return Path.GetFileName(FullPath.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar));
|
return Path.GetFileName(OriginPath.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return Path.GetFileName(FullPath);
|
return Path.GetFileName(OriginPath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetDir()
|
public string GetDir()
|
||||||
{
|
{
|
||||||
return Path.GetDirectoryName(FullPath);
|
return Path.GetDirectoryName(OriginPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ToolFile GetDirToolFile()
|
public ToolFile GetDirToolFile()
|
||||||
@@ -138,7 +141,7 @@ namespace Convention
|
|||||||
|
|
||||||
public string GetCurrentDirName()
|
public string GetCurrentDirName()
|
||||||
{
|
{
|
||||||
return Path.GetDirectoryName(FullPath);
|
return Path.GetDirectoryName(OriginPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ToolFile GetParentDir()
|
public ToolFile GetParentDir()
|
||||||
@@ -150,7 +153,7 @@ namespace Convention
|
|||||||
|
|
||||||
#region Exists
|
#region Exists
|
||||||
|
|
||||||
public bool Exists() => File.Exists(FullPath) || Directory.Exists(FullPath);
|
public bool Exists() => File.Exists(OriginPath) || Directory.Exists(OriginPath);
|
||||||
|
|
||||||
public static implicit operator bool(ToolFile file) => file.Exists();
|
public static implicit operator bool(ToolFile file) => file.Exists();
|
||||||
|
|
||||||
@@ -162,13 +165,13 @@ namespace Convention
|
|||||||
OriginInfo = null;
|
OriginInfo = null;
|
||||||
else if (IsDir())
|
else if (IsDir())
|
||||||
{
|
{
|
||||||
OriginInfo = new DirectoryInfo(FullPath);
|
OriginInfo = new DirectoryInfo(OriginPath);
|
||||||
FullPath = Path.GetFullPath(FullPath);
|
OriginPath = Path.GetFullPath(OriginPath);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
OriginInfo = new FileInfo(FullPath);
|
OriginInfo = new FileInfo(OriginPath);
|
||||||
FullPath = Path.GetFullPath(FullPath);
|
OriginPath = Path.GetFullPath(OriginPath);
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@@ -181,7 +184,7 @@ namespace Convention
|
|||||||
}
|
}
|
||||||
public T LoadAsJson<T>(string key = "data")
|
public T LoadAsJson<T>(string key = "data")
|
||||||
{
|
{
|
||||||
return ES3.Load<T>(key, FullPath);
|
return ES3.Load<T>(key, OriginPath);
|
||||||
}
|
}
|
||||||
public string LoadAsText()
|
public string LoadAsText()
|
||||||
{
|
{
|
||||||
@@ -217,7 +220,7 @@ namespace Convention
|
|||||||
if (IsFile() == false)
|
if (IsFile() == false)
|
||||||
throw new InvalidOperationException("Target is not a file");
|
throw new InvalidOperationException("Target is not a file");
|
||||||
|
|
||||||
var lines = File.ReadAllLines(FullPath);
|
var lines = File.ReadAllLines(OriginPath);
|
||||||
var result = new List<string[]>();
|
var result = new List<string[]>();
|
||||||
|
|
||||||
foreach (var line in lines)
|
foreach (var line in lines)
|
||||||
@@ -244,11 +247,11 @@ namespace Convention
|
|||||||
|
|
||||||
public Texture2D LoadAsImage()
|
public Texture2D LoadAsImage()
|
||||||
{
|
{
|
||||||
return ES3Plugin.LoadImage(FullPath);
|
return ES3Plugin.LoadImage(OriginPath);
|
||||||
}
|
}
|
||||||
public IEnumerator LoadAsImage([In] Action<Texture2D> callback)
|
public IEnumerator LoadAsImage([In] Action<Texture2D> callback)
|
||||||
{
|
{
|
||||||
UnityWebRequest request = UnityWebRequestTexture.GetTexture(FullPath);
|
UnityWebRequest request = UnityWebRequestTexture.GetTexture(OriginPath);
|
||||||
yield return request.SendWebRequest();
|
yield return request.SendWebRequest();
|
||||||
|
|
||||||
if (request.result == UnityWebRequest.Result.Success)
|
if (request.result == UnityWebRequest.Result.Success)
|
||||||
@@ -259,11 +262,11 @@ namespace Convention
|
|||||||
}
|
}
|
||||||
public AudioClip LoadAsAudio()
|
public AudioClip LoadAsAudio()
|
||||||
{
|
{
|
||||||
return ES3Plugin.LoadAudio(FullPath, GetAudioType(FullPath));
|
return ES3Plugin.LoadAudio(OriginPath, GetAudioType(OriginPath));
|
||||||
}
|
}
|
||||||
public IEnumerator LoadAsAudio([In] Action<AudioClip> callback)
|
public IEnumerator LoadAsAudio([In] Action<AudioClip> callback)
|
||||||
{
|
{
|
||||||
UnityWebRequest request = UnityWebRequestMultimedia.GetAudioClip(FullPath, GetAudioType(FullPath));
|
UnityWebRequest request = UnityWebRequestMultimedia.GetAudioClip(OriginPath, GetAudioType(OriginPath));
|
||||||
yield return request.SendWebRequest();
|
yield return request.SendWebRequest();
|
||||||
|
|
||||||
if (request.result == UnityWebRequest.Result.Success)
|
if (request.result == UnityWebRequest.Result.Success)
|
||||||
@@ -274,18 +277,18 @@ namespace Convention
|
|||||||
}
|
}
|
||||||
public AssetBundle LoadAsAssetBundle()
|
public AssetBundle LoadAsAssetBundle()
|
||||||
{
|
{
|
||||||
return AssetBundle.LoadFromFile(FullPath);
|
return AssetBundle.LoadFromFile(OriginPath);
|
||||||
}
|
}
|
||||||
public IEnumerator LoadAsAssetBundle([In] Action<AssetBundle> callback)
|
public IEnumerator LoadAsAssetBundle([In] Action<AssetBundle> callback)
|
||||||
{
|
{
|
||||||
AssetBundleCreateRequest result = AssetBundle.LoadFromFileAsync(FullPath);
|
AssetBundleCreateRequest result = AssetBundle.LoadFromFileAsync(OriginPath);
|
||||||
yield return result;
|
yield return result;
|
||||||
callback(result.assetBundle);
|
callback(result.assetBundle);
|
||||||
yield return null;
|
yield return null;
|
||||||
}
|
}
|
||||||
public IEnumerator LoadAsAssetBundle([In]Action<float> progress, [In] Action<AssetBundle> callback)
|
public IEnumerator LoadAsAssetBundle([In]Action<float> progress, [In] Action<AssetBundle> callback)
|
||||||
{
|
{
|
||||||
AssetBundleCreateRequest result = AssetBundle.LoadFromFileAsync(FullPath);
|
AssetBundleCreateRequest result = AssetBundle.LoadFromFileAsync(OriginPath);
|
||||||
while (result.isDone == false)
|
while (result.isDone == false)
|
||||||
{
|
{
|
||||||
progress(result.progress);
|
progress(result.progress);
|
||||||
@@ -311,11 +314,11 @@ namespace Convention
|
|||||||
}
|
}
|
||||||
public void SaveAsJson<T>(T data, string key = "data")
|
public void SaveAsJson<T>(T data, string key = "data")
|
||||||
{
|
{
|
||||||
ES3.Save(key, data,FullPath);
|
ES3.Save(key, data,OriginPath);
|
||||||
}
|
}
|
||||||
public void SaveAsText(string data)
|
public void SaveAsText(string data)
|
||||||
{
|
{
|
||||||
using var fs = new FileStream(FullPath, FileMode.CreateNew, FileAccess.Write);
|
using var fs = new FileStream(OriginPath, FileMode.CreateNew, FileAccess.Write);
|
||||||
using var sw = new StreamWriter(fs);
|
using var sw = new StreamWriter(fs);
|
||||||
sw.Write(data);
|
sw.Write(data);
|
||||||
sw.Flush();
|
sw.Flush();
|
||||||
@@ -337,7 +340,7 @@ namespace Convention
|
|||||||
|
|
||||||
public void SaveAsBinary(byte[] data)
|
public void SaveAsBinary(byte[] data)
|
||||||
{
|
{
|
||||||
SaveDataAsBinary(FullPath, data, (OriginInfo as FileInfo).OpenWrite());
|
SaveDataAsBinary(OriginPath, data, (OriginInfo as FileInfo).OpenWrite());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SaveAsCsv(List<string[]> csvData)
|
public void SaveAsCsv(List<string[]> csvData)
|
||||||
@@ -346,7 +349,7 @@ namespace Convention
|
|||||||
throw new InvalidOperationException("Target is not a file");
|
throw new InvalidOperationException("Target is not a file");
|
||||||
|
|
||||||
var lines = csvData.Select(row => string.Join(",", row));
|
var lines = csvData.Select(row => string.Join(",", row));
|
||||||
File.WriteAllLines(FullPath, lines);
|
File.WriteAllLines(OriginPath, lines);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SaveAsXml(string xmlData)
|
public void SaveAsXml(string xmlData)
|
||||||
@@ -380,9 +383,9 @@ namespace Convention
|
|||||||
{
|
{
|
||||||
if (Exists())
|
if (Exists())
|
||||||
{
|
{
|
||||||
return Directory.Exists(this.FullPath);
|
return Directory.Exists(this.OriginPath);
|
||||||
}
|
}
|
||||||
return this.FullPath[^1] == '\\' || this.FullPath[^1] == '/';
|
return this.OriginPath[^1] == '\\' || this.OriginPath[^1] == '/';
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsFile()
|
public bool IsFile()
|
||||||
@@ -420,7 +423,7 @@ namespace Convention
|
|||||||
{
|
{
|
||||||
if (IsDir())
|
if (IsDir())
|
||||||
{
|
{
|
||||||
return GetDirectorySize(FullPath);
|
return GetDirectorySize(OriginPath);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -458,6 +461,20 @@ namespace Convention
|
|||||||
#region Operator
|
#region Operator
|
||||||
|
|
||||||
public static ToolFile operator |(ToolFile left, string rightPath)
|
public static ToolFile operator |(ToolFile left, string rightPath)
|
||||||
|
{
|
||||||
|
if (rightPath == null)
|
||||||
|
{
|
||||||
|
return new ToolFile(left.IsDir() ? left.GetFullPath() : $"{left.GetFullPath().Replace('\\', '/')}/");
|
||||||
|
}
|
||||||
|
string first = left.GetFullPath().Replace('\\','/');
|
||||||
|
string second = rightPath.Replace('\\', '/');
|
||||||
|
if (first == "./")
|
||||||
|
return new ToolFile(second);
|
||||||
|
else if (first == "../")
|
||||||
|
return new ToolFile($"{new ToolFile(left.GetAbsPath()).GetParentDir()}/{second}");
|
||||||
|
return new ToolFile($"{first}/{second}");
|
||||||
|
}
|
||||||
|
public static ToolFile operator |(ToolFile left, ToolFile rightPath)
|
||||||
{
|
{
|
||||||
string lp = left.GetFullPath();
|
string lp = left.GetFullPath();
|
||||||
return new ToolFile(Path.Combine(lp, rightPath));
|
return new ToolFile(Path.Combine(lp, rightPath));
|
||||||
@@ -467,19 +484,19 @@ namespace Convention
|
|||||||
{
|
{
|
||||||
if (obj is ToolFile other)
|
if (obj is ToolFile other)
|
||||||
{
|
{
|
||||||
return Path.GetFullPath(FullPath).Equals(Path.GetFullPath(other.FullPath), StringComparison.OrdinalIgnoreCase);
|
return Path.GetFullPath(OriginPath).Equals(Path.GetFullPath(other.OriginPath), StringComparison.OrdinalIgnoreCase);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override int GetHashCode()
|
public override int GetHashCode()
|
||||||
{
|
{
|
||||||
return Path.GetFullPath(FullPath).GetHashCode();
|
return Path.GetFullPath(OriginPath).GetHashCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ToolFile Open(string path)
|
public ToolFile Open(string path)
|
||||||
{
|
{
|
||||||
this.FullPath = path;
|
this.OriginPath = path;
|
||||||
Refresh();
|
Refresh();
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@@ -492,9 +509,9 @@ namespace Convention
|
|||||||
if (Exists() == false)
|
if (Exists() == false)
|
||||||
{
|
{
|
||||||
if (IsDir())
|
if (IsDir())
|
||||||
Directory.CreateDirectory(this.FullPath);
|
Directory.CreateDirectory(this.OriginPath);
|
||||||
else
|
else
|
||||||
File.Create(this.FullPath).Close();
|
File.Create(this.OriginPath).Close();
|
||||||
Refresh();
|
Refresh();
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
@@ -511,7 +528,7 @@ namespace Convention
|
|||||||
var file = OriginInfo as FileInfo;
|
var file = OriginInfo as FileInfo;
|
||||||
file.MoveTo(newPath);
|
file.MoveTo(newPath);
|
||||||
}
|
}
|
||||||
FullPath = newPath;
|
OriginPath = newPath;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
public ToolFile Move(string path)
|
public ToolFile Move(string path)
|
||||||
@@ -537,7 +554,7 @@ namespace Convention
|
|||||||
public ToolFile Copy(string targetPath = null)
|
public ToolFile Copy(string targetPath = null)
|
||||||
{
|
{
|
||||||
if (targetPath == null)
|
if (targetPath == null)
|
||||||
return new ToolFile(FullPath);
|
return new ToolFile(OriginPath);
|
||||||
|
|
||||||
if (!Exists())
|
if (!Exists())
|
||||||
throw new FileNotFoundException("File not found");
|
throw new FileNotFoundException("File not found");
|
||||||
@@ -547,9 +564,9 @@ namespace Convention
|
|||||||
targetFile = targetFile | GetFilename();
|
targetFile = targetFile | GetFilename();
|
||||||
|
|
||||||
if (IsDir())
|
if (IsDir())
|
||||||
CopyDirectory(FullPath, targetFile.GetFullPath());
|
CopyDirectory(OriginPath, targetFile.GetFullPath());
|
||||||
else
|
else
|
||||||
File.Copy(FullPath, targetFile.GetFullPath());
|
File.Copy(OriginPath, targetFile.GetFullPath());
|
||||||
|
|
||||||
return targetFile;
|
return targetFile;
|
||||||
}
|
}
|
||||||
@@ -575,9 +592,9 @@ namespace Convention
|
|||||||
public ToolFile Delete()
|
public ToolFile Delete()
|
||||||
{
|
{
|
||||||
if (IsDir())
|
if (IsDir())
|
||||||
Directory.Delete(FullPath);
|
Directory.Delete(OriginPath);
|
||||||
else
|
else
|
||||||
File.Delete(FullPath);
|
File.Delete(OriginPath);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -598,7 +615,7 @@ namespace Convention
|
|||||||
}
|
}
|
||||||
public ToolFile TryCreateParentPath()
|
public ToolFile TryCreateParentPath()
|
||||||
{
|
{
|
||||||
string dirPath = Path.GetDirectoryName(FullPath);
|
string dirPath = Path.GetDirectoryName(OriginPath);
|
||||||
if (!string.IsNullOrEmpty(dirPath) && !Directory.Exists(dirPath))
|
if (!string.IsNullOrEmpty(dirPath) && !Directory.Exists(dirPath))
|
||||||
{
|
{
|
||||||
Directory.CreateDirectory(dirPath);
|
Directory.CreateDirectory(dirPath);
|
||||||
@@ -609,14 +626,14 @@ namespace Convention
|
|||||||
{
|
{
|
||||||
if (!IsDir())
|
if (!IsDir())
|
||||||
throw new InvalidOperationException("Target is not a directory");
|
throw new InvalidOperationException("Target is not a directory");
|
||||||
return Directory.GetFileSystemEntries(FullPath).ToList();
|
return Directory.GetFileSystemEntries(OriginPath).ToList();
|
||||||
}
|
}
|
||||||
public List<ToolFile> DirToolFileIter()
|
public List<ToolFile> DirToolFileIter()
|
||||||
{
|
{
|
||||||
if (!IsDir())
|
if (!IsDir())
|
||||||
throw new InvalidOperationException("Target is not a directory");
|
throw new InvalidOperationException("Target is not a directory");
|
||||||
var result = new List<ToolFile>();
|
var result = new List<ToolFile>();
|
||||||
foreach (var entry in Directory.GetFileSystemEntries(FullPath))
|
foreach (var entry in Directory.GetFileSystemEntries(OriginPath))
|
||||||
{
|
{
|
||||||
result.Add(new ToolFile(entry));
|
result.Add(new ToolFile(entry));
|
||||||
}
|
}
|
||||||
@@ -624,7 +641,7 @@ namespace Convention
|
|||||||
}
|
}
|
||||||
public ToolFile BackToParentDir()
|
public ToolFile BackToParentDir()
|
||||||
{
|
{
|
||||||
FullPath = GetDir();
|
OriginPath = GetDir();
|
||||||
Refresh();
|
Refresh();
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@@ -633,7 +650,7 @@ namespace Convention
|
|||||||
if (!IsDir())
|
if (!IsDir())
|
||||||
throw new InvalidOperationException("Target is not a directory");
|
throw new InvalidOperationException("Target is not a directory");
|
||||||
|
|
||||||
var entries = Directory.GetFileSystemEntries(FullPath);
|
var entries = Directory.GetFileSystemEntries(OriginPath);
|
||||||
if (ignore_folder)
|
if (ignore_folder)
|
||||||
{
|
{
|
||||||
return entries.Count(entry => File.Exists(entry));
|
return entries.Count(entry => File.Exists(entry));
|
||||||
@@ -740,13 +757,13 @@ namespace Convention
|
|||||||
{
|
{
|
||||||
if (IsDir())
|
if (IsDir())
|
||||||
{
|
{
|
||||||
ZipFile.CreateFromDirectory(FullPath, outputPath);
|
ZipFile.CreateFromDirectory(OriginPath, outputPath);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
using (var archive = ZipFile.Open(outputPath, ZipArchiveMode.Create))
|
using (var archive = ZipFile.Open(outputPath, ZipArchiveMode.Create))
|
||||||
{
|
{
|
||||||
archive.CreateEntryFromFile(FullPath, GetFilename());
|
archive.CreateEntryFromFile(OriginPath, GetFilename());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -778,7 +795,7 @@ namespace Convention
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
ZipFile.ExtractToDirectory(FullPath, outputPath);
|
ZipFile.ExtractToDirectory(OriginPath, outputPath);
|
||||||
return new ToolFile(outputPath);
|
return new ToolFile(outputPath);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@@ -897,7 +914,7 @@ namespace Convention
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
using (var hashAlgorithm = GetHashAlgorithm(algorithm))
|
using (var hashAlgorithm = GetHashAlgorithm(algorithm))
|
||||||
using (var stream = File.OpenRead(FullPath))
|
using (var stream = File.OpenRead(OriginPath))
|
||||||
{
|
{
|
||||||
byte[] hash = hashAlgorithm.ComputeHash(stream);
|
byte[] hash = hashAlgorithm.ComputeHash(stream);
|
||||||
return BitConverter.ToString(hash).Replace("-", "").ToLower();
|
return BitConverter.ToString(hash).Replace("-", "").ToLower();
|
||||||
@@ -955,7 +972,7 @@ namespace Convention
|
|||||||
|
|
||||||
// 注意:这是一个简化实现,实际的文件监控需要更复杂的实现
|
// 注意:这是一个简化实现,实际的文件监控需要更复杂的实现
|
||||||
// 可以使用 FileSystemWatcher 来实现完整功能
|
// 可以使用 FileSystemWatcher 来实现完整功能
|
||||||
var watcher = new FileSystemWatcher(FullPath)
|
var watcher = new FileSystemWatcher(OriginPath)
|
||||||
{
|
{
|
||||||
IncludeSubdirectories = recursive,
|
IncludeSubdirectories = recursive,
|
||||||
EnableRaisingEvents = true
|
EnableRaisingEvents = true
|
||||||
@@ -1087,7 +1104,7 @@ namespace Convention
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var fileInfo = new FileInfo(FullPath);
|
var fileInfo = new FileInfo(OriginPath);
|
||||||
var attributes = fileInfo.Attributes;
|
var attributes = fileInfo.Attributes;
|
||||||
|
|
||||||
permissions["read"] = true; // 如果能获取到文件信息,说明可读
|
permissions["read"] = true; // 如果能获取到文件信息,说明可读
|
||||||
@@ -1114,7 +1131,7 @@ namespace Convention
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var fileInfo = new FileInfo(FullPath);
|
var fileInfo = new FileInfo(OriginPath);
|
||||||
var attributes = fileInfo.Attributes;
|
var attributes = fileInfo.Attributes;
|
||||||
|
|
||||||
if (write.HasValue)
|
if (write.HasValue)
|
||||||
|
679
Convention/[Runtime]/Interaction.cs
Normal file
679
Convention/[Runtime]/Interaction.cs
Normal file
@@ -0,0 +1,679 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.Networking;
|
||||||
|
|
||||||
|
namespace Convention
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 统一的文件交互类,支持本地文件、网络文件和localhost路径的自适应处理
|
||||||
|
/// 使用UnityWebRequest实现跨平台兼容,支持WebGL和IL2CPP
|
||||||
|
///
|
||||||
|
/// <list type="bullet"><see cref="ToolFile"/>是依赖项</list>
|
||||||
|
/// </summary>
|
||||||
|
[Serializable]
|
||||||
|
public sealed class Interaction
|
||||||
|
{
|
||||||
|
#region Fields and Properties
|
||||||
|
|
||||||
|
private string originalPath;
|
||||||
|
private string processedPath;
|
||||||
|
private PathType pathType;
|
||||||
|
private object cachedData;
|
||||||
|
|
||||||
|
public string OriginalPath => originalPath;
|
||||||
|
public string ProcessedPath => processedPath;
|
||||||
|
public PathType Type => pathType;
|
||||||
|
|
||||||
|
public enum PathType
|
||||||
|
{
|
||||||
|
LocalFile, // 本地文件 (file://)
|
||||||
|
NetworkHTTP, // 网络HTTP (http://)
|
||||||
|
NetworkHTTPS, // 网络HTTPS (https://)
|
||||||
|
LocalServer, // 本地服务器 (localhost)
|
||||||
|
StreamingAssets // StreamingAssets目录
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
public Interaction(string path)
|
||||||
|
{
|
||||||
|
SetPath(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Setup
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 设置并处理路径
|
||||||
|
/// </summary>
|
||||||
|
public Interaction SetPath(string path)
|
||||||
|
{
|
||||||
|
originalPath = path;
|
||||||
|
processedPath = ProcessPath(path);
|
||||||
|
pathType = DeterminePathType(path);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 处理路径,转换为UnityWebRequest可识别的格式
|
||||||
|
/// </summary>
|
||||||
|
private string ProcessPath(string path)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(path))
|
||||||
|
return path;
|
||||||
|
|
||||||
|
// 网络路径直接返回
|
||||||
|
if (path.StartsWith("http://") || path.StartsWith("https://"))
|
||||||
|
{
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
// localhost处理
|
||||||
|
if (path.StartsWith("localhost"))
|
||||||
|
{
|
||||||
|
return path.StartsWith("localhost/") ? "http://" + path : "http://localhost/" + path;
|
||||||
|
}
|
||||||
|
|
||||||
|
// StreamingAssets路径处理
|
||||||
|
if (path.StartsWith("StreamingAssets/") || path.StartsWith("StreamingAssets\\"))
|
||||||
|
{
|
||||||
|
return Path.Combine(Application.streamingAssetsPath, path.Substring(16)).Replace("\\", "/");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 本地文件路径处理
|
||||||
|
string fullPath = Path.IsPathRooted(path) ? path : Path.GetFullPath(path);
|
||||||
|
|
||||||
|
// WebGL平台特殊处理
|
||||||
|
if (Application.platform == RuntimePlatform.WebGLPlayer)
|
||||||
|
{
|
||||||
|
// WebGL只能访问StreamingAssets,尝试构建StreamingAssets路径
|
||||||
|
return Application.streamingAssetsPath + "/" + Path.GetFileName(fullPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 其他平台使用file://协议
|
||||||
|
return "file:///" + fullPath.Replace("\\", "/");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 确定路径类型
|
||||||
|
/// </summary>
|
||||||
|
private PathType DeterminePathType(string path)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(path))
|
||||||
|
return PathType.LocalFile;
|
||||||
|
|
||||||
|
if (path.StartsWith("https://"))
|
||||||
|
return PathType.NetworkHTTPS;
|
||||||
|
if (path.StartsWith("http://"))
|
||||||
|
return PathType.NetworkHTTP;
|
||||||
|
if (path.StartsWith("localhost"))
|
||||||
|
return PathType.LocalServer;
|
||||||
|
if (path.StartsWith("StreamingAssets"))
|
||||||
|
return PathType.StreamingAssets;
|
||||||
|
|
||||||
|
return PathType.LocalFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Load
|
||||||
|
|
||||||
|
#region LoadAsync
|
||||||
|
|
||||||
|
public IEnumerator LoadAsTextAsync(Action<string> onSuccess, Action<string> onError = null)
|
||||||
|
{
|
||||||
|
using UnityWebRequest request = UnityWebRequest.Get(processedPath);
|
||||||
|
yield return request.SendWebRequest();
|
||||||
|
|
||||||
|
if (request.result == UnityWebRequest.Result.Success)
|
||||||
|
{
|
||||||
|
cachedData = request.downloadHandler.text;
|
||||||
|
onSuccess?.Invoke((string)cachedData);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
string errorMsg = $"Failed to load text from {originalPath}: {request.error}";
|
||||||
|
onError?.Invoke(errorMsg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerator LoadAsBinaryAsync(Action<byte[]> onSuccess, Action<string> onError = null)
|
||||||
|
{
|
||||||
|
using UnityWebRequest request = UnityWebRequest.Get(processedPath);
|
||||||
|
yield return request.SendWebRequest();
|
||||||
|
|
||||||
|
if (request.result == UnityWebRequest.Result.Success)
|
||||||
|
{
|
||||||
|
cachedData = request.downloadHandler.data;
|
||||||
|
onSuccess?.Invoke((byte[])cachedData);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
string errorMsg = $"Failed to load binary from {originalPath}: {request.error}";
|
||||||
|
onError?.Invoke(errorMsg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public IEnumerator LoadAsBinaryAsync(Action<float> progress, Action<byte[]> onSuccess, Action<string> onError = null)
|
||||||
|
{
|
||||||
|
using UnityWebRequest request = UnityWebRequest.Get(processedPath);
|
||||||
|
var result = request.SendWebRequest();
|
||||||
|
while (result.isDone == false)
|
||||||
|
{
|
||||||
|
progress(result.progress);
|
||||||
|
yield return null;
|
||||||
|
}
|
||||||
|
if (request.result == UnityWebRequest.Result.Success)
|
||||||
|
{
|
||||||
|
cachedData = request.downloadHandler.data;
|
||||||
|
onSuccess?.Invoke((byte[])cachedData);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
string errorMsg = $"Failed to load binary from {originalPath}: {request.error}";
|
||||||
|
onError?.Invoke(errorMsg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerator LoadAsRawJsonAsync<T>(Action<T> onSuccess, Action<string> onError = null)
|
||||||
|
{
|
||||||
|
yield return LoadAsTextAsync(
|
||||||
|
text =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
T result = JsonUtility.FromJson<T>(text);
|
||||||
|
cachedData = result;
|
||||||
|
onSuccess?.Invoke(result);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
onError?.Invoke($"Failed to parse JSON: {e.Message}");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onError
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerator LoadAsJsonAsync<T>(Action<T> onSuccess, Action<string> onError = null)
|
||||||
|
{
|
||||||
|
yield return LoadAsTextAsync(
|
||||||
|
text =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using StreamReader reader = new(new MemoryStream(System.Text.Encoding.UTF8.GetBytes(text)));
|
||||||
|
var jsonReader = new ES3Internal.ES3JSONReader(reader.BaseStream, new(originalPath));
|
||||||
|
onSuccess?.Invoke(jsonReader.Read<T>());
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
onError?.Invoke($"Failed to parse JSON: {e.Message}");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onError
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerator LoadAsImageAsync(Action<Texture2D> onSuccess, Action<string> onError = null)
|
||||||
|
{
|
||||||
|
using (UnityWebRequest request = UnityWebRequestTexture.GetTexture(processedPath))
|
||||||
|
{
|
||||||
|
yield return request.SendWebRequest();
|
||||||
|
|
||||||
|
if (request.result == UnityWebRequest.Result.Success)
|
||||||
|
{
|
||||||
|
Texture2D texture = DownloadHandlerTexture.GetContent(request);
|
||||||
|
cachedData = texture;
|
||||||
|
onSuccess?.Invoke(texture);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
string errorMsg = $"Failed to load image from {originalPath}: {request.error}";
|
||||||
|
onError?.Invoke(errorMsg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerator LoadAsAudioAsync(Action<AudioClip> onSuccess, Action<string> onError = null, AudioType audioType = AudioType.UNKNOWN)
|
||||||
|
{
|
||||||
|
if (audioType == AudioType.UNKNOWN)
|
||||||
|
audioType = GetAudioType(originalPath);
|
||||||
|
|
||||||
|
using (UnityWebRequest request = UnityWebRequestMultimedia.GetAudioClip(processedPath, audioType))
|
||||||
|
{
|
||||||
|
yield return request.SendWebRequest();
|
||||||
|
|
||||||
|
if (request.result == UnityWebRequest.Result.Success)
|
||||||
|
{
|
||||||
|
AudioClip audioClip = DownloadHandlerAudioClip.GetContent(request);
|
||||||
|
cachedData = audioClip;
|
||||||
|
onSuccess?.Invoke(audioClip);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
string errorMsg = $"Failed to load audio from {originalPath}: {request.error}";
|
||||||
|
onError?.Invoke(errorMsg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerator LoadAsAssetBundle(Action<float> progress, Action<AssetBundle> onSuccess, Action<string> onError = null)
|
||||||
|
{
|
||||||
|
AssetBundleCreateRequest request = null;
|
||||||
|
yield return LoadAsBinaryAsync(x => progress(x * 0.5f), data => request = AssetBundle.LoadFromMemoryAsync(data), onError);
|
||||||
|
while (request.isDone == false)
|
||||||
|
{
|
||||||
|
progress(0.5f + request.progress * 0.5f);
|
||||||
|
yield return null;
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
AssetBundle bundle = request.assetBundle;
|
||||||
|
if (bundle != null)
|
||||||
|
{
|
||||||
|
cachedData = bundle;
|
||||||
|
onSuccess?.Invoke(bundle);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
onError?.Invoke($"Failed to load AssetBundle from data.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
onError?.Invoke($"Failed to load AssetBundle: {e.Message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Load Sync
|
||||||
|
|
||||||
|
public string LoadAsText()
|
||||||
|
{
|
||||||
|
string buffer = null;
|
||||||
|
bool isEnd = false;
|
||||||
|
bool IsError = false;
|
||||||
|
var it = LoadAsTextAsync(x =>
|
||||||
|
{
|
||||||
|
buffer = x;
|
||||||
|
isEnd = true;
|
||||||
|
}, e =>
|
||||||
|
{
|
||||||
|
IsError = true;
|
||||||
|
throw new Exception(e);
|
||||||
|
});
|
||||||
|
try
|
||||||
|
{
|
||||||
|
while (!isEnd)
|
||||||
|
{
|
||||||
|
it.MoveNext();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
if(IsError)
|
||||||
|
{
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] LoadAsBinary()
|
||||||
|
{
|
||||||
|
byte[] buffer = null;
|
||||||
|
bool isEnd = false;
|
||||||
|
bool IsError = false;
|
||||||
|
var it = LoadAsBinaryAsync(x =>
|
||||||
|
{
|
||||||
|
buffer = x;
|
||||||
|
isEnd = true;
|
||||||
|
}, e =>
|
||||||
|
{
|
||||||
|
IsError = true;
|
||||||
|
throw new Exception(e);
|
||||||
|
});
|
||||||
|
try
|
||||||
|
{
|
||||||
|
while (!isEnd)
|
||||||
|
{
|
||||||
|
it.MoveNext();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
if (IsError)
|
||||||
|
{
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public T LoadAsRawJson<T>()
|
||||||
|
{
|
||||||
|
T buffer = default;
|
||||||
|
bool isEnd = false;
|
||||||
|
bool IsError = false;
|
||||||
|
var it = LoadAsRawJsonAsync<T>(x =>
|
||||||
|
{
|
||||||
|
buffer = x;
|
||||||
|
isEnd = true;
|
||||||
|
}, e =>
|
||||||
|
{
|
||||||
|
IsError = true;
|
||||||
|
throw new Exception(e);
|
||||||
|
});
|
||||||
|
try
|
||||||
|
{
|
||||||
|
while (!isEnd)
|
||||||
|
{
|
||||||
|
it.MoveNext();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
if (IsError)
|
||||||
|
{
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public T LoadAsJson<T>()
|
||||||
|
{
|
||||||
|
T buffer = default;
|
||||||
|
bool isEnd = false;
|
||||||
|
bool IsError = false;
|
||||||
|
var it = LoadAsJsonAsync<T>(x =>
|
||||||
|
{
|
||||||
|
buffer = x;
|
||||||
|
isEnd = true;
|
||||||
|
}, e =>
|
||||||
|
{
|
||||||
|
IsError = true;
|
||||||
|
throw new Exception(e);
|
||||||
|
});
|
||||||
|
try
|
||||||
|
{
|
||||||
|
while (!isEnd)
|
||||||
|
{
|
||||||
|
it.MoveNext();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
if (IsError)
|
||||||
|
{
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Texture2D LoadAsImage()
|
||||||
|
{
|
||||||
|
Texture2D buffer = null;
|
||||||
|
bool isEnd = false;
|
||||||
|
bool IsError = false;
|
||||||
|
var it = LoadAsImageAsync(x =>
|
||||||
|
{
|
||||||
|
buffer = x;
|
||||||
|
isEnd = true;
|
||||||
|
}, e =>
|
||||||
|
{
|
||||||
|
IsError = true;
|
||||||
|
throw new Exception(e);
|
||||||
|
});
|
||||||
|
try
|
||||||
|
{
|
||||||
|
while (!isEnd)
|
||||||
|
{
|
||||||
|
it.MoveNext();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
if (IsError)
|
||||||
|
{
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AudioClip LoadAsAudio(AudioType audioType = AudioType.UNKNOWN)
|
||||||
|
{
|
||||||
|
AudioClip buffer = null;
|
||||||
|
bool isEnd = false;
|
||||||
|
bool IsError = false;
|
||||||
|
var it = LoadAsAudioAsync(x =>
|
||||||
|
{
|
||||||
|
buffer = x;
|
||||||
|
isEnd = true;
|
||||||
|
}, e =>
|
||||||
|
{
|
||||||
|
IsError = true;
|
||||||
|
throw new Exception(e);
|
||||||
|
}, audioType);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
while (!isEnd)
|
||||||
|
{
|
||||||
|
it.MoveNext();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
if (IsError)
|
||||||
|
{
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Save
|
||||||
|
|
||||||
|
public Interaction SaveAsText(string content)
|
||||||
|
{
|
||||||
|
if (Application.platform == RuntimePlatform.WebGLPlayer)
|
||||||
|
{
|
||||||
|
throw new NotSupportedException("WebGL平台不支持文件保存。");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pathType != PathType.LocalFile)
|
||||||
|
{
|
||||||
|
throw new NotSupportedException("仅支持保存到本地文件路径。");
|
||||||
|
}
|
||||||
|
|
||||||
|
new ToolFile(originalPath).SaveAsText(content);
|
||||||
|
return this;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public Interaction SaveAsBinary(byte[] data)
|
||||||
|
{
|
||||||
|
if (Application.platform == RuntimePlatform.WebGLPlayer)
|
||||||
|
{
|
||||||
|
throw new NotSupportedException("WebGL平台不支持文件保存。");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pathType != PathType.LocalFile)
|
||||||
|
{
|
||||||
|
throw new NotSupportedException("仅支持保存到本地文件路径。");
|
||||||
|
}
|
||||||
|
|
||||||
|
new ToolFile(originalPath).SaveAsBinary(data);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Interaction SaveAsRawJson<T>(T obj)
|
||||||
|
{
|
||||||
|
new ToolFile(originalPath).SaveAsRawJson(obj);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Interaction SaveAsJson<T>(T obj)
|
||||||
|
{
|
||||||
|
new ToolFile(originalPath).SaveAsJson(obj);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Tools
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取本地文件路径
|
||||||
|
/// </summary>
|
||||||
|
private string GetLocalPath()
|
||||||
|
{
|
||||||
|
if (processedPath.StartsWith("file:///"))
|
||||||
|
{
|
||||||
|
return processedPath.Substring(8);
|
||||||
|
}
|
||||||
|
return originalPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 根据文件扩展名获取音频类型
|
||||||
|
/// </summary>
|
||||||
|
private AudioType GetAudioType(string path)
|
||||||
|
{
|
||||||
|
return BasicAudioSystem.GetAudioType(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 检查文件是否存在
|
||||||
|
/// </summary>
|
||||||
|
public bool Exists()
|
||||||
|
{
|
||||||
|
if (pathType == PathType.LocalFile && Application.platform != RuntimePlatform.WebGLPlayer)
|
||||||
|
{
|
||||||
|
return File.Exists(GetLocalPath());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// TODO : 网络文件和WebGL平台需要通过请求检查
|
||||||
|
// 当前默认存在
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 异步检查文件是否存在
|
||||||
|
/// </summary>
|
||||||
|
public IEnumerator ExistsAsync(Action<bool> callback)
|
||||||
|
{
|
||||||
|
using UnityWebRequest request = UnityWebRequest.Head(processedPath);
|
||||||
|
yield return request.SendWebRequest();
|
||||||
|
callback?.Invoke(request.result == UnityWebRequest.Result.Success);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Operator
|
||||||
|
|
||||||
|
public static implicit operator string(Interaction interaction) => interaction?.originalPath;
|
||||||
|
|
||||||
|
public override string ToString() => originalPath;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 路径连接操作符
|
||||||
|
/// </summary>
|
||||||
|
public static Interaction operator |(Interaction left, string rightPath)
|
||||||
|
{
|
||||||
|
if (left.pathType == PathType.NetworkHTTP || left.pathType == PathType.NetworkHTTPS || left.pathType == PathType.LocalServer)
|
||||||
|
{
|
||||||
|
string baseUrl = left.originalPath;
|
||||||
|
string newUrl = baseUrl.EndsWith("/") ? baseUrl + rightPath : baseUrl + "/" + rightPath;
|
||||||
|
return new Interaction(newUrl);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
string newPath = Path.Combine(left.originalPath, rightPath);
|
||||||
|
return new Interaction(newPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Tools
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取文件名
|
||||||
|
/// </summary>
|
||||||
|
public string GetFilename()
|
||||||
|
{
|
||||||
|
if (pathType == PathType.NetworkHTTP || pathType == PathType.NetworkHTTPS || pathType == PathType.LocalServer)
|
||||||
|
{
|
||||||
|
var uri = new Uri(processedPath);
|
||||||
|
return Path.GetFileName(uri.AbsolutePath);
|
||||||
|
}
|
||||||
|
return Path.GetFileName(originalPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取文件扩展名
|
||||||
|
/// </summary>
|
||||||
|
public string GetExtension()
|
||||||
|
{
|
||||||
|
return Path.GetExtension(GetFilename());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 检查扩展名
|
||||||
|
/// </summary>
|
||||||
|
public bool ExtensionIs(params string[] extensions)
|
||||||
|
{
|
||||||
|
string ext = GetExtension().ToLower();
|
||||||
|
string extWithoutDot = ext.Length > 1 ? ext[1..] : "";
|
||||||
|
|
||||||
|
foreach (string extension in extensions)
|
||||||
|
{
|
||||||
|
string checkExt = extension.ToLower();
|
||||||
|
if (ext == checkExt || extWithoutDot == checkExt || ext == "." + checkExt)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Tools
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 创建一个新的Interaction实例
|
||||||
|
/// </summary>
|
||||||
|
public static Interaction Create(string path) => new(path);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 从StreamingAssets创建
|
||||||
|
/// </summary>
|
||||||
|
public static Interaction FromStreamingAssets(string relativePath)
|
||||||
|
{
|
||||||
|
return new Interaction("StreamingAssets/" + relativePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 从本地服务器创建
|
||||||
|
/// </summary>
|
||||||
|
public static Interaction FromLocalhost(string path, int port = 80)
|
||||||
|
{
|
||||||
|
string url = port == 80 ? $"localhost/{path}" : $"localhost:{port}/{path}";
|
||||||
|
return new Interaction(url);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
11
Convention/[Runtime]/Interaction.cs.meta
Normal file
11
Convention/[Runtime]/Interaction.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 731a0091a68afe9458917e4dd0267656
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@@ -18,7 +18,7 @@ namespace Convention.WindowsUI
|
|||||||
|
|
||||||
[Content, OnlyPlayMode, Ignore] public RectTransformInfo BeforeMaximizeWindow = null;
|
[Content, OnlyPlayMode, Ignore] public RectTransformInfo BeforeMaximizeWindow = null;
|
||||||
[Content, OnlyPlayMode, Ignore] public float BeforeMaximizeWindowBackgroundColorA = 1f;
|
[Content, OnlyPlayMode, Ignore] public float BeforeMaximizeWindowBackgroundColorA = 1f;
|
||||||
private bool IsMaximizeWindowMode = false;
|
[SerializeField] private bool IsMaximizeWindowMode = false;
|
||||||
[Content, OnlyPlayMode]
|
[Content, OnlyPlayMode]
|
||||||
public void MaximizeWindow()
|
public void MaximizeWindow()
|
||||||
{
|
{
|
||||||
|
@@ -118,6 +118,14 @@ namespace Convention.WindowsUI.Variant
|
|||||||
dropdownImage.eulerAngles = new(0, 0, 0);
|
dropdownImage.eulerAngles = new(0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public virtual void RefreshChilds()
|
||||||
|
{
|
||||||
|
ConventionUtility.CreateSteps()
|
||||||
|
.Next(() => Switch())
|
||||||
|
.Next(() => Switch())
|
||||||
|
.Invoke();
|
||||||
|
}
|
||||||
|
|
||||||
public List<ItemEntry> CreateSubPropertyItem([In] PropertiesWindow propertyWindow, int count)
|
public List<ItemEntry> CreateSubPropertyItem([In] PropertiesWindow propertyWindow, int count)
|
||||||
{
|
{
|
||||||
List<ItemEntry> result = new();
|
List<ItemEntry> result = new();
|
||||||
|
Reference in New Issue
Block a user