using System.Collections; using System.Collections.Generic; using UnityEngine; using Platformer.Gameplay; using static Platformer.Core.Simulation; using Platformer.Model; using Platformer.Core; namespace Platformer.Mechanics { /// /// This is the main class used to implement control of the player. /// It is a superset of the AnimationController class, but is inlined to allow for any kind of customisation. /// public class PlayerController : KinematicObject { public AudioClip jumpAudio; public AudioClip respawnAudio; public AudioClip ouchAudio; /// /// Max horizontal speed of the player. /// public float maxSpeed = 7; /// /// Initial jump velocity at the start of a jump. /// public float jumpTakeOffSpeed = 7; public JumpState jumpState = JumpState.Grounded; private bool stopJump; /*internal new*/ public Collider2D collider2d; /*internal new*/ public AudioSource audioSource; public Health health; public bool controlEnabled = true; bool jump; Vector2 move; SpriteRenderer spriteRenderer; internal Animator animator; readonly PlatformerModel model = Simulation.GetModel(); public Bounds Bounds => collider2d.bounds; void Awake() { health = GetComponent(); audioSource = GetComponent(); collider2d = GetComponent(); spriteRenderer = GetComponent(); animator = GetComponent(); } protected override void Update() { if (controlEnabled) { move.x = Input.GetAxis("Horizontal"); if (jumpState == JumpState.Grounded && Input.GetButtonDown("Jump")) jumpState = JumpState.PrepareToJump; else if (Input.GetButtonUp("Jump")) { stopJump = true; Schedule().player = this; } } else { move.x = 0; } UpdateJumpState(); base.Update(); } void UpdateJumpState() { jump = false; switch (jumpState) { case JumpState.PrepareToJump: jumpState = JumpState.Jumping; jump = true; stopJump = false; break; case JumpState.Jumping: if (!IsGrounded) { Schedule().player = this; jumpState = JumpState.InFlight; } break; case JumpState.InFlight: if (IsGrounded) { Schedule().player = this; jumpState = JumpState.Landed; } break; case JumpState.Landed: jumpState = JumpState.Grounded; break; } } protected override void ComputeVelocity() { if (jump && IsGrounded) { velocity.y = jumpTakeOffSpeed * model.jumpModifier; jump = false; } else if (stopJump) { stopJump = false; if (velocity.y > 0) { velocity.y = velocity.y * model.jumpDeceleration; } } if (move.x > 0.01f) spriteRenderer.flipX = false; else if (move.x < -0.01f) spriteRenderer.flipX = true; animator.SetBool("grounded", IsGrounded); animator.SetFloat("velocityX", Mathf.Abs(velocity.x) / maxSpeed); targetVelocity = move * maxSpeed; } public enum JumpState { Grounded, PrepareToJump, Jumping, InFlight, Landed } } }