Search Unity

Recreating object movement with single touch (or mouse)

Discussion in 'Physics' started by lukagril, Jan 12, 2019.

  1. lukagril

    lukagril

    Joined:
    Nov 29, 2016
    Posts:
    48
    Hello,

    I am trying to recreate character movement, where player moves forward all the time, you just change direction (rotation) of object with a single finger (touch) on screen (or mouse in editor).

    Reference game: Crowd city from Voodoo
    Video:


    My current code:

    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class PlayerManager : MonoBehaviour {
    4.  
    5.     [SerializeField]
    6.     private float speed = 5f;
    7.  
    8.     private Rigidbody rb;
    9.  
    10.     // center where mouse is first clicked on the screen
    11.     private Vector2 mouseStartPosition = new Vector2(-1, -1);
    12.  
    13.     private void Awake()
    14.     {
    15.         rb = GetComponent<Rigidbody>();
    16.     }
    17.  
    18.  
    19.     void FixedUpdate ()
    20.     {
    21.         // if mouse is clicked
    22.         if (Input.GetMouseButton(0))
    23.         {
    24.             // if mouse center is not set ...
    25.             if (mouseStartPosition == new Vector2(-1, -1))
    26.             {
    27.                 mouseStartPosition = Input.mousePosition; // ... set mouse center and return function
    28.                 return;
    29.             }
    30.  
    31.             Vector2 mousePosition = Input.mousePosition;
    32.  
    33.             // calculate angle between mouseStartPosition and current position of the mouse
    34.             Vector2 v2 = (mousePosition - mouseStartPosition).normalized;
    35.  
    36.             /* took that part of code from web */
    37.             float angle = Mathf.Atan2(v2.y, v2.x) * Mathf.Rad2Deg;
    38.             if (angle < 0)
    39.             {
    40.                 angle = 360 + angle;
    41.             }
    42.             angle = 360 - angle;
    43.             angle -= 270f; // to set correct angle specific for my camera
    44.  
    45.  
    46.             // current y rotation of rigidbody
    47.             float yRotation = rb.rotation.eulerAngles.y;
    48.  
    49.             // smoothly rotate current rotation towards new angle
    50.             yRotation = Mathf.MoveTowardsAngle(yRotation, angle, 5f);
    51.  
    52.             // apply new rotation
    53.             rb.rotation = Quaternion.Euler(0f, yRotation, 0f);
    54.  
    55.         }
    56.         else
    57.         {
    58.             // if mouse released, delete center (first mouse position)
    59.             mouseStartPosition = new Vector2(-1, -1);
    60.         }
    61.  
    62.  
    63.         // player always drives forward with certain speed
    64.         rb.velocity = transform.forward * speed;
    65.  
    66.     }
    67.  
    68. }
    69.  
    My current concept is:
    - When I press/touch on the screen for the first time, point of press is set as center
    - While press/touch remains on screen, I calculate angle between center and current press/touch position
    - I smoothly move rigidbodys y-angle towards calculated angle
    - When press/touch is released, I delete center
    - Repeat

    My concept works OK, but not as good/smooth as referenced game. When my current press/touch position is far away from center, angle changes are smaller. Referenced game seems like it updates center all the time.

    Maybe any tips to implement this kind of movement/rotation ?

    Best Regards, L