Untitled

 avatar
unknown
plain_text
24 days ago
30 kB
1
Indexable
using System.Collections;
using UnityEngine;
using UnityEngine.Tilemaps;

public class PlayerController : MonoBehaviour
{
    [Header("Movement Settings")]
    public float speed;
    public float jump;
    public float maxJumpTime;
    public float jumpMultiplier;
    public LayerMask groundLayer;
    public Transform groundCheck;

    [Header("Attack Settings")]
    public GameObject meleeCheck;
    public GameObject projectilePrefab;
    public Transform shootPoint;
    public float projectileSpeed = 10f;

    [Header("Miscellaneous")]
    public GameObject fallDetector;
    public AudioClip jumpClip;
    public AudioClip atkClip;

    private CapsuleCollider2D boxCollider2d;
    private Rigidbody2D rigidbody2D;
    private Animator anim;
    private AudioSource audioPlayer;
    private SpriteRenderer spriteRenderer;
    private bool facingRight = true;
    public bool isJumping;
    public float currentJumpTime;
    public bool grounded = true;
    private bool isAttacking = false;
    public bool canShoot;
    [SerializeField] private GameObject OneWayHitCheck;

    private IEnvironmentModifier currentEnvironment;

    [SerializeField] private float wallCheckDistance = 0.5f; // Distance for wall detection
    [SerializeField] private LayerMask wallLayer;           // Layer for walls

    private bool isTouchingWall;


    private Vector2 slopeNormalPerp;
    private float slopeDownAngle;
    private float slopeSideAngle;
    private float lastSlopeAngle;
    public bool canMagicMeat;
    [SerializeField]
    private PhysicsMaterial2D noFriction;
    [SerializeField]
    private PhysicsMaterial2D fullFriction;
    //slopes
    [SerializeField]
    private float slopeCheckDistance;
    [SerializeField]
    private float maxSlopeAngle;
    [SerializeField]
    private bool isOnSlope;
    [SerializeField]
    private bool canWalkOnSlope;

    //platform
    public bool isOnPlatform;
    public Rigidbody2D platformRb;

    //double jump powerup
    public bool canDoubleJump;
    public bool ShouldDoubleJump = true;
    private Vector2 newVelocity;
    private Vector2 newForce;
    public bool faceRight = true;
    public bool isOnIce = false;
    void Awake()
    {
        boxCollider2d = GetComponent<CapsuleCollider2D>();
        rigidbody2D = GetComponent<Rigidbody2D>();
        anim = GetComponent<Animator>();
        audioPlayer = GetComponent<AudioSource>();
        meleeCheck.SetActive(false);
        //headCollider = transform.Find("headCheck").GetComponent<BoxCollider2D>();

        spriteRenderer = GetComponent<SpriteRenderer>();
        if(spriteRenderer.size == new Vector2(-4, 4))
        {
            faceRight = false;
        }
        else
        {
            faceRight = true;
        }
    }

    private void Update()
    {
        grounded = IsTouchingGround();
        isTouchingWall = IsTouchingWall();
        HandleAttack();
        HandleJump();
    }

    void FixedUpdate()
    {
        Debug.Log("Grounded: " + grounded);
        if (grounded)
        {
            SlopeCheck();
        }
        
        HandleMovement();
        
        
        
        
        
        
        if (currentEnvironment != null)
        {
            currentEnvironment.ApplyModifier(this);
            
        }
        
    }

