How to detect slope angle in 2D
Hi everyone,
there are some examples on google and forums but non of them useful. Please, in my 2D platformer game I want to detect slope angle the player is standing on using ray. I have read that there is a solution to shoot a ray from the player down to the ground and compute at what angle the player is standing on.
I am trying to atchieve different animations of sliding down slopes at different angles. If I am able to measure the angle, then I can slide different slopes with different speed and play different animations.
Please help.
Exactly as you say, look at Physics2D.Raycast and check what RaycastHit2D.normal is (that is the vector that would stick out of what was hit at a right angle), from that vector you can get an angle.
Or because it is normalised, you can base things directly on the size of the y component! For example if y < 0.707 then you are on a slope more than approx 45 degrees
Thanks for your reply. I forgot to say I am a begginer and ray is still too complex to me. Would you be able to write it down for me? I can revenge somehow. Rate your game, money...
Answer by Scribe · Aug 31, 2015 at 02:44 PM
For general scripting help, you should post in the HelpRoom, I've moved it for you this time. No payment necessary, just remember to accept the answer if it helps you solve your issue.
EDIT: This uses a slightly different method, RaycastNonAlloc which saves a specified number of hit points, in this case, I get the first 2 hits and save them in 'hits' that way the first is our characters collider, but the second... oh the second is our beautiful floor collider (hopefully).
void Update(){
RaycastHit2D[] hits = new RaycastHit2D[2];
int h = Physics2D.RaycastNonAlloc(transform.position, -Vector2.up, hits); //cast downwards
if (h > 1) { //if we hit something do stuff
Debug.Log(hits[1].normal);
angle = Mathf.Abs(Mathf.Atan2(hits[1].normal.x, hits[1].normal.y)*Mathf.Rad2Deg); //get angle
Debug.Log(angle);
if(angle > 30){
//DoSomething(); //change your animation
}
}
}
ORIGINAL: (see comments for why it doesn't work!)
Transform yourCharacter;
float angle;
void Update(){
RaycastHit2D hit = Physics2D.Raycast(yourCharacter.position, -Vector2.up); //cast downwards
if (hit.collider != null) { //if we hit something do stuff
Debug.Log(hit.normal);
angle = Mathf.Abs(Mathf.Atan2(hit.normal.x, hit.normal.y)*Mathf.Rad2Deg); //get angle
if(angle > 30){
DoSomething(); //change your animation
}
//you can use hit.normal.x to know which direction to slide in, negative = left, positive = right for standard 2D view
}
}
Thank you so much. I tested the code and tried to debug it but the angle is always 0 so the condition is not executed. The first condition is ok, ground is hit.
Can you debug hit.normal. is It ever not (0, 1) ? Also you could print the name of the collider that was hit, and see if that makes sense, and also the hit.point, and see if that is a sensible answer :)
Also, did you set the yourCharacter Transform to your character? and what did you attache this code to. $$anonymous$$ake sure your floors have 2D colliders on them.
Ok, I attached your code to my 2D player script. Deleted "Transform yourCharacter" and put Physics2D.Raycast(transform.position... ins$$anonymous$$d. Floor is made from many small cubes that have 2D colliders.
hit.normal is always as you say - (0, 1) even when the player is in the air. I noticed that in first line in Update when I change -Vector2.up to Vector2.up it always prints an angle, I mean the condition with an angle when collider is above the player even flat floor...
Right, I've found the issue, and it's a stupid one. Raycast doesn't ignore the collider of the object it is sent from... meaning the hit point we are getting returned is the bottom edge of the characters collider. Rather problematic, I will get back to you with a fix soon.
I am sorry, there is one more line I did not change:
Vector2 downSlope = new Vector2($$anonymous$$athf.Sign(hits [2].normal.x)*hits [2].normal.y, -($$anonymous$$athf.Sign(hits [2].normal.x)*hits [2].normal.x));
Sorry about that. Now it is really perfect. Thanks so much! Good luck.
Your answer
Follow this Question
Related Questions
Handling Slopes 0 Answers
Patrolling enemy not shooting at player 2d platformer 0 Answers
2d platformer knockback without addforce 1 Answer
How to Raycast 2D Diagonally instead of Horizontal on a Platformer game. 0 Answers
Need help making a ledge climber. The problem, transform.position always returns to vector( 0, 0) 0 Answers