Пример #1
0
        public float TryToMove(float distance, Dir4 dir, Vector2 deltaPosition = default)
        {
            float allowedMove   = GetAllowedMovement(distance, dir, deltaPosition);
            float effectiveMove = ForceMove(allowedMove, dir);

            return(effectiveMove);
        }
Пример #2
0
        public static MoveUnit FromVector2(Vector2 vector, int axis)
        {
            float distance = Mathf.Abs(vector[axis]);
            Dir4  dir      = Dir4.FromFloat(vector[axis], axis);

            return(new MoveUnit {
                distance = distance, dir = dir, axis = axis
            });
        }
        public void ForceMoveInto(RaycastHit2D hit, float moveAmount, Dir4 dir)
        {
            float             collideDistance = moveAmount - hit.distance;
            PhysicsCollidable moveable        = hit.collider.GetComponent <PhysicsCollidable>();

            if (moveable)
            {
                PhysicsMove physicsMove = new PhysicsMove(hit, collideDistance, dir, movement);
                moveable.OnMoveInto(physicsMove);
            }
        }
Пример #4
0
        public static Dir4 Clockwise(Dir4 dir)
        {
            Dir4[] list = Dir4.GetList();
            int    idx  = Array.IndexOf(list, dir);

            if (idx != -1)
            {
                return(list[(idx + 1) % 4]);
            }
            return(null);
        }
Пример #5
0
        public static float GetRotation(Dir4 dir)
        {
            Dir4[] list = Dir4.GetList();
            int    idx  = Array.IndexOf(list, dir);

            if (idx != -1)
            {
                return(idx == 0 ? 0 : (360 - (idx * 90)));
            }
            return(0);
        }
Пример #6
0
        public static Dir4 CounterClockwise(Dir4 dir)
        {
            Dir4[] list = Dir4.GetList();
            int    idx  = Array.IndexOf(list, dir);

            if (idx != -1)
            {
                return(list[idx > 0 ? idx - 1 : 3]);
            }
            return(null);
        }
Пример #7
0
 public static void RuntimeInit()
 {
     if (!instance)
     {
         instance = Resources.Load <KiteSettings>(resourceName);
         DirX.OnSettings(instance);
         DirY.OnSettings(instance);
         Dir4.OnSettings(instance);
         TileHelpers.OnSettings(instance);
     }
 }
Пример #8
0
        private float NoDistanceForceMove(Dir4 dir)
        {
            float rayDistance = RaycastHelpers.skinWidth;

            (RaycastHit2D[] raycastHits, int count) = raycaster.GetHits(rayDistance, dir);
            IEnumerable <RaycastHit2D> uniqueHits = collisionMoveHitsFactory.GetUnique(raycastHits, count);

            foreach (RaycastHit2D hit in uniqueHits)
            {
                collisionMoveController.ForceMoveInto(hit, 0, dir);
            }
            return(0);
        }
Пример #9
0
        private bool IsInsideTile(RaycastHit2D hit, Dir4 rayDir)
        {
            Tilemap tilemap = hit.collider.GetComponent <Tilemap>();

            if (tilemap)
            {
                Vector2    pointBeforeHit = hit.point + ((Vector2)(-rayDir) * RaycastHelpers.skinWidth);
                Vector2Int tileSize       = Vector2Int.RoundToInt(tilemap.cellSize);
                int        tileX          = Mathf.FloorToInt(pointBeforeHit.x / tileSize.x);
                int        tileY          = Mathf.FloorToInt(pointBeforeHit.y / tileSize.y);
                Vector3Int tilePosition   = new Vector3Int(tileX, tileY, 0);
                TileBase   tile           = tilemap.GetTile(tilePosition);
                return(tile);
            }
            return(false);
        }
