Spirinaut/Assets/Scripts/PlayerController.cs
Gerard Gascón 8103d0d89d init
2025-04-24 14:15:32 +02:00

240 lines
6.6 KiB
C#

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Cinemachine;
public class PlayerController : MonoBehaviour{
EnemyController[] enemies;
public SceneLoader sceneLoader;
public bool active;
public GameObject otherPlayer;
[Space]
public GameObject bloodExplosion;
[Space]
public float shootSpeed = 2;
public GameObject spiritPrefab;
public float spawnOffset;
[Space]
public CinemachineVirtualCamera vCam;
[Space]
public float speed;
[Range(0, .3f)] public float movementSmoothing = .05f;
float horizontalMove;
Vector2 velocity = Vector2.zero;
[Header("Jump")]
public float jumpForce;
public float fallMultiplier = 2.5f;
public float lowJumpMultiplier = 2f;
float gravityScale;
[Range(0, .3f)] public float jumpPressedRememberTime;
float jumpPressedRemember;
[Range(0, .3f)] public float groundedRememberTime;
float groundedRemember;
public Transform feetPos;
[Range(0, .5f)] public float feetRadius;
public LayerMask whatIsGround;
bool isGrounded;
bool wasGrounded;
bool jump;
[Header("Bounce")]
public float bounceForce;
public LayerMask whatIsBouncing;
public float playerBounceForce;
public LayerMask whatIsPlayerBouncing;
bool bouncing;
[Space]
public Animator anim;
public Animator bounce;
public Animator lightController;
Rigidbody2D rb2d;
void Awake(){
enemies = FindObjectsOfType<EnemyController>();
}
// Start is called before the first frame update
void Start(){
rb2d = GetComponent<Rigidbody2D>();
gravityScale = rb2d.gravityScale;
lightController.SetBool("Enabled", active);
}
bool canMove;
int h;
bool wasActive;
// Update is called once per frame
void Update(){
if(active && !wasActive){
foreach(EnemyController e in enemies){
e.WhoIsPlayer(gameObject);
}
wasActive = true;
}
if (canMove){
horizontalMove = Input.GetAxis("Horizontal") * speed;
if (Input.GetAxisRaw("Horizontal") != 0){
Flip(Input.GetAxisRaw("Horizontal"));
h = Mathf.RoundToInt(Input.GetAxisRaw("Horizontal"));
}
if (Input.GetButtonDown("Fire1")){
ShootSpirit((h == 0) ? 1 : h);
}
}else{
horizontalMove = 0;
}
isGrounded = Physics2D.OverlapCircle(feetPos.position, feetRadius, whatIsGround);
anim.SetBool("Grounded", isGrounded);
if (active){
canMove = true;
lightController.SetBool("Enabled", true);
}else{
canMove = false;
lightController.SetBool("Enabled", false);
}
#region Jump
if (isGrounded && !wasGrounded){
bounce.SetTrigger("Bounce");
wasGrounded = true;
}else if (!isGrounded){
wasGrounded = false;
}
jumpPressedRemember -= Time.deltaTime;
if (Input.GetButtonDown("Jump")){
jumpPressedRemember = jumpPressedRememberTime;
}
groundedRemember -= Time.deltaTime;
if (isGrounded){
groundedRemember = groundedRememberTime;
bouncing = false;
}
if ((jumpPressedRemember > 0) && (groundedRemember > 0)){
if (canMove){
jump = true;
jumpPressedRemember = 0;
groundedRemember = 0;
}
}
#endregion
bool isBouncing = Physics2D.OverlapCircle(feetPos.position, feetRadius, whatIsBouncing);
if (isBouncing){
Jump(bounceForce);
bouncing = true;
isBouncing = false;
}
bool isPlayerBouncing = Physics2D.OverlapCircle(feetPos.position, feetRadius, whatIsPlayerBouncing);
if (isPlayerBouncing){
Jump(playerBounceForce);
otherPlayer.GetComponent<PlayerController>().PlayBounceAnimation();
bouncing = true;
isBouncing = false;
}
}
void FixedUpdate(){
Vector2 targetVelocity = new Vector2(horizontalMove, rb2d.velocity.y);
rb2d.velocity = Vector2.SmoothDamp(rb2d.velocity, targetVelocity, ref velocity, movementSmoothing);
anim.SetFloat("Velocity", Mathf.Abs(rb2d.velocity.x));
#region Jump
if(!bouncing && canMove){
if (rb2d.velocity.y < 0){
rb2d.gravityScale = fallMultiplier * gravityScale;
}else if (rb2d.velocity.y > 0 && !Input.GetButton("Jump")){
rb2d.gravityScale = lowJumpMultiplier * gravityScale;
}else{
rb2d.gravityScale = gravityScale;
}
}
if (jump){
Jump(jumpForce);
jump = false;
}
#endregion
}
public void PlayBounceAnimation(){
bounce.SetTrigger("Bounce");
}
void Jump(float force){
bounce.SetTrigger("Bounce");
rb2d.velocity = new Vector2(rb2d.velocity.x, 0);
rb2d.AddForce(Vector2.up * force, ForceMode2D.Impulse);
}
void Flip(float h){
transform.localScale = new Vector3(Mathf.Abs(transform.localScale.x) * h, transform.localScale.y, transform.localScale.z);
}
void ShootSpirit(int direction){
var spirit = Instantiate(spiritPrefab, transform.position, transform.rotation);
Rigidbody2D rigidbody = spirit.GetComponent<Rigidbody2D>();
spirit.transform.position += new Vector3(spawnOffset * direction, 0, 0);
rigidbody.AddForce(new Vector2(shootSpeed * direction, 5), ForceMode2D.Impulse);
vCam.Follow = spirit.transform;
spirit.GetComponent<SpiritBall>().SetCamera(vCam, GetComponent<PlayerController>());
foreach(EnemyController e in enemies){
e.WhoIsPlayer(null);
}
wasActive = false;
active = false;
}
void Die(){
Instantiate(bloodExplosion, transform.position, Quaternion.identity);
sceneLoader.LoadScene(0);
gameObject.SetActive(false);
otherPlayer.SetActive(false);
}
void OnTriggerEnter2D(Collider2D col){
if(col.gameObject.tag == "InstantDeath"){
Die();
}
if(col.gameObject.tag == "Win"){
Time.timeScale = 0;
sceneLoader.LoadScene(0);
}
}
void OnCollisionEnter2D(Collision2D col){
if(col.gameObject.tag == "Enemy"){
Die();
}
}
void OnDrawGizmos(){
Gizmos.color = Color.red;
Gizmos.DrawWireSphere(feetPos.position, feetRadius);
}
}