[cb]SceneView 获取鼠标位置
本文为作者原创,转载请注明出处:https://www.cnblogs.com/zhaoqingqing/p/3801342.html
扩展需求#
在Scene视图中获取鼠标的位置
Demo#
在Scene视图中,当鼠标点击时实例化一个Cube
重点部分#
实现代码#
using UnityEngine; using UnityEditor; [CustomEditor(typeof(MyGrid))] public class MyGridInspector : Editor { MyGrid grid; public void OnEnable() { grid = (MyGrid)target;//初始化时获取引用 SceneView.onSceneGUIDelegate += GridUpdate;//获取SceneView的输入 } public void OnDisable() { // SceneView.onSceneGUIDelegate -= GridUpdate; } public override void OnInspectorGUI() { GUILayout.BeginHorizontal(); GUILayout.Label("网格宽度"); grid.width = EditorGUILayout.FloatField(grid.width, GUILayout.Width(50)); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); GUILayout.Label("网格高度"); grid.height = EditorGUILayout.FloatField(grid.height, GUILayout.Width(50)); GUILayout.EndHorizontal(); if (GUILayout.Button("打开Grid Window", GUILayout.Width(255))) { MyGridWindow window = (MyGridWindow)EditorWindow.GetWindow(typeof(MyGridWindow)); window.Init(); } SceneView.RepaintAll();//SceneView重绘 } void GridUpdate(SceneView sceneview) { Event e = Event.current;//获取事件 if (e.isKey && e.character == 'a') { //GameObject obj = GameObject.CreatePrimitive(PrimitiveType.Cube); GameObject obj; //如果选中Object //if (Selection.activeObject) //{ // obj = (GameObject)Instantiate(Selection.activeObject); // obj.transform.position = Vector3.zero; //} //在Editor模式实例化一个Prefab //if (Selection.activeObject) //{ // //找到Prefab // Object prefab = PrefabUtility.GetPrefabParent(Selection.activeObject); // if (prefab) // { // obj = (GameObject)PrefabUtility.InstantiatePrefab(prefab); // obj.transform.position = Vector3.zero; // } //} //根据鼠标点击的位置实例化Prefab if (Selection.activeObject) { //屏幕的鼠标坐标转换成世界坐标 /** * 1、从屏幕发出射线 * 2、我们需要转化事件的屏幕空间的空间是可以接受的screenpointtoray() * 3、e.mousePosition 左上角坐标(0,0),右下角坐标(Camera.current.pixelWidth, -Camera.current.pixelHeight), 把它转换成世界坐标变为左下角(0,9),右上角(Camera.current.pixelWidth, Camera.current.pixelHeight) */ /* Ray r = Camera.current.ScreenPointToRay(new Vector3(e.mousePosition.x, -e.mousePosition.y + Camera.current.pixelHeight)); Vector3 mousePos = r.origin;//mousepos向量保存射线的来源 //找到Prefab Object prefab = PrefabUtility.GetPrefabParent(Selection.activeObject); if (prefab) { obj = (GameObject)PrefabUtility.InstantiatePrefab(prefab); obj.transform.position = new Vector3(mousePos.x,mousePos.y,0.0f); }*/ } //将Cube对齐到网格中心位置? if (Selection.activeObject) { Ray r = Camera.current.ScreenPointToRay(new Vector3(e.mousePosition.x, -e.mousePosition.y + Camera.current.pixelHeight)); Vector3 mousePos = r.origin;//mousepos向量保存射线的来源 //找到Prefab Object prefab = PrefabUtility.GetPrefabParent(Selection.activeObject); if (prefab) { obj = (GameObject)PrefabUtility.InstantiatePrefab(prefab); Vector3 aligned = new Vector3(Mathf.Floor(mousePos.x / grid.width) * grid.width + grid.width / 2.0f, Mathf.Floor(mousePos.y / grid.height) * grid.height + grid.height / 2.0f, 0.0f); obj.transform.position = aligned; } } } else if (e.isKey && e.character == 'n' && e.clickCount==0) //在当前鼠标位置创建一个Cube { Ray r = Camera.current.ScreenPointToRay(new Vector3(e.mousePosition.x, -e.mousePosition.y + Camera.current.pixelHeight)); Vector3 mousePos = r.origin;//mousepos向量保存射线的来源 GameObject obj = GameObject.CreatePrimitive(PrimitiveType.Cube); Vector3 aligned = new Vector3(Mathf.Floor(mousePos.x / grid.width) * grid.width + grid.width / 2.0f, Mathf.Floor(mousePos.y / grid.height) * grid.height + grid.height / 2.0f, 0.0f); obj.transform.position = aligned; //注册撤消操作 Undo.RegisterCreatedObjectUndo(obj, "Create" + obj.name); Debug.Log("create"); } else if (e.isKey && e.character == 'd')//删除选中的GameObject { foreach (GameObject obj in Selection.gameObjects) { Debug.Log(obj.name); DestroyImmediate(obj); } } else if (e.isKey && e.character == '1') { GameObject obj; if (Selection.activeObject) { Ray r = Camera.current.ScreenPointToRay(new Vector3(e.mousePosition.x, -e.mousePosition.y + Camera.current.pixelHeight)); Vector3 mousePos = r.origin;//mousepos向量保存射线的来源 //找到Prefab Object prefab = PrefabUtility.GetPrefabParent(Selection.activeObject); if (prefab) { obj = (GameObject)PrefabUtility.InstantiatePrefab(prefab); Vector3 aligned = new Vector3(Mathf.Floor(mousePos.x / grid.width) * grid.width + grid.width / 2.0f, Mathf.Floor(mousePos.y / grid.height) * grid.height + grid.height / 2.0f, 0.0f); obj.transform.position = aligned; //注册撤消操作 Undo.RegisterCreatedObjectUndo(obj, "Create" + obj.name); Debug.Log("create"); } } } //撤消单个对象实例 else if (e.isKey && e.character == '4') { GameObject obj; if (Selection.activeObject) { Ray r = Camera.current.ScreenPointToRay(new Vector3(e.mousePosition.x, -e.mousePosition.y + Camera.current.pixelHeight)); Vector3 mousePos = r.origin;//mousepos向量保存射线的来源 //找到Prefab Object prefab = PrefabUtility.GetPrefabParent(Selection.activeObject); if (prefab) { Undo.IncrementCurrentGroup(); obj = (GameObject)PrefabUtility.InstantiatePrefab(prefab); Vector3 aligned = new Vector3(Mathf.Floor(mousePos.x / grid.width) * grid.width + grid.width / 2.0f, Mathf.Floor(mousePos.y / grid.height) * grid.height + grid.height / 2.0f, 0.0f); obj.transform.position = aligned; //注册撤消操作 Undo.RegisterCreatedObjectUndo(obj, "Create" + obj.name); Debug.Log("create"); } } } } }
参考资料#
http://code.tutsplus.com/tutorials/how-to-add-your-own-tools-to-unitys-editor--active-10047
作者:赵青青 一名在【网易游戏】做游戏开发的程序员,擅长Unity3D,游戏开发,.NET等领域。
本文版权归作者和博客园共有,欢迎转载,转载之后请务必在文章明显位置标出原文链接和作者,谢谢。
如果本文对您有帮助,请点击【推荐】您的赞赏将鼓励我继续创作!想跟我一起进步么?那就【关注】我吧。
本文版权归作者和博客园共有,欢迎转载,转载之后请务必在文章明显位置标出原文链接和作者,谢谢。
如果本文对您有帮助,请点击【推荐】您的赞赏将鼓励我继续创作!想跟我一起进步么?那就【关注】我吧。
分类:
Unity项目开发日志
, Unity Editor知识
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· DeepSeek “源神”启动!「GitHub 热点速览」
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
· DeepSeek R1 简明指南:架构、训练、本地部署及硬件要求
· 2 本地部署DeepSeek模型构建本地知识库+联网搜索详细步骤