Пример #1
0
		protected BufferZoneInfo GetBufferZoneInfo(float gravityScale, Direction.Vertical verticalDirection)
		{
			BufferZoneInfo bufferZoneInfo = new BufferZoneInfo();
			bool willSnapToLedgeHeight = wallClimb.enableClimbing || ledgeGrab.enableLedgeGrab;
			if(willSnapToLedgeHeight)
			{
				RaycastHelper.LedgeInfo ledgeInfo = RaycastHelper.DetectLedgeOnWall(controller.direction.horizontal, (Direction.Vertical)((int)verticalDirection * gravityScale), controller.slots.actor.GetComponent<BoxCollider2D>(), controller.slots.physicsObject.properties.velocity.y * PhysicsManager.Instance.fixedDeltaTime * -(int)verticalDirection);
				if(!ledgeInfo.didHit)
				{
					ledgeInfo = RaycastHelper.DetectLedgeOnWall(controller.direction.horizontal, (Direction.Vertical)((int)verticalDirection * gravityScale), controller.slots.actor.GetComponent<BoxCollider2D>(), controller.slots.physicsObject.properties.velocity.y * PhysicsManager.Instance.fixedDeltaTime * -(int)verticalDirection, 0.0f);
				}

				if(ledgeInfo.didHit)
				{
					bufferZoneInfo.isLedgeDetected = true;
					bufferZoneInfo.bufferCutoff = ledgeInfo.hitY - (controller.slots.actor.GetComponent<BoxCollider2D>().size.y * 0.5f * gravityScale * -(int)verticalDirection);
					float adjustedPositionY = transform.position.y + controller.slots.physicsObject.properties.velocity.y * PhysicsManager.Instance.fixedDeltaTime * -(int)verticalDirection;
					if(verticalDirection == Direction.Vertical.Down && ((gravityScale < 0.0f && adjustedPositionY < bufferZoneInfo.bufferCutoff) || (gravityScale > 0.0f && adjustedPositionY > bufferZoneInfo.bufferCutoff))) //At top of wall
					{
						bufferZoneInfo.isInBufferZone = true;
					}
					else if(verticalDirection == Direction.Vertical.Up && ((gravityScale < 0.0f && adjustedPositionY > bufferZoneInfo.bufferCutoff) || (gravityScale > 0.0f && adjustedPositionY < bufferZoneInfo.bufferCutoff)))
					{
						bufferZoneInfo.isInBufferZone = true;
					}
				}
			}

			return bufferZoneInfo;
		}
Пример #2
0
        //If a projectile is slotted, this spawns it
        public void CreateProjectile()
        {
            Direction.Horizontal direction = (slots.actor.slots.controller) ? slots.actor.slots.controller.direction.horizontal : Direction.Horizontal.Right;
            if (attackDirection == AttackDirection.Behind)
            {
                direction = (Direction.Horizontal)((int)direction * -1.0f);
            }

            Projectile newProjectile = projectile.rexPool.Spawn().GetComponent <Projectile>();

            Direction.Horizontal startingHorizontalDirection = direction;
            Direction.Vertical   startingVerticalDirection   = Direction.Vertical.Up;

            if (projectile.isAimable)
            {
                if (Mathf.Abs(slots.actor.slots.input.verticalAxis) == 1.0f && slots.actor.slots.input.horizontalAxis == 0.0f)
                {
                    startingHorizontalDirection = Direction.Horizontal.Neutral;
                }

                startingVerticalDirection = (Direction.Vertical)(slots.actor.slots.input.verticalAxis * PhysicsManager.Instance.gravityScale);
            }

            newProjectile.isAimable = projectile.isAimable;
            newProjectile.Fire(new Vector2(slots.actor.transform.position.x + transform.localPosition.x * (int)direction, transform.position.y), startingHorizontalDirection, startingVerticalDirection, slots.actor, projectile.rexPool);
        }