    private void HandleMovement()
    {
        
        float inputHorizontal = Input.GetAxisRaw("Horizontal");
            if (currentEnvironment is not WaterModifier)
            {
                if (isOnIce && grounded) //Ice physics
                {
                    ApplyIceEffects(inputHorizontal);
                }

                if (grounded && isOnSlope && canWalkOnSlope && !isJumping)
                {
                    HandleSlopeMovement(inputHorizontal);
                }
                else if (grounded && !isOnSlope && !isJumping && !isTouchingWall)
                {
                    HandleFlatMovement(inputHorizontal);
                }

                else if (!grounded)
                {
                    rigidbody2D.velocity = new Vector2(inputHorizontal * speed, rigidbody2D.velocity.y);
                }
                if (!grounded && !isTouchingWall)
                {
                    rigidbody2D.velocity = new Vector2(inputHorizontal * speed, rigidbody2D.velocity.y);
                }

            }


            // Sprite flip logic
            if (inputHorizontal > 0 && !facingRight)
            {
                Flip();
            }
            else if (inputHorizontal < 0 && facingRight)
            {
                Flip();
            }

            anim.SetBool("Run", inputHorizontal != 0);
        
    }


    private void ApplyIceEffects(float inputHorizontal)
    {
        if (!grounded) return; // Skip ice effects if airborne

        if (isOnSlope)
        {
            // Calculate the slope's tangent direction
            Vector2 slopeDirection = slopeNormalPerp.normalized;
            Debug.Log("slope direction " + slopeDirection);
            if (inputHorizontal != 0)
            {
                // Move along the slope based on input direction
                float moveDirection = Mathf.Sign(inputHorizontal); // +1 for right, -1 for left
                Vector2 targetVelocity = slopeDirection * (moveDirection * speed);
                rigidbody2D.velocity = Vector2.Lerp(rigidbody2D.velocity, targetVelocity, 0.1f);
                rigidbody2D.gravityScale = 1;
            }
            else
            {
                // Project velocity onto the slope's tangent for consistent sliding
                float projectedVelocity = Vector2.Dot(rigidbody2D.velocity, slopeDirection);
                Debug.Log("PROJECTED vELOCITY :" + projectedVelocity);
                Vector2 slideVelocity = slopeDirection * projectedVelocity;

                // Apply deceleration to stop sliding over time
                if (Mathf.Abs(projectedVelocity) < 0.1f)
                {
                    rigidbody2D.velocity = Vector2.zero; // Stop sliding completely
                    rigidbody2D.gravityScale = 0;
                }
                else
                {
                    Debug.Log("Sliding!" + slideVelocity * 0.95f);
                    rigidbody2D.velocity = slideVelocity * 0.95f; // Gradual deceleration
                    rigidbody2D.gravityScale = 1;
                }
            }
        }
        else
        {
            // Flat ground: consistent ice physics
            if (inputHorizontal == 0)
            {
                // Gradual deceleration when idle
                if (Mathf.Abs(rigidbody2D.velocity.x) < 0.1f)
                {
                    rigidbody2D.velocity = new Vector2(0, rigidbody2D.velocity.y);
                }
                else
                {
                    Debug.Log("Sliding!" + new Vector2(
                        rigidbody2D.velocity.x * 0.98f,
                        rigidbody2D.velocity.y
                    ));

                    rigidbody2D.velocity = new Vector2(
                        rigidbody2D.velocity.x * 0.98f,
                        rigidbody2D.velocity.y
                    );
                }
            }
            else
            {
                // Smooth movement based on input
                Vector2 targetVelocity = new Vector2(inputHorizontal * speed, rigidbody2D.velocity.y);
                Debug.Log("targetedVelocity: " + targetVelocity);
                rigidbody2D.velocity = Vector2.Lerp(rigidbody2D.velocity, targetVelocity, 0.1f);
            }
        }
    }




    private void HandleFlatMovement(float inputHorizontal)
    {
        if (isOnIce)
        {
            //ApplyIceEffects(inputHorizontal);
        }
        else
        {
            rigidbody2D.sharedMaterial = noFriction;
            Vector2 newVelocity = new Vector2(
                    inputHorizontal * speed,
                    rigidbody2D.velocity.y > 0 ? 0 : rigidbody2D.velocity.y // Prevent upward launch
                ); // Prevent upward launch
            rigidbody2D.velocity = newVelocity;
            rigidbody2D.gravityScale = 1;
        }                 
        

        if (inputHorizontal > 0 && !facingRight)
        {
            Flip();
        }
        else if (inputHorizontal < 0 && facingRight)
        {
            Flip();
        }
        anim.SetBool("Run", inputHorizontal != 0);
    }

