Move Player along normal of floor?
I wanted my player to be moved along the normal of my floor object. Something like this: 

I don't want the movement to be straight all the time, as it is noticeable when going down slopes. I also want the player to jump perpendicular to the floor at all times. I also tried to implement a quick and dirty speed limiter to make sure it does not go too fast.
The code I have currently does the perpendicular jumping fine, but the left-right movement is a bit messed up. Also, I am currently controlling the player with the rigidbody component.
 void Update()
 {
     if (active)
     {
         Vector2 velocity = Vector2.zero;
         Vector2 sideVelocity = Vector2.zero;
         Vector2 jumpVelocity = Vector2.zero;
         Vector3 sub = new Vector3(0, 1, 0);
         if (Input.GetKeyDown(KeyCode.W))
         {
             if (grounded)
             {
                 
                 Vector2 jumpVector = new Vector2(0, jump);
                 Vector2 normal = Vector2.zero;
                 RaycastHit2D hit = Physics2D.Raycast(transform.position-sub,-Vector2.up);
                 if (hit.collider != null)
                 {
                     
                     Debug.Log( "name of raycast collider:  "+ hit.collider.name);
                     
                     Quaternion rot = hit.collider.transform.rotation;
                     normal = hit.normal;
                     normal.Normalize();
                     jumpVelocity = rot*jumpVector;
                     //velocity = jumpVelocity;
                     Debug.Log("velocity:  " + rot * jumpVector);
                     
                     
                 }
             }
             else
             {
                 jumpVelocity = Vector2.zero;
             }
         }
         //Left Right Movement
         if (Input.GetKey(KeyCode.A))
         {
             RaycastHit2D hit = Physics2D.Raycast(transform.position - sub, -Vector2.up);
             if (hit.collider != null && grounded)
             {
                 Debug.Log("name of raycast collider:  " + hit.collider.name);
                 Quaternion rot = hit.collider.transform.rotation;
                 sideVelocity = rot*-speedVector;
             }
             else
             {
                 sideVelocity = speedVector;
             }
         }
         if (Input.GetKey(KeyCode.D))
         {
             RaycastHit2D hit = Physics2D.Raycast(transform.position - sub, -Vector2.up);
             if (hit.collider != null && grounded)
             {
                 Debug.Log("name of raycast collider:  " + hit.collider.name);
                 Quaternion rot = hit.collider.transform.rotation;
                 sideVelocity = rot * speedVector;
             }
             else
             {
                 sideVelocity = speedVector;
             }
         }
         velocity = sideVelocity + rb.velocity;
         if (velocity.x > maxXSpeed)
         {
             velocity.x = maxXSpeed;
         }
         if (velocity.x < -maxXSpeed)
         {
             velocity.x = -maxXSpeed;
         }
         if (velocity.y > maxYSpeed)
         {
             velocity.y = maxYSpeed;
         }
         if (velocity.y < -maxYSpeed)
         {
             velocity.y = -maxYSpeed;
         }
         rb.velocity = velocity;
         
     }
 }
 
               thanks for the help!
Answer by noorsy · Sep 20, 2016 at 10:06 PM
I tweaked the code a bit, and the script works pretty well now. Keep in mind my game only has flat floor objects, so no curves, and I have not tested it on curved objects. My platform object is just a rectangle, which i duplicate and rotate for different game obstacles. Since i use quaternions for all of the calculations, the floor object must be rotated parallel to the surface the player object will be interacting with.
 void Update()
 {
     if (active)
     {
         
         if (Input.GetKeyDown(KeyCode.W))
         {
             if (grounded)
             {
                 RaycastHit2D hit = Physics2D.Raycast(transform.position-sub,-Vector2.up);
                 if (hit.collider != null)
                 {
                     
                     Debug.Log( "name of raycast collider:  "+ hit.collider.name);
                     
                     Quaternion rot = hit.collider.transform.rotation;
                     jumpVelocity = rot*jumpVector;
                     
                     Debug.Log("velocity:  " + rot * jumpVector);
                     rb.velocity = rb.velocity + jumpVelocity;
                     
                 }      
             }
             else
             {
                 jumpVelocity = Vector2.zero;
             }
         }
         //Left Right Movement
         if (Input.GetKey(KeyCode.D))
         {
             if (grounded)
             {
                 Vector2 sideVector = new Vector2(0, speed);
                 RaycastHit2D hit = Physics2D.Raycast(transform.position - sub, -Vector2.up);
                 if (hit.collider != null)
                 {
                     Quaternion rot = hit.collider.transform.rotation;
                     rot = Quaternion.Euler(0, 0, 90) * rot;
                     sideVelocity = rot * -sideVector;
                     rb.velocity = rb.velocity + sideVelocity;
                 }
             }
             else
             {
                 
                 rb.velocity =new Vector2(rb.velocity.x+speed, rb.velocity.y);
             }
         }
         if (Input.GetKey(KeyCode.A))
         {
             if (grounded)
             {
                 Vector2 sideVector = new Vector2(0, speed);
                 RaycastHit2D hit = Physics2D.Raycast(transform.position - sub, -Vector2.up);
                 if (hit.collider != null)
                 {
                     Quaternion rot = hit.collider.transform.rotation;
                     rot = Quaternion.Euler(0, 0, 90) * rot;
                     sideVelocity = rot * -sideVector;
                    
                     rb.velocity = rb.velocity + -sideVelocity;
                 }
             }
             else
             {
                 rb.velocity = new Vector2(rb.velocity.x - speed, rb.velocity.y);
             }
         }
         if (rb.velocity.x > 10)
         {
             rb.velocity = new Vector2(10, rb.velocity.y);
         }
         if (rb.velocity.x < -10)
         {
             rb.velocity = new Vector2(-10, rb.velocity.y);
         }
     }
 }
 //Check if Grounded
 void OnCollisionEnter2D(Collision2D other)
 {
     string otherTag = other.gameObject.tag;
     Debug.Log("collided");
     if (other.gameObject.tag == "Floors")
     {
         Debug.Log("Hit floor");
         grounded = true;
     }
 
               }
 void OnCollisionStay2D(Collision2D other)
 {
     if (other.gameObject.tag == "Floors")
     {
         grounded = true;
     }
 }
 void OnCollisionExit2D(Collision2D other)
 {
     if (other.gameObject.tag == "Floors")
     {
         Debug.Log("stopped Hit floor");
         grounded = false;
     }
 }
 
              Your answer
 
             Follow this Question
Related Questions
I can't seem to rotate my character depending on what side he is running to (2D sidescroller) 0 Answers
[2D] How to stop 2 vectors from adding force on each other 0 Answers
Unity 2D Controller when active ignore another click 0 Answers
Issues with snake game in C# 2 Answers
How To Do Basic 2D Movement? 1 Answer