473 lines
15 KiB
C#
473 lines
15 KiB
C#
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);
|
|
}
|
|
|
|
#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
|
|
{
|
|
公司,
|
|
个人,
|
|
项目,
|
|
}
|
|
} |