141 lines
4.1 KiB
C#
141 lines
4.1 KiB
C#
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;
|
||
}
|
||
}
|