350 lines
12 KiB
C#
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;
|
|
}
|
|
}
|
|
}
|