MovementController.cs 7.78 KB
Newer Older
mthiele2's avatar
mthiele2 committed
1
using System.Collections;
2
3
4
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
5
using _Game.Scripts.Scriptable_Object;
6

7
[RequireComponent(typeof(Rigidbody2D), typeof(CapsuleCollider2D))]
Unknown's avatar
Unknown committed
8
9
public class MovementController : MonoBehaviour
{
Unknown's avatar
Unknown committed
10
	[SerializeField] private PlayerState r_State;
11
12
	private CapsuleCollider2D r_Collider;
	private Animator r_Animator;
Unknown's avatar
Unknown committed
13

14
	[Header("Movement")] [SerializeField] private float m_Speed = 10f;
Unknown's avatar
Unknown committed
15
	[SerializeField] private float m_JumpForce = 400f; // Amount of force added when the player jumps.
Unknown's avatar
Unknown committed
16
17
	[SerializeField] private float m_fallMultiplier = 2.5f;
	[SerializeField] private float m_lowJumpMultiplier = 2.0f;
Unknown's avatar
Unknown committed
18
	[Range(0, .3f)] [SerializeField] private float m_MovementSmoothing = .05f; // How much to smooth out the movement
Unknown's avatar
Unknown committed
19
	[SerializeField] private bool m_AirControl = false; // Whether or not a player can steer while jumping;
20
21
	[SerializeField] private bool m_CanSwim = true;

22
23
24
	[Header("Ground Check Control")] [SerializeField]
	private LayerMask m_WhatIsGround; // A mask determining what is ground to the character

Unknown's avatar
Unknown committed
25
	[SerializeField] private Transform m_GroundCheck; // A position marking where to check if the player is grounded.
Unknown's avatar
Unknown committed
26
	[SerializeField] private float m_GroundCheckDistance = 1.5f;
27
28
	[SerializeField] private float m_GroundedRadius = .2f;
	[SerializeField] private Vector2 m_GroundedOffset = Vector2.zero;
Unknown's avatar
Merge    
Unknown committed
29
	[SerializeField] private float m_SecondsWaitToJump = 0.3f;
Unknown's avatar
Unknown committed
30
	[SerializeField] private int m_MaxJumpCount = 1;
Unknown's avatar
Unknown committed
31

Unknown's avatar
Unknown committed
32
33
34
	private bool m_Grounded = false; // Whether or not the player is grounded.
	private bool m_Swimming = false;
	private bool m_Airborn = true;
35
	private Rigidbody2D m_Rigidbody2D;
Unknown's avatar
Unknown committed
36
	private bool m_FacingRight = true; // For determining which way the player is currently facing.
37
	private Vector3 m_Velocity = Vector3.zero;
Unknown's avatar
Unknown committed
38
	private int m_TempJumpCount = 0;
Unknown's avatar
Merge    
Unknown committed
39
	private bool m_Jumped = false;
40

Unknown's avatar
Unknown committed
41
42
43
44
	private RaycastHit2D[] m_RaycastHits2D = new RaycastHit2D[16];
	private ContactFilter2D m_ContactFilter2D;
	private Vector3 m_CurrentGroundNormal;

45
46
47
48
	private bool m_isMoving = false;
	private bool m_isJumping = false;
	private Vector2 m_Movement = Vector2.zero;

Unknown's avatar
Unknown committed
49
	[Header("Events")] [Space]
50

Unknown's avatar
Unknown committed
51
	//Wird Aktiviert wenn Spieler Landet
52
	public UnityEvent OnLandEvent;
53

Unknown's avatar
Unknown committed
54
55
	public UnityEvent OnSwimEvent;
	public UnityEvent OnJumpEvent;
56

Unknown's avatar
Unknown committed
57
58
59
	private void Awake()
	{
		m_Rigidbody2D = GetComponent<Rigidbody2D>();
60
61
		r_Collider = GetComponent<CapsuleCollider2D>();
		r_Animator = GetComponent<Animator>();
Unknown's avatar
Unknown committed
62
63

		m_ContactFilter2D.SetLayerMask(m_WhatIsGround);
64
65

		if (OnLandEvent == null)
Unknown's avatar
Unknown committed
66
			OnLandEvent = new UnityEvent();
67
68
	}

69

Unknown's avatar
Unknown committed
70
71
	private void FixedUpdate()
	{
72
73
74
		bool wasGrounded = m_Grounded;
		m_Grounded = false;

75
76
77
78
		Vector3 col = r_Collider.offset;
		m_GroundCheck.position = transform.position + col;
		GroundCheckDistance = r_Collider.size.y / 2 * transform.localScale.y + 0.2f;

Unknown's avatar
Unknown committed
79
		// The player is grounded if a circlecast to the groundcheck position hits anything designated as ground
80
		// This can be done using layers instead but Sample Assets will not overwrite your project settings.
Unknown's avatar
Unknown committed
81
82
83
84
85
86
87
88
		Vector3 pos = m_GroundCheck.position + new Vector3(m_GroundedOffset.x, m_GroundedOffset.y, 0);
		var c = Physics2D.CircleCast(pos, m_GroundedRadius, Vector2.down, m_ContactFilter2D, m_RaycastHits2D,
			m_GroundCheckDistance);
		for (var i = 0; i < c; i++)
		{
			if (m_RaycastHits2D[i].transform.gameObject == gameObject) continue;

			m_Grounded = true;
89
90
91
92
93
94
95
96
97
			if (r_State.GetCurrentElement() != InfusedElement.Air)
			{
				m_TempJumpCount = m_MaxJumpCount;
			}
			else
			{
				m_TempJumpCount = r_State.GetCharges();
			}

Unknown's avatar
Unknown committed
98
99
100
101
102
			m_CurrentGroundNormal = m_RaycastHits2D[i].normal;
			if (!wasGrounded)
			{
				OnLandEvent.Invoke();
			}
103
		}
104
105
106
107
108

		r_Animator.SetFloat("Speed", m_Movement.magnitude);
		r_Animator.SetBool("isJumping", m_Jumped);
		r_Animator.SetBool("isAirborn", m_Airborn);
		r_Animator.SetBool("isSwimming", m_Swimming);
109
110
	}

Unknown's avatar
Unknown committed
111

Unknown's avatar
Unknown committed
112
113
	public void Move(Vector2 move, bool jump)
	{
114
		m_Movement = move;
115
		//only control the player if grounded or airControl is turned on
116
		if (m_Grounded || (m_AirControl && (m_Airborn && !m_Grounded)) || (m_Swimming && m_CanSwim))
Unknown's avatar
Unknown committed
117
		{
118
			// Move the character by finding the target velocity
Unknown's avatar
Unknown committed
119
			Vector2 targetVelocity = new Vector2((move.x * m_Speed * Time.deltaTime) * 10f, m_Rigidbody2D.velocity.y);
Unknown's avatar
Unknown committed
120

121
			// And then smoothing it out and applying it to the character
Unknown's avatar
Unknown committed
122
123
			m_Rigidbody2D.velocity = Vector3.SmoothDamp(m_Rigidbody2D.velocity, targetVelocity, ref m_Velocity,
				m_MovementSmoothing);
124
125

			// If the input is moving the player right and the player is facing left...
Unknown's avatar
Unknown committed
126
127
			if (move.x > 0 && !m_FacingRight)
			{
128
				// ... flip the player.
Unknown's avatar
Unknown committed
129
				Flip();
130
131
			}
			// Otherwise if the input is moving the player left and the player is facing right...
Unknown's avatar
Unknown committed
132
133
			else if (move.x < 0 && m_FacingRight)
			{
134
				// ... flip the player.
Unknown's avatar
Unknown committed
135
				Flip();
136
137
			}
		}
Unknown's avatar
Unknown committed
138

139
		// If the player should jump...
Unknown's avatar
Unknown committed
140
141
		if (jump)
		{
142
143
144
145
146
147
148
149
			if (m_Grounded || (m_Swimming && m_CanSwim) && !m_Jumped)
			{
				m_Grounded = false;
				m_Rigidbody2D.velocity = Vector2.up * m_JumpForce;
				OnJumpEvent.Invoke();
				StartCoroutine(Wait(m_SecondsWaitToJump));
			}
			else if ((m_TempJumpCount > 0) && !m_Jumped)
Unknown's avatar
Unknown committed
150
			{
Unknown's avatar
Unknown committed
151
152
				m_Grounded = false;
				m_TempJumpCount--;
153
				if (r_State.GetCurrentElement() == InfusedElement.Air) r_State.ChangeCharges(-1);
Sebastian Frey's avatar
Sebastian Frey committed
154
				m_Rigidbody2D.velocity = Vector2.up * m_JumpForce;
Unknown's avatar
Unknown committed
155
				OnJumpEvent.Invoke();
Unknown's avatar
Merge    
Unknown committed
156
				StartCoroutine(Wait(m_SecondsWaitToJump));
Unknown's avatar
Unknown committed
157
			}
158
		}
Sebastian Frey's avatar
Sebastian Frey committed
159

Unknown's avatar
Unknown committed
160
		if (m_Rigidbody2D.velocity.y < 0 && !m_Swimming && !m_Grounded)
Sebastian Frey's avatar
Sebastian Frey committed
161
162
		{
			m_Rigidbody2D.velocity += Vector2.up * Physics2D.gravity.y * (m_fallMultiplier - 1) * Time.deltaTime;
163
		}
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
		else if (m_Rigidbody2D.velocity.y > 0 && !Input.GetButton("Jump"))
		{
			m_Rigidbody2D.velocity += Vector2.up * Physics2D.gravity.y * (m_lowJumpMultiplier - 1) * Time.deltaTime;
		}
	}

