using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.InputSystem; public class PlayerBehavior : MonoBehaviour { [Header("Physics:")] private float _hInput; private Rigidbody2D _rb; [HideInInspector] public int forward = 1; public PlayerInput playerInput; [Header("Tambourine:")] [SerializeField] private Launch launcher; [HideInInspector] public bool hasTambourine = true; GameObject tambourine; bool unlockedTambourine; [Header("Clarinet:")] [SerializeField] AudioSource clarinetAudio; bool unlockedClarinet; // things for dash private bool isDash = false; public float dashForce = 1f; public float dashTime = 1.0f; private float currentDash = 0.0f; private bool forceAdded = false; Vector2 dashVec; // things for bounce public float reflectForce = 1.1f; private Vector2 saveVelocity; private bool isInWater = false; private bool hasBounced = false; public float waterGravity = 0.5f; public float velocityCut = 1f; [Header("Cymbals:")] private float cymbalActiveTime = 0f; [SerializeField] AudioSource cymbalAudio; [Header("Grappling:")] [SerializeField] public Tutorial_GrapplingGun grapplingGun; [SerializeField] public Tutorial_GrapplingRope grapplingRope; private GameObject grappleSurface; [Header("Controllers:")] [SerializeField] private PlayerMovement playerController; private GameUIController gameUI; Animator animator; [HideInInspector] public bool playerIsAlive = true; [Header("Sound")] [SerializeField] public AudioClip footstepSound; [SerializeField] public AudioClip deathSound; AudioSource audioSource; void Awake() { // initialize _rb = GetComponent(); gameUI = GameObject.FindGameObjectWithTag("GameUICanvas").GetComponent(); audioSource = this.gameObject.GetComponent(); audioSource.clip = footstepSound; audioSource.loop = true; animator = this.gameObject.GetComponent(); GameObject.Find("Main Camera").GetComponent().player = this.gameObject; playerIsAlive = true; } void Start() { gameUI.UpdateInstrumentUI(); currentDash = dashTime; } void Update() { if (playerIsAlive) { if (this.cymbalActiveTime < 0) { this.gameUI.ToggleCymbal(true); } this.cymbalActiveTime -= Time.deltaTime; // throw tambourine unlockedTambourine = StateController.Instance.HasTambourine(); if (playerInput.actions["ThrowTambourine"].WasPressedThisFrame()) { ThrowTambourine(); } // grapple tambourine = GameObject.FindGameObjectWithTag("tambourine"); if (playerInput.actions["Grapple"].WasPressedThisFrame()) { AttemptGrapple(); } if (playerInput.actions["Grapple"].WasReleasedThisFrame() && grapplingRope.isGrappling) { LetGoOfGrapple(); } // clarinet unlockedClarinet = StateController.Instance.HasClarinet(); if (unlockedClarinet) { if (playerInput.actions["ClarinetDive"].WasPressedThisFrame() && !isInWater && !playerController.IsGrounded() && !isDash) { isDash = true; this.gameUI.ToggleClarinet(false); playerInput.DeactivateInput(); currentDash = 0.0f; clarinetAudio.Play(); } if (!playerController.IsGrounded() && isDash && (currentDash < dashTime)) { if (!forceAdded) { dashVec = new Vector2(0.5f * forward, -1f) * dashForce; _rb.AddForce(dashVec, ForceMode2D.Impulse); forceAdded = true; } currentDash += Time.deltaTime; } else if ((currentDash >= dashTime)) { // dash ends if (!isInWater) { isDash = false; this.gameUI.ToggleClarinet(true); forceAdded = false; _rb.AddForce(-(dashVec), ForceMode2D.Impulse); playerInput.ActivateInput(); } currentDash = 0.0f; dashVec = Vector2.zero; } else { isDash = false; this.gameUI.ToggleClarinet(true); forceAdded = false; playerInput.ActivateInput(); currentDash = 0.0f; dashVec = Vector2.zero; } } if (StateController.Instance.HasCymbal()) { if (this.playerInput.actions["CymbalCrash"].WasPressedThisFrame()) { // Play the sound this.gameUI.ToggleCymbal(false); cymbalAudio.Play(); // Set the cymbal active for the equivalent of one second this.cymbalActiveTime = 1; } } Animate(); } } void Animate() { // start walking if (playerInput.actions["Move"].WasPressedThisFrame()) { animator.SetBool("Walking", true); } // return to idle animation if (playerInput.actions["Move"].WasReleasedThisFrame()) { animator.SetBool("Walking", false); } } void OnMove(InputValue value) { if (playerIsAlive) { _hInput = value.Get().x; if (_hInput < 0) { if (forward != -1) { // if character hasnt already flipped FlipRenderer(); } forward = -1; } else if (_hInput > 0) { if (forward != 1) { // if character hasnt already flipped FlipRenderer(); } forward = 1; } } } void FlipRenderer() { GetComponent().flipX = !GetComponent().flipX; } void ThrowTambourine() { if (unlockedTambourine && hasTambourine && !grapplingRope.isGrappling) { launcher.ThrowTambourine(forward); SetHasTambourine(false); } } public void SetHasTambourine(bool state) { hasTambourine = state; gameUI.ToggleTambourine(state); } void AttemptGrapple() { if (tambourine != null) { // grapple to tambourine if (!grapplingRope.isGrappling && tambourine.GetComponent().pinned) { grapplingGun.GrappleToTambourine(tambourine); grapplingRope.isGrappling = true; } } else { if (grappleSurface != null) { grapplingGun.GrappleToSurface(grappleSurface.transform.position); grapplingRope.isGrappling = true; } } } void LetGoOfGrapple() { bool currentlyPaused = StateController.Instance.isPaused; if (grapplingRope.isGrappling && !currentlyPaused) { if (tambourine != null) { tambourine.GetComponent().DestroySelf(); } grapplingGun.ReleaseGrapple(); } } void Bounce() { Vector2 reflect; if (Mathf.Abs(saveVelocity.y) < 1f && hasBounced) { reflect = Vector2.zero; } else { reflect = new Vector2(saveVelocity.x * reflectForce, -(saveVelocity.y) * reflectForce); hasBounced = true; } _rb.AddForce(reflect, ForceMode2D.Impulse); reflect = Vector2.zero; isDash = false; } void Water() { if(isDash) { saveVelocity = _rb.velocity / velocityCut; if (isDash) { dashVec = new Vector2(1f * forward, -1f) * (dashForce / velocityCut); _rb.AddForce(dashVec, ForceMode2D.Force); } } else { playerController.FloatGravity(waterGravity); } } void OnTriggerEnter2D(Collider2D col) { if (col.tag == "grappleSurface") { grappleSurface = col.gameObject; } else if (col.tag == "instaDeath") { StartCoroutine(DestroyPlayer()); } else if (col.tag == "spawnPoint") { StateController.Instance.spawnPoint.GetComponent().DeactivateSpawnPoint(); col.GetComponent().ActivateSpawnPoint(); } else if (col.tag == "Trumpet") { this.playerController.in_range = true; this.playerController.enemy = col.transform.parent.gameObject; } else if (col.tag == "water") { isInWater = true; Water(); } else if (col.tag == "bouncePad") { // Assign the player's velocity to zero so that the player can // bounce on the same jump pad this.playerController.RB.velocity = Vector2.zero; Bouncepad pad = col.GetComponent(); switch (pad.Direction()) { case Bouncepad.Facing.Left: this.playerController.RB.AddForce( new Vector2(-pad.bounceForce, pad.verticalModifier * pad.bounceForce), ForceMode2D.Impulse ); break; case Bouncepad.Facing.Right: this.playerController.RB.AddForce( new Vector2(pad.bounceForce, pad.verticalModifier * pad.bounceForce), ForceMode2D.Impulse ); break; } } } void OnTriggerExit2D(Collider2D col) { if (col.tag == "grappleSurface") { grappleSurface = null; } else if (col.tag == "Trumpet") { this.playerController.in_range = false; this.playerController.enemy = null; } else if (col.tag == "water") { isInWater = false; isDash = false; hasBounced = false; playerInput.ActivateInput(); playerController.EndFloatGravity(); saveVelocity = Vector2.zero; } } void OnCollisionEnter2D(Collision2D collision) { if (collision.gameObject.tag == "Enemy" || collision.gameObject.tag == "ProjectileEnemy") { if (collision.transform.position.y < transform.position.y) { _rb.AddForce(Vector2.up * 8, ForceMode2D.Impulse); collision.gameObject.GetComponent().DefeatEnemy(); } else { StartCoroutine(DestroyPlayer()); } } else if (collision.gameObject.tag == "Projectile") { Destroy(collision.gameObject); if (this.cymbalActiveTime > 0) { Vector2 projVel = collision.gameObject.GetComponent().velocity; collision.gameObject.GetComponent().velocity = new Vector2( -projVel.x, -projVel.y ); } else { StartCoroutine(DestroyPlayer()); } } //stupid stuff for claude's house else if (collision.gameObject.tag == "SirJacques") { Destroy(collision.gameObject); } else if (collision.gameObject.tag == "Door") { StateController.Instance.RespawnPlayer(); } else if (collision.gameObject.tag == "bouncy") { Bounce(); } } IEnumerator DestroyPlayer() { if (playerIsAlive) { if (grapplingRope.isGrappling) { LetGoOfGrapple(); } playerIsAlive = false; audioSource.clip = deathSound; audioSource.loop = false; audioSource.Play(); playerInput.ActivateInput(); // animate animator.Play("Die"); yield return new WaitForSeconds(audioSource.clip.length); // destroy all tambourines GameObject[] currentTambourines = GameObject.FindGameObjectsWithTag("tambourine"); if (currentTambourines != null) { foreach (GameObject tambourine in currentTambourines) { if (tambourine != null) { tambourine.GetComponent().DestroySelf(); } } } StateController.Instance.RespawnPlayer(); } } }