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"); #region 插头当前信息 private Vector3 _startPos; private readonly Vector3 _pickupOffset = new(0, 0, 0); private readonly Quaternion _pickupRotationOffset = Quaternion.Euler(0, 0, 30); private readonly Quaternion _initRotation = Quaternion.Euler(0, 0, 180); #endregion #region 索引 private CableSystem _cableSystem; private SpriteRenderer _sprite; private Transform _plugRootPos; private EventTriggerEx _trigger; #endregion private bool _isDragging; private bool _isPhysicCableActive; private void Awake() { InitComponentRef(); EventRegister(); _startPos = new Vector3(transform.position.x + 0.3f, transform.position.y - 2f, transform.position.z); // 初始化时记录初始位置 } private void InitComponentRef() { _cableSystem = transform.parent.GetComponent(); _sprite = GetComponent(); _plugRootPos = transform.Find("Plug Root Pos"); _trigger = GetComponent(); // 处理插头高亮 _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); } /// /// 插入某个socket /// /// 目标socket private void InsertSocket(ISocket targetSocket) { // 修改插头位置 transform.position = targetSocket.GetSocketPos(); _cableSystem.CableRef.SetEndPos(transform); // 处理插槽插入 targetSocket.PlugIn(); AudioManager.Instance.PlaySfx("event:/FollowInput/plugin"); _sprite.enabled = false; _cableSystem.curSocket = targetSocket; if (targetSocket is BodyModule bodyModule) { // 插入模块时触发插入事件 EnumEventSystem.Global.Send(EventEnum.PlugIn); _cableSystem.curBodyModule = bodyModule; } } /// /// 从某个Socket拔出来 /// public void PullUpSocket() { // 修改线头位置 _cableSystem.CableRef.SetEndPos(_plugRootPos); _cableSystem.curSocket?.PlugOut(); AudioManager.Instance.PlaySfx("event:/FollowInput/plugout"); _sprite.enabled = true; if (_cableSystem.curSocket is BodyModule) { // 从模块拔出时触发事件 EnumEventSystem.Global.Send(EventEnum.PlugOut); _cableSystem.curBodyModule = null; // 清除屏幕 var screenSystem = FixSystemCenter.SystemDic.Get(); if (screenSystem != null) { screenSystem.ClearTextScreen(); } } _cableSystem.curSocket = null; } private void OnDrag(BaseEventData eventData) { // 系统被锁定就返回 if (!_cableSystem.IsPlugAvailable()) { Debug.Log("OnDrag - System not available"); return; } // 未被拖拽也返回 if (!_isDragging) { Debug.Log("OnDrag - Not dragging"); return; } if (eventData is PointerEventData pointerData) { transform.position = CameraKit.GetMouseWorldPos(pointerData.position); } } private void OnPointerDown(BaseEventData eventData) { if (eventData is PointerEventData { button: PointerEventData.InputButton.Right }) { return; } GetComponent().sortingLayerName = "Tools"; GetComponent().sortingOrder = 48; // 系统被锁定就返回 if (!_cableSystem.IsPlugAvailable()) return; // 首次拖拽后关闭高亮 if (GlobalVariableKit.IsPlugHighLight) { GlobalVariableKit.IsPlugHighLight = false; _sprite.material.SetFloat(ShineFade, 0); DialogController.Instance.StartDialogNode("拿起插头"); } // 开启拖拽 _isDragging = true; // 进行插拔动作 if (_cableSystem.curSocket != null) PullUpSocket(); // 调整插头形状 AdjustPlugPos(); // 关闭 PhysicCable 的更新,并显示 Cable 的 LineRenderer _cableSystem.PhysicCableRef.GetComponent().enabled = false; _isPhysicCableActive = false; _cableSystem.CableRef.ShowCable(); // 打开所有模块 FixSystemCenter.SystemDic.Get().OpenModuleSlots(); AudioManager.Instance.PlaySfx("event:/ActionFB/mods_open"); AudioManager.Instance.PlaySfx("event:/FollowInput/plugpick"); } private void OnPointerUp(BaseEventData eventData) { Debug.Log("OnPointerUp"); if (eventData is PointerEventData { button: PointerEventData.InputButton.Right }) { return; } // 停止拖拽 _isDragging = false; // 寻找可吸附的Module if (_cableSystem.TryFindClosestModule(transform.position, out var targetModule)) { // 找到了就插入目标Module InsertSocket(targetModule); FixSystemCenter.SystemDic.Get().CloseModuleSlots(targetModule); } else { // 没找到就回到初始位置 ReturnToStartPosition(); FixSystemCenter.SystemDic.Get().CloseModuleSlots(null); } } public void ReturnToStartPosition() { PlugPosBack(); transform.DOMove(_startPos, 0.1f).OnComplete(() => { _cableSystem.CableReelRef.ResetRotation(); SwitchToPhysicCableState(); }); } private void AdjustPlugPos() { transform.position += _pickupOffset; transform.rotation = _pickupRotationOffset; } private void PlugPosBack() { transform.position -= _pickupOffset; transform.rotation = _initRotation; } public void SwitchToPhysicCableState() { _cableSystem.PhysicCableRef.Init(transform.position); _cableSystem.CableRef.HideCable(); _cableSystem.PhysicCableRef.GetComponent().enabled = true; _isPhysicCableActive = true; } public void SetPhysicCableActive(bool active) { _isPhysicCableActive = active; } private void Update() { if (_isPhysicCableActive && !_cableSystem.isCableRetracted) { _cableSystem.PhysicCableRef.physicLine.UpdatePlug(transform); } } void OnDrawGizmosSelected() { Gizmos.color = Color.yellow; Gizmos.DrawWireSphere(transform.position, 0.5f); } public bool IsActive => true; public bool IsAvailable => _cableSystem.BodyModuleSystem.isAvailable && !_cableSystem.isCableRetracted; public GameObject GetGameObject() { return gameObject; } public Vector3 GetStartPos() { return _startPos; } } }