コード例 #1
0
    /**
     * // Find out our Y-position on the slope we're currently using
     * float CalculateAltitude(float progress)
     * {
     *      return ground.self.position.y + ground.verticalOffset * ground.self.localScale.y + ground.yScale * ground.slopeCurve.Evaluate(progress) * ground.self.localScale.y;
     * }
     *
     * // Called at each grounded movement
     * bool UpdateSlope()
     * {
     *      float progress = (self.position.x - ground.xMin) / (ground.xMax - ground.xMin);
     *      progress = Mathf.Clamp01(progress);
     *      float yNeeded = CalculateAltitude(progress);
     *
     *      // Manually set our Y-coordinate if we're grounded
     *      if(bottom < yNeeded)
     *      {
     *              self.position = new Vector3(self.position.x, yNeeded + bottomDelta, self.position.z);
     *
     *              if(!collisionFlags.down)
     *              {
     *                      if (onCollisionEnter != null) onCollisionEnter(new RaycastHitPlus());
     *                      if (onVerticalCollisionEnter != null) onVerticalCollisionEnter(new RaycastHitPlus());
     *              }
     *
     *              collisionFlags.down = true;
     *      }
     *      if(self.position.y == yNeeded + bottomDelta) collisionFlags.down = true;
     *
     *      return bottom <= yNeeded;
     * }
     *
     * // Get the angle of the current slope based on the altitude "just behind us" and "just in front of us".
     * float FindAngle()
     * {
     *      if(!ground || ignoreSlopeZones) return 0;
     *
     *      float result = 0;
     *
     *      float prevProgress = (self.position.x - stepSize - ground.xMin) / (ground.xMax - ground.xMin);
     *      prevProgress = Mathf.Clamp01(prevProgress);
     *      float yPrev = CalculateAltitude(prevProgress);
     *
     *      float nextProgress = (self.position.x + stepSize - ground.xMin) / (ground.xMax - ground.xMin);
     *      nextProgress = Mathf.Clamp01(nextProgress);
     *      float yNext = CalculateAltitude(nextProgress);
     *
     *      Vector2 before = new Vector2(self.position.x - stepSize, yPrev);
     *      Vector2 after = new Vector2(self.position.x + stepSize, yNext);
     *      Vector2 curSlope = after-before;
     *
     *      // If we're descending, let's say the angle equals zero (unless we want a slight acceleration, which is rarely the case)
     *      if (Mathf.Sign(curSlope.y) != Mathf.Sign(graphics.localScale.x)) result = 0;
     *      // When ascending, we must get the angle anyway.
     *      else result = Vector2.Angle(Vector2.right, curSlope);
     *
     *      return result;
     * }
     *
     * // Called when we might hit a ceiling. Same logic as UpdateSlope().
     * bool UpdateCeiling()
     * {
     *      float progress = (self.position.x - ceiling.xMin) / (ceiling.xMax - ceiling.xMin);
     *      progress = Mathf.Clamp01(progress);
     *
     *      float yNeeded = (ceiling.self.position.y + ceiling.verticalOffset - ceiling.zoneHeight) + ceiling.yScale * ceiling.ceilingCurve.Evaluate(progress);
     *
     *      if (top > yNeeded)
     *      {
     *              self.position = new Vector3(self.position.x, yNeeded + topDelta, self.position.z);
     *
     *              if(!collisionFlags.up)
     *              {
     *                      if (onCollisionEnter != null) onCollisionEnter(new RaycastHitPlus());
     *                      if (onVerticalCollisionEnter != null) onVerticalCollisionEnter(new RaycastHitPlus());
     *              }
     *
     *              collisionFlags.up = true;
     *      }
     *      if (self.position.y == yNeeded + topDelta) collisionFlags.up = true;
     *
     *      return top >= yNeeded;
     * }
     * /**/
    #endregion

    #region Movement

    private void MoveHorizontally(ref Vector3 deltaMovement)
    {
        float length       = Mathf.Abs(deltaMovement.x) + skinWidth;
        bool  isGoingRight = deltaMovement.x > 0;

        RayDirection   dir    = isGoingRight ? RayDirection.Right : RayDirection.Left;
        RaycastHitPlus result = raycaster.CastRays(dir, length);

        if (result.box != null)
        {
            // stop the horizontal movement as we bumped into something
            deltaMovement.x = 0;

            // flip the collision flags
            if (isGoingRight)
            {
                collisionFlags.right = true;
            }
            else
            {
                collisionFlags.left = true;
            }

            // And finally, call events
            if (onCollisionEnter != null)
            {
                onCollisionEnter(result);
            }
            if (onHorizontalCollisionEnter != null)
            {
                onHorizontalCollisionEnter(result);
            }
        }
    }
コード例 #2
0
    // Could be used for scale and rotation : cast rays in 4 directions simultaneously
    public RaycastHitPlus CastRaysEverywhere(float length)
    {
        RefreshRayOrigins();

        RaycastHitPlus result = CastRays(RayDirection.Left, length, true);

        if (result.box != null)
        {
            return(result);
        }

        result = CastRays(RayDirection.Right, length, true);
        if (result.box != null)
        {
            return(result);
        }

        result = CastRays(RayDirection.Up, length, true);
        if (result.box != null)
        {
            return(result);
        }

        result = CastRays(RayDirection.Down, length, true);
        return(result);
    }
コード例 #3
0
    CharacterController2D FindGround()
    {
        RaycastHitPlus hit = raycaster.CastRays(RayDirection.Down, 5 * skinWidth, true);

        if (hit.box == null)
        {
            return(null);
        }

        return(hit.box.GetComponent <CharacterController2D>());
    }
コード例 #4
0
    private void MoveVertically(ref Vector3 deltaMovement)
    {
        //if (disableVerticalPhysics) return;

        bool  isGoingUp = deltaMovement.y > 0;
        float length    = Mathf.Abs(deltaMovement.y) + skinWidth;

        RayDirection   dir    = isGoingUp ? RayDirection.Up : RayDirection.Down;
        RaycastHitPlus result = raycaster.CastRays(dir, length, false);

        if (result.box)
        {
            // set our new deltaMovement and recalculate the rayDistance taking it into account
            deltaMovement.y = result.hit.point.y - result.ray.y;

            // remember to remove the skinWidth from our deltaMovement
            if (isGoingUp)
            {
                deltaMovement.y  -= skinWidth;
                collisionFlags.up = true;
            }
            else
            {
                deltaMovement.y    += skinWidth;
                collisionFlags.down = true;
            }

            // Watch out, the global event could be called twice (one for horizontal movement, one for vertical movement).
            if (onCollisionEnter != null)
            {
                onCollisionEnter(result);
            }
            if (onVerticalCollisionEnter != null)
            {
                onVerticalCollisionEnter(result);
            }
        }
    }