Search Unity

Help with player grounding issue??

Discussion in 'Scripting' started by jasontressler, Jan 18, 2019.

  1. jasontressler

    jasontressler

    Joined:
    Nov 27, 2018
    Posts:
    2
    Fairly new to Unity and C# scripting, but I understand the majority of the logic. Trying to build a 2D platformer while I learn, but I can't for the life of me figure out why my bool "grounded" is so unpredictable... In general, if my character is facing right (default), grounded = true as it should. Though when I move left and Flip() executes, grounded = false. Also at certain spot on my terrain, the opposite happens. Any insight?

    Code (CSharp):
    1.  
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5.  
    6. public class CharController2d : MonoBehaviour {
    7.     [HideInInspector] public bool facingRight = true;
    8.     [HideInInspector] public bool jump = false;
    9.     [HideInInspector] public bool grounded;
    10.     private Vector3 m_Velocity = Vector3.zero;
    11.  
    12.     // public float moveForce = 365f;
    13.     // public float maxSpeed = 5f;
    14.     public float runSpeed = 40f;
    15.     public float jumpForce = 1000f;
    16.     [Range(0, .1f)] public float movementSmoothing = .05f;
    17.     public Transform groundCheck;
    18.  
    19.    
    20.     private Animator anim;
    21.     private Rigidbody2D rb2d;
    22.  
    23.     // Use this for initialization
    24.     void Start () {
    25.         anim = GetComponent<Animator>();
    26.         rb2d = GetComponent<Rigidbody2D>();
    27.  
    28.     }
    29.    
    30.     // Update is called once per frame
    31.     void Update () {
    32.         grounded = Physics2D.Linecast(transform.position, groundCheck.position, 1 << LayerMask.NameToLayer("Ground"));
    33.         Debug.Log(grounded);
    34.  
    35.         if (!grounded)
    36.             anim.SetBool("grounded", false);
    37.         else if (grounded)
    38.             anim.SetBool("grounded", true);
    39.        
    40.  
    41.         if (Input.GetButtonDown("Jump") && grounded)
    42.         {
    43.             jump = true;
    44.         }
    45.  
    46.     }
    47.  
    48.     void FixedUpdate()
    49.     {  
    50.         float h = Input.GetAxisRaw("Horizontal") * runSpeed;
    51.         anim.SetFloat("speed", Mathf.Abs(h));
    52.         // Move the character by finding the target velocity
    53.         Vector3 targetVelocity = new Vector2(h * Time.fixedDeltaTime * 10f, rb2d.velocity.y);
    54.         // And then smoothing it out and applying it to the character
    55.         rb2d.velocity = Vector3.SmoothDamp(rb2d.velocity, targetVelocity, ref m_Velocity, movementSmoothing);
    56.        
    57.         if (h > 0 && !facingRight)
    58.             Flip();
    59.         else if (h < 0 && facingRight)
    60.             Flip();
    61.  
    62.         if (jump)
    63.         {
    64.             rb2d.AddForce(new Vector2(0f, jumpForce));
    65.             jump = false;
    66.         }
    67.     }
    68.  
    69.     void Flip()
    70.     {
    71.         facingRight = !facingRight;
    72.         Vector3 theScale = transform.localScale;
    73.         theScale.x *= -1;
    74.         transform.localScale = theScale;
    75.     }
    76. }
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,742
    One way to get a better handle on this is to temporarily disable your game's physics and controls and replace them with direct mouse control.

    In this example above, just set the Rigidbody2D to ignore gravity:

    Code (csharp):
    1. rb2d.gravityScale = 0.0f;
    Now each frame take your Input.mousePosition and raycast into the scene (use the camera to get a ray) to find out world coordinates for that mouse position.

    At line 32 take that world coordinate and assign it to your player.

    This way you can drag your player around pixel by pixel and try to figure out what is going on, complete with watching the "isGrounded" spewing out of your Debug.Log().

    Two more observations: I assume groundCheck is a child object and is always offset downwards? Is it far enough into the ground to detect the player? Is the player's position up enough that you're sure it's not partially in the ground?
     
  3. jasontressler

    jasontressler

    Joined:
    Nov 27, 2018
    Posts:
    2
    It was indeed the position of groundCheck, it was .005 too high; the player's collider was interfering when !facingRight
     
    Kurt-Dekker likes this.