垂直于物体移动

Posted

技术标签:

【中文标题】垂直于物体移动【英文标题】:Moving perpendicular to an object 【发布时间】:2014-07-06 03:25:40 【问题描述】:

我试图在由不同对象组成的路径之间移动。我使用 Translate() 应用恒定速度并使用 Raycasting 使用右侧对象的垂直矢量旋转

虽然它会转动,但它是否旋转得不够快,无法完全转动并移出路径。

任何想法如何解决这个问题?或者其他方式来实现它?

任何帮助将不胜感激

帮助形象化的图像: Raycast and Rotation image

void Update() RaycastHit hit; if (!Physics.Raycast(transform.position, Vector3.right, out hit)) return; MeshCollider meshCollider = hit.collider as MeshCollider; if (meshCollider == null || meshCollider.sharedMesh == null) return; Mesh mesh = meshCollider.sharedMesh; Vector3[] normals = mesh.normals; int[] triangles = mesh.triangles; Vector3 n0 = normals[triangles[hit.triangleIndex * 3 + 0]]; Vector3 n1 = normals[triangles[hit.triangleIndex * 3 + 1]]; Vector3 n2 = normals[triangles[hit.triangleIndex * 3 + 2]]; Vector3 baryCenter = hit.barycentricCoordinate; Vector3 interpolatedNormal = n0 * baryCenter.x + n1 * baryCenter.y + n2 * baryCenter.z; interpolatedNormal = interpolatedNormal.normalized; Transform hitTransform = hit.collider.transform; interpolatedNormal = hitTransform.TransformDirection(interpolatedNormal); Vector3 targetDir = Vector3.Cross(interpolatedNormal, Vector3.up); // Get the perpendicular vector Vector3 newDir = Vector3.RotateTowards(transform.forward, targetDir, 20f, 0f); transform.rotation = Quaternion.LookRotation(newDir); // Rotate Object transform.Translate(0,0,0.2f); // Constant Speed Debug.DrawRay(transform.position, perp,Color.red);

【问题讨论】:

【参考方案1】:

我不认为这是一个好方法,但它对我有用。也许这可以帮助你。

public float fixedDist = 2.0f;
void WallDetect() 
    RaycastHit hit;
    if (!Physics.Raycast(transform.position, transform.TransformPoint(Vector3.right) - transform.position, out hit))
        return;

    Vector3 perp = Vector3.Cross(hit.normal, Vector3.up);
    Vector3 targetDir = Vector3.Project(transform.forward, perp).normalized;
    Vector3 currentDir = transform.TransformPoint (Vector3.forward) - transform.position;

    RaycastHit hit2;
    if (Physics.Raycast (transform.position, -hit.normal, out hit2)) 
        Vector3 fixedPos = hit2.point + hit.normal * fixedDist;
        Vector3 predictPos = fixedPos + targetDir;

        transform.position = Vector3.MoveTowards (transform.position, predictPos, 0.01f);
        transform.rotation = Quaternion.Lerp(transform.rotation, Quaternion.LookRotation (predictPos - transform.position), 0.05f);
    

【讨论】:

【参考方案2】:

第一件事:您似乎没有使用 HitInfo 结构中的数据 - 信不信由你,它已经包含一个 .normal Vector3 成员,在光线投射期间计算(或在请求时延迟计算,我不确定,但它没有差异),最好使用它而不是自己滚动,更简单且不易出错(您手动查找正常看起来永远正确,但我没有尝试过)

第二件事:你的最后一行有一个 t=0.05 的 Quaternion.Lerp,这意味着对于每个新的旋转,你仍然需要 95% 的原始旋转,这确实是非常缓慢的旋转。尝试 Time.deltaTime 范围内的东西(这大致相当于在一秒钟内接近)

第三件事:对于轮换而言,最好使用 Slerp 而不是 Lerp,除非您真正关心性能,考虑到其余代码,这似乎不是问题。

第四件事:不要硬编码线性和旋转速度,而是尝试使用 Time.deltaTime 的倍数,这样它们就不会依赖于帧率(就像现在一样)

第五件事:我觉得你不应该根据当前位置的正常设置目标旋转。你现在做的方式是你的旋转落后了 - 你应该从你当前位置的未来一步的位置进行光线投射,所以你知道要采取什么旋转,所以在你迈出那一步时它是正确的。目前,您将目标未来旋转设置为现在正确的旋转,这将滞后一帧。或者,您可以将转换步骤移动到循环的顶部,转换将更新,其余部分应按原样进行。

最后,您的图片链接不起作用。

希望对你有帮助

【讨论】:

感谢您的评论,但这个问题是 4 年前提出的。

以上是关于垂直于物体移动的主要内容,如果未能解决你的问题,请参考以下文章

OPENGL若干重要基础概念

真实物体(固体流体)的微元体应力状态

unity 自动排版(Vertical Layout Group)

Unity-控制2D物体移动

unity安卓关闭垂直同步

垂直于屏幕时,视图在 Y 轴上的旋转动画上剪辑