ofb/Assets/Scripts/PlayerBehavior.cs

469 lines
14 KiB
C#
Raw Normal View History

2023-04-11 19:55:24 -07:00
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
2023-04-17 00:01:49 -07:00
public class PlayerBehavior : MonoBehaviour
{
2023-04-11 19:55:24 -07:00
[Header("Physics:")]
private float _hInput;
private Rigidbody2D _rb;
[HideInInspector] public int forward = 1;
2023-04-11 19:55:24 -07:00
public PlayerInput playerInput;
2023-04-17 00:01:49 -07:00
2023-04-11 19:55:24 -07:00
[Header("Tambourine:")]
[SerializeField] private Launch launcher;
[HideInInspector] public bool hasTambourine = true;
GameObject tambourine;
bool unlockedTambourine;
2023-04-11 19:55:24 -07:00
2023-05-02 18:21:00 -07:00
[Header("Clarinet:")]
2023-05-06 16:47:57 -07:00
[SerializeField] AudioSource clarinetAudio;
2023-05-02 18:21:00 -07:00
bool unlockedClarinet;
2023-05-05 17:13:40 -07:00
// things for dash
2023-05-05 19:54:18 -07:00
private bool isDash = false;
public float dashForce = 1f;
public float dashTime = 1.0f;
2023-05-04 19:56:15 -07:00
private float currentDash = 0.0f;
private bool forceAdded = false;
2023-05-04 19:56:15 -07:00
Vector2 dashVec;
2023-05-05 17:13:40 -07:00
// things for bounce
2023-05-05 21:37:59 -07:00
public float reflectForce = 1.1f;
2023-05-05 17:13:40 -07:00
private Vector2 saveVelocity;
2023-05-05 19:54:18 -07:00
private bool isInWater = false;
private bool hasBounced = false;
2023-05-05 21:37:59 -07:00
public float waterGravity = 0.5f;
public float velocityCut = 1f;
2023-05-02 18:21:00 -07:00
[Header("Cymbals:")]
private float cymbalActiveTime = 0f;
[SerializeField]
private float cymbalBounceForce = 10f;
[SerializeField]
private float cymbalHitboxRange = 1.2f;
[SerializeField] AudioSource cymbalAudio;
2023-04-11 19:55:24 -07:00
[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;
2023-04-11 19:55:24 -07:00
void Awake()
{
2023-05-06 12:25:29 -07:00
// initialize
2023-04-11 19:55:24 -07:00
_rb = GetComponent<Rigidbody2D>();
gameUI = GameObject.FindGameObjectWithTag("GameUICanvas").GetComponent<GameUIController>();
audioSource = this.gameObject.GetComponent<AudioSource>();
audioSource.clip = footstepSound;
audioSource.loop = true;
animator = this.gameObject.GetComponent<Animator>();
GameObject.Find("Main Camera").GetComponent<CameraMovement>().player = this.gameObject;
playerIsAlive = true;
2023-04-11 19:55:24 -07:00
}
void Start()
{
gameUI.UpdateInstrumentUI();
2023-05-04 19:56:15 -07:00
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();
}
2023-04-11 19:55:24 -07:00
// grapple
tambourine = GameObject.FindGameObjectWithTag("tambourine");
if (playerInput.actions["Grapple"].WasPressedThisFrame())
{
AttemptGrapple();
}
if (playerInput.actions["Grapple"].WasReleasedThisFrame() && grapplingRope.isGrappling)
{
LetGoOfGrapple();
}
2023-04-11 19:55:24 -07:00
// clarinet
unlockedClarinet = StateController.Instance.HasClarinet();
if (unlockedClarinet)
{
if (playerInput.actions["ClarinetDive"].WasPressedThisFrame() && !isInWater && !playerController.IsGrounded() && !isDash)
{
isDash = true;
2023-05-05 22:46:31 -07:00
this.gameUI.ToggleClarinet(false);
playerInput.DeactivateInput();
currentDash = 0.0f;
2023-05-06 16:47:57 -07:00
clarinetAudio.Play();
2023-05-03 09:53:26 -07:00
}
if (!playerController.IsGrounded() && isDash && (currentDash < dashTime))
{
if (!forceAdded)
{
2023-05-06 14:46:20 -07:00
dashVec = new Vector2(0.5f * forward, -1f) * dashForce;
_rb.AddForce(dashVec, ForceMode2D.Impulse);
forceAdded = true;
}
currentDash += Time.deltaTime;
}
else if ((currentDash >= dashTime))
{
2023-05-06 12:25:29 -07:00
// dash ends
if (!isInWater)
{
isDash = false;
2023-05-05 22:46:31 -07:00
this.gameUI.ToggleClarinet(true);
forceAdded = false;
_rb.AddForce(-(dashVec), ForceMode2D.Impulse);
playerInput.ActivateInput();
}
currentDash = 0.0f;
dashVec = Vector2.zero;
}
else
{
isDash = false;
2023-05-05 22:46:31 -07:00
this.gameUI.ToggleClarinet(true);
forceAdded = false;
playerInput.ActivateInput();
currentDash = 0.0f;
dashVec = Vector2.zero;
2023-05-03 09:53:26 -07:00
}
2023-05-04 21:08:48 -07:00
}
if (StateController.Instance.HasCymbal())
{
if (this.playerInput.actions["CymbalCrash"].WasPressedThisFrame())
{
if (this.HasProjectileInRange())
{
this.gameUI.ToggleCymbal(false);
cymbalAudio.Play();
Vector2 curVel = this.playerController.RB.velocity;
this.playerController.RB.velocity = new Vector2(curVel.x, 0);
this.playerController.RB.AddForce(new Vector2(0, this.cymbalBounceForce), ForceMode2D.Impulse);
// Set the cymbal active for the equivalent of one second
this.cymbalActiveTime = 0.1f;
}
}
}
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);
}
2023-04-11 19:55:24 -07:00
}
void OnMove(InputValue value)
{
if (playerIsAlive)
{
_hInput = value.Get<Vector2>().x;
if (_hInput < 0)
{
if (forward != -1)
{
2023-05-06 12:25:29 -07:00
// if character hasnt already flipped
FlipRenderer();
}
forward = -1;
}
else if (_hInput > 0)
{
if (forward != 1)
{ // if character hasnt already flipped
FlipRenderer();
}
forward = 1;
}
2023-04-11 19:55:24 -07:00
}
}
void FlipRenderer()
{
GetComponent<SpriteRenderer>().flipX = !GetComponent<SpriteRenderer>().flipX;
}
void ThrowTambourine()
{
if (unlockedTambourine && hasTambourine && !grapplingRope.isGrappling)
{
launcher.ThrowTambourine(forward);
SetHasTambourine(false);
}
2023-04-11 19:55:24 -07:00
}
public void SetHasTambourine(bool state)
{
hasTambourine = state;
gameUI.ToggleTambourine(state);
}
void AttemptGrapple()
{
if (tambourine != null)
{ // grapple to tambourine
if (!grapplingRope.isGrappling && tambourine.GetComponent<TambourineBehavior>().pinned)
{
grapplingGun.GrappleToTambourine(tambourine);
grapplingRope.isGrappling = true;
}
2023-04-11 19:55:24 -07:00
}
else
{
if (grappleSurface != null)
{
grapplingGun.GrappleToSurface(grappleSurface.transform.position);
grapplingRope.isGrappling = true;
}
2023-04-11 19:55:24 -07:00
}
}
void LetGoOfGrapple()
{
bool currentlyPaused = StateController.Instance.isPaused;
if (grapplingRope.isGrappling && !currentlyPaused)
{
if (tambourine != null)
{
tambourine.GetComponent<TambourineBehavior>().DestroySelf();
}
grapplingGun.ReleaseGrapple();
2023-04-25 10:59:49 -07:00
}
2023-04-11 19:55:24 -07:00
}
2023-04-17 16:47:12 -07:00
void Bounce()
{
2023-05-04 21:08:48 -07:00
Vector2 reflect;
if (Mathf.Abs(saveVelocity.y) < 1f && hasBounced)
{
2023-05-05 17:13:40 -07:00
reflect = Vector2.zero;
2023-05-04 19:56:15 -07:00
}
else
{
2023-05-05 21:37:59 -07:00
reflect = new Vector2(saveVelocity.x * reflectForce, -(saveVelocity.y) * reflectForce);
2023-05-05 19:54:18 -07:00
hasBounced = true;
2023-05-04 21:08:48 -07:00
}
_rb.AddForce(reflect, ForceMode2D.Impulse);
reflect = Vector2.zero;
2023-05-05 19:54:18 -07:00
isDash = false;
2023-05-04 13:53:37 -07:00
}
void Water()
{
if (isDash)
{
saveVelocity = _rb.velocity / velocityCut;
if (isDash)
{
dashVec = new Vector2(1f * forward, -1f) * (dashForce / velocityCut);
_rb.AddForce(dashVec, ForceMode2D.Force);
}
2023-05-05 17:13:40 -07:00
}
else
{
2023-05-05 20:40:06 -07:00
playerController.FloatGravity(waterGravity);
2023-05-05 17:13:40 -07:00
}
2023-05-04 16:09:55 -07:00
}
bool HasProjectileInRange()
{
GameObject[] objs = GameObject.FindGameObjectsWithTag("Projectile");
foreach (GameObject proj in objs)
{
float distance = Vector2.Distance(proj.transform.position, this.transform.position);
Debug.Log($"Distance: {distance}");
if (distance <= this.cymbalHitboxRange)
{
Debug.Log("Yes");
return true;
}
}
Debug.Log("No");
return false;
}
void OnTriggerEnter2D(Collider2D col)
{
if (col.tag == "grappleSurface")
{
2023-04-17 16:47:12 -07:00
grappleSurface = col.gameObject;
}
else if (col.tag == "instaDeath")
{
StartCoroutine(DestroyPlayer());
2023-04-17 16:47:12 -07:00
}
else if (col.tag == "spawnPoint")
{
StateController.Instance.spawnPoint.GetComponent<SpawnPointBehavior>().DeactivateSpawnPoint();
col.GetComponent<SpawnPointBehavior>().ActivateSpawnPoint();
}
else if (col.tag == "Trumpet")
{
2023-04-27 15:56:36 -07:00
this.playerController.in_range = true;
this.playerController.enemy = col.transform.parent.gameObject;
}
else if (col.tag == "water")
{
2023-05-04 21:08:48 -07:00
isInWater = true;
2023-05-04 16:09:55 -07:00
Water();
2023-05-04 13:53:37 -07:00
}
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<Bouncepad>();
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;
}
}
2023-04-17 16:47:12 -07:00
}
void OnTriggerExit2D(Collider2D col)
{
if (col.tag == "grappleSurface")
{
2023-04-17 16:47:12 -07:00
grappleSurface = null;
}
else if (col.tag == "Trumpet")
{
2023-04-28 16:18:50 -07:00
this.playerController.in_range = false;
2023-04-27 15:56:36 -07:00
this.playerController.enemy = null;
}
else if (col.tag == "water")
{
2023-05-04 16:09:55 -07:00
isInWater = false;
2023-05-04 21:08:48 -07:00
isDash = false;
2023-05-05 19:54:18 -07:00
hasBounced = false;
2023-05-04 21:08:48 -07:00
playerInput.ActivateInput();
2023-05-05 19:54:18 -07:00
playerController.EndFloatGravity();
2023-05-04 17:11:09 -07:00
saveVelocity = Vector2.zero;
2023-05-04 16:09:55 -07:00
}
2023-04-17 16:47:12 -07:00
}
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<EnemyPatrol>().DefeatEnemy();
}
else
{
StartCoroutine(DestroyPlayer());
}
}
else if (collision.gameObject.tag == "Projectile")
{
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")
{
2023-05-04 16:09:55 -07:00
Bounce();
}
}
IEnumerator DestroyPlayer()
{
if (playerIsAlive)
{
if (grapplingRope.isGrappling)
{
LetGoOfGrapple();
}
playerIsAlive = false;
audioSource.clip = deathSound;
audioSource.loop = false;
audioSource.Play();
2023-05-04 21:08:48 -07:00
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<TambourineBehavior>().DestroySelf();
}
}
}
StateController.Instance.RespawnPlayer();
}
}
2023-04-17 00:01:49 -07:00
}