private void Move(Vector2 movement, bool snapped) { float distance = movement.magnitude; int count = rigid.Cast(movement, raycastHits, movement.magnitude); /*if (!snapped && count > 0) * { * distance = raycastHits[0].distance + 0.01f; //to fire collision * }*/ transform.Translate(movement.normalized * distance, Space.World); //Additional movement to correct on edges if (snapped) { if (count == 0 && grounded) //no collision => no point to update gravity { //Make a gravity step down count = rigid.Cast(Physics2D.gravity, raycastHits, Physics2D.gravity.magnitude * Time.deltaTime); if (count > 0) { if (raycastHits[0].distance < 0.01f) //there is some floating point bs { return; } var newMovement = raycastHits[0].distance * Physics2D.gravity.normalized; transform.Translate(newMovement, Space.World); } } } }
private void CheckState() { if (_character.ISPlayerCharacter) { _collisionCount = _rigidbody2D.Cast(transform.right, _results, 0.35f); } else { _collisionCount = _rigidbody2D.Cast(-transform.right, _results, -0.35f); } if (_collisionCount == 0) { _character.Move(); } else { _isAttackState = CheckAttackEnemy(); if (!_isAttackState) { _isAttackState = CheckAttackEnemyTower(); } if (!_isAttackState) { _character.Move(); } } _lastAttackTime -= Time.deltaTime; }
private bool PostSideCheck(float x) { RaycastHit2D[] hitBufferLeft = new RaycastHit2D[16]; int count = rb2d.Cast(new Vector2(x, 0), contactFilter, hitBufferLeft, 0.01f); List <RaycastHit2D> hitListLeft = new List <RaycastHit2D>(16); hitListLeft.Clear(); bool touching = false; for (int i = 0; i < count; i++) { if (hitBufferLeft[i].transform.gameObject.layer == (int)Layer.Wall) { hitListLeft.Add(hitBufferLeft[i]); } } for (int i = 0; i < hitListLeft.Count; i++) { Vector2 currentNormal = hitListLeft[i].normal; if (-currentNormal.x * x > -minSideNormalX * x) { touching = true; } } return(touching); }
void Drink() { anim.SetTrigger("Drink"); playSound.Play(1, 1, 1); if (powered) { RaycastHit2D[] drinkResults = new RaycastHit2D[1]; int drinks = 0; drinks = rb.Cast(new Vector2(1f, 0f), drinkFilter, drinkResults, drinkDistance); if (drinks > 0) { if (drinkResults[0].collider.tag == "BigPuke") { anim.SetTrigger("PermaDrink"); FreezeState(); gameOver = true; sceneM.EndingScreen(); } } } IdleState(1.1f); }
bool MovX(float delta) { SetMask(false); bool ret = false; float shellDIst = shellRadious; ignoreColliders.Clear(); Collider2D[] ov = new Collider2D[4]; int r = coll.OverlapCollider(cf, ov); for (int i = 0; i < r; i++) { ignoreColliders.Add(ov[i]); } Vector3 desp = new Vector3(delta, 0, 0); RaycastHit2D[] res = new RaycastHit2D[6]; r = coll.Cast(desp.normalized, cf, res, desp.magnitude + shellDIst); if (r == 0) { coll.transform.position = coll.transform.position + new Vector3(delta, 0, 0); return(false); } float sep = Mathf.Abs(delta); for (int i = 0; i < r; i++) { RaycastHit2D rc = res[i]; if (ignoreColliders.Contains(rc.collider)) { continue; } ret = true; float distance = rc.distance - shellDIst; if (distance < 0) { distance = 0; } if (distance < sep) { sep = distance; } } coll.transform.position = coll.transform.position + desp.normalized * sep; return(ret); }
void move(Vector2 dir, bool move_y) { float dist = dir.magnitude; Vector2 offset = Vector2.zero; if (dist >= MIN_MOVE_DISTANCE) { int count = rb2d.Cast(dir, contact_filter, hits, dist + SHELL_RADIUS); hit_list.Clear(); for (int i = 0; i < count; i++) { hit_list.Add(hits[i]); //db_hit_list.Add(hits[i]); } foreach (RaycastHit2D hit in hit_list) { Vector2 normal = hit.normal; if (normal.y > min_ground_normal_y) { is_grounded = true; if (move_y) { surface_normal = normal; normal.x = 0; } } else { is_sliding = true; } if (hit.collider.tag == "MovingTerrain") { PlatformMove moving_p = hit.collider.transform.GetComponent <PlatformMove>(); if (moving_p != null) { offset += moving_p.getVelocity(); } } //slows down velocity when object is hit float projection = Vector2.Dot(velocity, normal); if (projection < 0) { velocity = velocity - normal * projection; } float mod_dist = hit.distance - SHELL_RADIUS; dist = mod_dist < dist ? mod_dist : dist; } } Vector2 next_pos = rb2d.position + (dir.normalized * dist) + offset; rb2d.position = next_pos; }
private void MoveX(Vector2 move) { float moveDistance = move.magnitude; int hitCount = rig2d.Cast(move, filter2d, hits, move.magnitude + shellRadius); if (moveDistance > minMoveDistance) { if (hitCount > 0) { for (int i = 0; i < hitCount; i++) { switch (hits[i].transform.tag) { case "Platform": { if (hits[i].distance == 0 || hits[i].normal.y != 1f) { rig2d.position += move.normalized * moveDistance; velocity.x = 0; return; } break; } case "Coin": { // GameManager.Instance.PickUpCoin(); Destroy(hits[i].transform.gameObject); rig2d.position += move.normalized * moveDistance; velocity.x = 0; break; } case "Trap": { SceneManager.LoadScene("SampleScene", LoadSceneMode.Single); break; } } Vector2 normal = hits[i].normal; Vector2 groundNormal = new Vector2(normal.y, -normal.x); if (normal.x >= 0 && normal.x != 1f && normal.y >= 0) { move = -moveDistance * groundNormal.normalized * angleSpeed; } else if (normal.x <= 0 && normal.x != -1f && normal.y >= 0) { move = moveDistance * groundNormal.normalized * angleSpeed; } else { moveDistance = hits[i].distance - shellRadius; } } } rig2d.position += move.normalized * moveDistance; velocity.x = 0; } }
private void ApplyDeltaPosition(Vector2 deltaPosition, bool isVerticalDelta) { var deltaMagnitude = deltaPosition.magnitude; if (deltaMagnitude > sleepVelocity) { var nbCollidersDetected = rigidbody.Cast(deltaPosition, contactFilter, preallocaRaycastHits, deltaMagnitude + deltaPrecision); for (int i = 0; i < nbCollidersDetected; i++) { var collider = preallocaRaycastHits[i]; var colliderNormal = collider.normal; //If this a useable ground ? if (colliderNormal.y > 1 - maxGroundSlopeAngleArctan) { isGrounded = true; lastGroundedTime = Time.time; if (isVerticalDelta) { groundNormal = colliderNormal; colliderNormal.x = 0; #if UNITY_EDITOR if (showDebugInformation) { Debug.DrawLine(collider.point, collider.point + colliderNormal, Color.green); Debug.DrawLine(collider.point, collider.point + GetGroundMovementVector(), Color.yellow); } #endif } } //How much this collider should affect the velocity. The more the velocity vector //and the collider normal vector are opposed, the more the collider should absorb the velocity // //Using the Dot product, we know how much theses two vectors are opposed (if they are). //Negative number means vectors are opposed. var velocityNegationForce = Vector2.Dot(velocity, colliderNormal); if (velocityNegationForce < 0) { velocity -= velocityNegationForce * colliderNormal; } //Snap object to collider bound if distance between the object and the collider is less than //the delta precison. This prevent the object from going though the collider. var snappedDeltaMagnitude = collider.distance - deltaPrecision; deltaMagnitude = snappedDeltaMagnitude < deltaMagnitude ? snappedDeltaMagnitude : deltaMagnitude; } } rigidbody.position += deltaPosition.normalized * deltaMagnitude; }
bool CheckForCollision(int direction) { bool result = false; RaycastHit2D[] hitList = new RaycastHit2D[5]; Vector2 offset = Vector2.zero; switch (direction) { case StaticData.DIR_UP: offset.y = 1; break; case StaticData.DIR_DOWN: offset.y = -1; break; case StaticData.DIR_RIGHT: offset.x = 1; break; case StaticData.DIR_LEFT: offset.x = -1; break; } //offset = offset * grid ; int hitCount = rb.Cast(offset, hitList, grid / 2); if (hitCount > 5) { Debug.LogError("Do not have more than 5 items stacked on one tile! Bad designer, no twinkie!"); } for (int i = 0; i < hitCount; i++) { if (hitList[i].collider.isTrigger) { result = false; } else { result = true; } } return(result); }
void Movement(Vector2 Move) { float distance = Move.magnitude; if (distance > delta) { int count = rigidbody.Cast(Move, filter2D, hit2Ds, distance + ShellRadius); raycastHitsList.Clear(); for (int i = 0; i < count; i++) { raycastHitsList.Add(hit2Ds[i]); } foreach (RaycastHit2D ray in raycastHitsList) { Vector2 currentNormal = ray.normal; float projection = Vector2.Dot(Velocity, currentNormal); if (projection < 0) { Velocity = Velocity - projection * currentNormal; } float modifiedDistance = ray.distance - ShellRadius; distance = modifiedDistance < distance ? modifiedDistance : distance; } } rigidbody.position = rigidbody.position + Move.normalized * distance; }
void FixedUpdate() { float xInput = Input.GetAxisRaw("Horizontal"); float yInput = Input.GetAxisRaw("Vertical"); Vector3 inputDir = new Vector3(xInput, yInput, 0f).normalized; if (CurrentCastType == CastType.Physics2D) { Debug.DrawLine(transform.position, transform.position + inputDir * maxSpeed, Color.green); int count = Physics2D.Raycast(transform.position, inputDir, _contactFilter, _hits, maxSpeed); for (int i = 0; i < count; i++) { RaycastHit2D hit = _hits[i]; Debug.Log("hit something: " + hit.collider.name); } } else if (CurrentCastType == CastType.RigidBody2D) { Debug.DrawLine(transform.position, transform.position + inputDir * maxSpeed, Color.red); int count = _rigidBody.Cast(inputDir, _hits, maxSpeed); for (int i = 0; i < count; i++) { RaycastHit2D hit = _hits[i]; Debug.Log("hit something: " + hit.collider.name); } } }
/// <summary> /// Cast the rigidbodies colliders in the direction and return the closest hit in a castResult /// struct. /// </summary> /// <param name="body"></param> /// <param name="direction"></param> /// <param name="filter"></param> /// <param name="results"></param> /// <param name="skinWidth"></param> protected CastResult CollisionDetection(Rigidbody2D body, Vector2 direction, ContactFilter2D filter, List <RaycastHit2D> results, float skinWidth) { //--------------------------------------------------------------------------------------------------------- // Define values to return if nothing's hit //--------------------------------------------------------------------------------------------------------- float distance = direction.magnitude; Rigidbody2D returnedBody = null; Vector2 normal = Vector2.zero; //--------------------------------------------------------------------------------------------------------- // If we hit something, we should loop over all the hits and keep the one with the shortest // distance. //--------------------------------------------------------------------------------------------------------- int hits = body.Cast(direction, filter, results, distance + skinWidth); for (int i = 0; i < hits; i++) { float adjustedDistance = results[i].distance - skinWidth; if (adjustedDistance < distance) { distance = adjustedDistance; returnedBody = results[i].rigidbody; normal = results[i].normal; } } return(new CastResult(returnedBody, normal, distance)); }
// Update is called once per frame void Update() { float desiredDistance = Mathf.Min((nextWayPoint - (Vector2)transform.position).magnitude, speed * Time.deltaTime * GameManager.customTimeScale); Vector2 nextPosition = (nextWayPoint - (Vector2)transform.position).normalized; RaycastHit2D[] castResults = new RaycastHit2D[16]; int collisionCount = rb.Cast(nextPosition, collisionFilter, castResults, desiredDistance); Debug.Log("count " + collisionCount); if (collisionCount > 0) { Debug.Log("COLLISION"); stop = true; ChangeDirection(); nextPosition = (nextWayPoint - (Vector2)transform.position).normalized; } transform.Translate(nextPosition * desiredDistance); if (Vector2.Distance(transform.position, nextWayPoint) < minDesiredDistanceToWaypoint) { ChangeWaypoint(); } }
private float CalculateMovementCollisionOffset(Vector2 movement, bool updateCurrentFloorNormal) { float finalMovement = movement.magnitude; hitResults = new RaycastHit2D[16]; int hitCount = playerRigidbody.Cast(movement, contactFilter, hitResults, finalMovement + collisionPadding); if (hitCount > 0) { for (int i = 0; i < hitCount; i++) { Vector2 currentNormal = hitResults[i].normal; if (currentNormal.y > minGroundNormalY) { isGrounded = true; if (updateCurrentFloorNormal) { groundNormal = currentNormal; currentNormal.x = 0; } } float projection = Vector2.Dot(velocity, currentNormal); if (projection < 0) { velocity = velocity - projection * currentNormal; } float modifiedMoveDistance = hitResults[i].distance - collisionPadding; finalMovement = modifiedMoveDistance < finalMovement ? modifiedMoveDistance : finalMovement; } } return(finalMovement); }
void Movement(Vector2 move) { float distance = move.magnitude; if (distance > minMoveDistance) { rb2d.Cast(move, hitBuffer, distance + shellRadius); //Physics.Raycast (transform.position, Vector3.down, out singleBuffer, distance + shellRadius); Debug.DrawRay(transform.position, Vector3.down, Color.cyan, distance + shellRadius); Vector2 currentNormal = hitBuffer[0].normal; if (currentNormal.y > minGroundNormalY) { grounded = true; groundNormal = currentNormal; currentNormal.x = 0; } float projection = Vector2.Dot(velocity, currentNormal); if (projection < 0) { //velocity = velocity - projection * currentNormal; } float modifiedDistance = hitBuffer[0].distance - shellRadius; if (modifiedDistance < distance) { distance = modifiedDistance; } } transform.Translate(move.normalized * distance); }
public void SnapToGround() { string obj; if (canDrag) { obj = "Floor"; } else { obj = "Floor1"; } if (canDrag) { int hitNum = platformBody.Cast(Vector2.down, collisionCheck, floorCheckDistance); if (collisionCheck[0] != null && collisionCheck[0].transform != null) { bool foundFloor = false; if (collisionCheck[0].transform.name == obj && collisionCheck[0].distance != 0) { transform.position = new Vector3(transform.position.x, transform.position.y - collisionCheck[0].distance, transform.position.z); foundFloor = true; } if (!foundFloor) { transform.position = originalPosition; } isGrounded = foundFloor; } } }
void Movement(Vector2 move, bool yMovement) { float distance = move.magnitude; if (distance > MinMoveDistance) { int count = rigidBody2D.Cast(move, contactFilter, hitBuffer, distance + ShellRadius); for (int i = 0; i < count; i++) { Vector2 currentNormal = hitBuffer[i].normal; if (currentNormal.y > minGroundNormalY) { Grounded = true; if (yMovement) { groundNormal = currentNormal; currentNormal.x = 0; } } float projection = Vector2.Dot(velocity, currentNormal); if (projection < 0) { velocity = velocity - projection * currentNormal; } float modifiedDistance = hitBuffer[i].distance - ShellRadius; distance = modifiedDistance < distance ? modifiedDistance : distance; } } //rigidBody2D.position = rigidBody2D.position + move.normalized * distance; transform.Translate(move.normalized * distance); }
void FixedUpdate() { if (moveVec != Vector2.zero && (this.gameObject == PlayerManager.LocalPlayerInstance || !PhotonNetwork.IsConnected)) { Vector2 oldPosition = new Vector2(transform.position.x, transform.position.y); RaycastHit2D[] hits = new RaycastHit2D[10]; ContactFilter2D filter = new ContactFilter2D() { layerMask = 1 << LayerMask.NameToLayer("Player"), useLayerMask = true }; var numCollisions = controller.Cast(moveVec, filter, hits, 0.6f); if (numCollisions == 0 || isGhost || hits[0].rigidbody.isKinematic) { controller.MovePosition(oldPosition + (moveVec * speed * Time.deltaTime)); } if (moveVec.x > 0 && !facingRight || moveVec.x < 0 && facingRight) { transform.Find("Visual").transform.Rotate(new Vector3(0, 180, 0)); if (moveVec.x > 0) { facingRight = true; } else if (moveVec.x < 0) { facingRight = false; } } } }
IEnumerator doDeathState(State p_state) { current_state = State.DEAD; Vector2 velocity = new Vector2(); RaycastHit2D[] hits = new RaycastHit2D[16]; ContactFilter2D filter = new ContactFilter2D(); filter.useTriggers = false; filter.useLayerMask = true; filter.layerMask = walkable_mask; while (true) { velocity += 2.5f * Physics2D.gravity * Time.deltaTime; Vector2 dir = velocity * Time.deltaTime; int count = rb2d.Cast(dir, filter, hits, dir.magnitude); if (count > 0) { break; } rb2d.position += velocity * Time.deltaTime; yield return(new WaitForFixedUpdate()); } while (true) { yield return(new WaitForFixedUpdate()); } }
private float GetGroundYDistance() { float distance = 10000; if (rb2d) { int count = rb2d.Cast(Vector2.down, contactFilter, hitBuffer); for (int i = 0; i < count; i++) { distance = hitBuffer[i].distance < distance ? hitBuffer[i].distance : distance; } //Debug.Log("distance:" + distance); } return(distance); }
void BasicMovement(Vector2 playerVelocity, bool yMovement) { float distance = playerVelocity.magnitude; if (distance > minMoveDistance) { int count = player.Cast(playerVelocity, contactFilter, hitBuffer, distance + shellRadius); hitBufferList.Clear(); for (int i = 0; i < count; i++) { hitBufferList.Add(hitBuffer[i]); } for (int i = 0; i < hitBufferList.Count; i++) { Vector2 currentNoraml = hitBufferList[i].normal; if (currentNoraml.y > minGroundNormalY) { grounded = true; if (yMovement == true) { groundNormal = currentNoraml; currentNoraml.y = 0; } } float projection = Vector2.Dot(player.velocity, currentNoraml); if (projection < 0) { player.velocity = player.velocity - projection * currentNoraml; } float modifiedDistance = hitBufferList[i].distance - shellRadius; distance = modifiedDistance < distance ? modifiedDistance : distance; } } }
void Movement(Vector2 move, bool y_movement) { float distance = move.magnitude; RaycastHit2D[] collisions_buffer = new RaycastHit2D[16]; int collision_count = rb_2d.Cast(move, contact_filter, collisions_buffer, distance + shell_radius); collision_buffer_list.Clear(); for (int i = 0; i < collision_count; i++) { collision_buffer_list.Add(collisions_buffer[i]); //copy the components to a list for a better handling } for (int i = 0; i < collision_buffer_list.Count; i++) { Vector2 current_normal = collision_buffer_list[i].normal; if (current_normal.y > min_ground_normal_y) { grounded = true; velocity.y = 0.0f; } float modified_distance = collision_buffer_list[i].distance - shell_radius; distance = modified_distance < distance ? modified_distance : distance; } rb_2d.position = rb_2d.position + move.normalized * distance; }
private void Move(Vector2 movement) { grounded = false; for (int iter = 0; iter < 5; iter++) { //cast a bit var distance = movement.magnitude; var hitCount = rigidbody.Cast(movement, hits, distance); //if we hit nothing we can fly if (hitCount == 0) { rigidbody.position += movement; return; } //if we do, think about how to continue var hit = hits.First(); if (hit.normal == -movement) { rigidbody.position += movement; return; } if (hit.normal.y > (1 / Mathfs.SQRT2)) //reset fall speed when hitting ground (flatter than 45°) { fallSpeed = Mathfs.Max(fallSpeed, 0); //stop fall when we're on the ground grounded = true; } rigidbody.position += movement.WithMagnitude(hit.distance) + hit.normal * 0.001f; var tangent = hit.normal.Rotate90CW(); movement = movement.WithMagnitude(distance - hit.distance); //take away walked distance movement = tangent * Vector2.Dot(tangent, movement); //align with hit tangent } //didnt find a result in limited iterations rigidbody.position += movement; }
// Update is called once per frame void FixedUpdate() { if (!pause) { velocity -= gravityForce * Time.deltaTime; int numCollisions = rb2D.Cast(Vector3.down, hits, velocity); float distance = Mathf.Abs(velocity); for (int i = 0; i < numCollisions; i++) { //collide with the closest if (hits[i].distance < distance) { distance = hits[i].distance; grounded = true; velocity = 0; targetUp = hits[i].normal; } } if (jump && grounded) { velocity += jumpForce * Time.deltaTime; score += 10; jump = false; grounded = false; } transform.position += Vector3.up * velocity; transform.up = Vector3.Slerp(transform.up, targetUp, Time.deltaTime * 10); } }
public bool IsStandingOnSolidGround() { List <RaycastHit2D> results = new List <RaycastHit2D>(); _rigidbody.Cast(Vector2.down, results, 0.05f); return(results.Count > 0); // TODO better filtering }
void Movement(Vector2 move, bool yMovement) { var distance = move.magnitude; if (distance > minMoveDistance) { var count = rb2d.Cast(move, contactFilter, hitBuffer, distance + shellRadius); for (var i = 0; i < count; i++) { var currentNormal = hitBuffer [i].normal; if (currentNormal.y > minGroundNormalY) { grounded = true; if (yMovement) { groundNormal = currentNormal; currentNormal.x = 0; } } var projection = Vector2.Dot(velocity, currentNormal); if (projection < 0) { velocity = velocity - projection * currentNormal; } var modifiedDistance = hitBuffer [i].distance - shellRadius; distance = modifiedDistance < distance ? modifiedDistance : distance; } } rb2d.position = rb2d.position + move.normalized * distance; }
protected virtual void GroundCheck(Vector2 direction) { RaycastHit2D[] hits = new RaycastHit2D[1]; int hitCount = Rigidbody.Cast(direction.normalized, hits, GroundedDistance); Grounded = hitCount > 0 && hits[0].collider != null; }
public bool requireSpawn() { int count = rgb2d.Cast(-Vector2.up, contactFilter, hitBuffer, shellRadius); var d = new Dictionary <RaycastHit2D, float>(); if (count > 0) { for (int i = 0; i < count; i++) { d.Add(hitBuffer[i], hitBuffer[i].distance); } d.OrderBy(item => item.Value); //var hit = d.First().Key; foreach (var hitData in d) { var hit = hitData.Key; float soilUpperBound = hit.collider.gameObject.GetComponent <Collider2D>().bounds.center.y + hit.collider.gameObject.GetComponent <Collider2D>().bounds.extents.y; float playerLowerBound = GetComponent <BoxCollider2D>().bounds.center.y - GetComponent <BoxCollider2D>().bounds.extents.y; if (hit.collider != null && soilUpperBound <= playerLowerBound) { SpawnerTile st = hit.collider.gameObject.GetComponent <SpawnerTile>(); Vector3 pt = hit.point - Vector2.up * spawnOffset; if (st != null) { // check whether the object hit has a spawnertile component (that means, if it can spawn plants) st.spawnHere(gameObject, pt); // invoke spawn passing the player as arg //StartCoroutine(splat(hit.collider.gameObject)); GameObject.FindGameObjectWithTag("Player").GetComponent <PlayerPosUpdater>().setParams(20, 3.5f, 5f); return(true); } } } } return(false); }
void Movement(Vector2 move, bool yMovement) { float distance = move.magnitude; if (distance > minMoveDistance) { int count = rb2d.Cast(move, contactFilter, hitBuffer, distance + shellRadius); hitbufferList.Clear(); for (int i = 0; i < count; i++) { hitbufferList.Add(hitBuffer[i]); } for (int i = 0; i < hitbufferList.Count; i++) { Vector2 currentNormal = hitbufferList[i].normal; if (currentNormal.y > minGroundNormalY) { grounded = true; if (yMovement) { groundNormal = currentNormal; currentNormal.x = 0; } } float projection = Vector2.Dot(velocity, currentNormal); if (projection < 0) { velocity = velocity - projection * currentNormal; } float modifiedDistance = hitbufferList[i].distance - shellRadius; distance = modifiedDistance < distance ? modifiedDistance : distance; } } rb2d.position = rb2d.position + move.normalized * distance; }
private void Move(Vector2 dir, float d) { if (d < 0) { d *= -1; dir *= -1; } // See if we hit anything if (_Body.Cast(dir, _Hits, d) != 0) { Debug.Assert(_Hits[0].distance <= d); // If we are moving against a wall... if (Vector2.Dot(_Hits[0].normal, dir) < 0) { // Slide along the wall Vector2 tan = Quaternion.Euler(0, 0, 90) * _Hits[0].normal; Vector2 pen = Vector3.Project(dir, tan); var slide = pen * (d - _Hits[0].distance); // slide by remaining penetration d = Mathf.Max(_Hits[0].distance - 0.01f, 0); // truncate "unblocked" movement _Body.MovePosition(_Body.position + dir * d + slide); return; } } // Move player _Body.MovePosition(_Body.position + dir * d); }