垂直于物体移动

时间:2014-05-17 21:24:53

标签: c# unity3d rotation raycasting

我试图在不同对象的路径之间移动。我使用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);


    }

2 个答案:

答案 0 :(得分:0)

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

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);
    }
}

答案 1 :(得分:0)

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

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

第三件事:轮换使用Slerp而不是Lerp会更好,除非你关注性能,考虑到代码的其余部分,这似乎不是一个问题。

Fourt thing:尝试使用Time.deltaTime的倍数,而不是硬编码线性和旋转速度,这样他们就不会成为帧率依赖(因为它们当前是)

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

最后,您的图片链接无效。

我希望这有帮助

相关问题