Search Unity

  1. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Question Help getting a rigidbody sphere rolling in 8 directions

Discussion in 'Physics' started by yoyohohoxd, Jul 24, 2020.

  1. yoyohohoxd

    yoyohohoxd

    Joined:
    Jun 22, 2020
    Posts:
    6
    Hello there! This is my first post, so go easy on me. :D
    I'm trying to make a ball (sphere) to roll in all directions. I've currently written a script so I can get it moving north, south, west, and east but only one at a time. I want the player to be able to get the ball rolling e.g. southeast, northwest, etc.. I've been looking all around, but maybe not the right places?
    I really hope you guys can help me! Thank you :)

    Below is my code

    Code (CSharp):
    1. public class Controller : MonoBehaviour
    2. {
    3.     Vector3 input;
    4.     Rigidbody m_Rigidbody;
    5.     public float m_Speed = 2.0f;
    6.     private string direction;
    7.    
    8.     void Awake()
    9.     {
    10.         m_Rigidbody = GetComponent<Rigidbody>();
    11.     }
    12.  
    13.     // Update is called once per frame
    14.     void FixedUpdate()
    15.     {
    16.         GetInput();
    17.  
    18.         if (Mathf.Abs(input.x) < 1 && Mathf.Abs(input.y) < 1) return;
    19.         {
    20.             print(input);
    21.             if (Input.GetKey(KeyCode.S))
    22.             {
    23.                 m_Rigidbody.velocity = (Vector3.forward)  * (m_Speed * Time.deltaTime);
    24.             }
    25.             if (Input.GetKey(KeyCode.A))
    26.             {
    27.                 m_Rigidbody.velocity = Vector3.right * (m_Speed * Time.deltaTime);
    28.             }
    29.             if (Input.GetKey(KeyCode.W))
    30.             {
    31.                 m_Rigidbody.velocity = Vector3.back * (m_Speed * Time.deltaTime);
    32.             }
    33.             if (Input.GetKey(KeyCode.D))
    34.             {
    35.                 m_Rigidbody.velocity = Vector3.left * (m_Speed * Time.deltaTime);
    36.             }
    37.         }
    38.     }
    39.  
    40.     void GetInput()
    41.     {
    42.         input.x = Input.GetAxisRaw("Horizontal");
    43.         input.y = Input.GetAxisRaw("Vertical");
    44.     }
    45. }
     

    Attached Files:

  2. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,115
    You're just stomping over any previously set velocity. If you press S then you set the velocity but if you're also press W then you set the velocity and overwrite the movement for S.

    You should gather your input then calculate and set the velocity once.

    Here's a basic idea (not the most efficient and not tested but it'll give you an idea):
    Code (CSharp):
    1. var direction = Vector3.zero;
    2.  
    3. if (Input.GetKey(KeyCode.S))
    4. {
    5.     direction += Vector3.forward
    6. }
    7.  
    8. if (Input.GetKey(KeyCode.A))
    9. {
    10.     direction += Vector3.right
    11. }
    12.  
    13. if (Input.GetKey(KeyCode.W))
    14. {
    15.     direction += Vector3.back
    16. }
    17.  
    18. if (Input.GetKey(KeyCode.D))
    19. {
    20.     direction += Vector3.left
    21. }
    22.  
    23. m_Rigidbody.velocity = direction.normalized * m_Speed * Time.fixedDeltaTime;
    24.  
    Also note that you need to be careful when reading input during the fixed-update as you can miss certain types of input such as input that checks if something happened "this frame". FixedUpdate isn't per-frame.
     
    Last edited: Jul 24, 2020
    yoyohohoxd likes this.
  3. yoyohohoxd

    yoyohohoxd

    Joined:
    Jun 22, 2020
    Posts:
    6
    Alright, I will test your solution and get back to you whether it's working, but I understand the overall idea so thank you regardless! :D
     
    MelvMay likes this.
  4. yoyohohoxd

    yoyohohoxd

    Joined:
    Jun 22, 2020
    Posts:
    6
    Good lord, it works. Thank you so much! If you don't mind me asking, how do you like the solution of constant if-statements? Is there a better and less clumsy way of checking for user input?
     
  5. Deleted User

    Deleted User

    Guest