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. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Resolved Move the player around the walls and ceiling

Discussion in '2D' started by Stader, Jul 4, 2021.

  1. Stader

    Stader

    Joined:
    Jun 8, 2018
    Posts:
    15
    Hi, I searched a lot about this on the forum and on the internet, but I didn't find anything relevant to help me with this.

    I'm trying to create a mechanic that allows the player to walk normally in a straight line, but when he hits a wall he keeps walking normally, and the same for the ceiling.

    I'm using tilemap and 2d rigidbody

    I tried to use specific colliders that would indicate when the movement has to change, but with a bad feeling.

    I'm trying raycast right now, but it's not working. Could anyone give me any suggestions of what can be done?


    upload_2021-7-4_16-47-12.png upload_2021-7-4_16-47-31.png
     
  2. Tyrant7

    Tyrant7

    Joined:
    Aug 15, 2019
    Posts:
    34
    I don't think that the built in gravity will do the trick for you. In this case you'll have to apply a constant force when not in contact to the ground to emulate this effect, and then specify a direction using a vector2. You could find the direction by using a raycast in all four directions and taking whichever one hit last. The way I'd probably do that is something like this:
    Code (CSharp):
    1. Vector2 forceDirection = Vector2.down;
    2.  
    3. void Update()
    4. {
    5.         Vector2[] directions = new Vector2[4];
    6.         directions[0] = Vector2.down;
    7.         directions[1] = Vector2.right;
    8.         directions[2] = Vector2.up;
    9.         directions[3] = Vector2.left;
    10.  
    11.         foreach (Vector2 v in directions)
    12.         {
    13.                 if (Physics2D.Raycast(transform.position, v,  range))
    14.                         forceDirection = v;
    15.         }
    16.  
    17.         myRigidbody2D.Addforce(forceDirection * gravityMultiplier);
    18. }
     
    Pixitales and Stader like this.
  3. Stader

    Stader

    Joined:
    Jun 8, 2018
    Posts:
    15
    I used some of what you commented, and added 8 directions instead of 4 to allow diagonal edges.

    In this code, the idea is that the player walks automatically

    Thanks for helping

    Code (CSharp):
    1. public class Movement : MonoBehaviour
    2. {
    3.     private Rigidbody2D m_Rigidbody2D;
    4.  
    5.     public float gravityMultiplier;
    6.     public float maxspeed;
    7.  
    8.     public Vector2[] directions;
    9.  
    10.     private void Start()
    11.     {
    12.         m_Rigidbody2D = GetComponent<Rigidbody2D>();
    13.     }
    14.  
    15.     private void FixedUpdate()
    16.     {
    17.         foreach (Vector2 v in directions)
    18.         {
    19.             RaycastHit2D hit = Physics2D.Raycast(transform.position, v, 4);
    20.  
    21.             if (hit.collider != null)
    22.             {
    23.                 AddForce(v);
    24.             }
    25.          
    26.             //Debug.DrawRay(this.transform.position, v*2, Color.red);
    27.         }
    28.     }
    29.  
    30.     private void AddForce(Vector2 direction)
    31.     {
    32.         if (m_Rigidbody2D.velocity.magnitude > maxspeed)
    33.             return;
    34.         if (direction == directions[0])
    35.         {
    36.             m_Rigidbody2D.AddForce(Vector2.right * gravityMultiplier);
    37.         }
    38.         else if (direction == directions[1])
    39.         {
    40.             m_Rigidbody2D.AddForce(Vector2.up * gravityMultiplier);
    41.         }
    42.         else if (direction == directions[2])
    43.         {
    44.             m_Rigidbody2D.AddForce(Vector2.left * gravityMultiplier);
    45.         }
    46.         else if (direction == directions[3])
    47.         {
    48.             m_Rigidbody2D.AddForce(Vector2.down * gravityMultiplier);
    49.         }
    50.         else if (direction == directions[4])
    51.         {
    52.             m_Rigidbody2D.AddForce(Vector2.left * gravityMultiplier);
    53.             m_Rigidbody2D.AddForce(Vector2.up * gravityMultiplier);
    54.         }
    55.         else if (direction == directions[5])
    56.         {
    57.             m_Rigidbody2D.AddForce(Vector2.right * gravityMultiplier);
    58.             m_Rigidbody2D.AddForce(Vector2.down * gravityMultiplier);
    59.         }
    60.         else if (direction == directions[6])
    61.         {
    62.             m_Rigidbody2D.AddForce(Vector2.right * gravityMultiplier);
    63.             m_Rigidbody2D.AddForce(Vector2.up * gravityMultiplier);
    64.         }
    65.         else if (direction == directions[7])
    66.         {
    67.             m_Rigidbody2D.AddForce(Vector2.left * gravityMultiplier);
    68.             m_Rigidbody2D.AddForce(Vector2.down * gravityMultiplier);
    69.         }
    70.         Debug.Log(direction);
    71.     }
    72.  
    73.     private void OnDrawGizmos()
    74.     {
    75.         foreach (Vector2 v in directions)
    76.         {
    77.             Gizmos.color = Color.blue;
    78.             Gizmos.DrawLine(transform.position, new Vector2(v.x * 1.5f + transform.position.x, v.y * 1.5f + transform.position.y));
    79.         }
    80.     }
    81. }
    ScreenRecorderProject54_1.gif
     
  4. Tyrant7

    Tyrant7

    Joined:
    Aug 15, 2019
    Posts:
    34
    So I think that it's worth noting that the character will accelerate at double the speed on diagonal edges since simply since applying two forces means that the total force that you're applying is double what it should be.
    I don't know if this is what you intended, but if you'd like the player to remain moving at a constant force on diagonals I suggest adding the Vectors, and then normalizing them to keep them at a length of one like the other ones.
    Code (CSharp):
    1.  
    2.         else if (direction == directions[4])
    3.         {
    4.             m_Rigidbody2D.AddForce((Vector2.left + Vector2.up).normalized * gravityMultiplier);
    5.         }
    6.  
     
    Last edited: Jul 5, 2021
    Stader likes this.