Ejemplo n.º 1
0
    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);
    }
Ejemplo n.º 2
0
    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");
        }
    }
Ejemplo n.º 3
0
 public void Add(CollisionState2D s)
 {
     direction.Add(s.direction);
     becameGroundedThisFrame |= s.becameGroundedThisFrame;
     movingDownSlope         |= s.movingDownSlope;
     slopeAngle += s.slopeAngle;
 }
Ejemplo n.º 4
0
 public void Update(CollisionState2D s)
 {
     direction = s.direction;
     becameGroundedThisFrame = s.becameGroundedThisFrame;
     movingDownSlope         = s.movingDownSlope;
     slopeAngle = s.slopeAngle;
 }
Ejemplo n.º 5
0
    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);
    }
Ejemplo n.º 6
0
    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;
                }
            }
        }
    }
Ejemplo n.º 7
0
    public CollisionState2D GetBufferedCollisionState()
    {
        var result = new CollisionState2D();

        foreach (CollisionState2D collisionState in collisionBuffer)
        {
            result.Add(collisionState);
        }

        return(result);
    }
Ejemplo n.º 8
0
    /// <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);
            }
        }
    }
Ejemplo n.º 9
0
    /// <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]);
            }
        }
    }
Ejemplo n.º 10
0
 public void Update(CollisionState2D s)
 {
     state.Update(s);
 }
Ejemplo n.º 11
0
 public CollisionContext(CollisionContext other)
     : base(other)
 {
     state = new CollisionState2D(other.state);
 }
Ejemplo n.º 12
0
 public CollisionContext()
     : base()
 {
     state = new CollisionState2D();
 }
Ejemplo n.º 13
0
 public CollisionState2D(CollisionState2D other)
 {
     Update(other);
 }