using UnityEngine; using UnityEngine.EventSystems; using DG.Tweening; using UnityEngine.UI; using Yarn.Unity; using System.Collections.Generic; public class Crowbar : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler { public float rotationSpeed = 10f; // 拖动旋转的速度 public float rotationThreshold = 30f; // 触发撬动完成的旋转阈值 public Transform crowbarVisual; //public Transform crowbarBox; public Transform crowbarInPosition; private Vector3 crowbarOutPosition; private CrowBarSocket crowbarSocket; public Transform box; public bool IsInDialogue { get; set; } = false; private Vector3 startPosition; private Quaternion startRotation= Quaternion.Euler(0f, 0f, -225f); private bool isInserted = false; private Vector3 lastMousePosition; private float progress = 0f; private Image image; private bool isPryingCompleted = false; private List crowbarSockets; public Canvas crowbarCanvas; private void Awake() { image = GetComponent(); } private void Start() { crowbarOutPosition = transform.position; } private void Initialize() { isPryingCompleted = false; progress = 0; isInserted = false; crowbarVisual.rotation = startRotation; crowbarSocket=null; crowbarCanvas.sortingLayerName = "Tool"; crowbarCanvas.sortingOrder = 6; crowbarSockets = new List(FindObjectsOfType()); } [YarnCommand("CrowBarIn")] public void MoveIn() { DOTween.Kill(transform); DOTween.Kill(box); transform.position=crowbarOutPosition; box.position=crowbarOutPosition; transform.DOMove(crowbarInPosition.position, 1f); box.DOMove(crowbarInPosition.position, 1f); Initialize(); } [YarnCommand("CrowBarOut")] public void MoveOut() { // transform.DOMove(crowbarOutPosition, 0.1f).OnComplete(() => // { // }); box.DOMove(crowbarOutPosition, 1f); transform.position=crowbarOutPosition; } public void OnBeginDrag(PointerEventData eventData) { if (IsInDialogue || isInserted) return; image.raycastTarget = false; //crowbarSocket.InsertPlug(); RectTransform canvasRectTransform = (RectTransform)transform.root; Vector3 worldPoint; if (RectTransformUtility.ScreenPointToWorldPointInRectangle(canvasRectTransform, eventData.position, eventData.pressEventCamera, out worldPoint)) { transform.position = worldPoint; } lastMousePosition = Input.mousePosition; } public void OnDrag(PointerEventData eventData) { Debug.Log("Draging"); if (IsInDialogue || isPryingCompleted) return; if (isInserted) { Debug.Log("insert"); float deltaY = lastMousePosition.y - Input.mousePosition.y; lastMousePosition = Input.mousePosition; // 更新 lastMousePosition //Debug.Log("Progress :"+progress); progress += deltaY*0.3f * Time.deltaTime; progress = Mathf.Clamp01(progress); // 确保 progress 不会小于0 // 计算插入旋转和插入旋转-45度之间的插值 float startAngle = crowbarSocket.visual.transform.eulerAngles.z; float endAngle = startAngle + 40f; float currentAngle = Mathf.Lerp(startAngle, endAngle, progress); //Debug.Log("currentAngle :"+currentAngle); // 更新撬棍的旋转角度 crowbarVisual.rotation = Quaternion.Euler(0f, 0f, currentAngle); if (progress >= 1f) { crowbarSocket.Completed(); crowbarSocket.EnableSocket(); // 触发撬动完成的逻辑 Debug.Log("Crowbar action completed."); isPryingCompleted = true; // 定义目标位置 Vector3 targetPosition = transform.position + new Vector3(-1, 1, 0) * 6f; // 你可能需要根据你的场景来调整这个偏移量 // 使用 DOTween 来移动 crowbar transform.DOMove(targetPosition, 1f); transform.DORotate(new Vector3(0, 0, 360), 0.4f, RotateMode.FastBeyond360) .SetLoops(10, LoopType.Incremental) // 设置为无限循环 .SetEase(Ease.Linear).OnComplete(() => { ResetCrowbar(); }); } } else { RectTransform canvasRectTransform = (RectTransform)transform.root; Vector3 worldPoint; if (RectTransformUtility.ScreenPointToWorldPointInRectangle(canvasRectTransform, eventData.position, eventData.pressEventCamera, out worldPoint)) { transform.position = worldPoint; } CrowBarSocket socket= FindNearestSocket(); if(socket!=null) { socket.InsertPlug(); } } lastMousePosition = Input.mousePosition; } public void OnEndDrag(PointerEventData eventData) { if (IsInDialogue) return; if (isInserted) { ResetCrowbarProgress(); } else { CrowBarSocket nearestSocket = null; float minDistance = float.MaxValue; foreach (var socket in crowbarSockets) { if(!socket.gameObject.activeInHierarchy) { continue; } float distance = Vector3.Distance(transform.position, socket.transform.position); if (distance <= minDistance && socket.IsAvailable) { minDistance = distance; nearestSocket = socket; } } if (nearestSocket != null) { float snappingRange = 1f; // You might need to adjust this for WorldSpace Canvas if (minDistance <= snappingRange) { transform.position = nearestSocket.transform.position; crowbarVisual.rotation = nearestSocket.visual.transform.rotation; isInserted = true; nearestSocket.RemovePlug(); nearestSocket.DisableSocket(); crowbarSocket=nearestSocket; crowbarCanvas.sortingLayerName = "UnderModule"; crowbarCanvas.sortingOrder = 6; Debug.Log("crowbarsocket name"+crowbarSocket.name); } else { transform.DOMove(crowbarInPosition.position, 0.1f).OnComplete(() => { nearestSocket.RemovePlug(); }); } } else { transform.DOMove(crowbarInPosition.position, 0.1f).OnComplete(() => { crowbarCanvas.sortingLayerName = "Tool"; crowbarCanvas.sortingOrder = 6; }); } } } public CrowBarSocket FindNearestSocket() { CrowBarSocket nearestSocket = null; float minDistance = float.MaxValue; foreach (var socket in crowbarSockets) { if(!socket.gameObject.activeInHierarchy) { continue; } float distance = Vector3.Distance(transform.position, socket.transform.position); if (distance <= minDistance && socket.IsAvailable) { minDistance = distance; nearestSocket = socket; } } if (nearestSocket != null) { return nearestSocket; } else { return null; } } private void ResetCrowbarProgress() { //isInserted = false; progress = 0f; crowbarVisual.rotation = Quaternion.Euler(0f, 0f, 180f); //MoveOut(); } private void ResetCrowbar() { isInserted=false; progress = 0f; crowbarVisual.rotation = startRotation; //isPryingCompleted = false; transform.position=crowbarOutPosition; } }