话不多说直接上代码,都有注释,注释是个好习惯
using UnityEngine;
public class CameraRayCast : MonoBehaviour
{
[Header("是否点击")]
public bool isClicked = false;
[Header("是否悬停")]
public bool isHovering = false;
[Header("当前点击的对象")]
public GameObject curClickGo;
[Header("鼠标悬停时间")]
public float hoverTime = 0.5f;
private Ray ray;
private float timer;
private Vector3 offset;
private RaycastHit hit;
private GameObject lastClickGo;
private Vector3 clickGoScreenPos;
private Vector3 curMouseWorldPos;
private Vector3 curMouseScreenPos;
void Start()
{
}
void Update()
{
if (Input.GetMouseButtonDown(0))
{
RaycastDetection(MouseOperation.Click);
}
if (Input.GetMouseButtonUp(0))
{
isClicked = false;
curClickGo = null;
}
if (isClicked)
{
DragClickItem();
}
RaycastDetection(MouseOperation.Hover);
}
/// <summary>
/// 射线检测,包含鼠标点击和鼠标悬停
/// </summary>
private void RaycastDetection(MouseOperation curOperation)
{
ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out hit))
{
curClickGo = hit.collider.gameObject;
switch (LayerMask.LayerToName(curClickGo.layer))
{
case "DragItem":
switch (curOperation)
{
case MouseOperation.Click:
isClicked = true;
// 把点击的物体的世界坐标转换为屏幕坐标
clickGoScreenPos = Camera.main.WorldToScreenPoint(curClickGo.transform.position);
// 鼠标点击的位置坐标与物体的坐标差值
offset = curClickGo.transform.position - Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, clickGoScreenPos.z));
break;
case MouseOperation.Hover:
if (!isHovering)
{
timer += Time.deltaTime;
if (timer >= hoverTime)
{
// TODO:这里是悬停事件的操作
Debug.Log(string.Format("此时鼠标悬停在Layer为{0}的{1}上{2}秒", LayerMask.LayerToName(curClickGo.layer), curClickGo.name, timer));
isHovering = true;
timer = 0;
}
}
if (curClickGo != lastClickGo || lastClickGo == null)
{
isHovering = false;
}
break;
}
break;
}
lastClickGo = curClickGo;
}
}
/// <summary>
/// 拖拽电机的物体
/// </summary>
private void DragClickItem()
{
// 当前鼠标点击位置的屏幕坐标(带Z值)
curMouseScreenPos = new Vector3(Input.mousePosition.x, Input.mousePosition.y, clickGoScreenPos.z);
// 将鼠标点击的位置的坐标转换为世界坐标
curMouseWorldPos = Camera.main.ScreenToWorldPoint(curMouseScreenPos);
// 将时间坐标赋值给点击的物体
curClickGo.transform.position = curMouseWorldPos + offset;
}
}
public enum MouseOperation
{
Click, // 点击
Hover // 悬停
}