这种功能一般用在Scene窗口通过射线检测放置物体
因此首先要是场景中的物体不能通过鼠标点击选中,因为如果切换选中物体,Editor脚本就不会运行了
检测逻辑应该放在OnSceneGUI中
一、拦截鼠标点击场景物体选中
int controlID = GUIUtility.GetControlID(FocusType.Passive);
HandleUtility.AddDefaultControl(controlID);
这两行代码放在OnSceneGUI中就行
二、监听按键鼠标
需要使用Event,不能使用Input
Event current = Event.current;
if (current.keyCode == KeyCode.Z && current.type == EventType.KeyDown)
if (current.shift && current.type == EventType.MouseUp)
三、射线检测
Vector2 mousePosition = current.mousePosition;
mousePosition.y = (float)Screen.height - mousePosition.y - 40f;
Ray ray = Camera.current.ScreenPointToRay(mousePosition);
RaycastHit raycastHit;
if (Physics.Raycast(Camera.current.transform.position, ray.direction, out raycastHit, 3000f))
{
}
坐标y的变化,首先是因为左上,和左下开始的差别。减去40是窗口位置的问题,这样写就行
四、设备像素比devicePixelRatio
这个问题比较坑,一般很难发现,但是一般也不影响使用。因为我一个mac笔记本外接一个显示屏,才发现这个问题。设备像素比,因为mac笔记本设备像素比是2,普通屏幕是1。mouseposition是在设备尺寸像素的坐标,而Screen获取的屏幕大小是像素大小。如果是2,那么就会不匹配。需要把mouseposition扩大两倍,但是Unity怎么获取这个设备像素比,我没发现方法,如果有解决方案的,希望能留言一下,谢谢了。我现在直接判断dpi,超过200,我就认为设备像素比devicePixelRatio为2。
五、Editor修改数据后保存
不是prefab ,直接修改类的数据会自己保存的,但是如果物体是prefab,修改后面板数据会变化。但是运行时候又会还原。可以通过SetDirty让用户保存场景来保存。自己写的需要序列化的类或者结构体,如果在字段中标记为Hide。即使通过Editor绘制也不能显示出具体内部字段。