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

CharacterController movement Jittery

Discussion in 'iOS and tvOS' started by bpatters, Jan 31, 2010.

  1. bpatters

    bpatters

    Joined:
    Oct 5, 2009
    Posts:
    164
    I've got a CharacterController attached to my main character and I use it to move the character in my FixedUpdate method.

    I have it working great and the character can walk/run in any angle/direction just fine. However when I walk at certain angles the character is very very jittery. It only seems to effect certain angles and is very sensitive to the movement speed. IE if my character runs everywhere then there is no jitter, but if I slow down and walk slowly there is tons and tons of jitter.

    I'm at a loss on how to fix this, anyone ever seen this?
     
  2. andeeeee

    andeeeee

    Joined:
    Jul 19, 2005
    Posts:
    8,768
    Can you post the code you are using with the CharacterController?
     
  3. bpatters

    bpatters

    Joined:
    Oct 5, 2009
    Posts:
    164
    Yea here is the code in my FixedUpdate method:
    Code (csharp):
    1.  
    2. void FixedUpdate () {
    3.         PlayerState newState = PlayerState.Idle;
    4.         // if player action is paused then ignore touchpad velocity
    5.         if ((true == GameState.IsActionPaused()) || being.IsStunned()) {
    6.             movementVelocity = Vector3.zero;
    7.         } else {
    8.             movementVelocity = touchPad.getMovement();
    9.         }
    10.         float xdist = Mathf.Abs(movementVelocity.x);
    11.         float zdist = Mathf.Abs(movementVelocity.z);
    12.        
    13.        
    14.         if (xdist > 0.2f || zdist > 0.2f) {
    15.             newState = PlayerState.Running;
    16.         } else if (xdist > minimumMoveSpeed || zdist > minimumMoveSpeed) {
    17.             newState = PlayerState.Walking;
    18.         }
    19.        
    20.        
    21.         if (!character.isGrounded ||  (newState != PlayerState.Idle) ) {
    22.  
    23.            
    24.             if ((newState != PlayerState.Idle)  (performingAttack == false)) {
    25.            
    26.                 movementVelocity = movementVelocity.normalized;
    27.                 movementVelocity=cameraTransform.TransformDirection(movementVelocity);
    28.                 if (newState == PlayerState.Running) {
    29.                     movementVelocity *= runSpeed;
    30.                 } else {
    31.                     movementVelocity *= walkSpeed;
    32.                 }
    33.                 movementVelocity.y = 0;
    34.             } else {
    35.                 movementVelocity = Vector3.zero;
    36.             }
    37.            
    38.             // add gravity in so our magnitudes match up
    39.             if (false == character.isGrounded) {
    40.                 movementVelocity.y += Physics.gravity.y;
    41.             }      
    42.            
    43.             if (jumpingState == PlayerState.Jumping) {
    44.                 movementVelocity.y +=Mathf.Lerp(jumpSpeed,0,jumping);
    45.                 jumping += Time.fixedDeltaTime;
    46.                 if (jumping >= 1) {
    47.                     jumpingState = PlayerState.Idle;
    48.                 }
    49.             }
    50.             character.Move(movementVelocity*Time.fixedDeltaTime);
    51.             movementVelocity.y = 0;
    52.            
    53.             if (performingAttack == false) {
    54.  
    55.                
    56.                
    57.                 if ((movementState == PlayerState.Idle)  (newState == PlayerState.Walking))
    58.                     PlayerAnimations.CrossFade(WalkAnimation.name);
    59.                 else if ((movementState == PlayerState.Idle) || (movementState == PlayerState.Walking)  (newState == PlayerState.Running))
    60.                     PlayerAnimations.CrossFade(RunAnimation.name);
    61.                
    62.                 movementState = newState;
    63.                 lastMovementVector = movementVelocity;
    64.             }
    65.            
    66.         } else {
    67.             if (jumpingState == PlayerState.Jumping) {
    68.                 movementVelocity.y += Mathf.Lerp(jumpSpeed,0,jumping);
    69.                 jumping += Time.deltaTime;
    70.                 if (jumping >= 1) {
    71.                     jumpingState = PlayerState.Idle;
    72.                 }
    73.                 character.Move(movementVelocity*Time.fixedDeltaTime);
    74.             } else {
    75.                 movementState = PlayerState.Idle;
    76.                 PlayerAnimations.CrossFade(IdleAnimation.name);
    77.             }
    78.         }
    79.         UpdateDamageText();
    80.     }
    81.  
    My touchPad object returns a vector between -1 and 1 for the velocity to move. I've had print statements in there while it was jittering to ensure it wasn't the vector bouncing and it wasn't, the vector returned was consistently the same value.
     
  4. xian

    xian

    Joined:
    Dec 30, 2009
    Posts:
    45
    I had a similar problem and tried everything. The solution for me ended up being restarting Unity for some reason.
    xian
     
  5. bpatters

    bpatters

    Joined:
    Oct 5, 2009
    Posts:
    164
    Well this happens both in unity and on the iphone. I thought it was just delay between unity remote and unity but since it happens on the iphone also it's a big problem as it makes my game look like amateurish when you walk at certain angles.
     
  6. xian

    xian

    Joined:
    Dec 30, 2009
    Posts:
    45
    Why don't you try playing around with this value in the character controller (I put the value in bold below). If you make it larger the character won't turn unless more of an angle is reached on the thumbstick. The character will look increasingly like they are strafing, but hey, maybe that could be better than what you think is "amateurish" and jittery. ;) -xian

     
  7. bpatters

    bpatters

    Joined:
    Oct 5, 2009
    Posts:
    164
    Tried it and it didn't help. BTW When I say jittery and amateurish I mean the character looks like he's moving on land during a 9.5 magnitude earth quake. The jitter is REALLY bad.

    I tried magnitudes from 0.001f to 0.1f and neither had any effect.
     
  8. andeeeee

    andeeeee

    Joined:
    Jul 19, 2005
    Posts:
    8,768
    Which vector did you check, the input from the touchpad or the movementVelocity vector just before it is passed into the Move function? I think the jitter is caused by rapid alternation between the walking and running speeds. Try using the magnitude of the movementVelocity vector to select between walking and running speed rather than the maximum of X and Z speeds:-
    Code (csharp):
    1. movementVelocity.y = 0f;
    2. float fwdSpeed = movementVelocity.magnitude;
    3.  
    4. if (fwdSpeed > 0.2f) {
    5.     newState = PlayerState.Running;
    6. } else if (fwdSpeed > minimumMoveSpeed) {
    7.      newState = PlayerState.Walking;
    8. }
     
  9. bpatters

    bpatters

    Joined:
    Oct 5, 2009
    Posts:
    164
    Tried that and it didn't help. I also tried making it so that no matter what speed he moved at that he was walking and it still did it. It only does it at certain angles, never at other angles.

    I also tried a combination of everything suggested and still no luck.
     
  10. andeeeee

    andeeeee

    Joined:
    Jul 19, 2005
    Posts:
    8,768
    It might sound strange, but can you you roughly determine the angles where this happens? If it's a mathematical problem, this information might help solve it.
     
  11. bpatters

    bpatters

    Joined:
    Oct 5, 2009
    Posts:
    164
    Yea when I get home tonight I'll put some print outs of the vector's that are causing it.
     
  12. bpatters

    bpatters

    Joined:
    Oct 5, 2009
    Posts:
    164
    Sorry it took so long but here's a printout of the vector during jerky movement:
    Movement vector =(-2.6, 0.0, -3.0)
    Movement vector *Time.fixedDeltaTime=(-0.1, 0.0, -0.1)
    Movement vector =(-2.6, 0.0, -3.0)
    Movement vector *Time.fixedDeltaTime=(-0.1, 0.0, -0.1)
    Movement vector =(-2.6, 0.0, -3.0)
    Movement vector *Time.fixedDeltaTime=(-0.1, 0.0, -0.1)
    Movement vector =(-2.6, 0.0, -3.0)
    Movement vector *Time.fixedDeltaTime=(-0.1, 0.0, -0.1)
    Movement vector =(-2.6, 0.0, -3.0)
    Movement vector *Time.fixedDeltaTime=(-0.1, 0.0, -0.1)
    Movement vector =(-2.6, 0.0, -3.0)
    Movement vector *Time.fixedDeltaTime=(-0.1, 0.0, -0.1)

    With this code:
    Code (csharp):
    1.  
    2. void FixedUpdate () {
    3.         PlayerState newState = PlayerState.Idle;
    4.         // if player action is paused then ignore touchpad velocity
    5.         if ((true == GameState.IsActionPaused()) || being.IsStunned()) {
    6.             movementVelocity = Vector3.zero;
    7.         } else {
    8.             movementVelocity = touchPad.getMovement();
    9.         }
    10.         float xdist = Mathf.Abs(movementVelocity.x);
    11.         float zdist = Mathf.Abs(movementVelocity.z);
    12.        
    13.        
    14.         if (xdist > 0.2f || zdist > 0.2f) {
    15.             newState = PlayerState.Running;
    16.         } else if (xdist > minimumMoveSpeed || zdist > minimumMoveSpeed) {
    17.             newState = PlayerState.Walking;
    18.         }
    19.        
    20.        
    21.         if (!character.isGrounded ||  (newState != PlayerState.Idle) ) {
    22.  
    23.            
    24.             if ((newState != PlayerState.Idle)  (performingAttack == false)) {
    25.            
    26.                 movementVelocity = movementVelocity.normalized;
    27.                 movementVelocity=cameraTransform.TransformDirection(movementVelocity);
    28.                 if (newState == PlayerState.Running) {
    29.                     movementVelocity *= runSpeed;
    30.                 } else {
    31.                     movementVelocity *= walkSpeed;
    32.                 }
    33.                 movementVelocity.y = 0;
    34.             } else {
    35.                 movementVelocity = Vector3.zero;
    36.             }
    37.             Debug.Log("Movement vector ="+movementVelocity);
    38.             Debug.Log("Movement vector *Time.fixedDeltaTime="+movementVelocity*Time.fixedDeltaTime);
    39.             // add gravity in so our magnitudes match up
    40.             if (false == character.isGrounded) {
    41.                 movementVelocity.y += Physics.gravity.y;
    42.             }      
    43.            
    44.             if (jumpingState == PlayerState.Jumping) {
    45.                 movementVelocity.y +=Mathf.Lerp(jumpSpeed,0,jumping);
    46.                 jumping += Time.fixedDeltaTime;
    47.                 if (jumping >= 1) {
    48.                     jumpingState = PlayerState.Idle;
    49.                 }
    50.             }
    51.             character.Move(movementVelocity*Time.fixedDeltaTime);
    52.             movementVelocity.y = 0;
    53.            
    54.             if (performingAttack == false) {
    55.  
    56.                
    57.                
    58.                 if ((movementState == PlayerState.Idle)  (newState == PlayerState.Walking))
    59.                     PlayerAnimations.CrossFade(WalkAnimation.name);
    60.                 else if ((movementState == PlayerState.Idle) || (movementState == PlayerState.Walking)  (newState == PlayerState.Running))
    61.                     PlayerAnimations.CrossFade(RunAnimation.name);
    62.                
    63.                 movementState = newState;
    64.                 lastMovementVector = movementVelocity;
    65.             }
    66.            
    67.         } else {
    68.             if (jumpingState == PlayerState.Jumping) {
    69.                 movementVelocity.y += Mathf.Lerp(jumpSpeed,0,jumping);
    70.                 jumping += Time.deltaTime;
    71.                 if (jumping >= 1) {
    72.                     jumpingState = PlayerState.Idle;
    73.                 }
    74.                 character.Move(movementVelocity*Time.fixedDeltaTime);
    75.             } else {
    76.                 movementState = PlayerState.Idle;
    77.                 PlayerAnimations.CrossFade(IdleAnimation.name);
    78.             }
    79.         }
    80.         UpdateDamageText();
    81.     }
    82.  
     
  13. andeeeee

    andeeeee

    Joined:
    Jul 19, 2005
    Posts:
    8,768
    If the movement vector is exactly the same each time, but the actual movement is still jittery, it suggests there is some problem with the physics. Is it possible that the character starts off with its collider partly stuck in the ground or something like that?
     
  14. bpatters

    bpatters

    Joined:
    Oct 5, 2009
    Posts:
    164
    Doubtful. It only happens when I move certain directions and I can jump and land over and over and it still happens at the same angles.
     
  15. zannghast

    zannghast

    Joined:
    Aug 17, 2010
    Posts:
    80
    Hi bpatters, were you able to get around your jittery problem? 'coz I think I'm having the same problems (my objects, when dragged at a specific angle, go up and down as if they're jumping).
     
  16. andeeeee

    andeeeee

    Joined:
    Jul 19, 2005
    Posts:
    8,768
    Welcome to the forum, Dendrobium!

    Can you post the code that is giving you this problem?
     
  17. Ehren

    Ehren

    Joined:
    Jul 7, 2009
    Posts:
    47
    Do the jitters disappear if you do the movement in Update rather than FixedUpdate?
     
  18. Spanky55

    Spanky55

    Joined:
    Feb 20, 2011
    Posts:
    2
    I was experiencing the same issue myself. My character was a simple capsule with a scaled cube as a 'face'. I was having jitter issues but it was really only on angles. What I noticed, after using the awesome profiler, was that it was the .Move method of the character controller that was really slow. So I thought about it for a minute and then I realized that the cube itself still has a Box collision component on it. The capsule had its own collision component as well and these two things were penetrating each other. Disabling it on the "face" fixed my issues and my character controller is smooth again.

    Have you verified that you only have 1 collision component for all the parts that make up your character?
     
  19. Elematiest

    Elematiest

    Joined:
    Jul 20, 2011
    Posts:
    6
    Wow, this is crazy.. I was trying to debug this exact issue for ages, funny thing is it only became massively visible just recently when I switched from mesh's to terrains on iOS.

    I'd tried swapping out the camera a bunch of different code then after reading this went.. hmm no way it could be the box i'm using for raycast restrictions with touch based movement. Needless to say as soon as I moved the box off the terrain i was back up to significantly smoother movement. Thanks for the tip
     
  20. CrazySi

    CrazySi

    Joined:
    Jun 23, 2011
    Posts:
    538
    Had this problem, decided not to use Character controller, jittery and appears to be skipping animation frames.
     
  21. MrScary

    MrScary

    Joined:
    Dec 8, 2007
    Posts:
    94
    I ran across this thread looking into the same problem ( on the iPhone and iPad ). Turns out that disabling the profiling in iPhone_Profiler.h eliminated the horrible hitching. The internal profiler is of only limited use if it will cause these types of artifacts. Perhaps in an update to 3.4 they can address this?

    Setting #define ENABLE_INTERNAL_PROFILER 0 "fixed" the hitching I was seeing. Note, it would still hitch even if I wasn't running connected to XCode.
     
  22. jinseok

    jinseok

    Joined:
    Apr 10, 2013
    Posts:
    1
    Try give the "min move distance" a smaller value, the default was 0.1, that stuck your character when your character move slow.
     
  23. DeeDeeKaKa

    DeeDeeKaKa

    Joined:
    Sep 14, 2013
    Posts:
    5
    This usually happens if you are using the wrong update. I was using FixedUpdate with my CharacterController and switching to Update rid me of the jitters.
     
    greedyonyoutube likes this.
  24. xortrox

    xortrox

    Joined:
    Feb 13, 2011
    Posts:
    22
    For others that may come by this post having the same problem (as myself)
    My problem was that I had set Min Penetration For Penalty to 0 in the PhysicsManager under Edit -> Project Settings -> Physics.
    My original thought had been that this would make collision detection as good as it gets but it actually causes jittering to happen when it's 0 (or maybe just above zero)
    Setting it to 0.0001 fixed it for me. (it's 0.01 by default which is 1cm and might cause objects to get buried a bit into the ground, like swords or daggers in an RPG)
     
  25. oliiix

    oliiix

    Joined:
    Nov 8, 2018
    Posts:
    9
    i thought the character controllers move function doesn't have anything to do with physics so the update function should be used as fixedUpdate is "mainly" for physics? Please correct me if that's wrong ;)

    Anyway I actually fixed it by using the fixedUpdate instead of the update function haha :D the jittering is completely gone^^ using build settings for web,not tested other build settings,not sure if that makes a difference when playing the game inside unity editor, but thought I mention it anyways^^