【问题标题】:Build a collider around a gizmos line围绕 Gizmos 线构建对撞机
【发布时间】:2019-10-06 03:06:45
【问题描述】:

正如标题所暗示的,这个想法是在一个球体和另一个球体之间构建网格,通过禁用其网格渲染器或将 alpha 颜色设置为零来使网格透明。目前,因为一切正常,我必须为所有网格分配一个新层,因为它们在地板上不平行,但根据方向它们可以是倾斜的。在这种情况下,RayCast 将看不到被平面隐藏的网格部分。使用 RayCast 上的图层,我在网格的整个表面上得到了对撞机。但我想知道是否没有办法设置我传递的 4 Vector3 来创建网格,使其平行于平面。 为了找到网格的 4 个顶点,我使用了一个脚本来绘制更多平行的 Gizmos 线以获得更大的厚度。一旦我有了 4 个顶点,就很容易创建一个网格。我还尝试使用 linerenderer 设置 startWidth 和 endWidth to get a line with apparently parallel edges in Game View。它的行为方式相同。此外,linerenderer 的 BakeMesh 方法仅适用于最新版本的 Unity。 这是结果的图像,我放大了网格,使其倾斜度清晰可见

如您所见,只有在游戏视图中完全垂直的选定线位于平面上。

这是代码,我在球体中心位置的左右找到四个vector3并将它们存储在一个列表中:

Vector3 p1 = sphere1.transform.position;
Vector3 p2 = sphere2.transform.position;
Vector3 scp1 = cam.WorldToScreenPoint(p1);
Vector3 scp2 = cam.WorldToScreenPoint(p2);
Vector3 v1 = (scp2 - scp1).normalized;
Vector3 n = Vector3.Cross(v1, Vector3.forward);
Vector3 newVert;
Vector3 o = 6f * n * 3 * (0f / 3 - 0.5f);
newVert = cam.ScreenToWorldPoint(scp1 + o);
listVerts.Add(newVert );
newVert = cam.ScreenToWorldPoint(scp2 + o);
listVerts.Add(newVert );
o = 6f * n * 3 * (1 - 0.5f);
newVert = cam.ScreenToWorldPoint(scp2 + o);
listVerts.Add(newVert );
newVert = cam.ScreenToWorldPoint(scp1 + o);
listVerts.Add(newVert );

然后我将列表传递给创建网格的函数。 我必须做些什么来确保网格都放在地板上? 有没有更好的方法让点平行于球体的中心?

【问题讨论】:

  • 在这个问题中,听起来你只是想为碰撞(光线投射)目的制作一个网格,但在我的回答的评论中,你关心它的样子?然而,在你的问题中,你解释说无论如何你都会让它不可见。你在这里的目标对我来说仍然很不清楚。
  • 对不起,可能是我的英语不好。目标正是围绕 Gizmos 线创建一个对撞机。球体是主网格的顶点,通过移动球体我对其进行建模。碰撞器用于在点击点插入新球体(顶点)。然而,通过将不可见的网格(碰撞器)平行于工作平面放置,其中一些(尤其是水平的),由于相机的旋转,不再可见(目前我让它们可见以进行测试)。这意味着即使是 RayCast 也看不到它们或在其他情况下(斜线)[...继续]
  • 对撞机减小了它的厚度。只有垂直线显示定义宽度的对撞机。另一方面,如果我让网格对撞机保持倾斜,正如您在我发布的图像中看到的那样,它们总是面向相机并且 RayCast 完全击中它们。我不知道我是否能够很好地解释自己,我的方法也可以改进。如果我没有看到任何东西,如果你让我知道,我将不胜感激。
  • 如果您的球体数量较少,您也许可以在每对球体之间进行迭代,然后找出鼠标射线投射与直线之间的最短距离,以及直线的位置那是。您对 2 个球体之间的每条线都执行此操作,并找出哪个球体的距离最短。然后对于距离最短的那个,您在该线上的最近点处创建球(如果它实际上完全接近)查看wiki.unity3d.com/index.php/3d_Math_functions 并搜索“ClosestPointsOnTwoLines”以获得一些帮助。请记住 [...继续]
  • 上面的链接代码用于无限行,因此您需要确保忽略最近点超出球体和/或相机后面的情况。

标签: c# unity3d


【解决方案1】:

一种方法是用它旁边的球体底部的 y 分量覆盖每个顶点的 y 分量。

// I recall from your previous question that you have a formula to 
// calculate the scale / radius directly but it's not in the question, 
// so here's a way to estimate it:

float sphere1Radius = p1.transform.lossyScale.x / 2f; 
float sphere2Radius = p2.transform.lossyScale.x / 2f

float sphere1BottomY = p1.y - sphere1Radius;
float sphere2BottomY = p2.y - sphere2Radius;

newVert = cam.ScreenToWorldPoint(scp1 + o);
newVert.y = sphere1BottomY  
listVerts.Add(newVert );

newVert = cam.ScreenToWorldPoint(scp2 + o);
newVert.y = sphere2BottomY 
listVerts.Add(newVert );

o = 6f * n * 3 * (1 - 0.5f);
newVert = cam.ScreenToWorldPoint(scp2 + o);
newVert.y = sphere2BottomY
listVerts.Add(newVert );

newVert = cam.ScreenToWorldPoint(scp1 + o);
newVert.y = sphere1BottomY 
listVerts.Add(newVert );

【讨论】:

  • @Ruzihm 谢谢,你的指示是正确的,这样网格就平行于平面。然而,这种变化让我明白我做出了错误的考虑。通过旋转网格,它们根据它们的方向不再出现在游戏视图中,就好像它们是 Gizmo 线的轮廓一样,在某些情况下它们甚至不再可见。这当然是因为视角。我试图将它们移动到球体的中心和上方,但现在很明显,正是它们的旋转使我们能够在游戏视图中将它们视为矩形,以便 [...继续]
  • Gizmos 线的左侧和右侧的厚度相同。我真的相信唯一的解决方案是在他们的个人图层上使用 Ray Cast,即使与计划涵盖的部分发生碰撞。如果有人有建议,欢迎提出,这是论坛中很受欢迎的话题。
猜你喜欢
  • 1970-01-01
  • 2011-08-12
  • 2014-01-13
  • 2011-02-09
  • 1970-01-01
  • 1970-01-01
  • 2016-11-23
  • 1970-01-01
  • 2011-01-24
相关资源
最近更新 更多