Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Rotate rigidbody to face cursor position on screen

Discussion in 'Physics' started by Stezey, Oct 16, 2018.

  1. Stezey

    Stezey

    Joined:
    Jan 22, 2018
    Posts:
    3
    Hi all,

    I've been tinkering with the Tanks! tutorial file and have been trying to make the tanks use the mouse to aim, firing and facing in the direction of the cursor, I've managed to do this using the code below but the result isn't exactly what I had hoped for (the cursor controls the tank and it faces but its not overly accurate). pic to illustrate.



    The code for this is here



    Code (CSharp):
    1. private void Turn ()
    2.         {
    3.             objectPosition = camera.WorldToViewportPoint(transform.position);
    4.             mousePosition = (Vector2)camera.ScreenToViewportPoint (Input.mousePosition);
    5.             float angle = AngleBetweenTwoPoints(objectPosition, mousePosition);
    6.  
    7.    
    8.             m_Rigidbody.rotation = Quaternion.Euler(new Vector3(0, angle, 0));
    9.  
    10.         }
    11.  
    12.         float AngleBetweenTwoPoints(Vector2 a, Vector2 b)
    13.         {
    14.             return Mathf.Atan2(b.y - a.y, a.x - b.x) * Mathf.Rad2Deg;
    15.         }

    Can anyone help with making this more precise?
     
  2. Edy

    Edy

    Joined:
    Jun 3, 2010
    Posts:
    2,497
    I think you should use Camera.ScreenPointToRay and Physics.Raycast to project the position of the mouse onto the actual 3D scene. Use layers so the raycast hits the ground only (no tanks nor buildings). Then you may calculate the angle using Hit.point.
     
  3. SparrowGS

    SparrowGS

    Joined:
    Apr 6, 2017
    Posts:
    2,536
    Or just raycast to the ground and doing a LookAt(hit.point)

    Personally i like calculating the wanted rotation myself and slerping there, but this should work just fine for a game like this
     
  4. Stezey

    Stezey

    Joined:
    Jan 22, 2018
    Posts:
    3
    Can you do a LookAt using the rigidbody though? if i mess with the transform the movement functionality using W and S (to go forward and back) is lost.
     
  5. SparrowGS

    SparrowGS

    Joined:
    Apr 6, 2017
    Posts:
    2,536
    Then use Quaternion.LookRotation and assign it to the rigidbody.

    It takes a vector 3 in the form of direction, eg: rb.rotation = Quaternion.LookRotation(hit.point - rb.position)

    btw, i found that rb.position and transform.position returns the exact same value every time, but rb.position is alot more expensive to call so i'd advise to use it like this even if you're worried about setting the transform on a rigidbody.
    *I may be wrong on that one, it may indeed do something funky to the physics system, but i have tested this and found nothing but a performance difference

    Code (CSharp):
    1. rb.rotation = Quaternion.LookRotation(hit.point - transform.position)
    further more, i beg of you to slep this unless you intentionally want it to snap on the spot, if you don't know what it means look into it, it's 4AM so i'll just leave this here..

    Code (CSharp):
    1. rb.rotation = Quaternion.Slerp (transform.rotation, Quaternion.LookRotation (hit.point - transform.position), rotationSpeed * Time.deltaTime);
     
    muttsang likes this.