    private void HandleSlopeMovement(float inputHorizontal)
{
    if (inputHorizontal == 0)
    {
        // When stationary
        if (isOnIce)
        {
            ApplyIceEffects(inputHorizontal);
        }
        if (isOnSlope)
        {
            // Apply friction to prevent sliding on slopes
            rigidbody2D.sharedMaterial = fullFriction;
            rigidbody2D.velocity = Vector2.zero;
            rigidbody2D.gravityScale = 0; // Disable gravity when stationary on a slope
        }
        else
        {
            // Flat ground behavior
            rigidbody2D.sharedMaterial = fullFriction;
            rigidbody2D.velocity = Vector2.zero;
            rigidbody2D.gravityScale = 1; // Enable normal gravity
        }
    }
    else
    {
        // When moving
        rigidbody2D.sharedMaterial = noFriction;

        if (isOnSlope && slopeDownAngle > 0)
        {
            // Align velocity with slope
            newVelocity.Set(
                speed * slopeNormalPerp.x * -inputHorizontal,
                Mathf.Clamp(speed * slopeNormalPerp.y * -inputHorizontal, -5f,0)
            );
            rigidbody2D.velocity = newVelocity;
            rigidbody2D.gravityScale = 1; // Ensure normal gravity during movement
        }
        else
        {
            // Flat ground or non-slope movement
            newVelocity.Set(speed * inputHorizontal, 0f);
            rigidbody2D.velocity = newVelocity;
            rigidbody2D.gravityScale = 1;
        }
    }
}



    private void HandleJump()
    {
        //grounded = IsTouchingGround();
        
        if (currentEnvironment is not WaterModifier)
        {
            if (Input.GetButtonDown("Jump"))
            {
                if (grounded)
                {
                    isOnSlope = false;
                    isOnIce = false;
                    Debug.Log("Begun Jump");
                    ShouldDoubleJump = true;
                    // Jump only when grounded
                    isJumping = true;
                    currentJumpTime = 0f;
                    audioPlayer.PlayOneShot(jumpClip);
                }
                else if (isTouchingWall && !isJumping)
                
                {
                    isJumping = true;
                    currentJumpTime = 0f;
                    rigidbody2D.velocity = new Vector2(rigidbody2D.velocity.x, jump);
                    audioPlayer.PlayOneShot(jumpClip);
                }
                else if (ShouldDoubleJump && canDoubleJump && !isJumping && rigidbody2D.velocity.y > 0)
                {
                    ShouldDoubleJump = false;
                    isJumping = true;
                    currentJumpTime = 0f;
                    rigidbody2D.velocity = new Vector2(rigidbody2D.velocity.x, jump);
                    audioPlayer.PlayOneShot(jumpClip);
                    
                }

                if (Input.GetButton("Jump") && isJumping)
                {
                    if (currentJumpTime < maxJumpTime)
                    {
                        Debug.Log("Current Jump Time" + currentJumpTime);
                        rigidbody2D.velocity = new Vector2(rigidbody2D.velocity.x, jump + (currentJumpTime * jumpMultiplier));
                        currentJumpTime += Time.deltaTime;
                    }
                    else
                    {
                        Debug.Log("Max Jump Time");
                        isJumping = false;

                    }
                }
                if (Input.GetButtonUp("Jump"))
                {
                    isJumping = false;
                    Debug.Log("Not Jumping");
                }
                // Ceiling detection to cancel jump
                if (IsTouchingCeiling())
                {
                    Debug.Log("Touched Ceiling");
                    rigidbody2D.velocity = new Vector2(rigidbody2D.velocity.x, 0); // Cancel vertical velocity
                    currentJumpTime = maxJumpTime;
                    isJumping = false; // Stop the jump
                }
            }
            // Hold jump to increase height
            if (Input.GetButton("Jump") && isJumping)
            {
                if (currentJumpTime < maxJumpTime)
                {
                    rigidbody2D.velocity = new Vector2(rigidbody2D.velocity.x, jump + (currentJumpTime * jumpMultiplier));
                    currentJumpTime += Time.deltaTime;
                }
                else
                {
                    isJumping = false;
                }
            }


            // Release jump button
            if (Input.GetButtonUp("Jump"))
            {
                isJumping = false;
            }

            if (!grounded)
            {
                rigidbody2D.sharedMaterial = noFriction;
                rigidbody2D.gravityScale = 1;
            }
        }
        anim.SetBool("grounded", grounded);
    }