	public void UpdateMovementParameters()
	{
		MovementState state = r_State.GetCurrentMovementState();
		m_JumpForce = state.jumpForce;
		m_MovementSmoothing = state.smoothing;
		m_AirControl = state.airControl;
		m_CanSwim = state.canSwim;
		m_Speed = state.moveSpeed;
		m_MaxJumpCount = state.maxJumpCount;
		m_Rigidbody2D.mass = state.mass;
		m_Rigidbody2D.gravityScale = state.gravity;
Unknown's avatar
Merge    
Unknown committed
181
	}
182

Unknown's avatar
Unknown committed
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
	public void SetSwimming(bool value)
	{
		m_Swimming = value;
		if (value)
		{
			OnSwimEvent.Invoke();
			m_TempJumpCount = m_MaxJumpCount;
		}
	}

	public bool Swimming
	{
		get => m_Swimming;
	}

	public bool Grounded
	{
		get => m_Grounded;
	}

203
204
205
206
207
208
	public float GroundCheckDistance
	{
		set => m_GroundCheckDistance = value;
		get => m_GroundCheckDistance;
	}

209
210
211
212
213
214
215
216
217
218
219
220
	public Vector2 GroundCheckOffset
	{
		set => m_GroundedOffset = value;
		get => m_GroundedOffset;
	}

