private void ApplyVelocity(Vector2 velocity, bool isInputVelocity, int recurseDepth = 0) { var collision = new BoxProjection(this.Collider.bounds, this.Position, velocity).Project(); var adjustmentVectors = VectorSplitter.Split(velocity, collision); this.Position += adjustmentVectors.First; if (collision) { if (this.lastCollisionNormal == Vector2.zero || collision.normal.y > this.lastCollisionNormal.y) { this.lastCollisionNormal = collision.normal; } if ((Vector2.Angle(collision.normal, Vector2.up) < 45 && adjustmentVectors.Alignment == CollisionAlignment.Opposed) || collision.normal.y < 0) { // Ground / Ceiling if (!isInputVelocity) { this.Velocity = Vector2.zero; } } else { // Anything else if (!isInputVelocity) { this.Velocity = this.Velocity.Project(adjustmentVectors.Second); } if (adjustmentVectors.Second.sqrMagnitude > 0) { // HACK: Just give up. We can't seem to get this right. if (recurseDepth >= 3) { this.Position += adjustmentVectors.Second; } else { this.ApplyVelocity(adjustmentVectors.Second, isInputVelocity, recurseDepth + 1); } } } } else if (isInputVelocity) { this.ClampToSlopes(velocity); } }
private void ClampToSlopes(Vector2 velocity) { // If we're already jumping, don't bother if (this.Velocity.y > 0) { return; } var clampVector = new Vector2(0, -this.form.GetSlopeClampDistance()); var collision = new BoxProjection(this.Collider.bounds, this.Position, clampVector).Project(); if (collision) { if (Vector2.Angle(velocity, collision.normal) < 90) { this.Position += clampVector * collision.percentToHit; } } }