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 = transform.position; // 初始化时记录初始位置 } 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); } public void InitPlug() { ReturnToStartPosition(); } /// /// 插入某个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; } _cableSystem.curSocket = null; } private void OnDrag(BaseEventData eventData) { // 系统被锁定就返回 if (!_cableSystem.IsPlugAvailable()) return; // 未被拖拽也返回 if (!_isDragging) return; if (eventData is PointerEventData pointerData) { transform.position = CommonUtil.GetMouseWorldPos(pointerData.position, transform); } } private void OnPointerDown(BaseEventData eventData) { // 系统被锁定就返回 if (!_cableSystem.IsPlugAvailable()) return; // 首次拖拽后关闭高亮 if (GlobalVariableKit.IsPlugHighLight) { GlobalVariableKit.IsPlugHighLight = false; _sprite.material.SetFloat(ShineFade, 0); // 拖拽后还要高亮其他组件 var bodyModuleSystem = FixSystemCenter.SystemDic.Get(); foreach (var module in bodyModuleSystem.BodyModules) { module.Highlight(true); } } // 开启拖拽 _isDragging = true; // 进行插拔动作 if (_cableSystem.curSocket != null) PullUpSocket(); // 调整插头形状 AdjustPlugPos(); // 关闭 PhysicCable 的更新,并显示 Cable 的 LineRenderer _cableSystem.PhysicCableRef.GetComponent().enabled = false; _isPhysicCableActive = false; _cableSystem.CableRef.GetComponent().enabled = true; } private void OnPointerUp(BaseEventData eventData) { // 停止拖拽 _isDragging = false; // 寻找可吸附的Module if (_cableSystem.TryFindClosestModule(transform.position, out var targetModule)) { // 找到了就插入目标Module InsertSocket(targetModule); } else { // 没找到就回到初始位置 ReturnToStartPosition(); } } public void ReturnToStartPosition() { transform.DOMove(_startPos, 0.1f).OnComplete(SwitchToPhysicCableState); } private void AdjustPlugPos() { transform.position += _pickupOffset; transform.rotation = _pickupRotationOffset; } private void PlugPosBack() { transform.position -= _pickupOffset; transform.rotation = _initRotation; } private void SwitchToPhysicCableState() { // 隐藏 Cable 的 LineRenderer PlugPosBack(); _cableSystem.PhysicCableRef.Init(transform.position); _cableSystem.CableRef.GetComponent().enabled = false; // 激活 PhysicCable _cableSystem.PhysicCableRef.GetComponent().enabled = true; _isPhysicCableActive = true; } private void Update() { if (_isPhysicCableActive) { _cableSystem.PhysicCableRef.physicLine.UpdatePlug(this.transform); } } void OnDrawGizmosSelected() { Gizmos.color = Color.yellow; Gizmos.DrawWireSphere(transform.position, 0.5f); } public bool IsActive => true; public bool IsAvailable => _cableSystem.BodyModuleSystem.isAvailable; public GameObject GetGameObject() { return gameObject; } } }