How to Handle Slopes in 2D Platformers?
I haven't found a ton of useful information on this so far, so I'm just going to put this question out there. What's the best way to ensure that
1) My character's local y axis is always perpendicular to the ground underneath them, and 2) My character won't be pushed downwards by gravity while standing on a downward angled slope
Any kind of help on this is greatly appreciated
Answer by Nomppie · Jan 22, 2018 at 01:57 AM
I found an answer deep in the bowels of google that gives me the slope information i need, and it looks like this:
RaycastHit2D[] hits = new RaycastHit2D[2];
int h = Physics2D.RaycastNonAlloc(transform.position, -Vector2.up, hits,3.5f,myMask); //cast downwards
if (h > 1) { //if we hit something do stuff
angle = Mathf.Abs(Mathf.Atan2(hits[1].normal.y, hits[1].normal.x)*Mathf.Rad2Deg); //get angle
Debug.Log (angle);
}
This gets you the angle of the slope against the player's up vector. So if I want my character to rotate to be perpendicular to the slope, I just have to make my character's rotation plus the angle equal 90. I'm going to paste the code I have in just a sec, but for some reason, if the desired rotation is negative, it just breaks my code and I really don't understand why. My character just keeps spinning clockwise and it makes no sense
if (myGroundCheck.GetComponent<GroundCheckScript> ().isGrounded) {
targetRotation = angle - 90;
} else if (!myGroundCheck.GetComponent<GroundCheckScript> ().isGrounded) {
targetRotation = 0;
}
if (transform.rotation.eulerAngles.z < targetRotation) {
//if our rotation is less than the target rotation, add up to it
Vector3 tempRot = transform.rotation.eulerAngles;
tempRot.z += correctionRate * Time.deltaTime;
tempRot.z = Mathf.Clamp (tempRot.z, -slopeLimit, targetRotation);
transform.rotation = Quaternion.Euler(tempRot);
} else if (transform.rotation.eulerAngles.z > targetRotation) {
//if our rotation is more than the target rotation, subract down to it
Vector3 tempRot = transform.rotation.eulerAngles;
tempRot.z -= correctionRate * Time.deltaTime;
tempRot.z = Mathf.Clamp (tempRot.z, targetRotation, slopeLimit);
transform.rotation = Quaternion.Euler(tempRot);
}
This is extra weird because I can go from a positive rotation to zero no problem. I'm extra confused why negatives don't work here
The problem isn't with the code, it's with how my ground checking system works. I'll just have to change that up and do some fine tuning.
Your answer
Follow this Question
Related Questions
What is the Easiest Way to Check if Two Time Periods are Overlapping 0 Answers
Collision Not regestering 1 Answer
Problem with my dash ability, 1 Answer
Player Not Moving With Platform 2D 1 Answer
Having trouble with 2D Jumping 0 Answers