	public float GroundCheckRadius
	{
		set => m_GroundedRadius = value;
		get => m_GroundedRadius;
	}

Unknown's avatar
Unknown committed
221
222
223
224
225
	public void AddJumpCharge(int amount)
	{
		m_TempJumpCount += amount;
	}

Unknown's avatar
Merge    
Unknown committed
226
227
228
229
230
	private IEnumerator Wait(float s)
	{
		m_Jumped = true;
		yield return new WaitForSeconds(s);
		m_Jumped = false;
Unknown's avatar
Unknown committed
231
	}
232

Unknown's avatar
Unknown committed
233
234
	private void Flip()
	{
235
236
237
238
239
240
241
242
243
		// Switch the way the player is labelled as facing.
		m_FacingRight = !m_FacingRight;

		// Multiply the player's x local scale by -1.
		Vector3 theScale = transform.localScale;
		theScale.x *= -1;
		transform.localScale = theScale;
	}

244
245
	private void OnCollisionEnter2D(Collision2D other)
	{
Unknown's avatar
Unknown committed
246
		if (m_WhatIsGround == (m_WhatIsGround | (1 << other.gameObject.layer))){
247
			m_Airborn = false;
Unknown's avatar
Unknown committed
248
249
		}

250
251
252
253
	}

	private void OnCollisionExit2D(Collision2D other)
	{
Unknown's avatar
Unknown committed
254
255
		if (m_WhatIsGround == (m_WhatIsGround | (1 << other.gameObject.layer)))
		{
256
			m_Airborn = true;
Unknown's avatar
Unknown committed
257
258
		}

259
260
	}

Unknown's avatar
Unknown committed
261
262
263

	void OnDrawGizmos()
	{
264
		Gizmos.color = Color.green;
Unknown's avatar
Unknown committed
265
266
267
268
		Vector3 pos = m_GroundCheck.position + new Vector3(m_GroundedOffset.x, m_GroundedOffset.y, 0);
		//Gizmos.DrawWireSphere (m_GroundCheck.position + new Vector3(m_GroundedOffset.x, m_GroundedOffset.y, 0), m_GroundedRadius);
		Gizmos.DrawRay(pos, Vector3.down * m_GroundCheckDistance);
		Gizmos.DrawWireSphere(pos + Vector3.down * m_GroundCheckDistance, m_GroundedRadius);
Unknown's avatar
Unknown committed
269
	}
mthiele2's avatar
mthiele2 committed
270
}