找回密码
 注册帐号

扫一扫,访问微社区

Like Game视图选择Scene物体

7
回复
2928
查看
[ 复制链接 ]
排名
64952
昨日变化

5

主题

49

帖子

964

积分

Rank: 9Rank: 9Rank: 9

UID
354297
好友
0
蛮牛币
441
威望
0
注册时间
2020-11-3
在线时间
904 小时
最后登录
2021-4-20
2021-1-22 22:10:27 显示全部楼层 阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?注册帐号

x
【前言】

之前做很多项目的时候,在画面中突然出现的物体想要去选取调试,基本上都只能在scene去找,或者直接选择相机物体,在相机视野里双击物体查找,知道最近,在做一个项目时需要选择视野里的地砖查看视图,就想了却一下多年的心愿,写了这个插件。
01.png

配图:game视图选取地砖


【思路分析】

由于是Game视图选择物体,所以Game视图一般有两种选取方式:
一、使用射线检测碰撞体,也就意味着场景的物体身上必须有合适的碰撞体,然后根据检测信息知道物体选择物体。
二、UGUI有事件系统可以知道鼠标是否在UI上,这个接口或者EventTrigger需要勾选RaycastTarget,所以就猜想是否是射线检测,为此也写射线调试了下勾选了RaycastTarget的UI,好像是行不通,又或者是UI底层的射线和我们平时用的射线有所区别,由于UI没碰撞体的,所以可能是由屏幕位置来知道是否在UI上吧,反正我没看过UGUI源码不得而知。

综上所述,我们选择了第一种方式实现,这样的话索要选择的物体必须加碰撞体,如果场景中加碰撞体麻烦,建议在预制体加比较快。




【进入开发环节】

在开发过程中,我发现暂停后Update等生命周期函数会停止,于是乎我意识到,假设一个怪物在Game视图中突然出现很快消失,那么很不利于选择到该怪物,所以只能暂停停止生命周期,选择怪物,于是我舍弃了Update,改用了EditorApplication.update来替代Update相关功能,在暂停模式,这个方法便代替了Update执行动态选取。

1.Start方法生成Sphere(代替鼠标方便查看),再生成一个Sphere用于显示高亮效果,然后最最最重要的一点就是注册EditorApplication.update事件

