using UnityEngine; using DG.Tweening; using System.Collections; public class ClawMachineController : MonoBehaviour { [Header("组件引用")] [SerializeField] private Transform topEdge; // 上边沿 [SerializeField] private Transform leftClaw; // 左爪 [SerializeField] private Transform rightClaw; // 右爪 [Header("移动参数")] [SerializeField] private float moveSpeed = 5f; [SerializeField] private float scaleSpeed = 2f; [SerializeField] private float minScale = 0.8f; // 下降时的缩放比例 [Header("抓取参数")] [SerializeField] private float grabOffset = 0.1f; // 抓取时的位置偏移 [SerializeField] private float clawExtendSpeed = 2f; // 爪子伸缩速度 [Header("测试")] public Transform target; private Vector3 initialPosition; private Vector3 initialScale; private Transform currentTarget; private bool isGrabbing; private bool isMoving; private void Start() { initialPosition = transform.position; initialScale = transform.localScale; } private void Update() { if (Input.GetKeyDown(KeyCode.Space)) { GrabTarget(target); } } public void GrabTarget(Transform target) { if (isGrabbing || isMoving) return; currentTarget = target; StartCoroutine(GrabSequence()); } private IEnumerator GrabSequence() { isGrabbing = true; isMoving = true; // 1. 移动到目标上方 Vector3 targetPos = currentTarget.position; targetPos.x = transform.position.x; yield return MoveToPosition(targetPos); // 2. 调整位置和抓钩 yield return AdjustPositionAndClaws(); // 3. 下降 yield return Descend(); // 4. 再次调整抓钩 //yield return AdjustClawsForGrab(); // 5. 抓取目标 //currentTarget.SetParent(transform); // 6. 上升 //yield return Ascend(); // 7. 返回初始位置 //yield return ReturnToInitialPosition(); isGrabbing = false; isMoving = false; } private IEnumerator MoveToPosition(Vector3 targetPos) { float distance = Vector3.Distance(transform.position, targetPos); float duration = distance / moveSpeed; transform.DOMove(targetPos, duration).SetEase(Ease.Linear); yield return new WaitForSeconds(duration); } private IEnumerator AdjustPositionAndClaws() { if (currentTarget == null) yield break; SpriteRenderer targetSprite = currentTarget.GetComponent(); if (targetSprite == null) yield break; // 计算目标上边沿位置 float targetTop = targetSprite.bounds.max.y; float currentTop = topEdge.position.y; // 计算需要移动的距离 float moveDistance = targetTop - currentTop + grabOffset; // 调整位置使上边沿接近目标上边沿 Vector3 newPos = transform.position; newPos.y += moveDistance; yield return MoveToPosition(newPos); // 调整爪子位置 float targetWidth = targetSprite.bounds.size.x; float currentWidth = Vector3.Distance(leftClaw.position, rightClaw.position); // 计算需要的爪子伸缩量 float extendAmount = (targetWidth + grabOffset * 2) - currentWidth; yield return ExtendClaws(extendAmount); } private IEnumerator Descend() { Vector3 targetScale = initialScale * minScale; float duration = (initialScale.x - targetScale.x) / scaleSpeed; transform.DOScale(targetScale, duration).SetEase(Ease.Linear); yield return new WaitForSeconds(duration); } private IEnumerator AdjustClawsForGrab() { if (currentTarget == null) yield break; SpriteRenderer targetSprite = currentTarget.GetComponent(); if (targetSprite == null) yield break; // 计算目标宽度 float targetWidth = targetSprite.bounds.size.x; // 调整爪子位置以卡住边缘 float extendAmount = targetWidth + grabOffset; yield return ExtendClaws(extendAmount); } private IEnumerator ExtendClaws(float amount) { Vector3 leftTarget = leftClaw.localPosition; Vector3 rightTarget = rightClaw.localPosition; leftTarget.x -= amount / 2; rightTarget.x += amount / 2; float duration = amount / clawExtendSpeed; leftClaw.DOLocalMove(leftTarget, duration).SetEase(Ease.Linear); rightClaw.DOLocalMove(rightTarget, duration).SetEase(Ease.Linear); yield return new WaitForSeconds(duration); } private IEnumerator Ascend() { float duration = (initialScale.x - transform.localScale.x) / scaleSpeed; transform.DOScale(initialScale, duration).SetEase(Ease.Linear); yield return new WaitForSeconds(duration); } private IEnumerator ReturnToInitialPosition() { // 先回到初始Y位置 Vector3 targetPos = transform.position; targetPos.y = initialPosition.y; yield return MoveToPosition(targetPos); // 再回到初始X位置 targetPos.x = initialPosition.x; yield return MoveToPosition(targetPos); } }