MovementController.cs 8.41 KB
Newer Older
Sebastian Frey's avatar
Sebastian Frey committed
1
using System;
mthiele2's avatar
mthiele2 committed
2
using System.Collections;
3
4
5
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
6
using _Game.Scripts.Scriptable_Object;
mthiele2's avatar
mthiele2 committed
7
using _Game.Scripts.Player.PlayerAttacks.Earth;
8

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

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

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

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

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

Unknown's avatar
Unknown committed
44
45
46
47
	private RaycastHit2D[] m_RaycastHits2D = new RaycastHit2D[16];
	private ContactFilter2D m_ContactFilter2D;
	private Vector3 m_CurrentGroundNormal;

Sebastian Frey's avatar
Sebastian Frey committed
48
49
	//private bool m_isMoving = false;
	//private bool m_isJumping = false;
50
51
	private Vector2 m_Movement = Vector2.zero;

Unknown's avatar
Unknown committed
52
	[Header("Events")] [Space]
53

Unknown's avatar
Unknown committed
54
	//Wird Aktiviert wenn Spieler Landet
55
	public UnityEvent OnLandEvent;
56

Unknown's avatar
Unknown committed
57
58
	public UnityEvent OnSwimEvent;
	public UnityEvent OnJumpEvent;
59

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

66
67
		UpdateMovementParameters();

Unknown's avatar
Unknown committed
68
		m_ContactFilter2D.SetLayerMask(m_WhatIsGround);
69
70

		if (OnLandEvent == null)
Unknown's avatar
Unknown committed
71
			OnLandEvent = new UnityEvent();
72
73
	}

74

Unknown's avatar
Unknown committed
75
76
	private void FixedUpdate()
	{
77
78
79
		bool wasGrounded = m_Grounded;
		m_Grounded = false;

80
81
82
83
		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
84
		// The player is grounded if a circlecast to the groundcheck position hits anything designated as ground
85
		// This can be done using layers instead but Sample Assets will not overwrite your project settings.
Unknown's avatar
Unknown committed
86
87
88
89
90
91
92
93
		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;
94
95
96
97
98
99
100
101
102
			if (r_State.GetCurrentElement() != InfusedElement.Air)
			{
				m_TempJumpCount = m_MaxJumpCount;
			}
			else
			{
				m_TempJumpCount = r_State.GetCharges();
			}

Unknown's avatar
Unknown committed
103
104
105
106
107
			m_CurrentGroundNormal = m_RaycastHits2D[i].normal;
			if (!wasGrounded)
			{
				OnLandEvent.Invoke();
			}
108
		}
109
110
111
112
113

		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);
114
		//r_Animator.SetBool("isAirCharged", m_isAir);
115
116
	}

Unknown's avatar
Unknown committed
117

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

127
			// And then smoothing it out and applying it to the character
Unknown's avatar
Unknown committed
128
129
			m_Rigidbody2D.velocity = Vector3.SmoothDamp(m_Rigidbody2D.velocity, targetVelocity, ref m_Velocity,
				m_MovementSmoothing);
130
131

			// If the input is moving the player right and the player is facing left...
Unknown's avatar
Unknown committed
132
133
			if (move.x > 0 && !m_FacingRight)
			{
134
				// ... flip the player.
Unknown's avatar
Unknown committed
135
				Flip();
136
137
			}
			// Otherwise if the input is moving the player left and the player is facing right...
Unknown's avatar
Unknown committed
138
139
			else if (move.x < 0 && m_FacingRight)
			{
140
				// ... flip the player.
Unknown's avatar
Unknown committed
141
				Flip();
142
143
			}
		}
Unknown's avatar
Unknown committed
144

145
		// If the player should jump...
Unknown's avatar
Unknown committed
146
147
		if (jump)
		{
148
149
150
151
152
153
154
155
			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
156
			{
Unknown's avatar
Unknown committed
157
158
				m_Grounded = false;
				m_TempJumpCount--;
159
				if (r_State.GetCurrentElement() == InfusedElement.Air) r_State.ChangeCharges(-1);
160
				print("AirJump: Charges left = " + m_TempJumpCount);
Sebastian Frey's avatar
Sebastian Frey committed
161
				m_Rigidbody2D.velocity = Vector2.up * m_JumpForce;
Unknown's avatar
Unknown committed
162
				OnJumpEvent.Invoke();
Unknown's avatar
Merge    
Unknown committed
163
				StartCoroutine(Wait(m_SecondsWaitToJump));
Unknown's avatar
Unknown committed
164
			}
165
		}
Sebastian Frey's avatar
Sebastian Frey committed
166

Unknown's avatar
Unknown committed
167
		if (m_Rigidbody2D.velocity.y < 0 && !m_Swimming && !m_Grounded)
Sebastian Frey's avatar
Sebastian Frey committed
168
169
		{
			m_Rigidbody2D.velocity += Vector2.up * Physics2D.gravity.y * (m_fallMultiplier - 1) * Time.deltaTime;
170
		}
171
172
173
174
175
176
177
178
		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()
	{
mthiele2's avatar
mthiele2 committed
179
180
181
182
183
184
185
		if (GetComponentInParent<PlayerEarthAttack>().isStomping)
		{
			Invoke("UpdateMovementParameters", 0.01f);
		}
		else
		{
			MovementState state = r_State.GetCurrentMovementState();
186
187
188
189
190
191
192
193
			if (r_State.GetCurrentElement() == InfusedElement.Air)
			{
				m_isAir = true;
			}
			else
			{
				m_isAir = false;
			}
mthiele2's avatar
mthiele2 committed
194
195
196
197
198
199
200
201
202
			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
203
	}
204

205
206
207
208
209
210
	public void SetAirJumpCount()
	{
		if (r_State.GetCurrentElement() != InfusedElement.Air) return;
		m_TempJumpCount = r_State.GetCharges();
	}

Unknown's avatar
Unknown committed
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
	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;
	}

231
232
233
234
235
236
	public float GroundCheckDistance
	{
		set => m_GroundCheckDistance = value;
		get => m_GroundCheckDistance;
	}

237
238
239
240
241
242
243
244
245
246
247
248
	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
249
250
251
252
253
	public void AddJumpCharge(int amount)
	{
		m_TempJumpCount += amount;
	}

Unknown's avatar
Merge    
Unknown committed
254
255
256
257
258
	private IEnumerator Wait(float s)
	{
		m_Jumped = true;
		yield return new WaitForSeconds(s);
		m_Jumped = false;
Unknown's avatar
Unknown committed
259
	}
260

Unknown's avatar
Unknown committed
261
262
	private void Flip()
	{
263
264
265
266
267
268
269
270
271
		// 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;
	}

272
273
	private void OnCollisionEnter2D(Collision2D other)
	{
Unknown's avatar
Unknown committed
274
		if (m_WhatIsGround == (m_WhatIsGround | (1 << other.gameObject.layer))){
275
			m_Airborn = false;
Unknown's avatar
Unknown committed
276
277
		}

278
279
280
281
	}

	private void OnCollisionExit2D(Collision2D other)
	{
Unknown's avatar
Unknown committed
282
283
		if (m_WhatIsGround == (m_WhatIsGround | (1 << other.gameObject.layer)))
		{
284
			m_Airborn = true;
Unknown's avatar
Unknown committed
285
286
		}

287
288
	}

Unknown's avatar
Unknown committed
289
290
291

	void OnDrawGizmos()
	{
292
		Gizmos.color = Color.green;
Unknown's avatar
Unknown committed
293
294
295
296
		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
297
	}
mthiele2's avatar
mthiele2 committed
298
}