public float TryToMove(float distance, Dir4 dir, Vector2 deltaPosition = default) { float allowedMove = GetAllowedMovement(distance, dir, deltaPosition); float effectiveMove = ForceMove(allowedMove, dir); return(effectiveMove); }
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); } }
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); }
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); }
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); }
public static void RuntimeInit() { if (!instance) { instance = Resources.Load <KiteSettings>(resourceName); DirX.OnSettings(instance); DirY.OnSettings(instance); Dir4.OnSettings(instance); TileHelpers.OnSettings(instance); } }
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); }
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); }
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); }
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); } }
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)); }
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); }
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); }
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; }
public PhysicsMove(RaycastHit2D hit, float collideDistance, Dir4 dir, PhysicsMovement moving) => (this.hit, this.dir, this.collideDistance, this.moving) = (hit, dir, collideDistance, moving);
public override void Push(float distance, Dir4 dir) { movement.TryToMove(distance, dir); }
public float GetAllowedMovement(float distance, Dir4 direction, Vector2 deltaPosition = default) { return(GetAllowedMovementAt(distance, direction, deltaPosition)); }
private float GetAllowedMovementAt(float distance, Direction4 direction, Vector2 deltaPosition = default) { Dir4 dir = Direction4Helpers.ToDir4(direction); return(GetAllowedMovementAt(distance, dir, deltaPosition)); }
public bool CanMoveInDirection(Dir4 dir) { float testDistance = RaycastHelpers.skinWidth * 2; return(GetAllowedMovement(testDistance, dir) > RaycastHelpers.skinWidth); }
private bool CanBeCornerCorrected(float rayLength, Dir4 rayDir, RaycastHit2D cornerHit) => IsCorrectDistance(cornerHit.distance, jumpCornerCorrection) && cornerHit.collider && !IsInsideTile(cornerHit, rayDir) && !CanMoveInto(cornerHit, rayLength, rayDir);
// 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); }
public abstract void Push(float distance, Dir4 direction);