Пример #3
0
        protected void MoveVertical()
        {
            bool willTurn = false;

            if ((physicsObject.IsOnSurface() && willTurnOnWallContact))
            {
                willTurn = true;
            }
            else if (willTurnOnDistance && ((transform.position.y >= maxMovePositionVector.y && directionY == Direction.Vertical.Up) || (transform.position.y <= minMovePositionVector.y && directionY == Direction.Vertical.Down)))
            {
                willTurn = true;
                float snappingPosition;
                if (transform.position.y >= maxMovePositionVector.y && directionY == Direction.Vertical.Up)
                {
                    snappingPosition = maxMovePositionVector.y;
                }
                else
                {
                    snappingPosition = minMovePositionVector.y;
                }

                physicsObject.previousFrameProperties.position = new Vector3(transform.position.x, snappingPosition, transform.position.z);
                physicsObject.properties.position = new Vector3(transform.position.x, snappingPosition, transform.position.z);
            }

            if (willTurn)
            {
                directionY = (directionY == Direction.Vertical.Up) ? Direction.Vertical.Down : Direction.Vertical.Up;
            }

            physicsObject.SetVelocityY(moveSpeed.y * (int)directionY);
        }
Пример #4
0
    public static LedgeInfo DetectLedgeOnWall(Direction.Horizontal _direction, Direction.Vertical _verticalDirection, BoxCollider2D _collider, float velocityToCheck, float offset = 0.25f)
    {
        RaycastHit2D raycastHits        = new RaycastHit2D();
        int          collisionLayerMask = 1 << LayerMask.NameToLayer("Terrain");

        float   rayLength    = _collider.size.y + Mathf.Abs(velocityToCheck) + offset;
        Vector2 rayDirection = (_verticalDirection == Direction.Vertical.Up) ? Vector2.up : Vector2.down;
        bool    isConnected  = false;

        Vector2 rayOrigin = new Vector2(_collider.transform.position.x + (_collider.size.x * 0.5f) * (int)_direction, _collider.transform.position.y - (_collider.size.y * 0.5f * (int)_verticalDirection));

        rayOrigin.y = (rayDirection == Vector2.up) ? _collider.bounds.min.y - offset : _collider.bounds.max.y + offset;

        float raycastSpacing = _collider.size.x * 0.5f;

        rayOrigin.x = (_direction == Direction.Horizontal.Left) ? rayOrigin.x - raycastSpacing : rayOrigin.x + raycastSpacing;

        raycastHits = Physics2D.Raycast(rayOrigin, rayDirection, rayLength, collisionLayerMask);
        if (raycastHits.fraction > 0)
        {
            isConnected = true;
        }

                #if UNITY_EDITOR
        //Debug.DrawRay(rayOrigin, new Vector2(0.25f * (int)_direction, (int)rayDirection.y * rayLength), Color.red);
                #endif

        float     hitY      = (isConnected) ? raycastHits.point.y : 0.0f;
        LedgeInfo ledgeInfo = new LedgeInfo();
        ledgeInfo.didHit = isConnected;
        ledgeInfo.hitY   = hitY;

        return(ledgeInfo);
    }
