203 lines
6.2 KiB
C#
203 lines
6.2 KiB
C#
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<SpriteRenderer>();
|
|
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<SpriteRenderer>();
|
|
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<SpriteRenderer>();
|
|
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);
|
|
}
|
|
}
|