- Home /
Question by
S4breK4t · Aug 20, 2015 at 12:16 PM ·
platformerangleslope
Slope angle fix
Im simply trying to print out the slope angle because I will need to use later, but when Im on a slope it keeps changing between 45 (the actual angle) and 0, while im decending or next to a wall. I cant work out why this is happening, so Id really appreciate help. Here's my code.
using UnityEngine;
using System.Collections;
public class Controller2D : RaycastController {
public bool movementStopped = false;
public bool canRotate = false;
float maxClimbAngle = 50;
float maxDescendAngle = 50;
public float staticSlopeAngle = 0;
bool rotated = false;
public CollisionInfo collisions;
[HideInInspector]
public Vector2 playerInput;
public override void Start() {
base.Start ();
collisions.faceDir = 1;
}
void Update () {
boxCollider = GetComponent<BoxCollider2D> ();
UpdateRaycastOrigins ();
CalculateRaySpacing ();
print (collisions.slopeAngle);
}
void LateUpdate () {
float directionX = collisions.faceDir;
if (directionX == -1) {
//transform.RotateAround (bottomLeft, -transform.forward, collisions.slopeAngle);
} else if (directionX == 1) {
//transform.RotateAround (bottomRight, transform.forward, collisions.slopeAngle);
}
print (collisions.slopeAngle);
}
public void Move(Vector3 velocity, bool standingOnPlatform) {
movementStopped = false;
Move (velocity, Vector2.zero, standingOnPlatform);
}
public void Move(Vector3 velocity, Vector2 input, bool standingOnPlatform = false) {
movementStopped = false;
collisions.Reset ();
collisions.velocityOld = velocity;
playerInput = input;
if (velocity.x != 0) {
collisions.faceDir = (int)Mathf.Sign(velocity.x);
}
if (velocity.y < 0) {
DescendSlope(ref velocity);
}
HorizontalCollisions (ref velocity);
if (velocity.y != 0) {
VerticalCollisions (ref velocity);
}
transform.Translate (velocity);
if (standingOnPlatform) {
collisions.below = true;
}
}
void HorizontalCollisions(ref Vector3 velocity) {
float directionX = Mathf.Sign (velocity.x);
float rayLength = Mathf.Abs (velocity.x) + skinWidth;
for (int i = 0; i < horizontalRayCount; i ++) {
Vector2 rayOrigin = (directionX == -1)?bottomLeft: bottomRight;
rayOrigin += Vector2.up * (horizontalRaySpacing * i);
RaycastHit2D hit = Physics2D.Raycast(rayOrigin, Vector2.right * directionX, rayLength, collisionMask);
Debug.DrawRay(rayOrigin, Vector2.right * directionX * rayLength,Color.red);
if (hit) {
if (hit.distance == 0) {
continue;
}
float slopeAngle = Vector2.Angle(hit.normal, Vector2.up);
if (i == 0 && slopeAngle <= maxClimbAngle) {
if (collisions.descendingSlope) {
collisions.descendingSlope = false;
velocity = collisions.velocityOld;
}
float distanceToSlopeStart = 0;
if (slopeAngle != collisions.slopeAngleOld) {
distanceToSlopeStart = hit.distance-skinWidth;
velocity.x -= distanceToSlopeStart * directionX;
}
ClimbSlope(ref velocity, slopeAngle);
velocity.x += distanceToSlopeStart * directionX;
}
if (!collisions.climbingSlope || slopeAngle > maxClimbAngle) {
velocity.x = (hit.distance - skinWidth) * directionX;
rayLength = hit.distance;
if (collisions.climbingSlope) {
velocity.y = Mathf.Tan(collisions.slopeAngle * Mathf.Deg2Rad) * Mathf.Abs(velocity.x);
}
movementStopped = true;
collisions.left = directionX == -1;
collisions.right = directionX == 1;
}
}
}
}
void VerticalCollisions(ref Vector3 velocity) {
float directionY = Mathf.Sign (velocity.y);
float rayLength = Mathf.Abs (velocity.y) + skinWidth;
for (int i = 0; i < verticalRayCount; i ++) {
Vector2 rayOrigin = (directionY == -1)?bottomLeft: topLeft;
rayOrigin += Vector2.right * (verticalRaySpacing * i + velocity.x);
RaycastHit2D hit = Physics2D.Raycast(rayOrigin, Vector2.up * directionY, rayLength, collisionMask);
Debug.DrawRay(rayOrigin, Vector2.up * directionY * rayLength,Color.red);
if (hit) {
velocity.y = (hit.distance - skinWidth) * directionY;
rayLength = hit.distance;
if (collisions.climbingSlope) {
velocity.x = velocity.y / Mathf.Tan(collisions.slopeAngle * Mathf.Deg2Rad) * Mathf.Sign(velocity.x);
}
collisions.below = directionY == -1;
collisions.above = directionY == 1;
}
}
if (collisions.climbingSlope) {
float directionX = Mathf.Sign(velocity.x);
rayLength = Mathf.Abs(velocity.x) + skinWidth;
Vector3 rayOrigin = ((directionX == -1)? bottomLeft: bottomRight) + transform.up * velocity.y;
RaycastHit2D hit = Physics2D.Raycast(rayOrigin,Vector2.right * directionX,rayLength,collisionMask);
if (hit) {
float slopeAngle = Vector2.Angle(hit.normal,Vector2.up);
if (slopeAngle != collisions.slopeAngle) {
velocity.x = (hit.distance - skinWidth) * directionX;
collisions.slopeAngle = slopeAngle;
}
}
}
}
void ClimbSlope(ref Vector3 velocity, float slopeAngle) {
float moveDistance = Mathf.Abs (velocity.x);
float climbVelocityY = Mathf.Sin (slopeAngle * Mathf.Deg2Rad) * moveDistance;
if (velocity.y <= climbVelocityY) {
velocity.y = climbVelocityY;
velocity.x = Mathf.Cos (slopeAngle * Mathf.Deg2Rad) * moveDistance * Mathf.Sign (velocity.x);
collisions.below = true;
collisions.climbingSlope = true;
collisions.slopeAngle = slopeAngle;
}
}
void DescendSlope(ref Vector3 velocity) {
float directionX = Mathf.Sign (velocity.x);
Vector2 rayOrigin = (directionX == -1) ? bottomRight : bottomLeft;
RaycastHit2D hit = Physics2D.Raycast (rayOrigin, -Vector2.up, Mathf.Infinity, collisionMask);
if (hit) {
float slopeAngle = Vector2.Angle(hit.normal, Vector2.up);
if (slopeAngle != 0 && slopeAngle <= maxDescendAngle) {
if (Mathf.Sign(hit.normal.x) == directionX) {
if (hit.distance - skinWidth <= Mathf.Tan(slopeAngle * Mathf.Deg2Rad) * Mathf.Abs(velocity.x)) {
float moveDistance = Mathf.Abs(velocity.x);
float descendVelocityY = Mathf.Sin (slopeAngle * Mathf.Deg2Rad) * moveDistance;
velocity.x = Mathf.Cos (slopeAngle * Mathf.Deg2Rad) * moveDistance * Mathf.Sign (velocity.x);
velocity.y -= descendVelocityY;
collisions.slopeAngle = slopeAngle;
collisions.descendingSlope = true;
collisions.below = true;
}
}
}
}
}
public struct CollisionInfo {
public bool above, below;
public bool left, right;
public bool climbingSlope;
public bool descendingSlope;
public float slopeAngle, slopeAngleOld;
public Vector3 velocityOld;
public int faceDir;
public void Reset() {
above = below = false;
left = right = false;
climbingSlope = false;
descendingSlope = false;
slopeAngleOld = slopeAngle;
slopeAngle = 0;
}
}
}
Comment
Your answer
Follow this Question
Related Questions
Replicating genesis Sonic's collision physics 1 Answer
How to make a slope? 1 Answer
Problem with getting constructional slope angle. 0 Answers