260 lines
9.0 KiB
C#

/*
* @Author: 白哉
* @Description:
* @Date: 2026年01月26日 星期一 17:01:00
* @Modify:
*/
using System.Collections.Generic;
using System.IO;
using Logic.CrashSight;
using MemoryPack;
using TH1_Logic.Tools;
using UnityEngine;
using Vector2 = System.Numerics.Vector2;
namespace TH1_Logic.Comic
{
public class ComicManager
{
public static ComicManager Instance = new ComicManager();
private ComicAsset _asset;
private ImageMapData _imageMap;
public ComicAsset Asset => _asset;
public ImageMapData ImageMap => _imageMap;
private GameObject _comicPrefab;
private GameObject _comicInstance;
private ComicMono _comicMono;
private Dictionary<string, Sprite> _comicSprites = new Dictionary<string, Sprite>();
private ComicControl _comicControl = new ComicControl();
public ComicControl ComicControl => _comicControl;
public void InitComic(string comicName, GameObject root)
{
Refresh();
_asset?.EnsureCollectionsInitialized();
var sheet = _asset?.GetComicSheetByName(comicName);
if (sheet == null)
{
LogSystem.LogError($"[ComicManager] PlayComic failed: ComicSheet {comicName} not found");
return;
}
// IL2CPP 保护
sheet.EnsureCollectionsInitialized();
if (sheet.ComicDatas == null || sheet.ComicDatas.Count == 0)
{
LogSystem.LogError($"[ComicManager] PlayComic failed: ComicSheet {comicName} has no ComicData");
return;
}
_comicControl ??= new ComicControl();
_comicControl.Init(sheet, root);
}
public void Next()
{
_comicControl?.Next();
}
public void ForceNext()
{
_comicControl?.ForceNext();
}
public void Update()
{
_comicControl?.Update(Time.deltaTime);
}
public void Refresh()
{
_asset ??= LoadComicAsset() ?? new ComicAsset();
_imageMap ??= LoadImageMap() ?? new ImageMapData();
_comicControl ??= new ComicControl();
}
public void AddComicSheet(string name)
{
Refresh();
_asset.AddComicSheet(name);
}
public ComicDialogLayoutParam GetDialogLayoutParamByImageName(string imageName)
{
return _asset?.GetDialogLayoutParamByImageName(imageName);
}
public Sprite GetImage(string name)
{
if (_comicSprites.TryGetValue(name, out var image)) return image;
var texture = LoadImage(name);
if (texture) _comicSprites[name] = texture;
else LogSystem.LogError($"[ComicManager] GetImage failed: {name}");
return texture;
}
public Sprite LoadImage(string name)
{
var path = _imageMap?.GetImageMap(name);
if (string.IsNullOrEmpty(path)) return null;
var sprite = TH1Resource.ResourceLoader.Load<Sprite>(path);
if (!sprite) LogSystem.LogError($"[ComicManager] LoadImage failed: {path}");
return sprite;
}
public GameObject LoadPrefab(string name)
{
var prefab = TH1Resource.ResourceLoader.Load<GameObject>($"ArtResources/Comic/Prefab/{name}");
if (!prefab) LogSystem.LogError($"[ComicManager] LoadPrefab failed: {name}");
return prefab;
}
public ComicAsset LoadComicAsset()
{
try
{
string resourcePath = $"Comic/ComicAsset";
TextAsset textAsset = TH1Resource.ResourceLoader.Load<TextAsset>(resourcePath);
if (textAsset == null)
{
LogSystem.LogWarning($"LoadComicAsset: 未找到资源 {resourcePath}");
return null;
}
ComicAsset comicConfig = TH1Serialization.Deserialize<ComicAsset>(textAsset.bytes);
LogSystem.LogInfo($"LoadComicAsset: 加载成功");
return comicConfig;
}
catch (System.Exception e)
{
LogSystem.LogWarning($"LoadComicAsset: 加载失败 - {e.Message}");
return null;
}
}
public ImageMapData LoadImageMap()
{
try
{
string resourcePath = $"Comic/ImageMap";
TextAsset textAsset = TH1Resource.ResourceLoader.Load<TextAsset>(resourcePath);
if (textAsset == null)
{
LogSystem.LogWarning($"LoadImageMap: 未找到资源 {resourcePath}");
return null;
}
ImageMapData imageMap = TH1Serialization.Deserialize<ImageMapData>(textAsset.bytes);
LogSystem.LogInfo($"LoadImageMap: 加载成功");
return imageMap;
}
catch (System.Exception e)
{
LogSystem.LogWarning($"LoadImageMap: 加载失败 - {e.Message}");
return null;
}
}
public void SaveImageMapData()
{
#if UNITY_EDITOR
if (_imageMap == null) return;
try
{
// 确保文件夹存在
string folderPath = Path.Combine(Application.dataPath, "BundleResources", "Comic");
if (!Directory.Exists(folderPath)) Directory.CreateDirectory(folderPath);
string filePath = Path.Combine(folderPath, $"ImageMap.bytes");
byte[] bytes = TH1Serialization.Serialize(_imageMap);
File.WriteAllBytes(filePath, bytes);
// 刷新 AssetDatabase
UnityEditor.AssetDatabase.Refresh();
LogSystem.LogInfo($"SaveImageMapData: SaveImageMapData 保存成功,路径: {filePath}");
}
catch (System.Exception e)
{
LogSystem.LogWarning($"SaveImageMapData: 保存失败 - {e.Message}");
}
#endif
}
public void SaveComicData()
{
#if UNITY_EDITOR
if (_asset == null) return;
try
{
// 确保文件夹存在
string folderPath = Path.Combine(Application.dataPath, "BundleResources", "Comic");
if (!Directory.Exists(folderPath)) Directory.CreateDirectory(folderPath);
string filePath = Path.Combine(folderPath, $"ComicAsset.bytes");
byte[] bytes = TH1Serialization.Serialize(_asset);
File.WriteAllBytes(filePath, bytes);
// 刷新 AssetDatabase
UnityEditor.AssetDatabase.Refresh();
LogSystem.LogInfo($"SaveComicData: SaveComicData 保存成功,路径: {filePath}");
}
catch (System.Exception e)
{
LogSystem.LogWarning($"SaveComicData: 保存失败 - {e.Message}");
}
#endif
}
public void RefreshImageData()
{
#if UNITY_EDITOR
Refresh();
_imageMap.ImageMap.Clear();
// 获取 Resources/Comic 文件夹的物理路径
string comicPath = Path.Combine(Application.dataPath, "BundleResources", "ArtResources/Comic");
if (!Directory.Exists(comicPath))
{
LogSystem.LogWarning($"RefreshImageData: 未找到文件夹 {comicPath}");
return;
}
// 递归搜索所有图片文件
string[] imageExtensions = new[] { "*.png", "*.jpg", "*.jpeg" };
List<string> allImageFiles = new List<string>();
foreach (var extension in imageExtensions)
{
var files = Directory.GetFiles(comicPath, extension, SearchOption.AllDirectories);
allImageFiles.AddRange(files);
}
// 添加到 ImageMap
foreach (var filePath in allImageFiles)
{
// 获取 Resources 文件夹路径
string resourcesPath = Path.Combine(Application.dataPath, "BundleResources");
// 转换为相对于 Resources 的路径
string relativePath = filePath.Replace(resourcesPath, "").TrimStart(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
// 移除扩展名
string imageKey = Path.GetFileNameWithoutExtension(Path.GetFileName(relativePath));
// 转换为资源加载器使用的路径格式(移除扩展名)
string resourcePath = Path.ChangeExtension(relativePath, null).Replace(Path.DirectorySeparatorChar, '/');
_imageMap.ImageMap.TryAdd(imageKey, resourcePath);
}
LogSystem.LogInfo($"RefreshImageData: 已刷新 {_imageMap.ImageMap.Count} 张图片");
SaveImageMapData();
#endif
}
}
}