private void FixedUpdate()
    {
        if (playerController.Grounded)
        {
            wallNormal   = Vector3.zero;
            parkourState = ParkourState.NONE;
        }

        if (wallJumpRequest)
        {
            wallJumpRequest = false;

            WallJump();
        }

        if (wallRunRequest)
        {
            HandleWallRun();
        }
        else
        {
            parkourState = ParkourState.NONE;
            EndWallRun();
        }
    }
    private void HandleParkour(Collision collision, ContactPoint hit)
    {
        if (hit.normal != wallNormal && (hit.normal.x != 0 || hit.normal.z != 0)) // wallclimb
        {
            var wallAngle   = Vector3.Angle(Vector3.up, hit.normal);
            var playerAngle = Vector3.Angle(transform.forward, -hit.normal);

            if (playerAngle > -25 && playerAngle < 25)
            {
                if (Physics.Raycast(transform.position + (Vector3.up * 0.01f), transform.forward, 1, wallLayer, QueryTriggerInteraction.Ignore))
                {
                    StartParkour(collision, hit, ParkourState.CLIMB);

                    cameraLook.startRot = (int)Quaternion.LookRotation(-wallNormal.normalized).eulerAngles.y;

                    Debug.Log(cameraLook.startRot + " StartRot");
                    cameraLook.wallRunningMode = true;
                }
                else if (!Physics.Raycast(transform.position + (Vector3.up * 2), transform.forward, 2, wallLayer, QueryTriggerInteraction.Ignore))
                {
                    Debug.DrawRay(transform.position + (Vector3.up * 2) + (transform.forward), Vector3.down, Color.red);
                    if (Physics.Raycast(transform.position + (transform.forward), Vector3.down, 2.5f, wallLayer, QueryTriggerInteraction.Ignore))
                    {
                        transform.position = new Vector3(hit.point.x, hit.point.y + 1, hit.point.z);

                        Debug.Log("Climbed");

                        parkourState = ParkourState.NONE;
                    }
                }
            }
            else if (wallAngle > 80 && wallAngle < 110) //wallRun
            {
                if (playerAngle > minSideAngle && playerAngle < maxSideAngle)
                {
                    StartParkour(collision, hit, ParkourState.RUN);

                    bool right = RaycastSides();

                    if (right)
                    {
                        cameraLook.startRot = Quaternion.LookRotation(Vector3.Cross(Vector3.up, wallNormal)).eulerAngles.y;
                    }
                    else
                    {
                        cameraLook.startRot = Quaternion.LookRotation(-Vector3.Cross(Vector3.up, wallNormal)).eulerAngles.y;
                    }

                    cameraLook.wallRunningMode = true;
                }
            }
        }
    }
    private void StartParkour(Collision collision, ContactPoint hit, ParkourState newState)
    {
        CurrentWall = collision.gameObject;
        wallNormal  = hit.normal;

        startedWallRun = true;
        IsOnWall       = true;
        parkourState   = newState;

        rb.useGravity            = false;
        playerController.canMove = false;

        rb.velocity = Vector3.zero;
    }
    private void StartParkour(GameObject nearestWall, Vector3 hitNormal, ParkourState newState)
    {
        CurrentWall = nearestWall;
        wallNormal  = hitNormal;

        startedWallRun = true;
        IsOnWall       = true;
        parkourState   = newState;

        rb.useGravity            = false;
        playerController.canMove = false;

        rb.velocity = Vector3.zero;

        Debug.Log("Started Running");
    }
    private bool RaycastSides()
    {
        RaycastHit hit;
        bool       isRight = true;

        Vector3 wallDirection = Vector3.RotateTowards(-wallNormal, CurrentWall.transform.position, 0, 0);

        Debug.DrawLine(transform.position, transform.position + (wallDirection * wallDist));

        if (Physics.Raycast(transform.position, wallDirection, out hit, wallDist, wallLayer, QueryTriggerInteraction.Ignore))
        {
        }
        else if (Physics.Raycast(transform.position, transform.forward, out hit, wallDist, wallLayer, QueryTriggerInteraction.Ignore))
        {
        }
        else
        {
            if (parkourState == ParkourState.CLIMB)
            {
                if (!Physics.Raycast(transform.position + (Vector3.up * 2), transform.forward, out hit, 2, wallLayer, QueryTriggerInteraction.Ignore))
                {
                    Debug.DrawRay(transform.position + (Vector3.up * 2) + (transform.forward), Vector3.down, Color.red);
                    if (Physics.Raycast(transform.position + (transform.forward * 2f), Vector3.down, out hit, playerController.PlayerHeight / 2.5f, wallLayer, QueryTriggerInteraction.Ignore))
                    {
                        transform.position = new Vector3(hit.point.x, hit.point.y + (playerController.PlayerHeight / 2.5f), hit.point.z);

                        Debug.Log("Climbed");

                        parkourState = ParkourState.NONE;
                    }
                }
            }

            parkourState = ParkourState.NONE;
        }

        float crossed = Vector3.Cross(transform.forward, wallNormal).y;

        if (crossed > 0)
        {
            isRight = false;
        }

        return(isRight);
    }
    public void SwitchCanvas(ParkourState state)
    {
        introCanvas.gameObject.SetActive(false);
        GameplayCanvas.gameObject.SetActive(false);
        ScoringCanvas.gameObject.SetActive(false);
        switch (state)
        {
        case ParkourState.Intro:
            introCanvas.gameObject.SetActive(true);
            parkourNameDisplay.text = ParkourManager.Instance().parkourData.displayName;
            break;

        case ParkourState.Gameplay:
            GameplayCanvas.gameObject.SetActive(true);
            break;

        case ParkourState.Scoring:
            scoringParkourNameDisplay.text = ParkourManager.Instance().parkourData.displayName;
            chronoDisplay.text             = ChronoUI.TimerToChrono(ParkourManager.Instance().GetTimer());
            chronoScoreDisplay.text        = ParkourManager.Instance().TimeScore().ToString();
            Dictionary <int, int> hits = new Dictionary <int, int>();
            int hitsScoreTotal         = 0;
            foreach (int i in Enum.GetValues(typeof(HitFeedback)))
            {
                hits.Add(i, 0);
            }
            foreach (var hit in ParkourManager.Instance().hits)
            {
                hits[(int)hit.feedback]++;
                hitsScoreTotal += hit.score;
            }
            hitsScore.text = hitsScoreTotal.ToString();
            for (int i = 0; i < hitType.Length; i++)
            {
                hitType[i].text = hits[i].ToString();
            }
            totalScore.text = ParkourManager.Instance().score.ToString();
            ScoringCanvas.gameObject.SetActive(true);
            break;
        }
    }
    private void WallJump()
    {
        var wallDir = wallNormal;

        EndWallRun();

        Vector3 jumpDir = Vector3.zero;

        if (parkourState == ParkourState.RUN)
        {
            jumpDir = (transform.forward * 5) + (Vector3.up * 5) + (wallDir * 5);
        }
        else if (parkourState == ParkourState.CLIMB)
        {
            jumpDir = (wallDir * 5) + (Vector3.up * 10);
        }

        rb.AddForce(jumpDir, ForceMode.Impulse);

        parkourState = ParkourState.NONE;
    }
Exemple #8
0
 private void SwitchParkourState(ParkourState state)
 {
     parkourState = state;
     OnParkourSwitchState?.Invoke(parkourState);
 }