Search Unity

Why does my character jitter when translating him to the left or right? (Code included)

Discussion in 'Getting Started' started by JapaneseBreakfast, Sep 10, 2018.

  1. JapaneseBreakfast

    JapaneseBreakfast

    Joined:
    Sep 7, 2018
    Posts:
    44
    Hi! I've been following this awesome tutorial on how to build a runner but ran into either a bug or something I did wrong.
    I've managed to swipe left and right to move in those respective directions, and swipe up to jump.



    Everything works fine, but if I increase the speed of the forward movement, the character begins to jitter when I move in the horizontal axis.



    Speeds under 8.0f don't jitter, at least not at a rate that is visible to me. Also, if you've noticed, the jittering doesn't occur during a jump.

    - I commented out the camera follow script, it's not the camera.
    - I've isolated the jumping portion of my character's update, and it's not the jumping mechanic.
    - I've also logged the character's transform.position, and the x property is definitely adding and subtracting small numbers to the x property, essentially making the gameobject slightly move left and right every frame.

    What I've tried so far...

    At least that's what I think is happening. In fact for testing purposes, I made sure to clamp the x property and that fixed the issue, but obviously this is not a solution.

    Code (CSharp):
    1.         // Lane 0 is left, Lane 1 is center, Lane 2 is right
    2.         if (lane == 0) {
    3.            if (transform.position.x <= target.x) {
    4.                Vector3 newPos = transform.position;
    5.                newPos.x = target.x;
    6.                transform.position = newPos;
    7.            }
    8.         }
    9.  
    10.         else if (lane == 2) {
    11.            if (transform.position.x >= target.x) {
    12.                Vector3 newPos = transform.position;
    13.                newPos.x = target.x;
    14.                transform.position = newPos;
    15.            }
    16.         }
    I'm not sure what's going on with my code, but I'm sure it's something I did wrong and I can't see it. I'll share the entire character motor script, I've also removed some of the extra code and comments, so sorry about any typos. Thank you in advance for taking a look at my post!

    Complete Code

    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class HeroMotor : MonoBehaviour
    4. {
    5.  
    6.     private const float LANE_OFFSET = 3.0f;
    7.  
    8.     private const float TURN_SPEED = 0.05f;
    9.  
    10.     private CharacterController controller;
    11.     private Animator animator;
    12.  
    13.     private float jumpForce = 14.0f;
    14.     private float gravity = 38.0f;
    15.     private float verticalVelocity;
    16.  
    17.     private int lane = 0;
    18.  
    19.     private float originalSpeed = 14.0f;
    20.     private float speed;
    21.     private float speedIncreseTick;
    22.     private float speedIncreaseTime = 2.5f;
    23.     private float speedIncreaseAmt = 0.1f;
    24.  
    25.  
    26.     private void Start() {
    27.         controller = gameObject.GetComponent<CharacterController>();
    28.         animator = gameObject.GetComponent<Animator>();
    29.         speed = originalSpeed;
    30.     }
    31.  
    32.     private void Update() {
    33.  
    34.  
    35.         if ((Time.time - speedIncreaseTime) > speedIncreaseTime) {
    36.             speedIncreaseTime = Time.time;
    37.             speed += speedIncreaseAmt;
    38.         }
    39.  
    40.         if (MobileInput.Instance.SwipeLeft) MoveLane(false);
    41.         if (MobileInput.Instance.SwipeRight) MoveLane(true);
    42.        
    43.  
    44.         // Target
    45.         Vector3 target = transform.position.z * Vector3.forward;
    46.         if (lane == 0) target += Vector3.left * LANE_OFFSET;
    47.         else if (lane == 2) target += Vector3.right * LANE_OFFSET;
    48.  
    49.  
    50.         Vector3 move = Vector3.zero;
    51.         move.x = (target - transform.position).normalized.x * speed;
    52.  
    53.         bool isGrounded = IsGrounded();
    54.         animator.SetBool("Grounded", isGrounded);
    55.  
    56.         // Gravity
    57.         if (isGrounded) {
    58.             verticalVelocity = 0.0f;
    59.  
    60.             if (MobileInput.Instance.SwipeUp) {
    61.  
    62.                 animator.SetTrigger("Jump");
    63.                 verticalVelocity = jumpForce;
    64.  
    65.             }
    66.         }
    67.         else verticalVelocity -= (gravity * Time.deltaTime);
    68.  
    69.    
    70.         move.y = verticalVelocity;
    71.         move.z = speed;
    72.  
    73.         controller.Move(move * Time.deltaTime);
    74.  
    75.         //  Rotate Hero
    76.         Vector3 dir = controller.velocity;
    77.         if (dir != Vector3.zero)
    78.         {
    79.             dir.y = 0.0f;
    80.             transform.forward = Vector3.Lerp(transform.forward, dir, TURN_SPEED);
    81.         }
    82.  
    83.     }
    84.  
    85.     private void MoveLane(bool movingRight)
    86.     {
    87.  
    88.         if (!movingRight)
    89.         {
    90.             lane -= 1;
    91.             if (lane == -1) lane = 0;
    92.         }
    93.         else
    94.         {
    95.             lane += 1;
    96.             if (lane == 3) lane = 2;
    97.         }
    98.     }
    99.  
    100.     private bool IsGrounded()
    101.     {
    102.  
    103.         Ray groundRay = new Ray(
    104.             new Vector3(
    105.  
    106.                 controller.bounds.center.x,
    107.                 (controller.bounds.center.y - controller.bounds.extents.y) + 0.2f,
    108.  
    109.                 controller.bounds.center.z),
    110.             Vector3.down
    111.         );
    112.         Debug.DrawRay(groundRay.origin, groundRay.direction, Color.red, 1.0f);
    113.  
    114.         return Physics.Raycast(groundRay, 0.3f);
    115.     }
    116. }
    117.  
     
  2. JapaneseBreakfast

    JapaneseBreakfast

    Joined:
    Sep 7, 2018
    Posts:
    44
    A little update:

    The code seems fine. I think I found out what could be the issue, but haven't been able to solve it :(

    If I increase or decrease the center of the Character Controller (close to 0.92), the jittering begins, anything above or below a certain range is okay but the character model ends up above or below the floor.


    (it's not jittering in this gif since i need to move left or right to make the character jitter)

    After visualizing the Ray coming down from my character, I noticed several rays are created when the center of the Character controller is around 0.92! Which is why the stuttering stopped when I jumped, in mid-air only one ray is created.

    Also, I have my Character Controller set like this:



    But when I press Play on Unity, he automatically ends up at half the capsule:



    ...and this works so perfectly at any speed, but the character is half way in the air.

    Still trying to figure it out.
     
    Last edited: Sep 11, 2018
    DerrickMoore likes this.
  3. ripper1331

    ripper1331

    Joined:
    Nov 21, 2018
    Posts:
    1
    Hi,
    I am having this same issue, from the same tutorial, but I am not moving my character forward at all. I have to set my character controller the same as yours to lower the amount of jittering but it never stops it.

    I've built the tutorial files onto android and it works fine but I have't had any luck in getting it to work without jitters in another game, let me know if you had any luck in solving it!