MovementController.cs 8.01 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 Rigidbody2D m_Rigidbody2D;
Unknown's avatar
Unknown committed
38
	private bool m_FacingRight = true; // For determining which way the player is currently facing.
39
	private Vector3 m_Velocity = Vector3.zero;
Unknown's avatar
Unknown committed
40
	private int m_TempJumpCount = 0;
Unknown's avatar
Merge  
Unknown committed
41
	private bool m_Jumped = false;
42

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

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

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

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

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

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

65 66
		UpdateMovementParameters();

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

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

73

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

79 80 81 82
		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
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 111 112

		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);
113 114
	}

Unknown's avatar
Unknown committed
115

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

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

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

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

Unknown's avatar
Unknown committed
164
		if (m_Rigidbody2D.velocity.y < 0 && !m_Swimming && !m_Grounded)
Sebastian Frey's avatar
Sebastian Frey committed
165 166
		{
			m_Rigidbody2D.velocity += Vector2.up * Physics2D.gravity.y * (m_fallMultiplier - 1) * Time.deltaTime;
167
		}
168 169 170 171 172 173 174 175
		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
176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191
		if (GetComponentInParent<PlayerEarthAttack>().isStomping)
		{
			Invoke("UpdateMovementParameters", 0.01f);
		}
		else
		{
			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
192
	}
193

Unknown's avatar
Unknown committed
194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213
	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;
	}

214 215 216 217 218 219
	public float GroundCheckDistance
	{
		set => m_GroundCheckDistance = value;
		get => m_GroundCheckDistance;
	}

220 221 222 223 224 225 226 227 228 229 230 231
	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
232 233 234 235 236
	public void AddJumpCharge(int amount)
	{
		m_TempJumpCount += amount;
	}

Unknown's avatar
Merge  
Unknown committed
237 238 239 240 241
	private IEnumerator Wait(float s)
	{
		m_Jumped = true;
		yield return new WaitForSeconds(s);
		m_Jumped = false;
Unknown's avatar
Unknown committed
242
	}
243

Unknown's avatar
Unknown committed
244 245
	private void Flip()
	{
246 247 248 249 250 251 252 253 254
		// 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;
	}

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

261 262 263 264
	}

	private void OnCollisionExit2D(Collision2D other)
	{
Unknown's avatar
Unknown committed
265 266
		if (m_WhatIsGround == (m_WhatIsGround | (1 << other.gameObject.layer)))
		{
267
			m_Airborn = true;
Unknown's avatar
Unknown committed
268 269
		}

270 271
	}

Unknown's avatar
Unknown committed
272 273 274

	void OnDrawGizmos()
	{
275
		Gizmos.color = Color.green;
Unknown's avatar
Unknown committed
276 277 278 279
		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
280
	}
mthiele2's avatar
mthiele2 committed
281
}