SlopeMovement
unknown
plain_text
a year ago
3.2 kB
13
Indexable
using UnityEngine;
public class SlopeMovement : MonoBehaviour
{
[Header("Slope Settings")]
[SerializeField] private float slopeCheckDistance = 0.5f;
[SerializeField] private float maxSlopeAngle = 45f;
[SerializeField] private PhysicsMaterial2D noFriction;
[SerializeField] private PhysicsMaterial2D fullFriction;
[SerializeField] private LayerMask whatIsGround;
private Rigidbody2D rb;
private CapsuleCollider2D cc;
private bool isOnSlope;
private bool canWalkOnSlope;
private float slopeDownAngle;
private float slopeSideAngle;
private float lastSlopeAngle;
private Vector2 slopeNormalPerpendicular;
private Vector2 capsuleColliderSize;
void Start()
{
rb = GetComponent<Rigidbody2D>();
cc = GetComponent<CapsuleCollider2D>();
capsuleColliderSize = cc.size;
}
void FixedUpdate()
{
Vector2 checkPos = transform.position - new Vector3(0.0f, capsuleColliderSize.y / 2);
SlopeCheckHorizontal(checkPos);
SlopeCheckVertical(checkPos);
ApplySlopeFriction();
}
private void SlopeCheckHorizontal(Vector2 checkPos)
{
RaycastHit2D slopeHitFront = Physics2D.Raycast(checkPos, transform.right, slopeCheckDistance, whatIsGround);
RaycastHit2D slopeHitBack = Physics2D.Raycast(checkPos, -transform.right, slopeCheckDistance, whatIsGround);
isOnSlope = slopeHitFront || slopeHitBack;
if (slopeHitFront)
{
Debug.Log("slopeHitFront");
slopeSideAngle = Vector2.Angle(slopeHitFront.normal, Vector2.up);
}
else if (slopeHitBack)
{
Debug.Log("slopeHitBack");
slopeSideAngle = Vector2.Angle(slopeHitBack.normal, Vector2.up);
}
else
{
slopeSideAngle = 0f;
}
}
private void SlopeCheckVertical(Vector2 checkPos)
{
RaycastHit2D hit = Physics2D.Raycast(checkPos, Vector2.down, slopeCheckDistance, whatIsGround);
if (hit)
{
slopeNormalPerpendicular = Vector2.Perpendicular(hit.normal).normalized;
slopeDownAngle = Vector2.Angle(hit.normal, Vector2.up);
if (slopeDownAngle != lastSlopeAngle)
{
isOnSlope = true;
}
lastSlopeAngle = slopeDownAngle;
canWalkOnSlope = slopeDownAngle <= maxSlopeAngle && slopeSideAngle <= maxSlopeAngle;
}
}
private void ApplySlopeFriction()
{
if (isOnSlope && canWalkOnSlope && rb.velocity.x == 0)
{
rb.sharedMaterial = fullFriction;
}
else
{
rb.sharedMaterial = noFriction;
}
}
private void OnDrawGizmos()
{
Vector2 checkPos = transform.position - new Vector3(0.0f, capsuleColliderSize.y / 2);
Gizmos.color = Color.blue;
Gizmos.DrawLine(checkPos, checkPos + Vector2.right * slopeCheckDistance);
Gizmos.DrawLine(checkPos, checkPos + Vector2.left * slopeCheckDistance);
Gizmos.DrawLine(checkPos, checkPos + Vector2.down * slopeCheckDistance);
}
}
Editor is loading...
Leave a Comment