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(); } // Start is called before the first frame update void Start(){ rb2d = GetComponent(); 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().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(); spirit.transform.position += new Vector3(spawnOffset * direction, 0, 0); rigidbody.AddForce(new Vector2(shootSpeed * direction, 5), ForceMode2D.Impulse); vCam.Follow = spirit.transform; spirit.GetComponent().SetCamera(vCam, GetComponent()); 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); } }