Пример #10
0
        private (bool, float) GetJumpCornerCorrectionFor(float topMovementAmount, DirX rayDirX)
        {
            Dir4         rayDir      = Dir4.FromXFloat(rayDirX);
            Bounds       bounds      = movement.boxCollider.bounds;
            float        rayLength   = jumpCornerCorrection;
            Vector2      upperCorner = BoundsHelpers.GetCorner(bounds, rayDirX, DirY.up);
            Vector2      rayDelta    = new Vector2(-rayDirX * rayLength, topMovementAmount);
            Vector2      rayOrigin   = upperCorner + rayDelta;
            RaycastHit2D cornerHit   = RaycastHelpers.SingleHit(rayOrigin, rayLength, rayDir, movement.layerMask);

            if (CanBeCornerCorrected(rayLength, rayDir, cornerHit))
            {
                float correctionValue = -rayDirX * (rayLength - cornerHit.distance);
                return(true, correctionValue);
            }
            return(false, 0);
        }
Пример #11
0
        private bool CanMoveInto(RaycastHit2D hit, float distance, Dir4 dir)
        {
            PhysicsCollidable collidable = hit.collider.GetComponent <PhysicsCollidable>();

            if (collidable)
            {
                float collideDistance = distance - hit.distance;
                float allowedMove     = collidable.GetAllowedMoveInto(new PhysicsMove(hit, collideDistance, dir, movement));
                return(allowedMove == collideDistance);
            }
            else
            {
                float collideDistance = distance - hit.distance;
                float allowedMove     = 0;
                return(allowedMove == collideDistance);
            }
        }
Пример #12
0
        private float GetAllowedMovementAt(float distance, Dir4 dir, Vector2 deltaPosition = default)
        {
            if (!RaycastHelpers.IsValidDistance(distance))
            {
                return(0);
            }

            (RaycastHit2D[] raycastHits, int count) = raycaster.GetHits(distance, dir, deltaPosition);
            IEnumerable <RaycastHit2D> uniqueHits = collisionMoveHitsFactory.GetUnique(raycastHits, count);
            float allowedDistance = distance;

            foreach (RaycastHit2D hit in uniqueHits)
            {
                allowedDistance = collisionMoveController.GetAllowedMoveInto(hit, allowedDistance, dir);
            }
            return(allowedDistance);
        }
        public float GetAllowedMoveInto(RaycastHit2D hit, float wantsToMove, Dir4 dir)
        {
            if (wantsToMove <= hit.distance && !TilemapHelpers.IsColliderTilemap(hit.collider))
            {
                return(wantsToMove);
            }
            float             allowedCollideDistance = 0;
            PhysicsCollidable moveable = hit.collider.GetComponent <PhysicsCollidable>();

            if (moveable)
            {
                float       collideDistance = wantsToMove - hit.distance;
                PhysicsMove physicsMove     = new PhysicsMove(hit, collideDistance, dir, movement);
                allowedCollideDistance = moveable.GetAllowedMoveInto(physicsMove);
            }
            float allowedDistance = allowedCollideDistance + hit.distance;

            return(Mathf.Clamp(allowedDistance, 0, wantsToMove));
        }
Пример #14
0
        public (RaycastHit2D[], int) GetHits(Vector2 origin, float distance, Dir4 dir)
        {
            distance = RaycastHelpers.CeilDistance(distance);
            int rays             = rayDeltas.Length;
            int edgeRayHitsCount = 0;

            for (int i = 0; i < rays; i++)
            {
                Vector2 rayOrigin = origin + rayDeltas[i];
                (int singleRayHitsCount, RaycastHit2D[] singleRayHits) = RaycastHelpers.Raycast(rayOrigin, distance, dir, layerMask);
                if (edgeRayHitsCount + singleRayHitsCount > maxEdgeRayHitsCount)
                {
                    return(ForceReturnOverHitsResults(edgeRayHitsCount, singleRayHitsCount, singleRayHits));
                }
                Array.Copy(singleRayHits, 0, edgeRayHits, edgeRayHitsCount, singleRayHitsCount);
                edgeRayHitsCount += singleRayHitsCount;
            }

            return(edgeRayHits, edgeRayHitsCount);
        }