    private bool IsTouchingGround()
    {

        float yOffset = boxCollider2d.bounds.size.y / 2f;
        float xOffset = boxCollider2d.bounds.size.x / 2f;
        Vector2 bottomLeft = new Vector2(transform.position.x - xOffset, transform.position.y - yOffset);
        Vector2 bottomRight = new Vector2(transform.position.x + xOffset, transform.position.y - yOffset);
        float rayLength = 0.1f; // Adjust the ray length as needed
        bool notTouchingGround = (!isJumping && (currentJumpTime >= maxJumpTime) && (rigidbody2D.velocity.y > 0));
        Vector2 bottomCenter = new Vector2(transform.position.x, transform.position.y - yOffset);

        // Perform a box cast straight down from the bottom center of the player
        RaycastHit2D[] hits = Physics2D.BoxCastAll(bottomCenter, new Vector2(xOffset * 2, rayLength), 0f, Vector2.down, rayLength, groundLayer);

        // Visualize the box cast in the Scene view
        Debug.DrawRay(bottomCenter, Vector2.down * rayLength, Color.red);

        foreach (var hit in hits)
        {
            // Return true if the box cast hits the ground
            if (hit.collider != null)
            {
                //Debug.Log(hit.collider.gameObject.tag);
                if (hit.collider.gameObject.CompareTag("Ice"))
                {
                    Debug.Log("Is on Ice");
                    isOnIce = true;
                }
                else
                {
                    isOnIce = false;
                }

                // Add a condition to allow jumping through one-way platforms
                if (hit.collider.gameObject.layer == 3)
                {
                    // Handle one-way platforms in a Tilemap
                    if (hit.collider is CompositeCollider2D compositeCollider)
                    {
                        Tilemap tilemap = hit.collider.GetComponent<Tilemap>();
                        if (tilemap != null)
                        {
                            // Check tiles under both bottom corners
                            Vector3Int leftTilePosition = tilemap.WorldToCell(bottomLeft);
                            Vector3Int rightTilePosition = tilemap.WorldToCell(bottomRight);

                            TileBase leftTile = tilemap.GetTile(leftTilePosition);
                            TileBase rightTile = tilemap.GetTile(rightTilePosition);

                            // Ensure both corners are above tiles
                            if (leftTile != null && rightTile != null)
                            {
                                Vector3 leftTileWorldPosition = tilemap.GetCellCenterWorld(leftTilePosition);
                                Vector3 rightTileWorldPosition = tilemap.GetCellCenterWorld(rightTilePosition);

                                // Check for PlatformEffector2D components in the Tilemap
                                PlatformEffector2D leftEffector = tilemap.GetComponent<PlatformEffector2D>();
                                PlatformEffector2D rightEffector = tilemap.GetComponent<PlatformEffector2D>();

                                
                                Debug.Log("Not touching ground: " + notTouchingGround);
                                // Skip tiles with upward-facing Platform Effectors during upward movement
                                if (notTouchingGround)
                                {
                                    if ((leftEffector != null && Mathf.Approximately(leftEffector.rotationalOffset, 0f)) ||
                                        (rightEffector != null && Mathf.Approximately(rightEffector.rotationalOffset, 0f)))
                                    {
                                        Debug.Log("Plateforme");
                                        return false;
                                    }

                                    if ((transform.position.y - boxCollider2d.bounds.size.y) > leftTileWorldPosition.y &&
                                            (transform.position.y - boxCollider2d.bounds.size.y) > rightTileWorldPosition.y)
                                    {
                                        Debug.Log("Sur le sol");
                                        return true;
                                    }
                                }
                                else
                                {
                                    Debug.Log("Pas de sol");
                                    return false;
                                }
                                
                            }
                        }
                    }
                    // Handle other one-way platforms or solid ground
                    else if (hit.collider.TryGetComponent(out PlatformEffector2D effector))
                    {
                        if (currentJumpTime >= maxJumpTime &&
                            (transform.position.y - boxCollider2d.bounds.size.y) > hit.collider.bounds.max.y - 0.01f &&
                            bottomLeft.y > hit.collider.bounds.max.y - 0.01f &&
                            bottomRight.y > hit.collider.bounds.max.y - 0.01f)
                        {
                            Debug.Log("Plateforme solide");
                            return true;
                        }
                    }
                    else
                    {
                        // Handle solid ground
                        if (bottomLeft.y > hit.collider.bounds.max.y - 0.01f &&
                            bottomRight.y > hit.collider.bounds.max.y - 0.01f)
                        {
                            Debug.Log("Sol solide");
                            return true;
                        }
                    }



                }

                anim.SetBool("grounded", hit.collider != null);
                // Return true if the box cast hits the ground
                return hit.collider != null;
            }
        }
        return false;
    }

