将移动操纵杆与 Unity 3d RigidBody 结合使用

Use Mobile Joystick with Unity 3d RigidBody

我正在开发移动 3D 应用程序。我有一个具有刚体的游戏对象,我用操纵杆移动它。

我已经达到这样的程度,当我接受垂直输入时我可以向前移动对象,当我从操纵杆接受水平输入时我可以旋转它。

问题是,当我将刚体旋转 90 度时,我希望使用水平输入来向前或向后移动对象,并使用垂直操纵杆输入来旋转它。基本上我希望物体在拉动操纵杆的地方向前移动,但是根据当前设置,即使物体面向左侧或右侧,我也必须向上拉动操纵杆。我希望我解释得很好。如果不知道,请告诉我,我会详细解释。

    public Joystick m_Joystick;
    private float m_HorizontalValue;
    private float m_VerticalValue;

    void Update()
    {
        m_VerticalValue = m_Joystick.Vertical;
        m_HorizontalValue = m_Joystick.Horizontal;
    }

    // Same as update, but is used fo modifying values that are used to manipulate
    // game object's physics
    void FixedUpdate() 
    {
        Move();
        Turn();
    }

    void Move()
    {
        Vector3 movement = transform.forward * m_VerticalValue * m_Speed * Time.deltaTime;

        m_Rigidbody.MovePosition(m_Rigidbody.position + movement);
    }

    void Turn()
    {
        float turn = m_HorizontalValue * m_TurnSpeed * Time.deltaTime;

        Quaternion turnRotation = Quaternion.Euler(0f, turn, 0f);

        m_Rigidbody.MoveRotation(m_Rigidbody.rotation * turnRotation); 
    }

我尝试检查刚体的前向矢量(x 和 z 值)以在将操纵杆拉到所需方向时反转物体的运动,但效果不佳,因为当 x 时刚体会卡住和前向向量的 z 值相等。代码不完整我只测试了 x 和 z 坐标系的两个四分之一(第一和第二四分之一)。

    float GetVerticalOrHorizaontalValueMovement()
    {
        float xValue = m_Rigidbody.transform.forward.x;
        float zValue = m_Rigidbody.transform.forward.z;

        float auxX = Mathf.Abs(xValue);
        float auxZ = Mathf.Abs(zValue);

        if (xValue > -0.1f && zValue > -0.1f)
        {
            if (auxX <= auxZ)
                return  m_HorizontalValue;
            else if (auxX >= auxZ)
                return m_VerticalValue;
        }
        else if(xValue > -0.1f && zValue < 0.1f)
        {
            if (auxX >= auxZ)
                return m_VerticalValue;
            else if (auxX <= auxZ)
                return m_HorizontalValue;
        }

        return 0f;
    }

    float GetVerticalOrHorizaontalValueRotation()
    {
        float xValue = m_Rigidbody.transform.forward.x;
        float zValue = m_Rigidbody.transform.forward.z;

        float auxX = Mathf.Abs(xValue);
        float auxZ = Mathf.Abs(zValue);

        if (xValue > -0.1f && zValue > -0.1f)
        {
            if(auxX <= auxZ)
                return m_VerticalValue;
            else if(auxX >= auxZ)
                return m_HorizontalValue;
        }
        else if(xValue > -0.1f && zValue < 0.1f)
        {
            if (auxX >= auxZ)
                return m_HorizontalValue;
            else if (auxX <= auxZ)
                return m_VerticalValue;
        }

        return 0f;
    }

这些方法将代替 m_VerticalValue 和 m_HorizontalValue 变量放置在 Move() 和 Turn() 方法中。

我愿意接受任何可以让我的游戏对象使用操纵杆随心所欲移动的解决方案,但我必须将其保留为 RigidBody,因为我想对它和其他可能的力施加爆炸力。如果我没有解释清楚,请告诉我。

如果有人需要的话。这里是。它是使用移动操纵杆的简单运动。如果你有复杂的动作,你可能想根据你的需要修改它

 using UnityEngine;
 
 public class MovementOfPlayer : MonoBehaviour
 {
     Vector3 movementInput;
     Rigidbody playerRigidbody;
 
     void Start()
     {
         playerRigidbody = GetComponent<Rigidbody>();
         playerRigidbody.freezeRotation = true;
     }
 
     void FixedUpdate()
     {
         movementInput = Input.GetAxisRaw("Horizontal") * Vector3.right +
                         Input.GetAxisRaw("Vertical") * Vector3.forward;
         movementInput.Normalize();
 
         float y = playerRigidbody.velocity.y;
 
         if (movementInput != Vector3.zero)
         {
             if (transform.forward != movementInput)
             {
                 transform.rotation = Quaternion.RotateTowards(transform.rotation, Quaternion.LookRotation(movementInput), Time.deltaTime * 180);
 
                 playerRigidbody.velocity = Vector3.MoveTowards(playerRigidbody.velocity, Vector3.zero, Time.deltaTime * 30);
             }
             else
             {
                 playerRigidbody.velocity = Vector3.MoveTowards(playerRigidbody.velocity, movementInput * 10, Time.deltaTime * 30);
             }
         }
         else
         {
             playerRigidbody.velocity = Vector3.MoveTowards(playerRigidbody.velocity, Vector3.zero, Time.deltaTime * 30);
         }
         Vector3 velocity = playerRigidbody.velocity;
         velocity.y = y;
         playerRigidbody.velocity = velocity;
     }
 }