Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Help with character movement relative to rotation.

Discussion in 'Scripting' started by DrKainaan, Nov 19, 2018.

  1. DrKainaan

    DrKainaan

    Joined:
    Oct 22, 2018
    Posts:
    5
    Hey guys I would appreciate any help you could lend with this issue. I have been working on a top down style shooter game. I have the whole animation system implemented so that with certain keys he will walk forwad/backward/left/right and blend between those. Recently I have been working on the camera systems and have gotten the player to rotate and look at the mouse cursor using a raycast from the camera to the floor. However now when I move the character moves based on where he is looking. For Instance if I hold left or right he will simply walk in a circle around the mouse cursor. While this is neat I am trying to figure out a way to vary the MovementX and MovementY based on where he is looking. For example if he is looking completely right and you press "Up" he should begin to walk "left" which is up relative to the screen. I understand I need to normalize his look vector and than somehow generate a new vector based on the input x and y. I am unable to figure out the exact approach, everything I try gets very weird effects.
     
  2. BlackPete

    BlackPete

    Joined:
    Nov 16, 2016
    Posts:
    970
  3. DrKainaan

    DrKainaan

    Joined:
    Oct 22, 2018
    Posts:
    5
    The player is being moved VIA root motion so the footsteps line up properly. I could turn that off and write my own movement. Currently two values between -1 and 1 are being fed to the animation controller which is applying direction to animations. I need to find some way to modify these variables based on where he is looking. For instance if he is looking right (1,0) and moving up (0,1) the resultant vector should be (-1,0). Or if he is looking left (-1,0) and moving right (1,0) the resultant vector should be (0,-1). I understand what needs to happen but am unable to derive a formula.
     
  4. DrKainaan

    DrKainaan

    Joined:
    Oct 22, 2018
    Posts:
    5
    In theory I should rotate the look vector so that it is (0,1)(looking forward) and than rotate the movement vector by the same amount and that will give me the proper resultant. I am unsure as to how to go about doing that though.
     
  5. DrKainaan

    DrKainaan

    Joined:
    Oct 22, 2018
    Posts:
    5
    I think I have to do the following.
    Normalize look vector
    Calculate the signed angle between the look vector and (0,1)
    Generate a quaternion based on the resultant angle.
    multiply the quaternion by the movement vector to rotate it by that amount
    It should work in theory.
     
  6. DrKainaan

    DrKainaan

    Joined:
    Oct 22, 2018
    Posts:
    5
    Nevermind I figured it out. For reference if anyone is looking to perform a similar task I will put my code here.

    Code (CSharp):
    1.     void Update () {
    2.         movementX = Input.GetAxis("Horizontal");
    3.         movementY = Input.GetAxis("Vertical");
    4.         movementVector = new Vector2(movementX, movementY);
    5.         running = Input.GetKey(KeyCode.LeftShift);
    6.         runningF = System.Convert.ToSingle(running);
    7.     }
    8.  
    9.     private void FixedUpdate()
    10.     {
    11.         TurnPlayer(); //Rotate player and calculate normalized look vector
    12.         variationAngle = Vector2.SignedAngle(normalizedLook, forwardReference);//Calculate angel variation between movment and look
    13.         rotatedVector = Quaternion.AngleAxis(variationAngle, Vector3.forward) * movementVector;
    14.         playerAnimator.SetFloat("VelocityX", rotatedVector.x);
    15.         playerAnimator.SetFloat("VelocityY", rotatedVector.y);
    16.         playerAnimator.SetFloat("Speed", runningF);
    17.     }
    18.  
    19.     void TurnPlayer () {
    20.         Ray camRay = playerCamera.ScreenPointToRay(Input.mousePosition);
    21.         RaycastHit floorHit;
    22.         if(Physics.Raycast (camRay, out floorHit, camRayLength, floorMask))
    23.         {
    24.             Vector3 playerToMouse = floorHit.point - transform.position;
    25.             playerToMouse.y = 0f;
    26.             Quaternion newRotation = Quaternion.LookRotation(playerToMouse);
    27.             playerRigidbody.MoveRotation(newRotation);
    28.             normalizedLook = new Vector2(playerToMouse.x, playerToMouse.z).normalized;
    29.         }
    30.     }
    I am sure there is a better way to do this but it works.