2026-05-12 14:39:10 +08:00

350 lines
12 KiB
C#

/*
* @Author: 白哉
* @Description:
* @Date: 2026年01月29日 星期四 16:01:25
* @Modify:
*/
using System.Collections.Generic;
using Logic.CrashSight;
using UnityEngine;
namespace TH1_Logic.Comic
{
public enum ComicState
{
None = 0,
Prepared = 1,
Playing = 2,
Pausing = 3,
Ended = 4,
}
public class ComicControl
{
private GameObject _comicRoot;
private ComicData _comicData;
private ComicSheet _comicSheet;
private float _speed = 1f;
private float _progress = 0f;
private float _duration = 10f;
private int _actionIndex = 0;
private int _comicMaxIndex = 0;
private ComicState _state = ComicState.None;
private Dictionary<int, int> _actionHandle = new Dictionary<int, int>();
public GameObject ComicRoot => _comicRoot;
public ComicSheet ComicSheet => _comicSheet;
public ComicState State => _state;
public int ActionIndex => _actionIndex;
public int MaxIndex => _comicMaxIndex;
public float Progress => _progress;
public float Duration => _duration;
public void Init(ComicSheet sheet, GameObject comicRoot)
{
Clear();
if (!comicRoot) return;
// IL2CPP 保护:确保所有集合已初始化
sheet?.EnsureCollectionsInitialized();
_comicRoot = comicRoot;
_comicSheet = sheet;
var comicPrefab = ComicManager.Instance.LoadPrefab("ComicPrefab");
if (!comicPrefab)
{
LogSystem.LogError($"ComicControl Init Error ComicPrefab is null");
return;
}
var dialogPrefab = ComicManager.Instance.LoadPrefab("DialogPrefab");
if (!dialogPrefab)
{
LogSystem.LogError($"ComicControl Init Error DialogPrefab is null");
return;
}
var imagePrefab = ComicManager.Instance.LoadPrefab("ImagePrefab");
if (!imagePrefab)
{
LogSystem.LogError($"ComicControl Init Error ImagePrefab is null");
return;
}
var index = 0;
for (int i = 0; i < _comicSheet.ComicDatas.Count; i++)
{
var data = _comicSheet.ComicDatas[i];
var comicInstance = Object.Instantiate(comicPrefab, _comicRoot.transform, false);
data.Mono = comicInstance.GetComponent<ComicMono>();
if (!data.Mono)
{
LogSystem.LogError($"ComicControl Init Error _comicMono is null");
return;
}
data.ApplyToMono();
// IL2CPP 保护:跳过 null 集合
if (data.SubItems == null)
{
LogSystem.LogWarning($"[ComicControl] ComicData SubItems is null, initializing empty list");
data.SubItems = new List<ComicSubItem>();
}
foreach (var item in data.SubItems)
{
GameObject instance = null;
if(item.ItemType == ComicSubItemType.Image)
instance = Object.Instantiate(imagePrefab, data.Mono.ItemRoot, false);
if(item.ItemType == ComicSubItemType.Dialog)
instance = Object.Instantiate(dialogPrefab, data.Mono.ItemRoot, false);
var itemMono = instance?.GetComponent<ComicItemMono>();
if (!itemMono)
{
LogSystem.LogError($"ComicControl Init Error itemMono is null");
continue;
}
item.Mono = itemMono;
item.ApplyToItemMono();
}
if (i == 0)
{
data.InitFadeInAction(ComicActionType.FadeIn);
}
else
{
data.InitFadeInAction(ComicActionType.AllSlideInUp);
}
if (i == _comicSheet.ComicDatas.Count - 1)
{
data.InitFadeOutAction(ComicActionType.FadeOut);
}
else
{
data.InitFadeOutAction(ComicActionType.AllFadeOut);
}
data.FadeInAction.Index = index;
// IL2CPP 保护
if (data.Actions == null)
{
LogSystem.LogWarning($"[ComicControl] ComicData Actions is null, initializing empty list");
data.Actions = new List<ComicAction>();
}
foreach (var action in data.Actions)
{
index++;
action.Index = index;
}
index++;
data.FadeOutAction.Index = index;
}
_comicMaxIndex = index;
_actionIndex = 0;
_progress = 0;
_state = ComicState.Prepared;
Update(0f);
}
public void PreviewComicData(ComicData data, GameObject comicRoot)
{
Clear();
if (!comicRoot) return;
_comicRoot = comicRoot;
_comicData = data;
var comicPrefab = ComicManager.Instance.LoadPrefab("ComicPrefab");
if (!comicPrefab)
{
LogSystem.LogError($"ComicControl Init Error ComicPrefab is null");
return;
}
var dialogPrefab = ComicManager.Instance.LoadPrefab("DialogPrefab");
if (!dialogPrefab)
{
LogSystem.LogError($"ComicControl Init Error DialogPrefab is null");
return;
}
var imagePrefab = ComicManager.Instance.LoadPrefab("ImagePrefab");
if (!imagePrefab)
{
LogSystem.LogError($"ComicControl Init Error ImagePrefab is null");
return;
}
var comicInstance = Object.Instantiate(comicPrefab, _comicRoot.transform, false);
data.Mono = comicInstance.GetComponent<ComicMono>();
if (!data.Mono)
{
LogSystem.LogError($"ComicControl Init Error _comicMono is null");
return;
}
data.ApplyToMono();
foreach (var item in data.SubItems)
{
GameObject instance = null;
if(item.ItemType == ComicSubItemType.Image)
instance = Object.Instantiate(imagePrefab, data.Mono.ItemRoot, false);
if(item.ItemType == ComicSubItemType.Dialog)
instance = Object.Instantiate(dialogPrefab, data.Mono.ItemRoot, false);
var itemMono = instance?.GetComponent<ComicItemMono>();
if (!itemMono)
{
LogSystem.LogError($"ComicControl Init Error itemMono is null");
continue;
}
item.Mono = itemMono;
item.ApplyToItemMono();
}
}
public void ForceNext()
{
if (_state == ComicState.Ended) return;
if (_state == ComicState.Playing)
{
Update(Mathf.Max(_duration - _progress, 0f));
}
if (_state == ComicState.Prepared)
{
_state = ComicState.Playing;
_actionIndex = 0;
_progress = 0;
_state = ComicState.Playing;
}
if (_state == ComicState.Pausing)
{
if (_actionIndex >= _comicMaxIndex)
{
_state = ComicState.Ended;
return;
}
_actionIndex++;
_progress = 0;
_state = ComicState.Playing;
}
}
public void Next()
{
if (_state == ComicState.Ended) return;
if (_state == ComicState.Playing)
{
Update(Mathf.Max(_duration - _progress, 0f));
return;
}
if (_state == ComicState.Prepared)
{
_state = ComicState.Playing;
_actionIndex = 0;
_progress = 0;
_state = ComicState.Playing;
}
if (_state == ComicState.Pausing)
{
if (_actionIndex >= _comicMaxIndex)
{
_state = ComicState.Ended;
return;
}
_actionIndex++;
_progress = 0;
_state = ComicState.Playing;
}
}
public void Update(float deltaTime = 0.016f)
{
if (deltaTime != 0 && _state != ComicState.Playing) return;
_actionHandle.Clear();
_progress += deltaTime * _speed;
_duration = 0;
foreach (var data in _comicSheet.ComicDatas)
{
// IL2CPP 保护
if (data.Actions == null) continue;
foreach (var action in data.Actions) UpdateAction(data, action);
}
for (int i = _comicSheet.ComicDatas.Count - 1; i >= 0; i--)
{
UpdateAction(_comicSheet.ComicDatas[i], _comicSheet.ComicDatas[i].FadeOutAction);
}
for (int i = _comicSheet.ComicDatas.Count - 1; i >= 0; i--)
{
UpdateAction(_comicSheet.ComicDatas[i], _comicSheet.ComicDatas[i].FadeInAction);
}
if (_progress >= _duration) _state = ComicState.Pausing;
}
private void UpdateAction(ComicData data, ComicAction action)
{
var logic = ComicActionLogicFactory.GetActionLogic(action.ActionType);
var item = data.GetSubItemById(action.TargetId);
if (action.Index == _actionIndex)
{
var ratio = Mathf.Min(1, _progress / action.Duration);
logic.SetUpdateAction(data, item, action, ratio);
if (action.TargetId >= 0) _actionHandle[action.TargetId] = action.Index;
if (action.Duration > _duration) _duration = action.Duration;
}
if (_actionHandle.TryGetValue(action.TargetId, out var value)) return;
if (action.Index < _actionIndex)
{
logic.SetEndState(data, item, action);
}
if (action.Index > _actionIndex)
{
logic.SetStartState(data, item, action);
}
}
public void Exit()
{
Clear();
}
public void Clear()
{
_state = ComicState.None;
if (_comicSheet != null)
{
foreach (var data in _comicSheet.ComicDatas) ClearComicData(data);
}
if (_comicData != null) ClearComicData(_comicData);
}
public void ClearComicData(ComicData data)
{
if(data.Mono) Object.DestroyImmediate(data.Mono.gameObject);
foreach (var item in data.SubItems)
{
if (item.Mono) Object.DestroyImmediate(item.Mono.gameObject);
item.Mono = null;
}
data.Mono = null;
}
}
}