249 lines
7.7 KiB
C#
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
|
|
}
|
|
}
|