// Returns the closest safe point between target position and platform colliders public Vector2 GetClosestSafePosition(Vector2 position) { float closestDistance = 0.05f; Vector2 origin = transform.position; // position, angle, distance to box cast Vector2 heading = position - origin; float distance = heading.magnitude; Vector2 direction = heading / distance; float angle = transform.rotation.eulerAngles.z; // check for colliders at new position Collider2D hit = CODebug.OverlapBox(position, _boxCollider.size, angle, PlatformMask, Color.cyan, true, 1f); //DebugDrawBox(position, _boxCollider.size, angle, Color.cyan, 5f); // TODO - fix. doesn't handle rotation. // if no hit on box cast, then safe. return position; if (hit == null) { return(position); } Vector3 conflictHeading = (Vector2)hit.transform.position - origin; float conflictDistance = conflictHeading.magnitude; Vector2 conflictDirection = conflictHeading / conflictDistance; position += -conflictDirection * 0.05f; hit = CODebug.OverlapBox(position, _boxCollider.size, angle, PlatformMask, Color.red, true, 1f); if (hit == null) { return(position); } else { if (!disableWarnings) { Debug.LogWarning("Ignoring SetTransform request - no valid position detected"); } return(origin); } }
public virtual void HandleWallWalking() { HorizontalMovement direction = MovementDirection; if (controller == null) { controller = (CorgiControllerOverride)_controller; _boundsWidth = controller.BoundsWidth; _boundsHeight = controller.BoundsHeight; _boundsDiff = Mathf.Abs(_boundsWidth - _boundsHeight); } if (direction == HorizontalMovement.Left && _controller.State.IsCollidingLeft) { // shift position by difference between height / width to accommodate for pivot rotation controller.SetTransform(transform.position + transform.up * Mathf.Abs(_boundsDiff)); RotateGravity(direction); // no longer colliding due to rotational shift _controller.State.IsCollidingLeft = false; } else if (direction == HorizontalMovement.Right && _controller.State.IsCollidingRight) { // shift position by difference between height / width to accommodate for pivot rotation controller.SetTransform(transform.position + -transform.up * Mathf.Abs(_boundsDiff)); RotateGravity(direction); // no longer colliding due to rotational shift _controller.State.IsCollidingRight = false; } else if (IsOverLedge()) { // whether player is on vertical or horizontal plane //bool isVertical = _defaultGravityAngle == 90 || _defaultGravityAngle == 270; RotateGravity((HorizontalMovement)(-(float)direction)); Transition(true, GravityDirectionVector); // get forward direction depending which direction character is facing Vector3 forward = _character.IsFacingRight ? transform.right : -transform.right; Vector3 forwardAmount = (_boundsWidth * 0.5f * forward) + (_boundsWidth * ledgeCheckRayOffset) * forward + _boundsDiff * forward; Vector3 downAmount = (_boundsWidth * 0.5f * -transform.up) + (_boundsWidth * ledgeCheckRayOffset * -transform.up); Vector3 newPosition = transform.position + downAmount + forwardAmount; // check whether rotation / position shift is safe Collider2D hit = CODebug.OverlapBox(newPosition, controller.BoxCollider.size, _defaultGravityAngle, controller.PlatformMask, Color.cyan); // if safe, perform shift if (hit == null) { transform.localEulerAngles = new Vector3(0, 0, _defaultGravityAngle); // shift character position by overhang extent controller.SetTransform(newPosition); } else { CODebug.DebugDrawBox(newPosition, controller.BoxCollider.size, _defaultGravityAngle, Color.white, 5f); // reverse gravity change RotateGravity((HorizontalMovement)((float)direction)); } } }