Tuesday, October 13, 2020

Handle Slope 2d character

 https://github.com/Bardent/Rigidbody2D-Slopes-Unity/blob/master/Assets/Scripts/PlayerController.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
[SerializeField]
private float movementSpeed;
[SerializeField]
private float groundCheckRadius;
[SerializeField]
private float jumpForce;
[SerializeField]
private float slopeCheckDistance;
[SerializeField]
private float maxSlopeAngle;
[SerializeField]
private Transform groundCheck;
[SerializeField]
private LayerMask whatIsGround;
[SerializeField]
private PhysicsMaterial2D noFriction;
[SerializeField]
private PhysicsMaterial2D fullFriction;
private float xInput;
private float slopeDownAngle;
private float slopeSideAngle;
private float lastSlopeAngle;
private int facingDirection = 1;
private bool isGrounded;
private bool isOnSlope;
private bool isJumping;
private bool canWalkOnSlope;
private bool canJump;
private Vector2 newVelocity;
private Vector2 newForce;
private Vector2 capsuleColliderSize;
private Vector2 slopeNormalPerp;
private Rigidbody2D rb;
private CapsuleCollider2D cc;
private void Start()
{
rb = GetComponent<Rigidbody2D>();
cc = GetComponent<CapsuleCollider2D>();
capsuleColliderSize = cc.size;
}
private void Update()
{
CheckInput();
}
private void FixedUpdate()
{
CheckGround();
SlopeCheck();
ApplyMovement();
}
private void CheckInput()
{
xInput = Input.GetAxisRaw("Horizontal");
if (xInput == 1 && facingDirection == -1)
{
Flip();
}
else if (xInput == -1 && facingDirection == 1)
{
Flip();
}
if (Input.GetButtonDown("Jump"))
{
Jump();
}
}
private void CheckGround()
{
isGrounded = Physics2D.OverlapCircle(groundCheck.position, groundCheckRadius, whatIsGround);
if(rb.velocity.y <= 0.0f)
{
isJumping = false;
}
if(isGrounded && !isJumping && slopeDownAngle <= maxSlopeAngle)
{
canJump = true;
}
}
private void SlopeCheck()
{
Vector2 checkPos = transform.position - (Vector3)(new Vector2(0.0f, capsuleColliderSize.y / 2));
SlopeCheckHorizontal(checkPos);
SlopeCheckVertical(checkPos);
}
private void SlopeCheckHorizontal(Vector2 checkPos)
{
RaycastHit2D slopeHitFront = Physics2D.Raycast(checkPos, transform.right, slopeCheckDistance, whatIsGround);
RaycastHit2D slopeHitBack = Physics2D.Raycast(checkPos, -transform.right, slopeCheckDistance, whatIsGround);
if (slopeHitFront)
{
isOnSlope = true;
slopeSideAngle = Vector2.Angle(slopeHitFront.normal, Vector2.up);
}
else if (slopeHitBack)
{
isOnSlope = true;
slopeSideAngle = Vector2.Angle(slopeHitBack.normal, Vector2.up);
}
else
{
slopeSideAngle = 0.0f;
isOnSlope = false;
}
}
private void SlopeCheckVertical(Vector2 checkPos)
{
RaycastHit2D hit = Physics2D.Raycast(checkPos, Vector2.down, slopeCheckDistance, whatIsGround);
if (hit)
{
slopeNormalPerp = Vector2.Perpendicular(hit.normal).normalized;
slopeDownAngle = Vector2.Angle(hit.normal, Vector2.up);
if(slopeDownAngle != lastSlopeAngle)
{
isOnSlope = true;
}
lastSlopeAngle = slopeDownAngle;
Debug.DrawRay(hit.point, slopeNormalPerp, Color.blue);
Debug.DrawRay(hit.point, hit.normal, Color.green);
}
if (slopeDownAngle > maxSlopeAngle || slopeSideAngle > maxSlopeAngle)
{
canWalkOnSlope = false;
}
else
{
canWalkOnSlope = true;
}
if (isOnSlope && canWalkOnSlope && xInput == 0.0f)
{
rb.sharedMaterial = fullFriction;
}
else
{
rb.sharedMaterial = noFriction;
}
}
private void Jump()
{
if (canJump)
{
canJump = false;
isJumping = true;
newVelocity.Set(0.0f, 0.0f);
rb.velocity = newVelocity;
newForce.Set(0.0f, jumpForce);
rb.AddForce(newForce, ForceMode2D.Impulse);
}
}
private void ApplyMovement()
{
if (isGrounded && !isOnSlope && !isJumping) //if not on slope
{
Debug.Log("This one");
newVelocity.Set(movementSpeed * xInput, 0.0f);
rb.velocity = newVelocity;
}
else if (isGrounded && isOnSlope && canWalkOnSlope && !isJumping) //If on slope
{
newVelocity.Set(movementSpeed * slopeNormalPerp.x * -xInput, movementSpeed * slopeNormalPerp.y * -xInput);
rb.velocity = newVelocity;
}
else if (!isGrounded) //If in air
{
newVelocity.Set(movementSpeed * xInput, rb.velocity.y);
rb.velocity = newVelocity;
}
}
private void Flip()
{
facingDirection *= -1;
transform.Rotate(0.0f, 180.0f, 0.0f);
}
private void OnDrawGizmos()
{
Gizmos.DrawWireSphere(groundCheck.position, groundCheckRadius);
}
}

https://www.youtube.com/watch?v=QPiZSTEuZnw