/
DynamicController.cs
113 lines (102 loc) · 3.19 KB
/
DynamicController.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class DynamicController : MonoBehaviour
{
protected Rigidbody2D rb;
protected Collider2D col;
public LayerMask groundLayer;
public float xInput;
public float moveSpeed = 5f;
public float maxSlopeAngle = 45;
public float slopeCheckDistance = 0.5f;
private float slopeDownAngle;
private float slopeSideAngle;
private float lastSlopeAngle;
private bool onSlope;
private bool isGrounded;
Vector2 groundParallel;
void Start()
{
rb = GetComponent<Rigidbody2D>();
col = GetComponent<Collider2D>();
}
// Update is called once per frame
void Update()
{
xInput = Input.GetAxisRaw("Horizontal");
}
private void FixedUpdate()
{
float targetXVel = xInput * moveSpeed;
Vector2 bottomCenter = new(col.bounds.center.x, col.bounds.min.y);
CheckGround();
SlopeCheckHorizontal(bottomCenter);
SlopeCheckVertical(bottomCenter);
SetVelocity(targetXVel);
}
private void SetVelocity(float targetXVel)
{
if (isGrounded && !onSlope) //if not on slope
{
rb.velocity = new(targetXVel, 0.0f);
}
else if (isGrounded && onSlope) //If on slope
{
rb.velocity = new(moveSpeed * groundParallel.x * -xInput, moveSpeed * groundParallel.y * -xInput);
}
else if (!isGrounded) //If in air
{
rb.velocity = new(targetXVel, rb.velocity.y);
}
}
private void CheckGround()
{
isGrounded = Physics2D.BoxCast(col.bounds.center, col.bounds.size, 0f, Vector2.down, 0.1f, groundLayer);
}
private void SlopeCheckHorizontal(Vector2 bottomCenter)
{
RaycastHit2D hitRight = Physics2D.Raycast(bottomCenter, transform.right, slopeCheckDistance, groundLayer);
RaycastHit2D hitLeft = Physics2D.Raycast(bottomCenter, -transform.right, slopeCheckDistance, groundLayer);
if (hitRight)
{
onSlope = true;
slopeSideAngle = Vector2.Angle(hitRight.normal, Vector2.up);
}
else if (hitLeft)
{
onSlope = true;
slopeSideAngle = Vector2.Angle(hitLeft.normal, Vector2.up);
}
else
{
slopeSideAngle = 0;
onSlope = false;
}
}
private void SlopeCheckVertical(Vector2 bottomCenter)
{
RaycastHit2D hit = Physics2D.Raycast(bottomCenter, Vector2.down, slopeCheckDistance, groundLayer);
if (hit)
{
groundParallel = Vector2.Perpendicular(hit.normal).normalized;
slopeDownAngle = Vector2.Angle(hit.normal, Vector2.up);
Debug.DrawRay(hit.point, hit.normal, Color.red);
Debug.DrawRay(transform.position, groundParallel, Color.red);
if (slopeDownAngle != lastSlopeAngle)
{
onSlope = true;
}
lastSlopeAngle = slopeDownAngle;
}
if (onSlope && xInput == 0)
{
rb.sharedMaterial.friction = 1;
}
else
{
rb.sharedMaterial.friction = 0;
}
}
}