判断鼠标是否在UI上,可以判断鼠标是否在指定的某一个Canvas上,多个Canvas可分别判断。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
public class HelpScript : MonoBehaviour
{
#region 判断鼠标是否在UI上
/// <summary>
/// 判断鼠标是否在指定的Canvas上,若返回为flase,则不再,若返回为true,则在指定canvas的UI上,可多个Canvas同时判断
/// </summary>
/// <param name="GO_Canvas">用于指定的UI</param>
/// <returns></returns>
public static bool GetOverUI(GameObject GO_Canvas)
{
PointerEventData _PointerEventData = new PointerEventData(EventSystem.current);
_PointerEventData.position = Input.mousePosition;
GraphicRaycaster _GR = GO_Canvas.GetComponent<GraphicRaycaster>();
List<RaycastResult> _Results = new List<RaycastResult>();
_GR.Raycast(_PointerEventData, _Results);
if (_Results.Count != 0)
{
return true;
}
return false;
}
#endregion
}//end Class
相机的射线检测类,鼠标射线的碰撞检测,鼠标悬停在物体上、鼠标点选物体等触发的事件。下方的第一个脚本为相机更新和事件绑定脚本,第二个脚本为事件触发脚本。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using System;
/// <summary>
/// 序列化,场景一个unity的射线检测类
/// </summary>
[Serializable]
public class RaycastEvent :UnityEvent<RaycastHit> { }
/// <summary>
/// 相机的射线控制(脚本挂靠物体必须有相机)
/// </summary>
[RequireComponent(typeof(Camera))]
public class Control_CameraRaycaster : MonoBehaviour
{
/// <summary>
/// 事件更新类型枚举,判断事件在更新类型上更新
/// </summary>
public enum UpdateEvent {
Update,
LateUpdate,
OnPreCull,
OnPreRender,
OnPostRender,
}
#region Public Paramater
/// <summary>
/// 事件更新类型
/// </summary>
public UpdateEvent updateEvent = UpdateEvent.LateUpdate;
/// <summary>
/// 忽略层
/// </summary>
public LayerMask layerMask = -1;
/// <summary>
/// 射线长度 (-1 = infinity )
/// </summary>
public float rayLength = -1;
/// <summary>
/// 悬停时出发的事件
/// </summary>
public RaycastEvent Event_OnHover;
#endregion
#region Private Paramater
private Camera _Camera;
#endregion
#region Unity Method
private void Awake() {
_Camera = this.GetComponent<Camera>();
}
private void Update() {
PerformRaycast(UpdateEvent.Update);
}
void LateUpdate() {
PerformRaycast(UpdateEvent.LateUpdate);
}
void OnPreCull() {
PerformRaycast(UpdateEvent.OnPreCull);
}
void OnPreRender() {
PerformRaycast(UpdateEvent.OnPreRender);
}
void OnPostRender() {
PerformRaycast(UpdateEvent.OnPostRender);
}
#endregion
#region Perform Raycast 执行光线投射
/// <summary>
/// 执行光线投射事件
/// </summary>
/// <param name="currentEvent"></param>
void PerformRaycast(UpdateEvent currentEvent) {
if (currentEvent != updateEvent) { return; }
if (_Camera == null) { return; }
if (Event_OnHover == null) {
return;
}
//射线碰撞信息
RaycastHit hitInfo;
//射线
Ray ray = _Camera.ScreenPointToRay(Input.mousePosition);
//射线是否碰撞
if (Physics.Raycast(ray, out hitInfo, rayLength >= 0f ? rayLength : Mathf.Infinity, layerMask.value)) {
//鼠标悬停在物体上
Event_OnHover.Invoke(hitInfo);
}
}
#endregion
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//高亮
using HighlightingSystem;
/// <summary>
/// 摄像机射线事件
/// </summary>
public class CameraRaycasterEvent : MonoBehaviour
{
/// <summary>
/// 鼠标悬停事件
/// </summary>
/// <param name="hitInfo"></param>
public void OnHoverMethod(RaycastHit hitInfo) {
Transform Trans = hitInfo.collider.transform;
if (Trans == null) { return; }
//鼠标点击物体出发的所有事件
if (Input.GetMouseButtonDown(0)) {
//点击带有 Interface_RaycastHitInfo 接口的物体
var interfaceRaycastHit = Trans.GetComponentInParent<Interface_RaycastHitInfo>();
if (interfaceRaycastHit != null) {
interfaceRaycastHit.GetRaycastHitInfo(hitInfo);
}
}
}
}
/// <summary>
/// 摄像机射线的信息获取,所有需要用摄像机的射线来触发事件的物体,必须继承此接口
/// </summary>
public interface Interface_RaycastHitInfo {
void GetRaycastHitInfo(RaycastHit raycastHit);
}