unity3d - 在Unity3D中移动到RaycastHit点时使对象与某些其他对象发生碰撞?
问题描述
我正在使用鼠标指针的 Raycasting 制作一个简单的构建系统。要放置的对象被移动(并在单击时克隆)到射线的 RaycastHit.point,但我希望它与自己类型的对象完全碰撞,相对于命中点移动其位置。该对象可以与 gif 中所示的地形相交,但不应位于已放置的墙块内。我尝试使用 hit.distance 但无法确定检测结果,因为对象已经定位在碰撞点。我应该尝试检测位置应该如何相对于命中点移动,还是应该以某种方式使 MeshCollider 在不断移动到 RaycastHit.point 时工作?
解决方案
这是按照您的要求做的一种方法。
private void Update()
{
Vector3 hitPosition = Vector3.zero;
Ray ray = _camera.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out RaycastHit hit))
{
hitPosition = hit.point; // 0
if (hit.transform.gameObject.CompareTag("cube")) // 1
hitPosition = ComputeHit(hit, hitPosition);
}
_current.transform.position = hitPosition;
}
private Vector3 ComputeHit(RaycastHit hit, Vector3 currentPosition)
{
var bounds = hit.transform.GetComponent<MeshRenderer>().bounds; // 2
Faces face = GetFace(hit); // 3
switch (face)
{
case Faces.Up:
currentPosition += new Vector3(0, bounds.extents.x, 0);
break;
case Faces.Down:
currentPosition += new Vector3(0, -bounds.extents.x, 0);
break;
case Faces.East:
currentPosition += new Vector3(bounds.extents.x, 0, 0);
break;
case Faces.West:
currentPosition += new Vector3(-bounds.extents.x, 0, 0);
break;
case Faces.North:
currentPosition += new Vector3(0, 0, bounds.extents.x);
break;
case Faces.South:
currentPosition += new Vector3(0, 0, -bounds.extents.x);
break;
}
return currentPosition;
}
public Faces GetFace(RaycastHit hit)
{
Vector3 res = hit.normal - Vector3.up;
if (res == new Vector3(0, -1, -1))
return Faces.South;
if (res == new Vector3(0, -1, 1))
return Faces.North;
if (res == new Vector3(0, 0, 0))
return Faces.Up;
if (res == new Vector3(1, 1, 1))
return Faces.Down;
if (res == new Vector3(-1, -1, 0))
return Faces.West;
if (res == new Vector3(1, -1, 0))
return Faces.East;
return Faces.Nothing;
}
public enum Faces
{
Nothing,
Up,
Down,
East,
West,
North,
South
}
我将进一步解释:
在您的 Update 方法中,一旦您检测到hit.point
位置在哪里// 0
,您就可以检查您是否瞄准了立方体// 1
。我不知道实例化后如何管理它们,但我添加了一个名为cube
. 它可以是任何名称或图层。它也可以是一个组件,并通过hit.transform.GetComponent<...>()
方法检查该组件是否存在。
然后,您获得瞄准的立方体边界// 2
并使用法线确定您瞄准的方向// 3
。
从这里开始,取决于目标面(6 个中的一个),您hit.point
在 3 个轴之一上添加偏移量。
bounds.extents
给你一半的脸,bounds.extents.x
使用bounds.extents.y
和bounds.extents.z
。您只希望偏移量为面的一半长度,因为当您用鼠标移动立方体时,立方体的位置在它的中心。
这是一个例子:
推荐阅读
- php - HTML 标记
在聊天工具上发送消息时插入到 moodle ajax 响应中
- jenkins - 正确发送从我们不同的 Jenkins 工作发送的电子邮件的标准方法是什么?
- android - 使用 `xmpp` 和 `smack` 从 `vcard` 获取自定义元素
- laravel - 无法更新多对多 eloquent
- automation - 无法使用 ChromeDriver 和 Protractor 创建着色器缓存条目:-2
- sql - 如何将 postgreSQL 代码转换为 Oracle SQL
- python - 将文本和数据图表与构面相结合?
- javascript - Javascript not running on github, but runs on local machine
- php - 启用 HTTPS 后 Laravel 5.7 @csrf 无法正常工作
- javascript - IIFE 参数与声明