Пример #15
0
        public float ForceMove(float distance, Dir4 dir)
        {
            if (!RaycastHelpers.IsValidDistance(distance))
            {
                return(NoDistanceForceMove(dir));
            }

            Vector2 origin = rigidbody.position;

            (RaycastHit2D[] raycastHits, int count) = raycaster.GetHits(distance, dir);
            IEnumerable <RaycastHit2D> uniqueHits = collisionMoveHitsFactory.GetUnique(raycastHits, count);

            foreach (RaycastHit2D hit in uniqueHits)
            {
                collisionMoveController.ForceMoveInto(hit, distance, dir);
            }

            Vector2 moveAmount = (Vector2)dir * distance;

            rigidbody.position = origin + moveAmount;

            return(distance);
        }
Пример #16
0
        public static (int, RaycastHit2D[]) Raycast(Vector2 position, float distance, Dir4 direction, int layerMask)
        {
            Vector2 rayDirection = direction;
            Vector2 rayOrigin    = position + (-rayDirection * skinWidth);
            float   rayLength    = distance + skinWidth;
            int     count        = Physics2D.RaycastNonAlloc(rayOrigin, rayDirection, results, rayLength, layerMask);

            for (int i = 0; i < count; i++)
            {
                ref RaycastHit2D hit = ref results[i];
                if (hit.distance <= 0)
                {
                    continue;
                }

                hit.distance = Mathf.Max(hit.distance - skinWidth, 0);
                hit.fraction = hit.distance / distance;
            }
Пример #17
0
 public PhysicsMove(RaycastHit2D hit, float collideDistance, Dir4 dir, PhysicsMovement moving) =>
 (this.hit, this.dir, this.collideDistance, this.moving) = (hit, dir, collideDistance, moving);
Пример #18
0
 public override void Push(float distance, Dir4 dir)
 {
     movement.TryToMove(distance, dir);
 }
Пример #19
0
 public float GetAllowedMovement(float distance, Dir4 direction, Vector2 deltaPosition = default)
 {
     return(GetAllowedMovementAt(distance, direction, deltaPosition));
 }
Пример #20
0
        private float GetAllowedMovementAt(float distance, Direction4 direction, Vector2 deltaPosition = default)
        {
            Dir4 dir = Direction4Helpers.ToDir4(direction);

            return(GetAllowedMovementAt(distance, dir, deltaPosition));
        }
Пример #21
0
        public bool CanMoveInDirection(Dir4 dir)
        {
            float testDistance = RaycastHelpers.skinWidth * 2;

            return(GetAllowedMovement(testDistance, dir) > RaycastHelpers.skinWidth);
        }
Пример #22
0
 private bool CanBeCornerCorrected(float rayLength, Dir4 rayDir, RaycastHit2D cornerHit) =>
 IsCorrectDistance(cornerHit.distance, jumpCornerCorrection) &&
 cornerHit.collider &&
 !IsInsideTile(cornerHit, rayDir) &&
 !CanMoveInto(cornerHit, rayLength, rayDir);
Пример #23
0
        // TODO: Fix based on GetJumpCornerCorrection
        private float GetMoveCornerCorrection(float xMoveAmount, float correctionAmount, DirY dir)
        {
            Bounds  testBounds = movement.boxCollider.bounds;
            float   xSign      = Mathf.Sign(xMoveAmount);
            float   ySign      = dir.value;
            Vector2 rayVector  = dir;
            float   rayLength  = correctionAmount + RaycastHelpers.skinWidth;

            {
                Vector2 rayOrigin = new Vector2(
                    testBounds.center.x + xSign * testBounds.extents.x + xMoveAmount,
                    testBounds.center.y + ySign * (testBounds.extents.y - rayLength)
                    );
                RaycastHit2D rayHit = Physics2D.Raycast(rayOrigin, rayVector, rayLength, movement.layerMask);
                Debug.DrawRay(rayOrigin + Vector2.right * 5 * xSign, rayVector * rayLength);
                if (IsCorrectDistance(rayHit.distance, correctionAmount) && !CanMoveInto(rayHit, rayLength, Dir4.FromYFloat(dir)))
                {
                    return(-ySign * (rayLength - rayHit.distance));
                }
            }
            return(0);
        }
Пример #24
0
 public abstract void Push(float distance, Dir4 direction);