Search Unity

2D raycast collision detection

Discussion in 'Scripting' started by DekuJuice, Aug 25, 2014.

  1. DekuJuice

    DekuJuice

    Joined:
    Jul 19, 2014
    Posts:
    1
    I've written a simple movement script using transform.translate, and I'm using raycasts to determine if the player is touching a wall or not. The problem is the player sometimes clips into the wall before movement is stopped, and it seems to be completely random whether the player clips in or not. I'm still fairly inexperienced, and I have no idea what's causing the issue. Any help would be greatly appreciated.

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. public class PlayerController : MonoBehaviour
    4. {
    5.     //Variables
    6.  
    7.     //Movement
    8.  
    9.     Vector3 velocity;
    10.  
    11.     //Left and Right Movement
    12.  
    13.     private float move = 0f;
    14.     public float MaxSpeed = 5f;
    15.  
    16.     //Jumping
    17.  
    18.     private bool jump = false;
    19.  
    20.     //Raycasting
    21.  
    22.     private bool Twall = false;
    23.     private bool Bwall = false;
    24.     Rect PlayerBox;
    25.     Vector2 TopC;
    26.     Vector2 BotC;
    27.  
    28.     //layermasks
    29.  
    30.     private int DefaultMask;
    31.  
    32.     //animation
    33.      
    34.     // Use this for initialization
    35.  
    36.     void Awake ()
    37.     {
    38.         DefaultMask = 1 << LayerMask.NameToLayer("Default");
    39.     }
    40.  
    41.     void Start ()
    42.     {
    43.      
    44.     }
    45.  
    46.     // Update is called once per frame
    47.     void Update ()
    48.     {
    49.         //input
    50.      
    51.         move = Input.GetAxisRaw("Movement");
    52.      
    53.         //raycast origin points
    54.      
    55.         PlayerBox = new Rect( //storing the size of the player's hitbox
    56.             collider2D.bounds.min.x,
    57.             collider2D.bounds.min.y,
    58.             collider2D.bounds.size.x,
    59.             collider2D.bounds.size.y);
    60.      
    61.         TopC = new Vector2(PlayerBox.center.x,PlayerBox.yMax);
    62.         BotC = new Vector2(PlayerBox.center.x,PlayerBox.yMin);
    63.          
    64.         //debug
    65.      
    66.         Debug.Log (velocity.x);
    67.     }
    68.  
    69.     void FixedUpdate ()
    70.     {
    71.         velocity = new Vector3 (velocity.x,0,0);
    72.         velocity.x = move * Time.deltaTime * MaxSpeed;
    73.  
    74.         Twall = Physics2D.Raycast(TopC,Vector2.right * move,(0.05f + PlayerBox.width/2),DefaultMask);
    75.         Bwall = Physics2D.Raycast(BotC,Vector2.right * move,(0.05f + PlayerBox.width/2),DefaultMask);
    76.      
    77.         if(Twall || Bwall)
    78.         {
    79.             MaxSpeed = 0f;
    80.         }
    81.         else
    82.         {
    83.             MaxSpeed = 5f;
    84.         }
    85.     }
    86.  
    87.     void LateUpdate ()
    88.     {
    89.         transform.Translate(velocity);
    90.     }
    91. }
     
  2. Serge_Billault

    Serge_Billault

    Joined:
    Aug 26, 2014
    Posts:
    190
    FixedUpdate is called every fixed framerate frame while LateUpdate is scheduled for the end of a frame after all Updates have been called. If the collision in FixedUpdate is detected right after a LateUpdate but not before, bi-di-boom.

    The fact that MaxSpeed is updated after Velocity add to the problem. Velocity should reflect the very last MaxSpeed, for the moment you got one FixedUpdate delay before Velocity reflect the last MaxSpeed calculated.

    Usually, velocity is computed as if there were no collision, then collisions are checked, then the velocity vector is cliped to the nearest collision encountered if any.
     
    Last edited: Aug 31, 2014