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
}