Пример #5
0
    public static bool IsOnSurface(string surfaceTag, Direction.Vertical _verticalDirection, BoxCollider2D _collider, float gravityScaleMultiplier = 1.0f)
    {
        RaycastHit2D raycastHits        = new RaycastHit2D();
        int          collisionLayerMask = 1 << LayerMask.NameToLayer("Terrain") | 1 << LayerMask.NameToLayer("PassThroughBottom");

        float   rayLength    = _collider.size.y * 0.5f + 0.25f;
        Vector2 rayDirection = (_verticalDirection == Direction.Vertical.Up) ? Vector2.up : Vector2.down;
        bool    isConnected  = false;

        Vector2 rayOrigin = new Vector2(_collider.transform.position.x, _collider.transform.position.y + (_collider.offset.y * gravityScaleMultiplier));

        float raycastSpacing = _collider.size.x * 0.5f;

        rayOrigin.x = rayOrigin.x - raycastSpacing;

        for (int i = 0; i < 3; i++)
        {
            raycastHits = Physics2D.Raycast(rayOrigin, rayDirection, rayLength, collisionLayerMask);
            if (raycastHits.fraction > 0)
            {
                if (raycastHits.collider.tag == surfaceTag)
                {
                    isConnected = true;
                }
            }

                        #if UNITY_EDITOR
            //Debug.DrawRay(rayOrigin, new Vector2(0.0f, (int)_verticalDirection) * rayLength, Color.red);
                        #endif

            rayOrigin.x += raycastSpacing;
        }

        return(isConnected);
    }
Пример #6
0
    public static bool IsNextToLedge(Direction.Horizontal _direction, Direction.Vertical _verticalDirection, BoxCollider2D _collider, float gravityScaleMultiplier = 1.0f)
    {
        RaycastHit2D raycastHits        = new RaycastHit2D();
        int          collisionLayerMask = 1 << LayerMask.NameToLayer("Terrain") | 1 << LayerMask.NameToLayer("PassThroughBottom");

        float   rayLength    = _collider.size.y * 0.5f + 0.1f;
        Vector2 rayDirection = (_verticalDirection == Direction.Vertical.Up) ? Vector2.up : Vector2.down;
        bool    isConnected  = false;

        Vector2 rayOrigin = new Vector2(_collider.transform.position.x, _collider.transform.position.y + (_collider.offset.y * gravityScaleMultiplier));

        float raycastSpacing = _collider.size.x * 0.5f;

        rayOrigin.x = (_direction == Direction.Horizontal.Left) ? rayOrigin.x - raycastSpacing : rayOrigin.x + raycastSpacing;

        raycastHits = Physics2D.Raycast(rayOrigin, rayDirection, rayLength, collisionLayerMask);
        if (raycastHits.fraction > 0)
        {
            isConnected = true;
        }

                #if UNITY_EDITOR
        //Debug.DrawRay(rayOrigin, new Vector2(0.0f, (int)_verticalDirection) * rayLength, Color.red);
                #endif

        return(!isConnected);
    }
Пример #7
0
    public static bool DropThroughFloorRaycast(Direction.Vertical _verticalDirection, BoxCollider2D _collider, float gravityScaleMultiplier = 1.0f)
    {
        RaycastHit2D raycastHits        = new RaycastHit2D();
        int          collisionLayerMask = 1 << LayerMask.NameToLayer("PassThroughBottom");

        Vector3 rayDirection = (_verticalDirection == Direction.Vertical.Down) ? Vector3.down : Vector3.up;
        bool    isConnected  = false;

        Vector2 rayOrigin      = new Vector2(_collider.transform.position.x, _collider.transform.position.y + (_collider.offset.y * gravityScaleMultiplier));
        float   raycastSpacing = _collider.size.x * 0.5f;
        float   rayLength      = _collider.size.y * 0.5f + 0.05f;

        rayOrigin.x -= rayLength;

        for (int i = 0; i < 3; i++)
        {
            raycastHits = Physics2D.Raycast(rayOrigin, rayDirection, rayLength, collisionLayerMask);
            if (raycastHits.fraction > 0)
            {
                isConnected = true;
            }

            //Debug.DrawRay(rayOrigin, rayDirection * rayLength, Color.red);

            rayOrigin.x += rayLength;
        }

        return(isConnected);
    }
