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][1] 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 [1]: http://docs.unity3d.com/ScriptReference/Physics2D.Raycast.html
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...
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. Make 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... instead. 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.
Check my edit, hopefully that works! You should note that you can add another argument at the end of the RaycastNonAlloc method to specify the distance the ray travels, for example: RaycastNonAlloc(transform.position, -Vector2.up, hits, 2f);
Exactly as you say, look at [Physics2D.Raycast][1] 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 [1]: http://docs.unity3d.com/ScriptReference/Physics2D.Raycast.html
– ScribeThanks 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...
– Codaby