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(); yield return new WaitForSeconds(0.5f); // 4. 再次调整抓钩 yield return AdjustClawsForGrab(); // 5. 抓取目标 currentTarget.SetParent(transform); yield return new WaitForSeconds(0.5f); // 6. 上升 yield return Ascend(); yield return new WaitForSeconds(0.5f); // 7. 返回初始位置 yield return ReturnToInitialPosition(); isGrabbing = false; isMoving = false; } private IEnumerator MoveToPosition(Vector3 targetPos) { if (currentTarget == null) yield break; SpriteRenderer targetSprite = currentTarget.GetComponent(); if (targetSprite == null) yield break; float targetLeft = targetSprite.bounds.min.x; float targetRight = targetSprite.bounds.max.x; targetPos.x=(targetLeft+targetRight)/2; 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 targetLeft = targetSprite.bounds.min.x; float topOffset = targetTop - topEdge.position.y + 0.5f; // 确保上边沿高于目标 float leftOffset = leftClaw.position.x -(targetLeft-0.5f); // 确保左爪超出目标左边界 // 调整位置 Vector3 newPos = transform.position; newPos.y += topOffset; yield return MoveToPosition(newPos); // 调整爪子位置 float extendAmount=leftOffset; 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 targetTop = targetSprite.bounds.max.y; float targetLeft = targetSprite.bounds.min.x; // float topOffset = targetTop - topEdge.position.y + grabOffset; // 确保上边沿高于目标 float leftOffset = leftClaw.position.x -(targetLeft-grabOffset); // 确保左爪超出目标左边界 // 调整位置 // Vector3 newPos = transform.position; // newPos.y += topOffset; // yield return MoveToPosition(newPos); // 调整爪子位置 float extendAmount=leftOffset; yield return ExtendClaws(extendAmount); } private IEnumerator ExtendClaws(float amount) { Vector3 leftTarget = leftClaw.localPosition; Vector3 rightTarget = rightClaw.localPosition; leftTarget.x -= amount; rightTarget.x += amount; float duration = Mathf.Abs(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); } }