using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Events; using UnityEngine.EventSystems; namespace GOEventSystem { public class EventSystem_Camera : MonoBehaviour { Camera rayCamera; bool isUsed = true;//事件监测系统是否启用 bool hoverTriggerEnter; Transform hoverRecord;//记录当前触发hover的物体 public float rayDistacne = 800; public LayerMask rayGOLayer; GOPointerEventData eventData = new GOPointerEventData(); [Header("Hovr检测的灵敏度,检测时间间隔")] public float hoverCheckTime = 0.2f;//射线重复检测时才会触发hover 理论上触发最大时长为hoverCheckTime*2-0.02f; float upTime;//一帧运行时间 float timer;//计时器 public UnityAction> clickOperatorsEvent; public UnityAction> doubleClickOperatorsEvent; public UnityAction clickOutUIEvent; // Start is called before the first frame update void Start() { rayGOLayer = ~(1 << -1); rayCamera = this.GetComponent(); if (rayCamera == null && Camera.main) { rayCamera = Camera.main; } if (!rayCamera) { isUsed = false; Debug.Log("无有效检测相机,EventSystem_Camera置位不可用模式"); } upTime = Time.fixedDeltaTime; timer = hoverCheckTime; } /// /// 某些情况下可关闭或再次开启事件检测系统 /// /// public void SetUsed(bool used) { isUsed = used; if (!isUsed && hoverRecord != null&& hoverTriggerEnter) { hoverRecord.GetComponent().OnHoverExit(eventData); hoverRecord = null; } } // Update is called once per frame void Update() { if (!isUsed) return; if (EventSystem.current!=null&& EventSystem.current.IsPointerOverGameObject()) return;//UI触发时不做检测 //HoverCheck(); ClickCheck(); } void HoverCheck() { timer-= upTime; if (timer > 0) return; timer = hoverCheckTime; Transform rayHit = CameraRay(); if (rayHit == null)//没有检测到物体 { if (hoverRecord && hoverTriggerEnter) { hoverRecord.GetComponentInParent()?.OnHoverExit(eventData); } hoverRecord = null; hoverTriggerEnter = false; } else if (rayHit == hoverRecord) //检测到的物体与记录的物体是重复的 { if (hoverTriggerEnter) return;//避免hover重复触发 hoverTriggerEnter = true; rayHit.GetComponentInParent()?.OnHoverEnter(eventData); } else//检测到其他物体时 { if (hoverRecord&&hoverTriggerEnter) hoverRecord.GetComponentInParent()?.OnHoverExit(eventData); hoverTriggerEnter = false; hoverRecord = rayHit; } } private float clickTimer; [Header("双击检测的灵敏度,最大触发时间间隔")] public float DoubClickTime = 0.2f;//多长时间内再次点击时触发双击 void ClickCheck() { if (clickTimer > 0) { clickTimer -= Time.deltaTime; } if (Input.GetMouseButtonDown(0) || Input.GetMouseButtonDown(1)) { clickOutUIEvent?.Invoke();//点击地形空白位置 } if (Input.GetMouseButtonDown(0)) { eventData.gOInputButton = GOInputButton.Left; if (clickTimer <= 0) { Click(); } else DoubleClick(); } } List clickOperators = new List(); void Click() { clickTimer = DoubClickTime; CameraRay()?.GetComponentInParent()?.OnPointerClick(eventData); //RaycastHit[] raycastHits = CameraRayCastAll(); //if (raycastHits.Length > 0) //{ // clickOperators.Clear(); // for (int i = 0; i < raycastHits.Length; i++) // { // clickOperators.Add(raycastHits[i].transform.GetComponent().id); // //Debug.Log("Click Trigger"+ raycastHits[i].transform.name); // } // clickOperatorsEvent?.Invoke(clickOperators); //} } private void DoubleClick() { CameraRay()?.GetComponentInParent()?.OnPointerDoubleClick(eventData); //RaycastHit[] raycastHits = CameraRayCastAll(); //if (raycastHits.Length > 0) //{ // clickOperators.Clear(); // for (int i = 0; i < raycastHits.Length; i++) // { // clickOperators.Add(raycastHits[i].transform.GetComponent().id); // //Debug.Log("Click Trigger"+ raycastHits[i].transform.name); // } // doubleClickOperatorsEvent?.Invoke(clickOperators); //} } Ray ray; RaycastHit raycastHit; Transform CameraRay() { ray = Camera.main.ScreenPointToRay(Input.mousePosition); if (Physics.Raycast(ray, out raycastHit, rayDistacne, rayGOLayer)) { return raycastHit.collider.transform; } else return null; } /// /// 获取射线检测到的所有物体 /// /// RaycastHit[] CameraRayCastAll() { ray = Camera.main.ScreenPointToRay(Input.mousePosition); return Physics.RaycastAll(ray, rayDistacne, rayGOLayer); } } }