Card/Assets/Scripts/Card.cs
2025-01-07 20:55:39 +08:00

141 lines
4.1 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using UnityEngine;
using UnityEngine.EventSystems;
using System.Collections.Generic;
using System.Collections;
public class Card : MonoBehaviour
{
private Vector3 offset; // 鼠标与卡牌之间的偏移量
private Camera mainCamera; // 主相机
private Vector3 originalPosition; // 卡牌的初始位置
private bool isRaised = false; // 标记卡牌是否已经抬起
private float raiseHeight = 0.5f; // 抬起高度
private bool isDragging = false; // 标记是否正在拖拽
private Plane dragPlane; // 拖拽平面
void Start()
{
// 获取主相机
mainCamera = Camera.main;
if (mainCamera == null)
{
Debug.LogError("主相机未设置为 MainCamera Tag请检查");
return;
}
// 记录卡牌初始位置
originalPosition = transform.position;
}
void OnMouseDown()
{
if (mainCamera == null) return;
// 检测是否点击在 UI 上
if (IsPointerOverUIObject())
{
Debug.Log("点击在 UI 上,忽略卡牌拖动");
return;
}
// 定义拖拽平面:平面法向量为 Vector3.up与 Y 轴平行),高度为卡牌的当前 Y 值
dragPlane = new Plane(Vector3.up, transform.position);
// 使用鼠标射线计算点击点与卡牌的偏移
Ray ray = mainCamera.ScreenPointToRay(Input.mousePosition);
if (dragPlane.Raycast(ray, out float enter))
{
Vector3 hitPoint = ray.GetPoint(enter); // 鼠标点击点的世界坐标
offset = transform.position - hitPoint; // 计算偏移
Debug.Log("点击点与卡牌的偏移:" + offset);
}
else
{
Debug.LogError("鼠标射线未与拖拽平面相交");
return;
}
// 抬起卡牌
if (!isRaised)
{
isRaised = true;
StopAllCoroutines(); // 停止所有协程
StartCoroutine(MoveToPosition(transform.position + new Vector3(0, raiseHeight, 0), 0.2f)); // 平滑抬起
}
isDragging = true; // 开始拖拽
}
void OnMouseDrag()
{
if (!isDragging || mainCamera == null) return;
// 使用拖拽平面计算鼠标的世界位置
Ray ray = mainCamera.ScreenPointToRay(Input.mousePosition);
if (dragPlane.Raycast(ray, out float enter))
{
Vector3 hitPoint = ray.GetPoint(enter); // 鼠标光线与平面的交点
transform.position = new Vector3(hitPoint.x + offset.x, originalPosition.y, hitPoint.z + offset.z); // 固定 Y 值
Debug.Log("拖拽中卡牌位置:" + transform.position);
}
else
{
Debug.LogError("鼠标射线未与拖拽平面相交");
}
}
void OnMouseUp()
{
if (!isDragging) return;
isDragging = false;
// 放下卡牌
if (isRaised)
{
isRaised = false;
StopAllCoroutines();
StartCoroutine(MoveToPosition(new Vector3(transform.position.x, originalPosition.y, transform.position.z), 0.2f)); // 平滑放下
}
Debug.Log("卡牌拖拽结束,位置:" + transform.position);
}
// 平滑移动协程
private IEnumerator MoveToPosition(Vector3 targetPosition, float duration)
{
Vector3 startPosition = transform.position;
float time = 0f;
while (time < duration)
{
time += Time.deltaTime;
transform.position = Vector3.Lerp(startPosition, targetPosition, time / duration);
yield return null;
}
transform.position = targetPosition; // 确保最终位置
}
// 检测鼠标是否点击在 UI 上
private bool IsPointerOverUIObject()
{
// 检查是否存在 EventSystem
if (EventSystem.current == null)
{
Debug.LogWarning("场景中缺少 EventSystem请添加一个 EventSystem");
return false;
}
// 检测鼠标是否点击在 UI 上
PointerEventData eventData = new PointerEventData(EventSystem.current)
{
position = Input.mousePosition
};
List<RaycastResult> results = new List<RaycastResult>();
EventSystem.current.RaycastAll(eventData, results);
return results.Count > 0;
}
}