如何确定厚度与宽度? (使用光线投射)
How to determine thickness vs width? (Using Raycasting)
视觉教具
厚度与宽度:here
请查看动图
这里的厚度不同于宽度,因为有多个壁,因为有外圆柱和内圆柱。厚度是圆柱体任意一侧的 outer/inner 壁之间距离的测量值,其中厚度是从一端到另一端的距离,包含空心 space 之间。
提供的 gif 的快速概要
- 每次单击时,都会创建原点(蓝色)和目标点(橙色)球体以指示用户单击的位置以及用于计算距离的解释终点(显示在 GUI 上)。
原点定义用户在对象碰撞器表面上单击的位置,目标定义点,垂直于原点的世界 Y 轴,第二条光线投向第一条光线,击中另一侧对撞机。
当前:
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit))
{
//obtain the vector where the ray hit the collider.
hitPoint = hit.point; //origin point
//offset the ray, keeping it along the XZ plane of the hit
Vector3 offsetDirection = -1 * hit.normal;
//offset a long way, minimum thickness of the object
ray.origin = hit.point + offsetDirection * 100;
//point the ray back at the first hit point
ray.direction = (hit.point - ray.origin).normalized;
//raycast all, because there might be other objects in the way
RaycastHit[] hits = Physics.RaycastAll(ray);
foreach (RaycastHit h in hits)
{
if (h.collider == hit.collider)
{
hitBack = h.point; //destination point
}
}
}
目前,宽度是适当的功能。我想计算厚度而不必进入对象内部(如 gif 中所示)。
惊人的参考
http://answers.unity3d.com/questions/386698/detecting-how-many-times-a-raycast-collides-with-a.html
这个人基本上和我有同样的问题,并且有一个可能有效的解决方案。我不确定 Linecasting 与 Raycasting 的工作原理。
保留:
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit))
{
//obtain the vector where the ray hit the collider.
hitPoint = hit.point; //origin point
//offset the ray, keeping it along the XZ plane of the hit
Vector3 offsetDirection = -1 * hit.normal;
//offset a long way, minimum thickness of the object
ray.origin = hit.point + offsetDirection * 100;
//point the ray back at the first hit point
ray.direction = (hit.point - ray.origin).normalized;
替换:
//raycast all, because there might be other objects in the way
RaycastHit[] hits = Physics.RaycastAll(ray);
foreach (RaycastHit h in hits)
{
if (h.collider == hit.collider)
{
hitBack = h.point; //destination point
}
}
感谢(感谢 MirrorMirror's 富有洞察力的 post,以及@ryemoss 的工具性建议和帮助):
int counter = 0;
bool calculating = false; //set this to true on click
Vector3 Point, PreviousPoint, Goal, Direction;
Point = ray.origin;
Goal = hit.point;
Direction = ray.direction;
PreviousPoint = Vector3.zero;
while (calculating == true)
{
counter++;
RaycastHit hit2;
if (Physics.Linecast(Point, Goal, out hit2))
{
if(counter > 100)
{
hitBack = hitPoint;
counter = 0;
calculating = false;
break;
}
PreviousPoint = hit2.point;
Point = hit2.point + (Direction / 10000f);
}
else
{
if (PreviousPoint == Vector3.zero)
hitBack = hitPoint;
else
hitBack = PreviousPoint;
calculating = false;
counter = 0;
}
}
Linecast 与 Raycast
使用光线投射,您可以设置起点、方向和沿该方向检查的距离,而使用线投射,您只需设置起点和终点,它就会在这两个点之间进行检查。
所以,如果你知道具体的终点,就用linecast,如果你想检查一个特定的方向,但没有具体的终点,就用raycast。
解决方案
首先,使用初始光线投射获得第一个点,hit.point。然后,将ray.origin设置为collider(我们第一次碰撞的对象的collider得到hit.point)外的worldspace中的一个点,将ray.direction设置为在第一个点将光线面向后方,hit.point.
最后,使用while循环在ray.origin的新位置创建一个新的linecast(每次通过while循环更新,直到linecast到达hit.point),每次与该对象会出现,直到线路广播到达 hit.point。一旦达到 hit.point,就意味着物体的每个表面都被击中,每次击中都会创建一条新线,直到一条线到达第一个初始点 hit.point。要计算厚度,请取第一个命中 hit.point 与反向线播命中之前的命中 hit.point、PreviousPoint.
之间的距离
更新
1-修改代码以正确处理单面对象(例如:平面)。
2-添加计数器以防止无法计算的特殊情况。
3-提高可读性。
视觉教具
厚度与宽度:here
请查看动图
这里的厚度不同于宽度,因为有多个壁,因为有外圆柱和内圆柱。厚度是圆柱体任意一侧的 outer/inner 壁之间距离的测量值,其中厚度是从一端到另一端的距离,包含空心 space 之间。
提供的 gif 的快速概要
- 每次单击时,都会创建原点(蓝色)和目标点(橙色)球体以指示用户单击的位置以及用于计算距离的解释终点(显示在 GUI 上)。
原点定义用户在对象碰撞器表面上单击的位置,目标定义点,垂直于原点的世界 Y 轴,第二条光线投向第一条光线,击中另一侧对撞机。
当前:
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit))
{
//obtain the vector where the ray hit the collider.
hitPoint = hit.point; //origin point
//offset the ray, keeping it along the XZ plane of the hit
Vector3 offsetDirection = -1 * hit.normal;
//offset a long way, minimum thickness of the object
ray.origin = hit.point + offsetDirection * 100;
//point the ray back at the first hit point
ray.direction = (hit.point - ray.origin).normalized;
//raycast all, because there might be other objects in the way
RaycastHit[] hits = Physics.RaycastAll(ray);
foreach (RaycastHit h in hits)
{
if (h.collider == hit.collider)
{
hitBack = h.point; //destination point
}
}
}
目前,宽度是适当的功能。我想计算厚度而不必进入对象内部(如 gif 中所示)。
惊人的参考
http://answers.unity3d.com/questions/386698/detecting-how-many-times-a-raycast-collides-with-a.html
这个人基本上和我有同样的问题,并且有一个可能有效的解决方案。我不确定 Linecasting 与 Raycasting 的工作原理。
保留:
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit))
{
//obtain the vector where the ray hit the collider.
hitPoint = hit.point; //origin point
//offset the ray, keeping it along the XZ plane of the hit
Vector3 offsetDirection = -1 * hit.normal;
//offset a long way, minimum thickness of the object
ray.origin = hit.point + offsetDirection * 100;
//point the ray back at the first hit point
ray.direction = (hit.point - ray.origin).normalized;
替换:
//raycast all, because there might be other objects in the way
RaycastHit[] hits = Physics.RaycastAll(ray);
foreach (RaycastHit h in hits)
{
if (h.collider == hit.collider)
{
hitBack = h.point; //destination point
}
}
感谢(感谢 MirrorMirror's 富有洞察力的 post,以及@ryemoss 的工具性建议和帮助):
int counter = 0;
bool calculating = false; //set this to true on click
Vector3 Point, PreviousPoint, Goal, Direction;
Point = ray.origin;
Goal = hit.point;
Direction = ray.direction;
PreviousPoint = Vector3.zero;
while (calculating == true)
{
counter++;
RaycastHit hit2;
if (Physics.Linecast(Point, Goal, out hit2))
{
if(counter > 100)
{
hitBack = hitPoint;
counter = 0;
calculating = false;
break;
}
PreviousPoint = hit2.point;
Point = hit2.point + (Direction / 10000f);
}
else
{
if (PreviousPoint == Vector3.zero)
hitBack = hitPoint;
else
hitBack = PreviousPoint;
calculating = false;
counter = 0;
}
}
Linecast 与 Raycast
使用光线投射,您可以设置起点、方向和沿该方向检查的距离,而使用线投射,您只需设置起点和终点,它就会在这两个点之间进行检查。
所以,如果你知道具体的终点,就用linecast,如果你想检查一个特定的方向,但没有具体的终点,就用raycast。
解决方案
首先,使用初始光线投射获得第一个点,hit.point。然后,将ray.origin设置为collider(我们第一次碰撞的对象的collider得到hit.point)外的worldspace中的一个点,将ray.direction设置为在第一个点将光线面向后方,hit.point.
最后,使用while循环在ray.origin的新位置创建一个新的linecast(每次通过while循环更新,直到linecast到达hit.point),每次与该对象会出现,直到线路广播到达 hit.point。一旦达到 hit.point,就意味着物体的每个表面都被击中,每次击中都会创建一条新线,直到一条线到达第一个初始点 hit.point。要计算厚度,请取第一个命中 hit.point 与反向线播命中之前的命中 hit.point、PreviousPoint.
之间的距离更新
1-修改代码以正确处理单面对象(例如:平面)。
2-添加计数器以防止无法计算的特殊情况。
3-提高可读性。