Files
aibis-dream/Assets/Scripts/FixSystemNew/Cable/Plug.cs
T

222 lines
6.3 KiB
C#

using System;
using AibisDream.Framework;
using AibisDream.Kit;
using AibisDream.Utility;
using DG.Tweening;
using UnityEngine;
using UnityEngine.EventSystems;
namespace AibisDream.FixSystem
{
[RequireComponent(typeof(EventTriggerEx))]
public class Plug : MonoBehaviour, IInteraction
{
private static readonly int ShineFade = Shader.PropertyToID("_ShineFade");
private const string SortingLayerDragging = "Tools";
private const int SortingOrderDragging = 48;
#region 插头当前信息
[SerializeField] private Vector3 startPosOffset = new(0.3f, -2f, 0);
private Vector3 _startPos;
private readonly Quaternion _pickupRotation = Quaternion.Euler(0, 0, 30);
private readonly Quaternion _defaultRotation = Quaternion.Euler(0, 0, 180);
#endregion
#region 索引
private CablePanel cablePanel;
private SpriteRenderer _sprite;
private Transform _plugRootPos;
private EventTriggerEx _trigger;
public Transform PlugRoot => _plugRootPos;
#endregion
public event Action<ISocket> OnInsertSocket;
public event Action OnPullUpSocket;
public event Action OnPlugPointerDown;
private bool _isDragging;
private void Awake()
{
InitComponentRef();
EventRegister();
_startPos = transform.position + startPosOffset;
}
private void InitComponentRef()
{
cablePanel = transform.GetComponentInParent<CablePanel>(true);
_sprite = GetComponent<SpriteRenderer>();
_plugRootPos = transform.Find("Plug Root Pos");
_trigger = GetComponent<EventTriggerEx>();
// 处理插头高亮
_sprite.material.SetFloat(ShineFade, GlobalVariableKit.IsPlugHighLight ? 1 : 0);
}
private void EventRegister()
{
_trigger.Register(EventTriggerType.Drag, OnDrag);
_trigger.Register(EventTriggerType.PointerDown, OnPointerDown);
_trigger.Register(EventTriggerType.PointerUp, OnPointerUp);
}
/// <summary>
/// 插入某个socket
/// </summary>
/// <param name="targetSocket">目标socket</param>
private void InsertSocket(ISocket targetSocket)
{
// 修改插头位置
transform.position = targetSocket.GetSocketPos().position;
// 处理插槽插入
targetSocket.PlugIn();
_sprite.enabled = false;
OnInsertSocket?.Invoke(targetSocket);
}
/// <summary>
/// 从某个Socket拔出来
/// </summary>
public void PullUpSocket()
{
_sprite.enabled = true;
OnPullUpSocket?.Invoke();
}
/// <summary>读档/静默:仅恢复插头精灵可见,不触发 CablePanel 事件。</summary>
public void PullUpSocketSilent()
{
_sprite.enabled = true;
}
/// <summary>读档:无动画回到初始位。</summary>
public void RestoreAtStartPositionImmediate()
{
transform.rotation = _defaultRotation;
transform.position = _startPos;
}
/// <summary>读档:无动画插入指定 socket 的视觉终态。</summary>
public void RestoreInsertedAt(Transform socketPos)
{
if (socketPos == null) return;
transform.position = socketPos.position;
_sprite.enabled = false;
}
public void SetSpriteVisible(bool visible)
{
_sprite.enabled = visible;
}
private void OnDrag(BaseEventData eventData)
{
if (!_isDragging) return;
if (eventData is PointerEventData pointerData)
{
transform.position = CameraKit.GetMouseWorldPos(pointerData.position);
}
}
private void OnPointerDown(BaseEventData eventData)
{
if (EventSystemEx.Instance.isLocked) return;
if (eventData is PointerEventData { button: PointerEventData.InputButton.Right })
return;
_sprite.sortingLayerName = SortingLayerDragging;
_sprite.sortingOrder = SortingOrderDragging;
OnPlugPointerDown?.Invoke();
TryCloseHighlight();
_isDragging = true;
AdjustPlugPos();
AudioManager.Instance.PlaySfx("event:/FollowInput/plugpick");
}
private void TryCloseHighlight()
{
if (!GlobalVariableKit.IsPlugHighLight) return;
GlobalVariableKit.IsPlugHighLight = false;
_sprite.material.SetFloat(ShineFade, 0);
}
private void OnPointerUp(BaseEventData eventData)
{
if (EventSystemEx.Instance.isLocked)
{
_isDragging = false;
return;
}
if (eventData is PointerEventData { button: PointerEventData.InputButton.Right })
{
return;
}
// 停止拖拽
_isDragging = false;
// 寻找可吸附的Module
if (cablePanel.TryFindClosestModule(transform.position, out var targetModule))
{
InsertSocket(targetModule);
}
else
{
ReturnToStartPosition();
}
}
public void ReturnToStartPosition()
{
transform.rotation = _defaultRotation;
transform.DOMove(_startPos, 0.1f).OnComplete(() =>
{
cablePanel.CableReelRef.ResetRotation();
cablePanel.CableRef.RestoreDefaultSorting();
cablePanel.SetCableMode(CableMode.Physic, transform);
});
}
private void AdjustPlugPos()
{
transform.rotation = _pickupRotation;
}
void OnDrawGizmosSelected()
{
Gizmos.color = Color.yellow;
Gizmos.DrawWireSphere(transform.position, 0.5f);
}
public bool IsActive => true;
public bool IsAvailable => !cablePanel.isCableRetracted;
public GameObject GetGameObject()
{
return gameObject;
}
public Vector3 GetStartPos()
{
return _startPos;
}
}
}