使用Unity3D中的操纵杆平滑旋转

时间:2018-07-30 11:44:09

标签: c# unity3d joystick

我正在尝试使用操纵杆旋转2D播放器汽车,但旋转不平稳。我怎样才能做到这一点。有帮助吗?

我想要的是:Click Here

正在发生Click Here

public class RightJoystickPlayerController : MonoBehaviour
{
    public RightJoystick rightJoystick;
    public Transform rotationTarget;
    private Vector3 rightJoystickInput;
    public bool flipRot = true;
    public static float angle;

    private float horizontal;
    private float vertical;

    private void Update()
    {
        rightJoystickInput = rightJoystick.GetInputDirection();
        horizontal = rightJoystickInput.x;
        vertical   = rightJoystickInput.y;
        angle      = Mathf.Atan2(horizontal, vertical) * Mathf.Rad2Deg;
        angle      = flipRot ? -angle : angle;
        rotationTarget.rotation = Quaternion.Euler(new Vector3(0, 0, angle));
    }
}

2 个答案:

答案 0 :(得分:1)

我建议您跟踪数组中最后4、8或16个旋转,并使用Quaternion.Lerp将旋转设置为这4、8或16个旋转的平均值。

以下是在16圈之间平滑的示例(这是极端平滑):

private List<Quaternion> lastRotations = new List<Quaternion>();

Quaternion quatA = lastRotations[0];
Quaternion quatB = lastRotations[1];
Quaternion quatC = lastRotations[2];
Quaternion quatD = lastRotations[3];
Quaternion quatE = lastRotations[4];
Quaternion quatF = lastRotations[5];
Quaternion quatG = lastRotations[6];
Quaternion quatH = lastRotations[7];
Quaternion quatI = lastRotations[8];
Quaternion quatJ = lastRotations[9];
Quaternion quatK = lastRotations[10];
Quaternion quatL = lastRotations[11];
Quaternion quatM = lastRotations[12];
Quaternion quatN = lastRotations[13];
Quaternion quatO = lastRotations[14];
Quaternion quatP = lastRotations[15];

Quaternion quatAB = Quaternion.Lerp(quatA, quatB, 0.5f);
Quaternion quatCD = Quaternion.Lerp(quatC, quatD, 0.5f);
Quaternion quatEF = Quaternion.Lerp(quatE, quatF, 0.5f);
Quaternion quatGH = Quaternion.Lerp(quatG, quatH, 0.5f);
Quaternion quatIJ = Quaternion.Lerp(quatI, quatJ, 0.5f);
Quaternion quatKL = Quaternion.Lerp(quatK, quatL, 0.5f);
Quaternion quatMN = Quaternion.Lerp(quatM, quatN, 0.5f);
Quaternion quatOP = Quaternion.Lerp(quatO, quatP, 0.5f);

Quaternion quatABCD = Quaternion.Lerp(quatAB, quatCD, 0.5f);
Quaternion quatEFGH = Quaternion.Lerp(quatEF, quatGH, 0.5f);
Quaternion quatIJKL = Quaternion.Lerp(quatIJ, quatKL, 0.5f);
Quaternion quatMNOP = Quaternion.Lerp(quatMN, quatOP, 0.5f);

Quaternion quatABCDEFGH = Quaternion.Lerp(quatABCD, quatEFGH, 0.5f);
Quaternion quatIJKLMNOP = Quaternion.Lerp(quatIJKL, quatMNOP, 0.5f);

Quaternion quatABCDEFGHIJKLMNOP = Quaternion.Lerp(quatABCDEFGH, quatIJKLMNOP, 0.5f);

然后将“ quatABCDEFGHIJKLMNOP”应用于您的汽车旋转。

您收到的每帧新的操纵杆输入都会将其添加到列表中。如果列表计数大于16,则使用lastRotations.RemoveAt(0);删除最后一个旋转。

首先在列表中填充16个相同的旋转角度(也许是Quaternion.identity),以声明汽车的初始旋转角度。

