首页 > 解决方案 > Unity 3D如何旋转对象以使其基于地平面正确定向?

问题描述

我正在使用一个名为 Dreamteck Splines 的资产来创建一条路径,我想做的是让它在我旋转样条曲线时游戏对象在这种情况下粉红色立方体也会旋转,因此它在路径上是否正确定向它像过山车一样颠倒或侧向。出于某种原因,我只能在立方体停止旋转以使其与路径对齐之前将路径旋转到大约 90 度。 GIF

if (Input.GetKey(KeyCode.W))
    {
        vehicle.transform.Translate(0, 0, speed * Time.deltaTime);

    }
    if (Physics.Raycast(vehicle.transform.position, Vector3.down, out hit, 100))
    {
        Vector3 surfaceNormal = hit.normal; // Assign the normal of the surface to surfaceNormal
        Vector3 forwardRelativeToSurfaceNormal = Vector3.Cross(vehicle.transform.InverseTransformDirection(vehicle.transform.right), surfaceNormal);
        Quaternion targetRotation = Quaternion.LookRotation(forwardRelativeToSurfaceNormal, surfaceNormal); //check For target Rotation.
        vehicle.transform.rotation = Quaternion.Lerp(vehicle.transform.rotation, targetRotation, Time.deltaTime * 20); //Rotate Character accordingly.

    }

标签: c#unity3d

解决方案


我发现这可以实现我想要实现的目标:

 void Update()
{
    /*Here we get user input to calculate the speed the ship will get*/
    if (Input.GetKey(KeyCode.W))
    {
        /*Increase our current speed only if it is not greater than fwd_max_speed*/
        current_speed += (current_speed >= fwd_max_speed) ? 0f : fwd_accel * Time.deltaTime;
    }
    else
    {
        if (current_speed > 0)
        {
            /*The ship will slow down by itself if we dont accelerate*/
            current_speed -= brake_speed * Time.deltaTime;
        }
        else
        {
            current_speed = 0f;
        }
    }

    /*We get the user input and modifiy the direction the ship will face towards*/
    yaw += turn_speed * Time.deltaTime * Input.GetAxis("Horizontal");
    /*We want to save our current transform.up vector so we can smoothly change it later*/
    prev_up = transform.up;
    /*Now we set all angles to zero except for the Y which corresponds to the Yaw*/
    transform.rotation = Quaternion.Euler(0, yaw, 0);

    RaycastHit hit;
    if (Physics.Raycast(transform.position, -prev_up, out hit))
    {
        Debug.DrawLine(transform.position, hit.point);

        /*Here are the meat and potatoes: first we calculate the new up vector for the ship using lerp so that it is smoothed*/
        Vector3 desired_up = Vector3.Lerp(prev_up, hit.normal, Time.deltaTime * pitch_smooth);
        /*Then we get the angle that we have to rotate in quaternion format*/
        Quaternion tilt = Quaternion.FromToRotation(transform.up, desired_up);
        /*Now we apply it to the ship with the quaternion product property*/
        transform.rotation = tilt * transform.rotation;

        /*Smoothly adjust our height*/
        smooth_y = Mathf.Lerp(smooth_y, hover_height - hit.distance, Time.deltaTime * height_smooth);
        transform.localPosition += prev_up * smooth_y;
    }

    /*Finally we move the ship forward according to the speed we calculated before*/
    transform.position += transform.forward * (current_speed * Time.deltaTime);
}

推荐阅读