    private void HandleAttack()
    {
        if (Input.GetButtonDown("Fire2") && !isAttacking)
        {
            anim.SetTrigger("Attack2");
            StartCoroutine(DoAttack());
            if (canShoot)
            {
                ShootProjectile();
            }
        }
    }

    IEnumerator DoAttack()
    {
        isAttacking = true;
        meleeCheck.SetActive(true);
        audioPlayer.PlayOneShot(atkClip);

        yield return new WaitForSeconds(0.3f);

        isAttacking = false;
        meleeCheck.SetActive(false);
    }

    private void Flip()
    {
        facingRight = !facingRight;
        Vector3 currentScale = transform.localScale;
        currentScale.x *= -1;
        transform.localScale = currentScale;
    }

    private void OnTriggerEnter2D(Collider2D collision)
    {
        if (collision.TryGetComponent<IEnvironmentModifier>(out var modifier))
        {
            currentEnvironment = modifier;
        }
    }

    private void OnTriggerExit2D(Collider2D collision)
    {
        if (collision.TryGetComponent<IEnvironmentModifier>(out var modifier) && modifier == currentEnvironment)
        {
            currentEnvironment = null;
        }
    }

    private bool IsTouchingCeiling()
    {
        float yOffset = boxCollider2d.bounds.extents.y;
        float xOffset = boxCollider2d.bounds.extents.x;
        Vector2 topLeft = new Vector2(transform.position.x - xOffset, transform.position.y + yOffset);
        Vector2 topRight = new Vector2(transform.position.x + xOffset, transform.position.y + yOffset);

        RaycastHit2D[] hits = Physics2D.BoxCastAll(topLeft, new Vector2(boxCollider2d.bounds.size.x, 0.1f), 0f, Vector2.up, 0.1f, groundLayer);

        foreach (var hit in hits)
        {
            if (hit.collider != null)
            {
                // Skip upward-facing Platform Effectors during upward movement
                if (hit.collider.TryGetComponent(out PlatformEffector2D effector))
                {
                    if (Mathf.Approximately(effector.rotationalOffset, 0f) && rigidbody2D.velocity.y > 0)
                    {
                        Debug.Log("Plateforme");
                        return false ;
                    }
                }
                else if (hit.collider is CompositeCollider2D compositeCollider)
                {
                    Tilemap tilemap = hit.collider.GetComponent<Tilemap>();
                    if (tilemap != null)
                    {
                        Vector3Int tilePosition = tilemap.WorldToCell(transform.position + new Vector3(0, yOffset + 0.05f, 0));

                        TileBase tile = tilemap.GetTile(tilePosition);
                        if (tile != null)
                        {
                            PlatformEffector2D tileEffector = tilemap.GetComponent<PlatformEffector2D>();

                            // Skip tiles with upward-facing Platform Effectors during upward movement
                            if (tileEffector != null && Mathf.Approximately(tileEffector.rotationalOffset, 0f) && rigidbody2D.velocity.y > 0)
                            {
                                Debug.Log("Plateforme");
                                continue;
                            }

                            Vector3 tileWorldPosition = tilemap.GetCellCenterWorld(tilePosition);
                            if (transform.position.y < tileWorldPosition.y)
                            {
                                Debug.Log("Plafond!");
                                return true;
                            }
                        }
                    }
                }
                else
                {
                    // Handle solid objects
                    if (topLeft.y < hit.collider.bounds.min.y && topRight.y < hit.collider.bounds.min.y)
                    {
                        Debug.Log("Plafond Solide!");
                        return true;
                    }
                }
            }
        }

        return false;
    }
    private bool IsTouchingWall()
    {
        // Cast ray to the left and right of the player
        Vector2 position = transform.position;

        RaycastHit2D wallHitLeft = Physics2D.Raycast(position, Vector2.left, wallCheckDistance, wallLayer);
        RaycastHit2D wallHitRight = Physics2D.Raycast(position, Vector2.right, wallCheckDistance, wallLayer);

        Debug.DrawRay(position, Vector2.left * wallCheckDistance, Color.red);  // Visualize left ray
        Debug.DrawRay(position, Vector2.right * wallCheckDistance, Color.red); // Visualize right ray

        // Check if the left wall is not an upward-facing Platform Effector
        bool wallOnLeft = wallHitLeft.collider != null &&
                          (!wallHitLeft.collider.TryGetComponent(out PlatformEffector2D effectorLeft) ||
                           !Mathf.Approximately(effectorLeft.rotationalOffset, 0f));

        // Check if the right wall is not an upward-facing Platform Effector
        bool wallOnRight = wallHitRight.collider != null &&
                           (!wallHitRight.collider.TryGetComponent(out PlatformEffector2D effectorRight) ||
                            !Mathf.Approximately(effectorRight.rotationalOffset, 0f));
        Debug.Log("Murs: " + (wallOnLeft || wallOnRight));
        return wallOnLeft || wallOnRight;
    }


