项目开发到后期之后,考虑性能优化,Ugui需要创建多个Canvas渲染不同的界面,然后会导致想要在scene视图选中某个组件时,点击许多次都无法正确选中目标对象,给调试带来不便,这里使用EventSystem实现快速选中的效果。代码注释如下
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using System;
public class MiddleClickUIEditor : MonoBehaviour
{
//由于场景中对象过多,有时并不需要检测所有,所以加以筛选,避免“垃圾”过多
public bool SelectButton = true;//是否检测按钮
public bool SelectImage = false;//是否检测Image
public bool SelectText = true;//是否检测Text
public bool SelectToggle = true;//..Toggle
public bool SelectInput = true;//..InputField
// Start is called before the first frame update
void Start()
{
DontDestroyOnLoad(gameObject);
}
private EventSystem eventSystem;
void GetObjFormClick()
{
if (eventSystem == null)
eventSystem = GameObject.FindObjectOfType<EventSystem>();//获取场景中EventSystem
if (eventSystem == null)
throw new System.Exception("EventSystem is Null");
PointerEventData eventData = new PointerEventData(eventSystem);//需要使用PointerEventData分发事件
eventData.pressPosition = Input.mousePosition;//PointerEventData 由press开始,表示按下坐标
eventData.position = Input.mousePosition;//抬起坐标
GraphicRaycaster[] graphicRaycasters = Resources.FindObjectsOfTypeAll<GraphicRaycaster>();//获取场景中所有GraphicRaycaster,该组件挂载在各个Canvas上面
for (int i = 0; i < graphicRaycasters.Length; i++)
{
List<RaycastResult> results = new List<RaycastResult>();
graphicRaycasters[i].Raycast(eventData, results);//各个Canvas分别根据PointerEventData数据,进行射线检测,返回所有检测成功的对象列表
for (int j = 0; j < results.Count; j++)
{
RaycastResult result = results[j];
if (SelectButton && result.gameObject.GetComponent<Button>() != null)//检测对象中包含按钮 且 对象上有按钮组件,以下同理。由于有筛选条件存在,故这里不做统一处理
Debug.Log(result.gameObject.name, result.gameObject);//第二个参数为Object类型,传入表示该log有哪个对象输出,点击log信息可以自动选中该对象
else if (SelectToggle && result.gameObject.GetComponent<Toggle>() != null)
Debug.Log(result.gameObject.name, result.gameObject);
else if (SelectText && result.gameObject.GetComponent<Text>() != null)
Debug.Log(result.gameObject.name, result.gameObject);
else if (SelectInput && result.gameObject.GetComponent<InputField>() != null)
Debug.Log(result.gameObject.name, result.gameObject);
else if (SelectImage && result.gameObject.GetComponent<Image>() != null)
Debug.Log(result.gameObject.name, result.gameObject);
}
}
}
// Update is called once per frame
void Update()
{
if (Input.GetMouseButtonDown(2))//鼠标中键
{
GetObjFormClick();
}
}
}