Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice

Question Animations with Contactfilter2D

Discussion in 'Physics' started by unity_mats, Apr 29, 2024.

  1. unity_mats

    unity_mats

    Joined:
    Oct 12, 2016
    Posts:
    4
    I'm found a guide on how to change animations with code instead of transitions in the unity animator, and started to try it out on a simple platform game.

    I got everything to work except for the jumping animation where the character keeps the idle or running animation. I have tried a lot of fixes and the only thing that worked was by changing the groundcheck from using contactfilter2D to a raycast
    Code (CSharp):
    1.  //Check if player is on the ground (Works)
    2. RaycastHit2D hit = Physics2D.Raycast(transform.position, Vector2.down, 0.1f, groundMask); //See if ray hits ground below players position
    3. if (hit.collider != null)
    4. {
    5.      isGrounded = true;
    6. }
    7. else
    8. {
    9.      isGrounded = false;
    10. }
    11.  
    12. //Check if player is on the ground (Won't work)
    13. isGrounded = rb.IsTouching(groundFilter);
    Code (CSharp):
    1.         //Check if trying to jump
    2.         if (isJumpPressed && isGrounded)
    3.         {
    4.             rb.AddForce(Vector2.up * jumpForce, ForceMode2D.Impulse);
    5.             isJumpPressed = false;
    6.             ChangeAnimationState(PLAYER_JUMP);
    7.         }
    Code (CSharp):
    1.     void ChangeAnimationState(string newAnimation)
    2.     {
    3.         if (currentAnimaton == newAnimation) return;
    4.  
    5.         animator.Play(newAnimation);
    6.         currentAnimaton = newAnimation;
    7.     }
    I reed in the manual that "IsTouching" is performed against the last physics system update. But I'm not sure if that is the problem here, and if that is the case, how to fix it. I could just go with the raycast, but I really like the simplicity of the contactfilter.
     
  2. dstears

    dstears

    Joined:
    Sep 6, 2021
    Posts:
    156
    How have you set your groundFilter variable? If you add Debug.Log to report the state of IsTouching, does it ever return true?
    Also, are you calling IsTouching in Update or FixedUpdate?
     
  3. unity_mats

    unity_mats

    Joined:
    Oct 12, 2016
    Posts:
    4
    The ground filter is set to use layermask to check for ground, if that was your question. It does return true and the character jumps. I tired calling it in Update and FixedUpdate without any difference.
    I also tried to Debug the animation state of the character, and found that it only on occasion changes to "PLAYER_JUMP", but mostly it sticks to Idle.
     
  4. dstears

    dstears

    Joined:
    Sep 6, 2021
    Posts:
    156
    Can you share the code where you call ChangeAnimationState to change to other states like running or idle? Does your animation controller have any transitions between the states?
     
  5. unity_mats

    unity_mats

    Joined:
    Oct 12, 2016
    Posts:
    4
    Sure! Here is the code that controls run and idle.
    Code (CSharp):
    1.         if (isGrounded && !isAttacking)
    2.         {
    3.             if (movement.x != 0)
    4.             {
    5.                 ChangeAnimationState(PLAYER_RUN);
    6.                 transform.localScale = new Vector2(Mathf.Sign(movement.x), transform.localScale.y);  //Mirror sprite if moving left
    7.             }
    8.             else
    9.             {
    10.                 ChangeAnimationState(PLAYER_IDLE);
    11.             }
    12.         }
    The animation controller doesn't have any transitions, only the animation clips, which is the whole point of the ChangeAnimationState method since I don't like battling the web of transitions :)
     
  6. dstears

    dstears

    Joined:
    Sep 6, 2021
    Posts:
    156
    Are you updating the animation state in Update or FixedUpdate? If you are doing the animations in Update, then you may see several Update calls between each FixedUpdate. When you start the jump, isGrounded may still return true for a few Updates until the physics has been recalculated.

    I'd recommend adding Debug.Log prints for the isGrounded calculation and for the ChangeAnimationState function so that you can see the order of events in the logfile.