public Vector2 Move(Vector2 deltaMovement) { prevCollisionState = new CollisionState(collisionState); collisionState.Reset(); if (!ignoreCollisions) { center = position + offset; center.x += Horizontal(ref deltaMovement); center.y += Vertical(ref deltaMovement); } transform.Translate(deltaMovement, Space.World); if (collisionState.slope) { deltaMovement.y = 0; } velocity = deltaMovement / Time.deltaTime; if (collisionState.down && !prevCollisionState.down) { onLanded(); } return(velocity); }
// Update is called once per frame public void Move(Vector2 velocity, Vector2 acceleration) { collisionState.Reset(); HandleVerticalCollisions(ref velocity, ref acceleration); HandleHorizontalCollisions(ref velocity, ref acceleration); transform.Translate(new Vector3(velocity.x, velocity.y) + new Vector3(acceleration.x / 2, acceleration.y / 2)); }
public void Move(Vector3 deltaMovement) { collisionState.Reset(); if (deltaMovement.x != 0f) { MoveHorizontal(ref deltaMovement); } if (deltaMovement.y != 0f) { MoveVertical(ref deltaMovement); } transform.Translate(deltaMovement, Space.World); }
/// <summary> /// attempts to move the object to position + deltaMovement. Any colliders in the way will cause the movement to /// stop when run into. Returns velocity. /// <param name="velo">Velocity.</param> /// </summary> public Vector2 Move(Vector2 velo) { velocity = velo; float deltaTime = Time.deltaTime; Vector2 deltaMovement = velocity * deltaTime; collisionState.onGroundLastFrame = collisionState.onGround; collisionState.Reset(); FindState(); switch (movementState) { case MovementState.Grounded: GroundedMove(ref deltaMovement); break; case MovementState.Upward: UpwardMove(ref deltaMovement); break; case MovementState.Downward: DownwardMove(ref deltaMovement); break; } Vector3 deltaPosition = new Vector3(deltaMovement.x, deltaMovement.y, 0); transform.Translate(deltaPosition, Space.World); if (!collisionState.onGroundLastFrame && collisionState.onGround) { collisionState.becameOnGroundLastFrame = true; } if (deltaTime > 0f) { velocity = deltaMovement / deltaTime; } return(velocity); }
public void TestCollisions(ref Vector2 motion, Rectangle boxColliderBounds, CollisionState collisionState) { _boxColliderBounds = boxColliderBounds; // save off our current grounded state which we will use for wasGroundedLastFrame and becameGroundedThisFrame collisionState.WasGroundedLastFrame = collisionState.Below; // reset our collisions state collisionState.Reset(ref motion); // reset rounded motion for us while dealing with subpixel movement so fetch the rounded values to use for our actual detection var motionX = (int)motion.X; var motionY = (int)motion.Y; // first, check movement in the horizontal dir if (motionX != 0) { var direction = motionX > 0 ? Edge.Right : Edge.Left; var sweptBounds = CollisionRectForSide(direction, motionX); int collisionResponse; if (TestMapCollision(sweptBounds, direction, collisionState, out collisionResponse)) { // react to collision. get the distance between our leading edge and what we collided with motion.X = collisionResponse - boxColliderBounds.GetSide(direction); collisionState.Left = direction == Edge.Left; collisionState.Right = direction == Edge.Right; collisionState._movementRemainderX.Reset(); } else { collisionState.Left = false; collisionState.Right = false; } } // next, check movement in the vertical dir { var direction = motionY >= 0 ? Edge.Bottom : Edge.Top; var sweptBounds = CollisionRectForSide(direction, motionY); sweptBounds.X += (int)motion.X; int collisionResponse; if (TestMapCollision(sweptBounds, direction, collisionState, out collisionResponse)) { // react to collision. get the distance between our leading edge and what we collided with motion.Y = collisionResponse - boxColliderBounds.GetSide(direction); collisionState.Above = direction == Edge.Top; collisionState.Below = direction == Edge.Bottom; collisionState._movementRemainderY.Reset(); if (collisionState.Below && collisionState._lastGroundTile != null && collisionState._lastGroundTile.IsSlope()) { collisionState.SlopeAngle = MathHelper.ToDegrees((float)Math.Atan(collisionState._lastGroundTile.GetSlope())); } } else { collisionState.Above = false; collisionState.Below = false; collisionState._lastGroundTile = null; } // when moving down we also check for collisions in the opposite direction. this needs to be done so that ledge bumps work when // a jump is made but misses by the colliderVerticalInset if (direction == Edge.Bottom) { direction = direction.OppositeEdge(); sweptBounds = CollisionRectForSide(direction, 0); sweptBounds.X += (int)motion.X; sweptBounds.Y += (int)motion.Y; if (TestMapCollision(sweptBounds, direction, collisionState, out collisionResponse)) { // react to collision. get the distance between our leading edge and what we collided with motion.Y = collisionResponse - boxColliderBounds.GetSide(direction); // if we collide here this is an overlap of a slope above us. this small bump down will prevent hitches when hitting // our head on a slope that connects to a solid tile. It puts us below the slope when the normal response would put us // above it motion.Y += 2; collisionState.Above = true; } } } // set our becameGrounded state based on the previous and current collision state if (!collisionState.WasGroundedLastFrame && collisionState.Below) { collisionState.BecameGroundedThisFrame = true; } }