    void ShootProjectile()
    {
        if (projectilePrefab != null && shootPoint != null)
        {
            // Instantiate the projectile at the shootPoint position and rotation
            GameObject newProjectile = Instantiate(projectilePrefab.gameObject, shootPoint.position, shootPoint.rotation);
            PlayerProjectle playerProjectle = newProjectile.GetComponent<PlayerProjectle>();
            Debug.Log("Tir");
            // Calculate the direction of the projectile
            Vector2 shootDirection = facingRight ? Vector2.right : Vector2.left;
            playerProjectle.facingRight = facingRight ? true : false;
            // Access the projectile's Rigidbody2D component
            Rigidbody2D projectileRigidbody = playerProjectle.GetComponent<Rigidbody2D>();
            if (projectileRigidbody != null)
            {
                // Apply force to the projectile in the shoot direction
                //playerProjectle.maxDistance += Math.Abs(rigidbody2D.velocity.x/2);
                projectileRigidbody.velocity = shootDirection * playerProjectle.speed + rigidbody2D.velocity;
                Debug.Log("Vitesse projectile:" + projectileRigidbody.velocity);
            }
        }
    }
    //Slope methods
    private void SlopeCheck()
    {
        // Position at the player's feet (adjusted to align with bottom edge)
        Vector2 checkPos = (Vector2)transform.position - new Vector2(0f, boxCollider2d.bounds.extents.y);

        // Perform horizontal and vertical slope checks
        SlopeCheckHorizontal(checkPos);
        SlopeCheckVertical(checkPos);
        
        if (isOnSlope)
        {
            Debug.Log("Is on Slope");
            rigidbody2D.sharedMaterial = fullFriction;
            Debug.Log("SlopeNormalPerp:" + slopeNormalPerp.x + ", " + slopeNormalPerp.y);
        }
        else
        {
            Debug.Log("Not on Slope");
        }
    }