Пример #8
0
    public static bool IsUnderOverhang(Direction.Vertical _verticalDirection, Vector2 _colliderSize, Vector3 _colliderPosition)
    {
        RaycastHit2D raycastHits        = new RaycastHit2D();
        int          collisionLayerMask = 1 << LayerMask.NameToLayer("Terrain");
        float        sideBuffer         = 0.025f; //This pulls the raycasts slightly in from the sides of the collider; it prevents the player from crouching NEXT TO an overhang and being unable to get back up

        float   rayLength    = _colliderSize.y * 0.5f + 0.25f;
        Vector2 rayDirection = (_verticalDirection == Direction.Vertical.Up) ? Vector2.up : Vector2.down;
        bool    isConnected  = false;

        Vector2 rayOrigin = new Vector2(_colliderPosition.x, _colliderPosition.y);

        float raycastSpacing = _colliderSize.x * 0.5f - sideBuffer;

        rayOrigin.x = rayOrigin.x - raycastSpacing;

        for (int i = 0; i < 3; i++)
        {
            raycastHits = Physics2D.Raycast(rayOrigin, rayDirection, rayLength, collisionLayerMask);
            if (raycastHits.fraction > 0)
            {
                isConnected = true;
            }

                        #if UNITY_EDITOR
            //Debug.DrawRay(rayOrigin, new Vector2(0.0f, (int)_verticalDirection) * rayLength, Color.red);
                        #endif

            rayOrigin.x += raycastSpacing;
        }

        return(isConnected);
    }
Пример #9
0
        //Used internally for added safety when checking slope collisions
        private void CheckForSlopesInOtherDirection()
        {
            box = GetRectAtPosition(properties.position);
            Direction.Vertical direction = (properties.velocity.y + properties.externalVelocity.y <= 0.0f) ? Direction.Vertical.Up : Direction.Vertical.Down;

            if (Mathf.Abs(properties.velocity.y + properties.externalVelocity.y) == 0.0f)
            {
                return;
            }

            float   edgeBuffer = 0.025f;
            Vector2 startPoint = new Vector2(box.xMin + edgeBuffer, box.center.y);
            Vector2 endPoint   = new Vector2(box.xMax - edgeBuffer, box.center.y);

            RaycastHit2D[] raycastHits = new RaycastHit2D[raycastAmounts.vertical];

            float rayLength      = box.height / 2.0f + slopeDetectionMargin;
            float lowestFraction = Mathf.Infinity;
            int   savedIndex     = 0;

            bool didCollide = false;

            for (int i = 0; i < raycastAmounts.vertical; i++)
            {
                float   raycastSpacing = (float)i / (float)(raycastAmounts.vertical - 1);
                Vector2 rayOrigin      = Vector2.Lerp(startPoint, endPoint, raycastSpacing);
                Vector2 rayDirection   = (direction == Direction.Vertical.Down) ? -Vector2.up : Vector2.up;

                raycastHits[i] = Physics2D.Raycast(rayOrigin, rayDirection, rayLength, collisionLayerMask);
                if (raycastHits[i].fraction > 0)
                {
                    didCollide = true;
                    if (raycastHits[i].fraction < lowestFraction)
                    {
                        savedIndex     = i;
                        lowestFraction = raycastHits[i].fraction;
                    }
                }
            }

            if (didCollide)
            {
                if (direction == Direction.Vertical.Down)
                {
                    Vector2 tempNewPosition = properties.position + Vector2.down * (raycastHits[savedIndex].fraction * rayLength - box.height / 2);
                    if (properties.position.y < tempNewPosition.y)
                    {
                        properties.position += Vector2.down * (raycastHits[savedIndex].fraction * rayLength - box.height / 2);
                    }
                }
                else
                {
                    Vector2 tempNewPosition = properties.position + Vector2.up * (raycastHits[savedIndex].fraction * rayLength - box.height / 2);
                    if (properties.position.y > tempNewPosition.y)
                    {
                        properties.position += Vector2.up * (raycastHits[savedIndex].fraction * rayLength - box.height / 2);
                    }
                }
            }
        }
Пример #10
0
 void Start()
 {
     directionX = startingDirectionX;
     directionY = startingDirectionY;
     if (!willStartWhenPlayerIsOnTop && isMovementEnabled)
     {
         StartMoving();
     }
 }