更新: 用欧拉角方法代替四元数的完整示例:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class RightJoystickPlayerController : MonoBehaviour
{
    public RightJoystick rightJoystick;
    public Transform rotationTarget;
    private Vector3 rightJoystickInput;
    public bool flipRot = true;
    public static float angle;

    private float horizontal;
    private float vertical;

    private List<float> lastRotations = new List<float>();

    private void Start()
    {
        for (int i = 0; i < 16; i++)
        {
            lastRotations.Add(0f);
        }
    }

    private void Update()
    {
        rightJoystickInput = rightJoystick.GetInputDirection();
        horizontal = rightJoystickInput.x;
        vertical = rightJoystickInput.y;
        angle = Mathf.Atan2(horizontal, vertical) * Mathf.Rad2Deg;
        angle = flipRot ? -angle : angle;

        lastRotations.Add(angle);
        while (lastRotations.Count > 16)
        {
            lastRotations.RemoveAt(0);
        }

        float rotA = lastRotations[0];
        float rotB = lastRotations[1];
        float rotC = lastRotations[2];
        float rotD = lastRotations[3];
        float rotE = lastRotations[4];
        float rotF = lastRotations[5];
        float rotG = lastRotations[6];
        float rotH = lastRotations[7];
        float rotI = lastRotations[8];
        float rotJ = lastRotations[9];
        float rotK = lastRotations[10];
        float rotL = lastRotations[11];
        float rotM = lastRotations[12];
        float rotN = lastRotations[13];
        float rotO = lastRotations[14];
        float rotP = lastRotations[15];

        float rotAB = Mathf.LerpAngle(rotA, rotB, 0.5f);
        float rotCD = Mathf.LerpAngle(rotC, rotD, 0.5f);
        float rotEF = Mathf.LerpAngle(rotE, rotF, 0.5f);
        float rotGH = Mathf.LerpAngle(rotG, rotH, 0.5f);
        float rotIJ = Mathf.LerpAngle(rotI, rotJ, 0.5f);
        float rotKL = Mathf.LerpAngle(rotK, rotL, 0.5f);
        float rotMN = Mathf.LerpAngle(rotM, rotN, 0.5f);
        float rotOP = Mathf.LerpAngle(rotO, rotP, 0.5f);

        float rotABCD = Mathf.LerpAngle(rotAB, rotCD, 0.5f);
        float rotEFGH = Mathf.LerpAngle(rotEF, rotGH, 0.5f);
        float rotIJKL = Mathf.LerpAngle(rotIJ, rotKL, 0.5f);
        float rotMNOP = Mathf.LerpAngle(rotMN, rotOP, 0.5f);

        float rotABCDEFGH = Mathf.LerpAngle(rotABCD, rotEFGH, 0.5f);
        float rotIJKLMNOP = Mathf.LerpAngle(rotIJKL, rotMNOP, 0.5f);

        float rotABCDEFGHIJKLMNOP = Mathf.LerpAngle(rotABCDEFGH, rotIJKLMNOP, 0.5f);

        rotationTarget.rotation = Quaternion.Euler(new Vector3(0, 0, rotABCDEFGHIJKLMNOP));
    }
}

答案 1 :(得分:0)

旋转不平稳,因为您直接设置了Transform.rotation。命名有点混乱。 Transform.rotation不会使其旋转-它定义了其面对的方向。

相反,请尝试以下操作:

rotationTarget.Rotate(新的Vector3(0,0,角度* Time.deltaTime * ROTATION_SPEED));

Time.deltaTime是使旋转平滑而与帧率无关

所必需的

ROTATION_SPEED应该是您自己定义的const float,具体取决于您希望汽车转弯多快。

根据您的说明进行编辑:要使您的汽车向给定方向旋转,请尝试使用Quaternion.LookRotation将水平/垂直方向转换为四元数,然后按照其他建议,使用Lerp平稳地过渡过渡rotationTarget.rotation向目标旋转。并乘以Time.deltaTime和速度常数。