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

226 lines
7.0 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System;
using AibisDream.Framework;
using AibisDream.Kit;
using AibisDream.Utility;
using UnityEngine;
using UnityEngine.EventSystems;
namespace AibisDream.FixSystem
{
[RequireComponent(typeof(EventTriggerEx))]
public class Plug : MonoBehaviour, IInteraction
{
private static readonly int ShineFade = Shader.PropertyToID("_ShineFade");
// 插头常态排序:与线缆(Tools/47)同层且在其上,拖拽不再切层——
// 原型里插头永远画在线之上、画序不随交互变化;整套线缆系统被外部元素
// 遮挡时也必须整体一起被盖,不能插头浮出而线身沉底。
// Tools 整层高于 FixTop(屏幕 UI Canvas 在 FixTop/100),Tools/48 是插头
// 历史沿用且验证过不被面板遮挡的位置;剪线演出(Tools/50+)仍可盖住整套线缆
private const string NormalSortingLayer = "Tools";
private const int NormalSortingOrder = 48;
#region 插头当前信息
[SerializeField] private Vector3 startPosOffset = new(0.3f, -2f, 0);
private Vector3 _startPos;
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;
// 预制体里序列化的还是旧的 Tools 层,启动时归一化;收起态由 CablePanel 之后覆盖
ApplyNormalSorting();
}
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;
ApplyNormalSorting();
OnPullUpSocket?.Invoke();
}
/// <summary>读档/静默:仅恢复插头精灵可见,不触发 CablePanel 事件。</summary>
public void PullUpSocketSilent()
{
_sprite.enabled = true;
ApplyNormalSorting();
}
/// <summary>恢复插头常态排序(收起态会被 CablePanel 压到线盘下方,放下时调回)。</summary>
public void ApplyNormalSorting()
{
_sprite.sortingLayerName = NormalSortingLayer;
_sprite.sortingOrder = NormalSortingOrder;
}
/// <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)
{
// 指针只驱动线缆送线与末端钉住目标,插头本体由绳末端带动(CablePanel.LateUpdate
cablePanel.UpdateDragPointer(CameraKit.GetMouseWorldPos(pointerData.position));
}
}
private void OnPointerDown(BaseEventData eventData)
{
if (EventSystemEx.Instance.isLocked) return;
if (eventData is PointerEventData { button: PointerEventData.InputButton.Right })
return;
ApplyNormalSorting();
OnPlugPointerDown?.Invoke();
TryCloseHighlight();
_isDragging = true;
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()
{
// 解除末端钉住,线缆自动回收到最短长度,插头挂在绳末端跟着回去
cablePanel.ReleasePlug();
}
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;
}
}
}