EditorTool3D/Assets/ZXL/Scripts/Manager/AssetManager.cs

473 lines
15 KiB
C#
Raw Normal View History

2024-12-17 23:11:00 +08:00
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Newtonsoft.Json;
using TriLibCore;
using TriLibCore.SFB;
using UnityEngine;
using UnityEngine.Networking;
using ZXL.Helper;
namespace ZXL.Manager
{
class AssetManager : Manager<AssetManager>
{
private Dictionary<string, Dictionary<string, AssetInfo>> assets;
private AssetConfigCas cas;
private Camera renderCamera;
RenderTexture renderTexture;
Texture2D capturedImage;
private GameObject object_M;
/// <summary>
/// 上传模型成功的回调
/// </summary>
public Action<AssetInfo> addItemAction;
/// <summary>
/// 初始化成功的回调
/// </summary>
public Action initAction;
public override void OnAwake()
{
base.OnAwake();
assets = new Dictionary<string, Dictionary<string, AssetInfo>>();
assets.Add(AssetTag..ToString(), new Dictionary<string, AssetInfo>());
assets.Add(AssetTag..ToString(), new Dictionary<string, AssetInfo>());
assets.Add(AssetTag..ToString(), new Dictionary<string, AssetInfo>());
if (File.Exists(ZConst.AssetConfigPath))
{
var text = File.ReadAllText(ZConst.AssetConfigPath);
cas = JsonConvert.DeserializeObject<AssetConfigCas>(text);
}
if (cas == null)
{
cas = new AssetConfigCas();
cas.AssetConfigCa = new Dictionary<string, Dictionary<string, AssetConfigCa>>();
cas.AssetConfigCa.Add("公司", new Dictionary<string, AssetConfigCa>());
cas.AssetConfigCa.Add("个人", new Dictionary<string, AssetConfigCa>());
cas.AssetConfigCa.Add("项目", new Dictionary<string, AssetConfigCa>());
}
object_M = new GameObject("object_M");
object_M.SetActive(false);
StartCoroutine(Init());
}
public void SetCamera(Camera camera)
{
renderCamera = camera;
// renderTexture = new RenderTexture(renderCamera.pixelWidth, renderCamera.pixelHeight, 24);
renderTexture = renderCamera.targetTexture;
}
#region Config (完成)
/// <summary>
/// init config
/// </summary>
/// <returns></returns>
/// <exception cref="ArgumentOutOfRangeException"></exception>
IEnumerator Init()
{
foreach (var dic in cas.AssetConfigCa.Values)
{
foreach (var ca in dic.Values)
{
var context = AssetLoader.LoadModelFromFile(ca.AssetPath, null, null, OnProgress, null, object_M);
while (true)
{
if (context.LoadingProgress >= 1)
break;
yield return null;
}
context.WrapperGameObject.name = ca.Name;
var sprite = LoadSprite(ca.SpritePath);
var assetInfo = new AssetInfo()
{
Name = ca.Name, GameObject = context.WrapperGameObject, Sprite = sprite, AssetTag = ca.AssetTag,
Config = ca
};
if (assets.TryGetValue(ca.AssetTag, out Dictionary<string, AssetInfo> infos))
{
infos.Add(ca.Name, assetInfo);
Debug.Log($"init add {ca.Name} !");
}
}
}
initAction?.Invoke();
void OnProgress(AssetLoaderContext arg1, float arg2)
{
}
}
/// <summary>
/// update config asset data
/// </summary>
private void UpdateAssetData()
{
var s = JsonConvert.SerializeObject(cas);
if (!File.Exists(ZConst.AssetConfigPath))
File.CreateText(ZConst.AssetConfigPath).Dispose();
File.WriteAllText(ZConst.AssetConfigPath, s);
}
/// <summary>
/// add config item
/// </summary>
/// <param name="fname"></param>
/// <param name="assetPath"></param>
/// <param name="spritePath"></param>
/// <param name="assetTag"></param>
void AddConfig(AssetConfigCa configCa)
{
cas.AssetConfigCa[configCa.AssetTag].Add(configCa.Name, configCa);
UpdateAssetData();
}
void DeleteConfig(string assetTag, string configName)
{
cas.AssetConfigCa[assetTag].Remove(configName);
UpdateAssetData();
}
#endregion
#region AssetInfo
#region 上传(完成)
/// <summary>
/// upload and load to scene
/// </summary>
/// <param name="title"></param>
/// <param name="wrapperGameObject"></param>
/// <param name="assetTag"></param>
/// <param name="callback"></param>
public void PushAsset(string title, GameObject wrapperGameObject, AssetTag assetTag,
Action<string, string, GameObject> callback = null)
{
StartCoroutine(PushModel_I(title, wrapperGameObject, assetTag, callback));
}
IEnumerator PushModel_I(string title, GameObject wrapperGameObject, AssetTag assetTag,
Action<string, string, GameObject> callback = null)
{
string exten = "";
var paths = StandaloneFileBrowser.OpenFilePanel(title ?? "Open File", "", exten, false);
if (paths.Count == 0)
{
Debug.Log("Selected file: " + paths[0].Name);
yield break;
}
else
{
var strings = paths[0].Name.Split("/");
var name = strings[strings.Length - 1];
string savePathWithName;
switch (assetTag)
{
case AssetTag.:
savePathWithName = $"{ZConst.AssetRootPath_GS}/{name}";
break;
case AssetTag.:
savePathWithName = $"{ZConst.AssetRootPath_GR}/{name}";
break;
case AssetTag.:
savePathWithName = $"{ZConst.AssetRootPath_XM}/{name}";
break;
default:
throw new ArgumentOutOfRangeException(nameof(assetTag), assetTag, null);
}
tempFilePath = savePathWithName;
if (File.Exists(savePathWithName))
{
File.Delete(savePathWithName);
}
UnityWebRequest request = UnityWebRequest.Get(paths[0].Name);
request.SendWebRequest();
while (true)
{
if (request.isDone)
{
byte[] results = request.downloadHandler.data;
// 通过模型数据写入本地
FileInfo file = new FileInfo(savePathWithName);
if (file.Directory != null) file.Directory.Create();
Stream sw;
sw = file.Create();
sw.Write(results, 0, results.Length);
sw.Close();
sw.Dispose();
break;
}
else if (request.isNetworkError)
{
Debug.Log("Download Error:" + request.error);
break;
}
yield return new WaitForSeconds(Time.deltaTime);
}
GameObject obj = null;
bool isTrue = false;
var loadModelFromFile =
AssetLoader.LoadModelFromFile(savePathWithName, null, null, OnProgress, null, wrapperGameObject);
while (!isTrue)
{
Debug.Log(loadModelFromFile.LoadingProgress);
yield return null;
}
obj = loadModelFromFile.RootGameObject;
obj.transform.SetWithChildLayer(LayerMask.NameToLayer("PushModel"));
tempGameObject = obj;
var split = name.Split(".")[0];
callback?.Invoke(split, savePathWithName, obj);
yield break;
void OnProgress(AssetLoaderContext arg1, float arg2)
{
if (arg2.Equals(1f) || arg1.RootGameObject!=null)
{
isTrue = true;
}
}
}
}
string tempFilePath;
GameObject tempGameObject;
public void CancelAsset()
{
if (File.Exists(tempFilePath))
File.Delete(tempFilePath);
GameObject.Destroy(tempGameObject);
tempFilePath = null;
tempGameObject = null;
}
#endregion
#region 搜索
#endregion
#region 删除(完成)
public void DeleteAssets(AssetInfo info)
{
if (assets.TryGetValue(info.AssetTag, out var value))
{
DeleteConfig(info.AssetTag, info.Name);
value.Remove(info.Name);
//TODO: is with delete asset ?
var directoryInfo = new FileInfo(info.Config.AssetPath).Directory;
directoryInfo?.Parent?.Delete(true);
}
}
#endregion
#region 重命名 (完成)
public void RenameAsset(string assetTag, AssetInfo info, string newName)
{
string cstr = info.Name;
info.Name = newName;
var config = info.Config;
if (config == null)
throw new NullReferenceException();
config.Name = newName;
var asset = FileHelper.RenameFile(config.AssetPath, newName);
config.AssetPath = asset;
asset = FileHelper.RenameFile(config.SpritePath, newName);
config.SpritePath = asset;
cas.AssetConfigCa[assetTag][cstr] = config;
assets[assetTag][cstr] = info;
UpdateAssetData();
}
#endregion
#region 拷贝 (完成)
public void CopyAsset(string assetTag, AssetInfo info)
{
string cstr = info.Name;
var configAssetPath = info.Config.AssetPath;
FileHelper.CopyFile(configAssetPath);
assets[assetTag][cstr] = info;
cas.AssetConfigCa[assetTag][cstr] = info.Config;
UpdateAssetData();
}
#endregion
#region 移动
public void MoveAsset(string oldPath, string newPath)
{
FileHelper.MoveDirectoryWithFiles(oldPath, newPath);
2024-12-17 23:11:00 +08:00
}
#endregion
#region 筛选
#endregion
#region Icon
/// <summary>
/// 更新图标
/// </summary>
/// <param name="fileName"></param>
/// <param name="assetPathWithName"></param>
/// <param name="assetTag"></param>
/// <param name="go"></param>
/// <exception cref="ArgumentOutOfRangeException"></exception>
public void AddItemAndGenIcon(string fileName, string assetPathWithName, AssetTag assetTag, GameObject go)
{
var pngPath = Path.Combine(ZConst.AssetCacheIcon, fileName) + ".jpg";
var sprite = JT(pngPath);
var tagStr = assetTag.ToString();
AssetConfigCa ca = new AssetConfigCa();
ca.Name = fileName;
ca.AssetPath = assetPathWithName;
ca.SpritePath = pngPath;
ca.AssetTag = tagStr;
var assetInfo = new AssetInfo()
{
Name = fileName,
Sprite = sprite,
GameObject = go,
AssetTag = tagStr,
Config = ca
};
if (assets.TryGetValue(tagStr, out var value))
{
if (value.TryAdd(fileName, assetInfo))
{
AddConfig(ca);
addItemAction?.Invoke(assetInfo);
}
value[fileName] = assetInfo;
}
}
Sprite JT(string assetPathWithName)
{
// 创建一个 Texture2D 用来存储相机捕捉的画面
capturedImage = new Texture2D(renderTexture.width, renderTexture.height, TextureFormat.RGB24, false);
// 从 RenderTexture 中读取像素数据到 Texture2D
RenderTexture.active = renderTexture;
capturedImage.ReadPixels(new Rect(0, 0, renderTexture.width, renderTexture.height), 0, 0);
capturedImage.Apply();
// 重置 RenderTexture 的激活状态
RenderTexture.active = null;
// 此时 capturedImage 就包含了当前帧的画面,你可以进行保存或者其他操作
// 示例:保存为 PNG 文件
byte[] bytes = capturedImage.EncodeToJPG();
new FileInfo(assetPathWithName).Directory?.Create();
if (File.Exists(assetPathWithName))
File.Delete(assetPathWithName);
System.IO.File.WriteAllBytes(assetPathWithName, bytes);
// 清理资源
Destroy(capturedImage);
var sprite = LoadSprite(assetPathWithName);
return sprite;
}
Sprite LoadSprite(string assetPathWithName)
{
var bytes = File.ReadAllBytes(assetPathWithName);
Texture2D texture2D = new Texture2D(10, 10);
texture2D.LoadImage(bytes);
Sprite sp = Sprite.Create(texture2D, new Rect(0, 0, texture2D.width, texture2D.height), Vector2.zero);
return sp;
}
#endregion
#endregion
public List<AssetInfo> GetAssets(AssetTag assetTag)
{
if (assets.TryGetValue(assetTag.ToString(), out var value))
{
return value.Values.ToList();
}
return null;
}
}
[System.Serializable]
public class AssetInfo
{
public string Name;
public GameObject GameObject;
public Sprite Sprite;
public string AssetTag;
public AssetConfigCa Config = new AssetConfigCa();
}
[System.Serializable]
public class AssetConfigCas
{
/// <summary>
/// the first str is tag ,
/// the second str is fileName ,
/// no double names allowed
/// </summary>
public Dictionary<string, Dictionary<string, AssetConfigCa>> AssetConfigCa =
new Dictionary<string, Dictionary<string, AssetConfigCa>>();
}
[System.Serializable]
public class AssetConfigCa
{
public string Name;
public string AssetPath;
public string SpritePath;
public string AssetTag;
}
public enum AssetTag
{
,
,
,
}
}