- Home /
2D Platform Player moving instantly from upper platform to lower, only when moving left
I've run into a snag while following a 3DBuzz tut on making a 2D Platformer, https://www.youtube.com/watch?v=dqKudBbp3_I&list=PLt_Y3Hw1v3QSFdh-evJbfkxCK_bjUD37n∈dex=11. When moving left on a flat surface and meeting another flat surface not too far below (if it's ~1.5 units or less below), the player's rays will detect the platform and instantly "teleport" him to the surface below.
This doesn't happen when moving right, so I assume the issue has to do with the isGoingRight var, but I can't figure out how it all fits together. I can use Debug.Log to get the size of the rays being cast but I'm not sure how to use the information provided to solve the problem.
Here's a gif of my problem: http://i.imgur.com/2TnpYx9.gif
Thanks in advance, and let me know if more info is needed. (I edited out comments I made but can put them back if necessary.)
private void CalculateRayOrigins()
{
var size = new Vector2(_boxCollider.size.x * Mathf.Abs(_localScale.x), _boxCollider.size.y * Mathf.Abs(_localScale.y)) / 2;
var center = new Vector2(_boxCollider.center.x * _localScale.x, _boxCollider.center.y * _localScale.y);
_raycastTopLeft = transform.position + new Vector3(center.x - size.x + SkinWidth, center.y + size.y - SkinWidth);
_raycastBottomRight = transform.position + new Vector3(center.x + size.x - SkinWidth, center.y - size.y + SkinWidth);
_raycastBottomLeft = transform.position + new Vector3(center.x - size.x + SkinWidth, center.y - size.y + SkinWidth);
}
private void MoveHorizontally(ref Vector2 deltaMovement)
{
var isGoingRight = deltaMovement.x > 0;
var rayDistance = Mathf.Abs(deltaMovement.x);
var rayDirection = isGoingRight ? Vector2.right : -Vector2.right;
var rayOrigin = isGoingRight ? _raycastBottomRight : _raycastBottomLeft;
for (var i = 0; i<TotalHorizontalRays; i++)
{
var rayVector = new Vector2(rayOrigin.x, rayOrigin.y + (i * _verticalDistanceBetweenRays));
Debug.DrawRay(rayVector, rayDirection * rayDistance, Color.black);
var raycastHit = Physics2D.Raycast(rayVector, rayDirection, rayDistance, PlatformMask);
if (!raycastHit)
continue;
if (i == 0 && HandleHorizontalSlope(ref deltaMovement, Vector2.Angle(raycastHit.normal, Vector2.up), isGoingRight))
break;
deltaMovement.x = raycastHit.point.x - rayVector.x;
rayDistance = Mathf.Abs(deltaMovement.x) - SkinWidth;
if (isGoingRight)
{
deltaMovement.x -= SkinWidth;
State.IsCollidingRight = true;
}
else
{
deltaMovement.x += SkinWidth;
State.IsCollidingLeft = true;
}
if (rayDistance < SkinWidth + .0001f)
break;
}
}
private void MoveVertically(ref Vector2 deltaMovement)
{
var isGoingUp = deltaMovement.y > 0;
var rayDistance = Mathf.Abs(deltaMovement.y) + SkinWidth;
var rayDirection = isGoingUp ? Vector2.up : -Vector2.up;
var rayOrigin = isGoingUp ? _raycastTopLeft : _raycastBottomLeft;
rayOrigin.x += deltaMovement.x ;
var standingOnDistance = float.MaxValue;
for (var i = 0; i < TotalVerticalRays; i++)
{
var rayVector = new Vector2(rayOrigin.x + (i * _horizontalDistanceBetweenRays), rayOrigin.y);
Debug.DrawRay(rayVector, rayDirection * rayDistance, Color.red);
var raycastHit = Physics2D.Raycast(rayVector, rayDirection, rayDistance, PlatformMask);
if (!raycastHit)
{
continue;
}
if (!isGoingUp)
{
var verticalDistanceToHit = _transform.position.y - raycastHit.point.y;
if (verticalDistanceToHit < standingOnDistance)
{
standingOnDistance = verticalDistanceToHit;
StandingOn = raycastHit.collider.gameObject;
}
}
deltaMovement.y = raycastHit.point.y - rayVector.y;
rayDistance = Mathf.Abs(deltaMovement.y);
if (isGoingUp)
{
deltaMovement.y -= SkinWidth;
State.IsCollidingAbove = true;
}
else
{
deltaMovement.y += SkinWidth;
State.IsCollidingBelow = true;
}
if (!isGoingUp && deltaMovement.y > .0001f)
State.IsMovingUpSlope = true;
if (rayDistance < SkinWidth + .0001f)
break;
}
}
private void HandleVerticalSlope(ref Vector2 deltaMovement)
{
var center = (_raycastBottomLeft.x + _raycastBottomRight.x)/2;
var direction = -Vector2.up;
var slopeDistance = SlopeLimitTangent * (_raycastBottomRight.x - center);
var slopeRayVector = new Vector2(center, _raycastBottomLeft.y);
Debug.DrawRay(slopeRayVector, direction * slopeDistance, Color.green);
var raycastHit = Physics2D.Raycast(slopeRayVector, direction, slopeDistance, PlatformMask);
if (!raycastHit)
return;
var isMovingDownSlope = Mathf.Sign(raycastHit.normal.x) == Mathf.Sign(deltaMovement.x);
if (!isMovingDownSlope)
return;
var angle = Vector2.Angle(raycastHit.normal, Vector2.up);
if (Mathf.Abs(angle) < .0001f)
return;
State.IsMovingDownSlope = true;
State.SlopeAngle = angle;
deltaMovement.y = raycastHit.point.y - slopeRayVector.y;
}
private bool HandleHorizontalSlope(ref Vector2 deltaMovement, float angle, bool IsGoingRight)
{
if (Mathf.RoundToInt(angle) == 90)
return false;
if (angle > Parameters.SlopeLimit)
{
deltaMovement.x = 0;
return true;
}
if (deltaMovement.y > 0.007f)
return true;
deltaMovement.x += IsGoingRight ? -SkinWidth : SkinWidth;
deltaMovement.y = Mathf.Abs(Mathf.Tan(angle * Mathf.Deg2Rad) * deltaMovement.x);
State.IsMovingUpSlope = true;
State.IsCollidingBelow = true;
return true;
}
Your answer
Follow this Question
Related Questions
Aligning a sprite to the ground's normal using raycasts 1 Answer
2D Slope acceleration 1 Answer
Make a 2D jump? 0 Answers
2d Platformer sprites background 1 Answer