Пример #11
0
 protected void SetVerticalDirection(Direction.Vertical _direction)
 {
     direction.vertical = _direction;
     if (direction.vertical == Direction.Vertical.Down)
     {
         transform.localScale = new Vector3(-1.0f, 1.0f, 1.0f);
     }
     else if (direction.vertical == Direction.Vertical.Up)
     {
         transform.localScale = new Vector3(1.0f, 1.0f, 1.0f);
     }
 }
Пример #12
0
        public bool CanExitCrouch()
        {
            bool canExit = true;

            Direction.Vertical direction = (Direction.Vertical)controller.GravityScaleMultiplier();

            if (RaycastHelper.IsUnderOverhang(direction, nonCrouchingColliderSize, boxCollider.transform.position))
            {
                canExit = false;
            }

            return(canExit);
        }
Пример #13
0
        //Checks to see if we hit either the floor or the ceiling
        private bool CheckForCeilingFloorContact(Direction.Vertical _direction, bool willDetectWithMargin = false)
        {
            float   edgeBuffer = 0.025f;
            Vector2 startPoint = new Vector2(box.xMin + edgeBuffer, box.center.y);
            Vector2 endPoint   = new Vector2(box.xMax - edgeBuffer, box.center.y);

            RaycastHit2D[] raycastHits        = new RaycastHit2D[raycastAmounts.vertical];
            int            numberOfCollisions = 0;
            float          fraction           = 0;

            float   margin     = (willDetectWithMargin) ? 0.25f : 0.001f;
            float   rayLength  = box.height / 2 + margin;
            Vector3 direction  = new Vector3(0.0f, (int)_direction, 0.0f);
            bool    didCollide = false;

            float lowestFraction = Mathf.Infinity;
            int   savedIndex     = 0;

            for (int i = 0; i < raycastAmounts.vertical; i++)
            {
                float   raycastSpacing = (float)i / (float)(raycastAmounts.vertical - 1);
                Vector2 rayOrigin      = Vector2.Lerp(startPoint, endPoint, raycastSpacing);
                Vector2 rayDirection   = (_direction == Direction.Vertical.Down) ? -Vector2.up : Vector2.up;
                int     mask           = (_direction == Direction.Vertical.Down) ? collisionLayerMaskDown : collisionLayerMask;
                raycastHits[i] = Physics2D.Raycast(rayOrigin, rayDirection, rayLength, mask);
                if (raycastHits[i].fraction > 0)
                {
                    didCollide = true;
                    if (_direction == Direction.Vertical.Up)
                    {
                        properties.isAgainstCeiling = true;

                        return(true);
                    }
                    else if (_direction == Direction.Vertical.Down)
                    {
                        properties.isGrounded  = true;
                        willSnapToFloorOnStart = false;
                        return(true);
                    }

                    break;
                }
            }

            return(false);
        }
Пример #14
0
        public void Fire(Vector2 _startingPosition, Direction.Horizontal _horizontal, Direction.Vertical _vertical, RexActor _spawningActor, RexPool _parentSpawnPool = null)
        {
            if (!willDestroyWhenSceneChanges)
            {
                DontDestroyOnLoad(gameObject);
            }

            isFiring         = true;
            isBeingReflected = false;
            movementSpeed    = originalMovementSpeed;
            spawningActor    = _spawningActor;

            if (sounds.fireSound)
            {
                GetComponent <AudioSource>().PlayOneShot(sounds.fireSound);
            }

            if (_parentSpawnPool != null)
            {
                parentSpawnPool = _parentSpawnPool;
            }

            SetPosition(_startingPosition);
            SetHorizontalDirection(_horizontal);
            SetVerticalDirection((Direction.Vertical)((int)startingVerticalDirection * (int)_vertical * PhysicsManager.Instance.gravityScale));

            firingDirection = _horizontal;

            slots.physicsObject.properties.acceleration = Vector2.zero;

            float startingXSpeed = (acceleration == 0.0f) ? movementSpeed.x * (int)direction.horizontal : 0.0f;

            slots.physicsObject.SetVelocityX(startingXSpeed);
            slots.physicsObject.SetAccelerationCapX(movementSpeed.x * (int)direction.horizontal);

            float startingYSpeed = (acceleration == 0.0f) ? movementSpeed.y * (int)direction.vertical : 0.0f;

            slots.physicsObject.SetVelocityY(startingYSpeed);
            slots.physicsObject.SetAccelerationCapY(movementSpeed.y * (int)direction.vertical);
        }