    private void SlopeCheckHorizontal(Vector2 checkPos)
    {
        RaycastHit2D slopeHitFront = Physics2D.Raycast(checkPos, transform.right, slopeCheckDistance*2, groundLayer);
        RaycastHit2D slopeHitBack = Physics2D.Raycast(checkPos, -transform.right, slopeCheckDistance*2, groundLayer);

        Debug.DrawRay(checkPos, transform.right * slopeCheckDistance, Color.red);
        Debug.DrawRay(checkPos, -transform.right * slopeCheckDistance, Color.blue);

        if (slopeHitFront || slopeHitBack)
        {
            slopeSideAngle = slopeHitFront ? Vector2.Angle(slopeHitFront.normal, Vector2.up) : Vector2.Angle(slopeHitBack.normal, Vector2.up);
            if (slopeSideAngle <= maxSlopeAngle)
            {
                Debug.Log("Is On Slope H");
                isOnSlope = true;


                Debug.Log("slope side angle " + slopeSideAngle);
                return;
            }
            

        }
        else
        {
            Debug.Log("Is not on slope H");
            slopeSideAngle = 0f;
            isOnSlope = false;
        }
    }

    private void SlopeCheckVertical(Vector2 checkPos)
    {
        float colliderWidth = boxCollider2d.bounds.size.x;
        int rayCount = 5; // Number of rays to cast
        float raySpacing = colliderWidth / (rayCount - 1);
        float rayStartOffset = -colliderWidth / 2; // Start at the left of the collider

        slopeDownAngle = 0f; // Reset slope angle
        isOnSlope = false;   // Reset slope state
        canWalkOnSlope = false;

        for (int i = 0; i < rayCount; i++)
        {
            // Calculate the position for this ray
            Vector2 rayOrigin = checkPos + new Vector2(rayStartOffset + (i * raySpacing), 0);
            RaycastHit2D hit = Physics2D.Raycast(rayOrigin, Vector2.down, slopeCheckDistance, groundLayer);

            Debug.DrawRay(rayOrigin, Vector2.down * slopeCheckDistance, Color.yellow); // Debug visualization

            if (hit)
            {
                // Calculate the slope angle and perpendicular direction
                float currentSlopeAngle = Vector2.Angle(hit.normal, Vector2.up);

                // Update slope values if this ray detects a valid slope
                if ((currentSlopeAngle>0)&&(currentSlopeAngle <= maxSlopeAngle))
                {
                    slopeNormalPerp = Vector2.Perpendicular(hit.normal).normalized;
                    slopeDownAngle = currentSlopeAngle;

                    isOnSlope = true;
                    canWalkOnSlope = true;

                    Debug.DrawRay(hit.point, slopeNormalPerp, Color.green); // Slope perpendicular
                    Debug.DrawRay(hit.point, hit.normal, Color.red);        // Slope normal
                    return; // Stop further checks once a valid slope is found
                }
            }
        }

        // If no valid slope is detected
        slopeNormalPerp = Vector2.zero;
        slopeDownAngle = 0f;
        isOnSlope = false;
        canWalkOnSlope = false;
    }



    private void OnCollisionEnter2D(Collision2D collision)
    {
        if (collision.collider.CompareTag("Ice"))
        {
            isOnIce = true;
        }
    }

    private void OnCollisionExit2D(Collision2D collision)
    {
        if (collision.collider.CompareTag("Ice"))
        {
            isOnIce = false;
        }
    }

}
Leave a Comment