Search Unity

Issues with positions and leaning in FPS

Discussion in 'Scripting' started by link0016, Jul 2, 2022.

  1. link0016

    link0016

    Joined:
    Mar 12, 2022
    Posts:
    28
    I've been trying to put a lean mechanic into my game that's similar to Goldeneye and Perfect Dark, where instead of the usual "rotate gun + player", the character is set to a horizontal position when button is held, then back to normal when button is let go.

    Relevant code:
    Code (CSharp):
    1. public void checkLeanL()
    2.     {
    3.      RaycastHit lHit;
    4.      if(Physics.Raycast (camRay.transform.position, camRay.transform.TransformDirection(Vector3.left * 0.5f), out lHit, 0.5f))
    5.      {
    6.       canLeanL = false;
    7.       leanX = 0.0f;
    8.      }
    9.      else
    10.      {
    11.       canLeanL = true;
    12.       leanX = -0.5f;
    13.      }
    14.     }
    15.     public void checkLeanR()
    16.     {
    17.      RaycastHit rHit;
    18.      if(Physics.Raycast (camRay.transform.position, camRay.transform.TransformDirection(Vector3.right * 0.5f), out rHit, 0.5f))
    19.      {
    20.       canLeanR = false;
    21.       leanX = 0.0f;
    22.      }
    23.      else
    24.      {
    25.       canLeanR = true;
    26.       leanX = 0.5f;
    27.     }
    28.     }
    29.  
    30.     // The lean works kinda well.. need to figure out how reset back to starting position, especially if player's Y starts
    31.     // up high
    32.     // The issue lies within the 'leanX' variable and
    33.     public void onLeanL(InputAction.CallbackContext value)
    34.     {
    35.  
    36.      checkLeanL();
    37.      if(!isLeanedright)
    38.      {
    39.      if(value.performed && canLeanL==true)
    40.      {
    41.       player.transform.Translate(Vector3.right * leanX);
    42.       isLeanedleft = true;
    43.       canLeanR = false;
    44.      }
    45.  
    46.      else if(value.canceled)
    47.     {
    48.     player.transform.Translate(Vector3.left * leanX);//camRb.MovePosition(transform.TransformPoint(leanX,camRb.transform.position.y,camRb.transform.position.z));//camRb.MovePosition(camRb.position - transform.right * leanX);
    49.     isLeanedleft = false;
    50.     }
    51.      }
    52.     }
    53.  
    54.  
    55.     public void onLeanR(InputAction.CallbackContext value)
    56.     {
    57.  
    58.      checkLeanR();
    59.      if(!isLeanedleft)
    60.      {
    61.      if(value.performed && canLeanR == true)
    62.      {
    63.       player.transform.Translate(Vector3.right * leanX);
    64.       isLeanedright = true;
    65.       canLeanL = false;
    66.       }
    67.      else if(value.canceled)
    68.      {
    69.      player.transform.Translate(Vector3.left * leanX);
    70.       isLeanedright = false;
    71.     }
    72.     }
    73.     }

    The code works as intended until I tap the keys rapidly, which causes the player to get moved further across the level (the X values in transform may go by a bit fast)


    Meanwhile in Goldeneye (as well as Perfect Dark), the player's position does not get pushed further along the well no matter how many times the buttons are tapped


    Is there any way I can prevent these sudden jumps in positioning when the buttons are mashed?
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,749
    I'm not gonna try and untangle that logic, but I suggest instead this approach:

    - have a currentLean variable (float) and a desiredLean float

    Each frame:

    - assume desiredLean is zero

    - if a lean key is held, set desiredLean to -1 or +1

    - always move currentLean towards desiredLean (by some rate; see below)

    - use currentLean to offset / rotate your player

    That way mashing doesn't matter... it's always moving towards "being correct."

    Here's more reading of this basic technique:

    Smoothing movement between any two particular values:

    https://forum.unity.com/threads/beginner-need-help-with-smoothdamp.988959/#post-6430100

    You have currentQuantity and desiredQuantity.
    - only set desiredQuantity
    - the code always moves currentQuantity towards desiredQuantity
    - read currentQuantity for the smoothed value

    Works for floats, Vectors, Colors, Quaternions, anything continuous or lerp-able.

    The code: https://gist.github.com/kurtdekker/fb3c33ec6911a1d9bfcb23e9f62adac4
     
  3. Stardog

    Stardog

    Joined:
    Jun 28, 2010
    Posts:
    1,913
    You should just move the camera, not the player. Parent your weapon models to the camera.
     
  4. link0016

    link0016

    Joined:
    Mar 12, 2022
    Posts:
    28
    I previously had the lean only move the camera's position
    but then there was the issue of the collider just staying in one position.. which meant that the player isn't really hiding behind cover.

    Thus I changed gears to trying to move the player (which has the collider) position. It works as intended unless the keys button mashed, causing player to get moved along the level - and even the collider to be ignored