Files
aibis-dream/Assets/Scripts/FixSystemNew/Screen System/Core/RepairSystemManager.cs
T

249 lines
7.7 KiB
C#

using System;
using System.Collections.Generic;
using AibisDream.Kit;
using DG.Tweening;
using UnityEngine;
using Sequence = DG.Tweening.Sequence;
namespace AibisDream.FixSystem
{
/// <summary>
/// 维修系统注册信息
/// </summary>
public class RegisteredSystem
{
public Type SystemType;
public Transform Transform;
public Vector3 OriginalPosition;
public Vector3 OriginalScale;
public Vector3 Offset;
}
/// <summary>
/// 维修系统管理器 - 管理面板中央的维修系统切换和视图控制
/// </summary>
public class RepairSystemManager : Singleton<RepairSystemManager>
{
[Header("位置配置")]
[Tooltip("面板中央放置位(激活系统位置)")]
[SerializeField] private Transform centerSlot;
[Tooltip("屏幕外隐藏位置(非激活系统位置)")]
[SerializeField] private Transform hiddenSlot;
[Header("缩放动画")]
[SerializeField] private float scaleDuration = 0.3f;
[SerializeField] private Ease scaleEase = Ease.OutBack;
// 注册的系统字典
private readonly Dictionary<Type, RegisteredSystem> _registeredSystems = new();
// 当前激活的系统类型
private Type _currentSystemType = typeof(BodyModuleSystem);
private Sequence _activeScaleTween;
private void OnDisable()
{
_registeredSystems.Clear();
}
#region 系统注册
/// <summary>
/// 注册维修系统到管理器(供系统自注册使用)
/// </summary>
public static void Register<T>(T instance) where T : class
{
if (instance is not MonoBehaviour mb)
{
Debug.LogError($"[RepairSystemManager] 注册失败:{typeof(T).Name} 不是 MonoBehaviour");
return;
}
var type = typeof(T);
var system = new RegisteredSystem
{
SystemType = type,
Transform = mb.transform,
OriginalPosition = mb.transform.position,
OriginalScale = mb.transform.localScale,
Offset = Vector3.zero
};
if (Instance != null)
{
Instance._registeredSystems[type] = system;
}
Debug.Log($"[RepairSystemManager] 注册系统: {type.Name}");
}
#endregion
#region 系统切换
/// <summary>
/// 切换到指定类型的维修系统
/// </summary>
public void SwitchSystem<T>() where T : class
{
SwitchSystem(typeof(T));
}
/// <summary>
/// 切换到指定类型的维修系统
/// </summary>
public void SwitchSystem(Type systemType)
{
if (_currentSystemType == systemType) return;
if (!_registeredSystems.TryGetValue(systemType, out var targetSystem))
{
Debug.LogError($"[RepairSystemManager] 未找到系统: {systemType.Name}");
return;
}
PerformSwitch(targetSystem);
}
private void PerformSwitch(RegisteredSystem targetSystem)
{
// 停止当前动画
_activeScaleTween?.Kill();
_activeScaleTween = null;
// 获取当前系统
RegisteredSystem currentSystem = null;
if (_currentSystemType != null)
{
_registeredSystems.TryGetValue(_currentSystemType, out currentSystem);
}
// 重置当前系统的缩放和偏移
if (currentSystem != null)
{
currentSystem.Transform.localScale = currentSystem.OriginalScale;
}
// 位置移动
if (currentSystem != null)
{
currentSystem.Transform.position = hiddenSlot.position + currentSystem.Offset;
}
targetSystem.Transform.position = centerSlot.position + targetSystem.Offset;
_currentSystemType = targetSystem.SystemType;
}
#endregion
#region 缩放控制
/// <summary>
/// 缩放当前激活的系统
/// </summary>
/// <param name="targetScale">目标缩放倍数(相对于原始大小)</param>
/// <param name="anchor">锚点世界坐标,null则使用物体中心</param>
public Tween ScaleCurrentSystem(float targetScale, Vector3? anchor = null)
{
if (_currentSystemType == null) return null;
if (!_registeredSystems.TryGetValue(_currentSystemType, out var system)) return null;
_activeScaleTween?.Kill();
// 参数初始化
var transform = system.Transform;
var finalScale = system.OriginalScale * targetScale;
var anchorPos = (2*transform.position - anchor) ?? transform.position;
// 计算偏移量
system.Offset = anchorPos - transform.position;
// 并行执行缩放和位移
var sequence = DOTween.Sequence();
sequence.Join(transform.DOScale(finalScale, scaleDuration).SetEase(scaleEase));
sequence.Join(transform.DOMove(anchorPos, scaleDuration).SetEase(scaleEase));
_activeScaleTween = sequence;
return sequence;
}
/// <summary>
/// 恢复当前系统的原始缩放
/// </summary>
public void ResetCurrentSystemScale()
{
if (_currentSystemType == null) return;
if (!_registeredSystems.TryGetValue(_currentSystemType, out var system)) return;
_activeScaleTween?.Kill();
var transform = system.Transform;
// 恢复到中心位置,减去之前记录的偏移量来还原位置
var targetPosition = centerSlot.position - system.Offset;
var sequence = DOTween.Sequence();
sequence.Join(transform.DOScale(system.OriginalScale, scaleDuration).SetEase(scaleEase));
sequence.Join(transform.DOMove(targetPosition, scaleDuration).SetEase(scaleEase));
_activeScaleTween = sequence;
}
#endregion
#region 查询方法
/// <summary>
/// 获取当前激活的系统类型
/// </summary>
public Type GetCurrentSystemType()
{
return _currentSystemType;
}
/// <summary>
/// 获取当前激活系统的 Transform
/// </summary>
public Transform GetCurrentSystemTransform()
{
if (_currentSystemType == null) return null;
return _registeredSystems.TryGetValue(_currentSystemType, out var system)
? system.Transform
: null;
}
/// <summary>读档:按已注册类型名切换中央维修视图(无动画)。</summary>
public void RestoreSystemType(string typeName)
{
Type targetType = typeof(BodyModuleSystem);
if (!string.IsNullOrEmpty(typeName))
{
Type matched = null;
foreach (var kv in _registeredSystems)
{
if (kv.Key.Name == typeName)
{
matched = kv.Key;
break;
}
}
if (matched != null)
{
targetType = matched;
}
else
{
Debug.LogWarning($"[RepairSystemManager] 未找到已注册系统: {typeName},保持当前类型。");
return;
}
}
SwitchSystem(targetType);
}
#endregion
}
}