MovementController.cs 8.46 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
		Vector3 col = r_Collider.offset;
		GroundCheckDistance = r_Collider.size.y / 2 * transform.localScale.y + 0.2f;

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

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

		r_Animator.SetFloat("Speed", m_Movement.magnitude);
		r_Animator.SetBool("isJumping", m_Jumped);
Unknown's avatar
Unknown committed
111
		r_Animator.SetBool("isGrounded", m_Grounded);
112 113
		r_Animator.SetBool("isAirborn", m_Airborn);
		r_Animator.SetBool("isSwimming", m_Swimming);
Unknown's avatar
Unknown committed
114 115
		r_Animator.SetBool("isAirCharged", m_isAir);
		r_Animator.SetBool("isCharging", r_State.isCharging);
116 117
	}

Unknown's avatar
Unknown committed
118

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

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

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

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

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

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

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

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

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

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

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

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

279 280 281 282
	}

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

288 289
	}

Unknown's avatar
Unknown committed
290 291 292

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