public CollisionState2D CheckProximity(float distance, Direction2D mask) { var proximityCollision = new CollisionState2D(); // Check below if (FlagsHelper.IsSet(mask, Direction2D.DOWN)) { proximityCollision.Below = CheckBelow(distance, data.skinWidth); } // Check above if (FlagsHelper.IsSet(mask, Direction2D.UP)) { proximityCollision.Above = CheckAbove(distance, data.skinWidth); } // Check right. if (FlagsHelper.IsSet(mask, Direction2D.RIGHT)) { proximityCollision.Right = CheckRight(distance, data.skinWidth); } // Check left if (FlagsHelper.IsSet(mask, Direction2D.LEFT)) { proximityCollision.Left = CheckLeft(distance, data.skinWidth); } return(proximityCollision); }
public void SetPlayerState(Vector3 velocity, CollisionState2D state) { if ((isMovingRight && velocity.x < -directJudge) || (!isMovingRight && velocity.x > directJudge)) { transform.localScale = new Vector3(-transform.localScale.x, transform.localScale.y, transform.localScale.z); isMovingRight = !isMovingRight; } if (state.below && Mathf.Abs(velocity.x) > moveJudge) { if (anim.GetCurrentAnimatorClipInfo(0)[0].clip.name != "Player_Run") { anim.Play("Player_Run"); } } else if (!state.below && state.wasGroundLastFrame) { anim.Play("Player_JumpStart"); //audioSource.Play(); } else if (state.below && !state.wasGroundLastFrame) { anim.Play("Player_JumpLand"); } else if (state.below && velocity.magnitude < moveJudge) { anim.Play("Player_Idle"); } }
public void Add(CollisionState2D s) { direction.Add(s.direction); becameGroundedThisFrame |= s.becameGroundedThisFrame; movingDownSlope |= s.movingDownSlope; slopeAngle += s.slopeAngle; }
public void Update(CollisionState2D s) { direction = s.direction; becameGroundedThisFrame = s.becameGroundedThisFrame; movingDownSlope = s.movingDownSlope; slopeAngle = s.slopeAngle; }
public CollisionState2D CheckProximity(float distance, Direction2D mask) { var proximityCollision = new CollisionState2D(); // Check below if (FlagsHelper.IsSet(mask, Direction2D.DOWN)) { proximityCollision.Below = Check(Constants.Directions.DOWN, distance); } // Check above if (FlagsHelper.IsSet(mask, Direction2D.UP)) { proximityCollision.Above = Check(Constants.Directions.UP, distance); } // Check right. if (FlagsHelper.IsSet(mask, Direction2D.RIGHT)) { proximityCollision.Right = Check(Constants.Directions.RIGHT, distance); } // Check left if (FlagsHelper.IsSet(mask, Direction2D.LEFT)) { proximityCollision.Left = Check(Constants.Directions.LEFT, distance); } return(proximityCollision); }
private void moveVertically(ref Vector3 deltaMovement, CollisionState2D oldCollisionState) { var isGoingUp = deltaMovement.y > 0; var rayDistance = Mathf.Abs(deltaMovement.y) + data.skinWidth; var rayDirection = isGoingUp ? Vector2.up : -Vector2.up; var initialRayOrigin = isGoingUp ? _raycastOrigins.topLeft : _raycastOrigins.bottomLeft; // apply our horizontal deltaMovement here so that we do our raycast from the actual position we would be in if we had moved initialRayOrigin.x += deltaMovement.x; // if we are moving up, we should ignore the layers in oneWayPlatformMask var mask = data.platformMask; if (isGoingUp && !oldCollisionState.Below) { mask &= ~data.oneWayPlatformMask; } for (var i = 0; i < data.totalVerticalRays; i++) { var ray = new Vector2(initialRayOrigin.x + i * _horizontalDistanceBetweenRays, initialRayOrigin.y); DrawRay(ray, rayDirection * rayDistance, Color.blue); _raycastHit = Physics2D.Raycast(ray, rayDirection, rayDistance, mask); if (_raycastHit) { // set our new deltaMovement and recalculate the rayDistance taking it into account deltaMovement.y = _raycastHit.point.y - ray.y; rayDistance = Mathf.Abs(deltaMovement.y); // remember to remove the skinWidth from our deltaMovement if (isGoingUp) { deltaMovement.y -= data.skinWidth; collision.Above = true; } else { deltaMovement.y += data.skinWidth; collision.Below = true; } _raycastHitsThisFrame.Add(_raycastHit); // this is a hack to deal with the top of slopes. if we walk up a slope and reach the apex we can get in a situation // where our ray gets a hit that is less then skinWidth causing us to be ungrounded the next frame due to residual velocity. if (!isGoingUp && deltaMovement.y > 0.00001f) { _isGoingUpSlope = true; } } } }
public CollisionState2D GetBufferedCollisionState() { var result = new CollisionState2D(); foreach (CollisionState2D collisionState in collisionBuffer) { result.Add(collisionState); } return(result); }
/// <summary> /// we have to use a bit of trickery in this one. The rays must be cast from a small distance inside of our /// collider (skinWidth) to avoid zero distance rays which will get the wrong normal. Because of this small offset /// we have to increase the ray distance skinWidth then remember to remove skinWidth from deltaMovement before /// actually moving the player /// </summary> private void moveHorizontally(ref Vector3 deltaMovement, CollisionState2D oldCollisionState) { var isGoingRight = deltaMovement.x > 0; var rayDistance = Mathf.Abs(deltaMovement.x) + data.skinWidth; var rayDirection = isGoingRight ? Vector2.right : -Vector2.right; var initialRayOrigin = isGoingRight ? _raycastOrigins.bottomRight : _raycastOrigins.bottomLeft; for (var i = 0; i < data.totalHorizontalRays; i++) { var ray = new Vector2(initialRayOrigin.x, initialRayOrigin.y + i * _verticalDistanceBetweenRays); DrawRay(ray, rayDirection * rayDistance, Color.red); // if we are grounded we will include oneWayPlatforms only on the first ray (the bottom one). this will allow us to // walk up sloped oneWayPlatforms if (i == 0 && oldCollisionState.Below) { _raycastHit = Physics2D.Raycast(ray, rayDirection, rayDistance, data.platformMask); } else { _raycastHit = Physics2D.Raycast(ray, rayDirection, rayDistance, data.platformMask & ~data.oneWayPlatformMask); } if (_raycastHit) { // the bottom ray can hit slopes but no other ray can so we have special handling for those cases if (i == 0 && handleHorizontalSlope(ref deltaMovement, Vector2.Angle(_raycastHit.normal, Vector2.up))) { _raycastHitsThisFrame.Add(_raycastHit); break; } // set our new deltaMovement and recalculate the rayDistance taking it into account deltaMovement.x = _raycastHit.point.x - ray.x; rayDistance = Mathf.Abs(deltaMovement.x); // remember to remove the skinWidth from our deltaMovement if (isGoingRight) { deltaMovement.x -= data.skinWidth; collision.Right = true; } else { deltaMovement.x += data.skinWidth; collision.Left = true; } _raycastHitsThisFrame.Add(_raycastHit); } } }
/// <summary> /// attempts to move the character to position + deltaMovement. Any colliders in the way will cause the movement to /// stop when run into. /// </summary> /// <param name="deltaMovement">Delta movement.</param> public void Move(Vector3 deltaMovement) { // save off our current grounded state which we will use for becameGroundedThisFrame var oldCollisionState = new CollisionState2D(collision); // clear our state collision.Reset(); _raycastHitsThisFrame.Clear(); _isGoingUpSlope = false; var desiredPosition = entity.Position + deltaMovement; primeRaycastOrigins(desiredPosition, deltaMovement); // first, we check for a slope below us before moving // only check slopes if we are going down and grounded if (deltaMovement.y < 0 && oldCollisionState.Below) { handleVerticalSlope(ref deltaMovement); } // now we check movement in the horizontal dir if (Mathf.Abs(deltaMovement.x) > 0) { moveHorizontally(ref deltaMovement, oldCollisionState); } // next, check movement in the vertical dir if (Mathf.Abs(deltaMovement.y) > 0) { moveVertically(ref deltaMovement, oldCollisionState); } // move then update our state if (data.usePhysicsForMovement) { rigidBody.MovePosition(entity.Position + deltaMovement); velocity = rigidBody.velocity; } else { //transform.Translate( deltaMovement, Space.World ); var newPosition = entity.Position + deltaMovement; entity.SetPosition(newPosition); // only calculate velocity if we have a non-zero deltaTime if (FrameCounter.Instance.deltaTime > 0) { velocity = deltaMovement / FrameCounter.Instance.deltaTime; } } // After translation, update proximity check so collision state is fresh. // Without this, collision state doesn't get updated if there's no delta movement. collision = CheckProximity(data.skinWidth * 2, Direction2D.ALL); // Add to the collision buffer. collisionBuffer.AddFirst(new CollisionState2D(collision)); if (collisionBuffer.Count > data.collisionBufferMax) { collisionBuffer.RemoveLast(); } // set our becameGrounded state based on the previous and current collision state if (!oldCollisionState.Below && collision.Below) { collision.becameGroundedThisFrame = true; } // if we are going up a slope we artificially set a y velocity so we need to zero it out here if (_isGoingUpSlope) { velocity.y = 0; } // send off the collision events if we have a listener if (OnControllerCollidedEvent != null) { for (var i = 0; i < _raycastHitsThisFrame.Count; i++) { OnControllerCollidedEvent(_raycastHitsThisFrame[i]); } } }
public void Update(CollisionState2D s) { state.Update(s); }
public CollisionContext(CollisionContext other) : base(other) { state = new CollisionState2D(other.state); }
public CollisionContext() : base() { state = new CollisionState2D(); }
public CollisionState2D(CollisionState2D other) { Update(other); }