Unity射线检测

话不多说直接上代码,都有注释,注释是个好习惯

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   // 悬停
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

人无两度s

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值