using UnityEngine; using System.Collections.Generic; using UnityEngine.EventSystems; using UnityEngine.UI; using System.Linq; using DG.Tweening; using AibisDream; using Yarn.Unity; using System; public class Plug : MonoBehaviour, IDragHandler, IPointerDownHandler, IPointerUpHandler { public delegate void PlugEventHandler(Plug plug); public event PlugEventHandler OnPlugStartDrag; public event PlugEventHandler OnPlugEndDrag; private Vector3 startPosition; private Quaternion startRotation; private bool isDragging = false; [HideInInspector] public Socket currentSocket = null; private Image image; private Vector3 pickupOffset = new Vector3(0, 0, 0); private Quaternion pickupRotationOffset = Quaternion.Euler(0, 0, 30); public Socket initialSocket; // new variable public Image plugSprite; // new variable public bool IsInDialogue { get; set; } = false; public bool IsActive { get; set; } = true; private Cable cableref; public Cable CableRef { get { return cableref; } set { cableref = value; } } public event Action OnPlugInserted; public event Action OnPlugRemoved; private void Awake() { image = GetComponent(); cableref=FindObjectOfType(); cableref.End=transform; } private void Start() { startPosition = initialSocket.GetPosition(); transform.position = startPosition; initialSocket.InsertPlug(this); plugSprite.enabled = false; currentSocket=initialSocket; DialogController.OnDialogueStart += HandleDialogueStart; DialogController.OnDialogueComplete += HandleDialogueComplete; } void OnDestroy() { // Unsubscribe from dialogue events DialogController.OnDialogueStart -= HandleDialogueStart; DialogController.OnDialogueComplete -= HandleDialogueComplete; } public void HandleDialogueStart() { // Dialogue has started, disable plug interactions IsInDialogue = true; //Debug.Log("in dialogue"); } public void HandleDialogueComplete() { // Dialogue has completed, enable plug interactions IsInDialogue = false; //Debug.Log("dialoguecompleted"); } [YarnCommand("Disable_plugInput")] public void Disable_plugInput() { // Dialogue has started, disable plug interactions IsActive = false; //Debug.Log("in dialogue"); } [YarnCommand("Enable_plugInput")] public void Enable_plugInput() { // Dialogue has completed, enable plug interactions IsActive = true; //Debug.Log("dialoguecompleted"); } public void OnPointerDown(PointerEventData eventData) { if (!IsActive) { return; } if (IsInDialogue) { return; } isDragging = true; image.raycastTarget = false; // 通知 DialogueManager 开始拖拽 DialogueManager.Instance.SetDragging(true); currentSocket?.RemovePlug(this); OnPlugRemoved?.Invoke(); plugSprite.enabled = true; transform.position += pickupOffset; transform.rotation = pickupRotationOffset; } public void OnDrag(PointerEventData eventData) { if (!IsActive) { return; } if (IsInDialogue) { return; } if (isDragging) { CableRef.End=transform.GetChild(0).transform; Vector3 screenPosition = new Vector3(eventData.position.x, eventData.position.y, Camera.main.WorldToScreenPoint(transform.position).z); Vector3 move = Camera.main.ScreenToWorldPoint(screenPosition); move.z = transform.position.z; transform.position = move; plugSprite.enabled = true; } } public void OnPointerUp(PointerEventData eventData) { if (!IsActive || IsInDialogue) { return; } isDragging = false; image.raycastTarget = true; // 通知 DialogueManager 结束拖拽 DialogueManager.Instance.SetDragging(false); // 通过射线检测来检查是否有Socket PointerEventData pointerEventData = new PointerEventData(EventSystem.current) { position = eventData.position }; List raycastResults = new List(); GraphicRaycaster graphicRaycaster = GameObject.Find("FaceCanvas").GetComponent(); graphicRaycaster.Raycast(pointerEventData, raycastResults); // 查找是否有Socket被检测到 Socket targetSocket = raycastResults .Where(result => result.gameObject.GetComponent() != null) .Select(result => result.gameObject.GetComponent()) .FirstOrDefault(); if (targetSocket != null) { // 插入到找到的Socket currentSocket = targetSocket; currentSocket.InsertPlug(this); OnPlugInserted?.Invoke(this); // 触发插入事件 transform.position = currentSocket.GetPosition(); plugSprite.enabled = false; } else { // 没有找到有效的Socket,将插头移动回原位置 transform.DOMove(startPosition, 0.1f).OnComplete(() => { initialSocket.InsertPlug(this); OnPlugInserted?.Invoke(this); // 触发插入事件 plugSprite.enabled = false; }); } } void OnDrawGizmosSelected() { Gizmos.color = Color.yellow; float snappingRange = 1.0f; // You might need to adjust this for WorldSpace Canvas Gizmos.DrawWireSphere(transform.position, snappingRange); } private bool IsSocketBlocked(Socket socket) { // 获取Socket的屏幕位置 Vector2 socketPosition = RectTransformUtility.WorldToScreenPoint(Camera.main, socket.GetComponent().position); // 创建PointerEventData进行射线检测 PointerEventData pointerEventData = new PointerEventData(EventSystem.current) { position = socketPosition }; // 使用GraphicRaycaster检测遮挡 GraphicRaycaster graphicRaycaster = GameObject.Find("FaceCanvas").GetComponent(); List results = new List(); graphicRaycaster.Raycast(pointerEventData, results); // 如果检测到其他UI元素遮挡,返回true foreach (var result in results) { if (result.gameObject != socket.gameObject) { return true; // 被遮挡 } } return false; // 未被遮挡 } }