private void Start()
{
print(\"Start\");
// 鼠标的屏幕坐标转成世界坐标的点
mousePoint = GameObject.CreatePrimitive(PrimitiveType.Sphere).GetComponent<Transform>();//创建一个Sphere物体
DestroyImmediate(mousePoint.GetComponent<Collider>());//去除掉碰撞体
mousePoint.localScale = Vector3.one * 0.1f;//设置尺寸

// 用于边缘效果展示的物体
highLightObj = GameObject.CreatePrimitive(PrimitiveType.Sphere).GetComponent<Transform>(); print(\"highLightObj=\" + highLightObj);//创建一个Sphere用于选中边缘描边
DestroyImmediate(highLightObj.GetComponent<Collider>());//同样去掉碰撞体
highLightObj.GetComponent<MeshRenderer>().material = Resources.Load<Material>(\"MT_Silhouette\");//更换成边缘描边材质球
highLightObj.gameObject.SetActive(false);//初始化关闭描边的物体
EditorApplication.update += Update0;//注册EditorApplication.update事件
}

2.Update0里面动态做射线检测,用于比对前后帧的物体来更换材质球,来显示到描边效果,最后在鼠标左键单击,来定位到选择的物体上。


void Update0()
{
print(\"update\");
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit raycastHit = new RaycastHit();
if (Physics.Raycast(ray out raycastHit))
{
//print(!nowObj);
if (!nowObj || nowObj.name != raycastHit.transform.name)//把上次检测到的物体和新检测的raycastHit的物体名比对,如果不是上一次的物体进入逻辑
{
if (nowObj)
{
// 换回原来的材质
nowObj.GetComponent<MeshRenderer>().material = oldMaterial;
}
// 射线当前检测到的物体
nowObj = raycastHit.transform.gameObject;
// 更换材质球
oldMaterial = raycastHit.transform.GetComponent<MeshRenderer>().sharedMaterial;
nowObj.GetComponent<MeshRenderer>().material = Resources.Load<Material>(\"MT_HighLingh\");
// 显示选中效果
highLightObj.position = raycastHit.transform.position;
highLightObj.rotation = raycastHit.transform.rotation;
highLightObj.localScale = raycastHit.transform.localScale;
highLightObj.GetComponent<MeshFilter>().mesh = raycastHit.collider.GetComponent<MeshFilter>().sharedMesh;
highLightObj.gameObject.SetActive(true);
print(nowObj);
}
if (Input.GetMouseButtonDown(0))
{
if (nowObj != null)//如果选取的对象存在,那么在scene视图定位到该物体
{
Selection.activeGameObject = nowObj;
SceneView.lastActiveSceneView.FrameSelected();
}
}
}
else
{
//print(\"射线未射到\");
if (highLightObj.gameObject.activeSelf)
{
//print(\"highLightObj处于激活\");
// 隐藏选中效果
highLightObj.gameObject.SetActive(false);
// 换回原来的材质
nowObj.GetComponent<MeshRenderer>().material = oldMaterial;
// 置空射线检测到的物体
nowObj = null;
}
}
Debug.DrawRay(Camera.main.transform.position GetMousePositionOnWorld() - Camera.main.transform.position Color.red);//将射线绘制出来,方便查看
mousePoint.position = GetMousePositionOnWorld();//将鼠标的屏幕坐标转换成世界坐标
}


【最后想说】

底下有源码资源包,起初,我想过没有运行前也能从Game视图选择物体,虽然EditorApplication.update支持刷新,但是射线的相关功能好像在主线程中才能使用(运行unity后),所以没有运行选取没有想到更好的解决方案,如果有更好的意见,可以留言我,评论我都会一一查看的。


案例源码:
码云下载Game视图选择物体unitypackage.txt (49 Bytes, 下载次数: 6, 售价: 10 蛮牛币)
回复

使用道具 举报

7日久生情
1576/5000
排名
2122
昨日变化

3

主题

82

帖子

1576

积分

Rank: 7Rank: 7Rank: 7Rank: 7

UID
9302
好友
1
蛮牛币
5065
威望
0
注册时间
2013-12-1
在线时间
839 小时
最后登录
2021-4-20
2021-1-23 11:40:14 显示全部楼层
有点意思
回复

使用道具 举报

9以坛为家
10611/50000
排名
1658
昨日变化

0

主题

7207

帖子

1万

积分

Rank: 9Rank: 9Rank: 9

UID
185339
好友
1
蛮牛币
1957
威望
0
注册时间
2016-11-20
在线时间
2624 小时
最后登录
2021-4-20
2021-1-26 09:11:41 显示全部楼层
{:107:}{:107:}
回复

使用道具 举报

3偶尔光临
272/300

0

主题

48

帖子

272

积分

Rank: 3Rank: 3Rank: 3

UID
349739
好友
0
蛮牛币
96
威望
0
注册时间
2020-7-2
在线时间
224 小时
最后登录
2021-4-19
2021-3-6 21:55:51 显示全部楼层
有点意思
回复

使用道具 举报

7日久生情
2874/5000
排名
4264
昨日变化

5

主题

233

帖子

2874

积分

Rank: 7Rank: 7Rank: 7Rank: 7

UID
122909
好友
1
蛮牛币
13
威望
0
注册时间
2015-9-17
在线时间
2378 小时
最后登录
2021-4-20
2021-3-10 15:23:51 显示全部楼层

有点意思
回复

使用道具 举报

排名
64952
昨日变化

5

主题

49

帖子

964

积分

Rank: 9Rank: 9Rank: 9

UID
354297
好友
0
蛮牛币
441
威望
0
注册时间
2020-11-3
在线时间
904 小时
最后登录
2021-4-20
楼主 2021-3-12 09:55:57 显示全部楼层
案例中Game选择物体Scene视图定位,有点类似于Scene视图双击物体定位一样,除此之外,还做了选择的物体描边,还有一些编辑器功能
回复 支持 反对

使用道具 举报

5熟悉之中
952/1000
排名
12881
昨日变化

3

主题

307

帖子

952

积分

Rank: 5Rank: 5

UID
256916
好友
0
蛮牛币
346
威望
0
注册时间
2017-11-29
在线时间
572 小时
最后登录
2021-4-16
2021-3-12 10:54:20 显示全部楼层
很实用的功能
回复

使用道具 举报

5熟悉之中
705/1000
排名
9775
昨日变化

0

主题

97

帖子

705

积分

Rank: 5Rank: 5

UID
29289
好友
0
蛮牛币
0
威望
0
注册时间
2014-6-11
在线时间
494 小时
最后登录
2021-4-18
2021-3-27 13:01:18 显示全部楼层
好教程!学习了
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册帐号

本版积分规则

关注游戏蛮牛公众号送vip