Пример #15
0
        //Checks our vertical collisions, and either stops us from moving or enables us to continue moving
        private void CheckVerticalCollisions(float velocityToCheck, bool isTranslatingDirectly = false)
        {
            if (!willStickToMovingPlatforms)
            {
                movingPlatform = null;
            }

            box = GetRectAtPosition(properties.position);

            Direction.Vertical direction = (velocityToCheck <= 0.0f) ? Direction.Vertical.Down : Direction.Vertical.Up;

            if (velocityToCheck == 0.0f)
            {
                return;
            }

            //The edge buffer prevents you from standing on a ledge with the very corner of your hitbox
            //This fixes problems where you jump straight up *next to* a ledge and the end up resting on the ledge itself on the way down
            float   edgeBuffer = 0.025f;
            Vector2 startPoint = new Vector2(box.xMin + edgeBuffer, box.center.y);
            Vector2 endPoint   = new Vector2(box.xMax - edgeBuffer, box.center.y);

            RaycastHit2D[] raycastHits = new RaycastHit2D[raycastAmounts.vertical];

            float rayLength      = box.height / 2.0f + (((properties.isGrounded && direction == Direction.Vertical.Down) || (properties.isAgainstCeiling && direction == Direction.Vertical.Up)) ? slopeDetectionMargin : Mathf.Abs(velocityToCheck));
            float lowestFraction = Mathf.Infinity;
            int   savedIndex     = 0;

            bool didCollide = false;

            for (int i = 0; i < raycastAmounts.vertical; i++)
            {
                float   raycastSpacing = (float)i / (float)(raycastAmounts.vertical - 1);
                Vector2 rayOrigin      = Vector2.Lerp(startPoint, endPoint, raycastSpacing);
                Vector2 rayDirection   = (direction == Direction.Vertical.Down) ? -Vector2.up : Vector2.up;
                //Debug.DrawRay(rayOrigin, rayDirection * rayLength, Color.red);

                int mask = ((direction == Direction.Vertical.Down && gravitySettings.gravityScale > 0.0f) || (direction == Direction.Vertical.Up && gravitySettings.gravityScale <= 0.0f)) ? collisionLayerMaskDown : collisionLayerMask;

                raycastHits[i] = Physics2D.Raycast(rayOrigin, rayDirection, rayLength, mask);
                if (raycastHits[i].fraction > 0)
                {
                    didCollide = true;
                    if (raycastHits[i].fraction < lowestFraction)
                    {
                        savedIndex     = i;
                        lowestFraction = raycastHits[i].fraction;
                    }
                }
            }

            //This prevents you from walking off a one-way platform, holding left or right to be back inside it as you fall, and clipping back up on top of it
            if (didCollide && raycastHits[savedIndex].collider.gameObject.layer == LayerMask.NameToLayer("PassThroughBottom"))
            {
                float buffer = 0.1f;
                if ((gravitySettings.gravityScale > 0.0f && box.yMin < raycastHits[savedIndex].collider.bounds.max.y - buffer) || (gravitySettings.gravityScale <= 0.0f && box.yMax > raycastHits[savedIndex].collider.bounds.min.y + buffer))
                {
                    didCollide = false;
                }
            }

            //In rare instances, if the actor is already on top of a PassThroughBottom collider when they land on the ground, the above raycast can fail to detect the terrain; this is a failsafe
            if (!didCollide && raycastAmounts.enableRedundantVerticalCollisions)
            {
                int adjustedVerticalRaycasts = Mathf.CeilToInt(raycastAmounts.vertical * 0.5f);
                for (int i = 0; i < adjustedVerticalRaycasts; i++)
                {
                    float   raycastSpacing = (float)i / (float)(adjustedVerticalRaycasts - 1);
                    Vector2 rayOrigin      = Vector2.Lerp(startPoint, endPoint, raycastSpacing);
                    Vector2 rayDirection   = (direction == Direction.Vertical.Down) ? -Vector2.up : Vector2.up;
                    int     mask           = collisionLayerMask;
                    raycastHits[i] = Physics2D.Raycast(rayOrigin, rayDirection, rayLength, mask);
                    if (raycastHits[i].fraction > 0)
                    {
                        didCollide = true;
                        if (raycastHits[i].fraction < lowestFraction)
                        {
                            savedIndex     = i;
                            lowestFraction = raycastHits[i].fraction;
                        }
                    }
                }
            }

            if (didCollide)
            {
                properties.velocity         = new Vector2(properties.velocity.x, 0);
                properties.externalVelocity = new Vector2(properties.externalVelocity.x, 0);

                if (direction == Direction.Vertical.Down)
                {
                    properties.isGrounded  = true;
                    willSnapToFloorOnStart = false;
                    properties.isFalling   = false;

                    properties.isAgainstCeiling = false;
                    properties.position        += Vector2.down * (raycastHits[savedIndex].fraction * rayLength - box.height / 2);

                    MovingPlatform platform = raycastHits[savedIndex].collider.GetComponent <MovingPlatform>();
                    if (platform != null)
                    {
                        movingPlatform = platform;
                        movingPlatform.NotifyOfObjectOnTop();
                    }
                    else
                    {
                        movingPlatform = null;
                    }
                }
                else
                {
                    if (willStickToMovingPlatforms)
                    {
                        MovingPlatform platform = raycastHits[savedIndex].collider.GetComponent <MovingPlatform>();
                        if (platform != null)
                        {
                            movingPlatform = platform;
                        }
                        else
                        {
                            movingPlatform = null;
                        }
                    }

                    properties.isAgainstCeiling = true;
                    if (gravitySettings.gravityScale > 0.0f)                    //Hit your head on the ceiling; stop your jump
                    {
                        properties.isFalling = true;
                    }
                    else
                    {
                        properties.isFalling = false;
                    }

                    properties.position += Vector2.up * (raycastHits[savedIndex].fraction * rayLength - box.height / 2);
                }

                if (DidLandThisFrame())
                {
                    if (gravitySettings.gravityScale >= 0.0f)
                    {
                        NotifyOfCollision(raycastHits[savedIndex].collider, RexObject.Side.Bottom, RexObject.CollisionType.Enter);
                    }
                    else
                    {
                        NotifyOfCollision(raycastHits[savedIndex].collider, RexObject.Side.Top, RexObject.CollisionType.Enter);
                    }
                }

                if (DidHitCeilingThisFrame())
                {
                    if (gravitySettings.gravityScale >= 0.0f)
                    {
                        NotifyOfCollision(raycastHits[savedIndex].collider, RexObject.Side.Top, RexObject.CollisionType.Enter);
                    }
                    else
                    {
                        NotifyOfCollision(raycastHits[savedIndex].collider, RexObject.Side.Bottom, RexObject.CollisionType.Enter);
                    }
                }
            }
            else
            {
                properties.isAgainstCeiling = false;
                properties.isGrounded       = false;

                if (isTranslatingDirectly)
                {
                    properties.position = new Vector2(transform.position.x, properties.position.y + velocityToCheck);
                }
            }
        }