unity3d - 检查游戏对象在当前相机上是否可见
问题描述
我一直在搜索堆栈溢出和互联网,试图寻找解决此问题的方法,每次我尝试使用 OnBecameVisible() 或 OnBecameInvisible() 或 TestPlanesAABB 来检查对象是否通过墙壁不可见时,相机仍然可以通过实心墙看到物体。
问题视频在这里: https ://youtu.be/3HiEugm6On8
正如你所看到的,如果我看着他,他会停止移动,如果我转身并且他“卸载”或“变得隐形”,他会靠近,但如果我绕过一个角落仍然看着他的方向,他会停止移动,因为如果我能看到他并且那里没有墙,这就是我要解决的问题
这是一个四处游荡的敌人,我希望他只有在我看不见他的情况下才移动,我认为这很简单,但可惜它似乎没有我想的那么简单
我当前的代码是基本的:
public bool IsSeen = false;
public void OnBecameVisible()
{
Debug.Log("I can now see you");
IsSeen = true;
}
public void OnBecameInvisible()
{
Debug.Log("I can't see you");
IsSeen = false;
}
这附加到我希望通过墙壁检测/不检测的对象上,我相信这会检查对象是否可以被我选择的相机看到。
有人对我如何解决/实现这一点有任何想法吗?
解决方案
如前所述,一般的“问题”Renderer.OnBecameVisible
是
请注意,当需要在场景中渲染对象时,它被认为是可见的。它可能实际上不会被任何相机看到,但仍需要为阴影进行渲染。此外,在编辑器中运行时,场景视图摄像机也会导致调用此函数。
所以它对你不是真的有用。
有没有一种简单的方法来对整个屏幕进行光线投射?
不幸的是不是真的:/
您可以避免使用这种方法GeometryUtility.CalculateFrustumPlanes
来获得相机截锥体的四个平面。然后你可以检查对象是否真的在视锥体内GeometryUtility.TestPlanesAABB
var cam = Camera.main;
var planes = GeometryUtility.CalculateFrustumPlanes(cam);
var objCollider = GetComponent<Collider>();
if (GeometryUtility.TestPlanesAABB(planes, objCollider.bounds))
{
Debug.Log("I am inside the camera frustrum!");
}
else
{
Debug.Log("I am out of sight...");
}
但是,这仍然没有覆盖目标对象前面的任何其他对象,因此实际上覆盖了它。
您需要准确定义可见的含义(例如,网格的任何部分?对象的中心是否足以测试?等)。
例如,仅测试对象的中心,您可以使用Physics.Linecast
类似的方法,例如
if (GeometryUtility.TestPlanesAABB(planes, objCollider.bounds))
{
Debug.Log("I am inside the camera frustrum!");
if(Physics.LineCast(cam.transform.position, objCollider.GetComponentInChildren<Renderer>().bounds.center, out var hit)
{
if(hit.gameObject != objCollider.gameObject)
{
Debug.Log("..but something else is in the way..");
}
else
{
Debug.Log("Now you see me, muhaha!");
}
}
}
如果您希望它更精确并且可以看到网格的任何部分的跟踪,那么它实际上会变得很棘手。根据您的需要,您需要对边界框的多个关键点(例如每个角、边缘的中心等)进行光线投射。
推荐阅读
- python - Python将字符串转换为日期时间以查找差异
- javascript - JS:加载的 json 未定义,即使它不是
- reporting-services - 不根据 IF 更改 Tablix rdlc 中的字体或单元格颜色 - 改为更改文本
- sql - 如何在 Sql Server 中以原子方式更新复合对象?
- sql - SQL 查询在 DBeaver 中有效,但在 Oracle Apex 中无效
- javascript - 是否可以在 v-card 组件中专门使用 Vue/Vuetify 中的多个底部边框
- python-3.x - 尝试在 Excel 文件中删除列
- docker - 如何从 docker 桌面公开 kubernetes 的端口
- python - 如何知道 Python 中特定日期的日期(是星期一、星期二还是……)
- javascript - 将字符串数组转换为枚举