Search Unity

Resolved Key strokes getting ignored intermittently

Discussion in 'Input System' started by djweaver, Aug 24, 2020.

  1. djweaver

    djweaver

    Joined:
    Jul 4, 2020
    Posts:
    105
    QUICK RUNDOWN:

    I'm trying to implement jump functionality using the new input system. I have it bound to the spacebar. When I hit the spacebar my player jumps but not always.

    I am using an interface in the auto-generated class from my Input Action Asset, which is named
    IWorldActions

    Code (CSharp):
    1. ...
    2.  
    3. public class PlayerControl : MonoBehaviour, PlayerInput.IWorldActions
    4. {
    5.  
    6. ...
    The Input Action Map
    World
    has its callbacks set to my Player Control class (this)
    Code (CSharp):
    1.  
    2.     void Awake() {
    3.         _rigidbody = GetComponent<Rigidbody>();
    4.         playerBody = transform.GetChild(0).GetComponent<PlayerBody>();
    5.         playerSensor = transform.GetChild(1).GetComponent<PlayerSensor>();
    6.         playerInput = new PlayerInput();
    7.         playerInput.World.SetCallbacks(this);
    8.     }
    The "Jump" event from the interface is processed here. When I press spacebar, it changes a global boolean flag
    isJumping
    to true (while also logging that it was pressed to console)
    Code (CSharp):
    1.  
    2.     public void OnJump(InputAction.CallbackContext context) {
    3.         if(context.performed) {
    4.             print("Spacebar pressed");
    5.             isJumping = true;
    6.         }  
    7.     }
    When
    isJumping == true
    my jump function is called in the fixed update. My movement is handled in a similar fashion (and works fine)
    Code (CSharp):
    1.  
    2.     void FixedUpdate()
    3.     {
    4.         if(isMoving) PlayerMove(movementDirection);
    5.         if(isJumping) PlayerJump();
    6.     }
    My PlayerJump() function is rather simple, and uses my rigidbody to apply force
    Code (CSharp):
    1.     void PlayerJump() {
    2.        
    3.         if(transform.position.y == 0f){
    4.            _rigidbody.AddForce(jumpForce * Vector3.up);
    5.         }
    6.         isJumping = false;
    7.     }

    So I press spacebar, sometimes it jumps, sometimes it doesn't. The ratio is about 50/50 but very random. I'm not entirely sure this is an input system issue, because after comparing the logs of the key event versus the actual player jump function, I've noticed that the spacebar is registering once every time it is hit, as it should, however, the
    PlayerJump()
    function that is supposed to be triggered by the boolean flag is what is not always executing.


    FULL CODE:

    Code (CSharp):
    1. using System.Collections;
    2.  
    3. using System.Collections.Generic;
    4.  
    5. using UnityEngine;
    6.  
    7. using UnityEngine.InputSystem;
    8.  
    9.  
    10.  
    11. public class PlayerControl : MonoBehaviour, PlayerInput.IWorldActions
    12.  
    13. {
    14.  
    15.  
    16.  
    17.     // V A R I A B L E S
    18.  
    19.  
    20.  
    21.     [SerializeField] private Transform playerCamera = null; // Camera object (within the rig)
    22.  
    23.     private PlayerBody playerBody = null; // Collider script of Body
    24.  
    25.     private PlayerSensor playerSensor = null; // PlayerSensor script
    26.  
    27.     private PlayerInput playerInput = null;
    28.  
    29.  
    30.  
    31.     private Rigidbody _rigidbody;
    32.  
    33.     [SerializeField] private float jumpForce = 300f;
    34.  
    35.    
    36.  
    37.     // Movement system variables
    38.  
    39.     [SerializeField] private bool isMoving = false;
    40.  
    41.     [SerializeField] private bool isJumping = false;
    42.  
    43.     [SerializeField] private float movementSpeed = 2.0f;
    44.  
    45.     private Vector2 movementDirection;
    46.  
    47.     private Quaternion rotationInput;
    48.  
    49.     private Quaternion rotationChange;
    50.  
    51.     private Quaternion rotationOutput;
    52.  
    53.  
    54.  
    55.     // I N I T I A L I Z A T I O N
    56.  
    57.  
    58.  
    59.     void Awake() {
    60.  
    61.         _rigidbody = GetComponent<Rigidbody>();
    62.  
    63.         playerBody = transform.GetChild(0).GetComponent<PlayerBody>();
    64.  
    65.         playerSensor = transform.GetChild(1).GetComponent<PlayerSensor>();
    66.  
    67.         playerInput = new PlayerInput();
    68.  
    69.         playerInput.World.SetCallbacks(this);
    70.  
    71.     }                  
    72.  
    73.  
    74.  
    75.     void OnEnable() {
    76.  
    77.         playerInput.Enable();
    78.  
    79.     }
    80.  
    81.  
    82.  
    83.     void OnDisable(){
    84.  
    85.         playerInput.Disable();
    86.  
    87.     }
    88.  
    89.  
    90.  
    91.     // I N P U T
    92.  
    93.  
    94.  
    95.     public void OnMove(InputAction.CallbackContext context) {
    96.  
    97.         isMoving = true;
    98.  
    99.         movementDirection = context.ReadValue<Vector2>();
    100.  
    101.     }
    102.  
    103.  
    104.  
    105.     public void OnJump(InputAction.CallbackContext context) {
    106.  
    107.         if(context.performed) {
    108.  
    109.             print("Spacebar pressed");
    110.  
    111.             isJumping = true;
    112.  
    113.         }  
    114.  
    115.     }
    116.  
    117.     public void OnActivate(InputAction.CallbackContext context) {
    118.  
    119.     }
    120.  
    121.     public void OnTarget(InputAction.CallbackContext context) {
    122.  
    123.     }
    124.  
    125.     public void OnMenu(InputAction.CallbackContext context) {
    126.  
    127.     }
    128.  
    129.  
    130.  
    131.     // U P D A T E S
    132.  
    133.  
    134.  
    135.     void Update(){
    136.  
    137.     }
    138.  
    139.  
    140.  
    141.     void FixedUpdate()
    142.  
    143.     {
    144.  
    145.         if(isMoving) PlayerMove(movementDirection);
    146.  
    147.         if(isJumping) PlayerJump();
    148.  
    149.     }
    150.  
    151.  
    152.  
    153.     // M O V E M E N T
    154.  
    155.  
    156.  
    157.     void PlayerRotate() {
    158.  
    159.  
    160.  
    161.         // Takes our current rotation
    162.  
    163.         rotationInput = transform.rotation;
    164.  
    165.  
    166.  
    167.         // Adds the Y Euler angle of playerCamera to rotationInput to create a new quaternion
    168.  
    169.         // --this is necessary because you cannot do arithmetic on quaternions directly
    170.  
    171.         rotationChange = Quaternion.Euler(new Vector3(  rotationInput.x,
    172.  
    173.                                                         rotationInput.y + playerCamera.eulerAngles.y,
    174.  
    175.                                                         rotationInput.z ));
    176.  
    177.        
    178.  
    179.         // Interpolates between current rotation and the desired rotation
    180.  
    181.         rotationOutput = Quaternion.Slerp(transform.rotation, rotationChange, .05f);
    182.  
    183.     }
    184.  
    185.  
    186.  
    187.     void PlayerJump() {
    188.  
    189.        
    190.  
    191.         if(transform.position.y == 0f) _rigidbody.AddForce(jumpForce * Vector3.up);
    192.  
    193.         isJumping = false;
    194.  
    195.     }
    196.  
    197.  
    198.  
    199.     void PlayerMove(Vector2 direction){
    200.  
    201.         if(direction.magnitude == 0f) isMoving = false;
    202.  
    203.  
    204.  
    205.         PlayerRotate();
    206.  
    207.  
    208.  
    209.         // Forward
    210.  
    211.         if(direction.y > 0) transform.position += transform.forward * Time.fixedDeltaTime * movementSpeed;
    212.  
    213.        
    214.  
    215.         // Backward
    216.  
    217.         if(direction.y < 0) transform.position -= (transform.forward / 2) * Time.fixedDeltaTime * movementSpeed;
    218.  
    219.        
    220.  
    221.         // Right (strafe)
    222.  
    223.         if(direction.x > 0) transform.position += transform.right * Time.fixedDeltaTime * movementSpeed;
    224.  
    225.        
    226.  
    227.         // Left (strafe)
    228.  
    229.         if(direction.x < 0) transform.position -= transform.right * Time.fixedDeltaTime * movementSpeed;
    230.  
    231.  
    232.  
    233.         transform.rotation = rotationOutput;
    234.  
    235.  
    236.  
    237.     }
    238.  
    239. }
    240.  
    241.  

     
  2. djweaver

    djweaver

    Joined:
    Jul 4, 2020
    Posts:
    105
    I just realized that my conditional to make sure that my player is grounded at 0 on Y axis before allowing the jump to occur is what is throwing this off. My player is grounded on the terrain at 0 initially. The terrain is perfectly flat, yes. But I noticed my y-axis transform position varying wildly between 3 and -3, even though my player was firmly on the ground.

    So my player is an empty object with objects inside. Those objects are offset on the Y to compensate for their height, yet the empty is at Y 0 as I said. The rigidbody is on the empty, and I suspect that because this empty is positioned at virtually the same level as the terrain I might be having a collision issue where it is fighting with the terrain, yet I can't see it.

    I repositioned the empty at 1 on the Y-axis and shifted its inner shape objects down to compensate. This appears to be the solution, as my y transform is steadily between 1 and 0.9999998, however I removed the height-based conditional upon realizing that I will still want my player to jump even if they are not at 0, so I have to find a different way to check if player is in mid-jump.