216 lines
7.2 KiB
C#
216 lines
7.2 KiB
C#
|
|
using System.Collections;
|
|||
|
|
using System.Collections.Generic;
|
|||
|
|
using UnityEngine;
|
|||
|
|
using UnityEngine.SceneManagement;
|
|||
|
|
|
|||
|
|
public class PlayerController : MonoBehaviour {
|
|||
|
|
|
|||
|
|
[Header("Editable player setting")]
|
|||
|
|
[SerializeField] private float speed = 2.5f;
|
|||
|
|
[SerializeField] private float force = 4.0f;
|
|||
|
|
[SerializeField] private float shootForce = 5;
|
|||
|
|
[SerializeField] private float reloadTime = 5;
|
|||
|
|
[SerializeField] private int minimalHeight = -10;
|
|||
|
|
[SerializeField] private Vector3 direction;
|
|||
|
|
[SerializeField] private Arrow arrow;
|
|||
|
|
[SerializeField] private Transform arrowSpawnPoint;
|
|||
|
|
[SerializeField] private int arrowsCount = 3;
|
|||
|
|
[SerializeField] private Rigidbody2D m_Rigidbody2D;
|
|||
|
|
[SerializeField] private SpriteRenderer m_SpriteRenderer;
|
|||
|
|
[SerializeField] private GroundDetection m_GroundDetection;
|
|||
|
|
[SerializeField] private Animator m_Animator;
|
|||
|
|
[SerializeField] private BuffReceiver buffReceiver;
|
|||
|
|
[SerializeField] private Health _health;
|
|||
|
|
|
|||
|
|
public bool IsEnd { get; private set; }
|
|||
|
|
public float ReloadTimer { get; private set; }
|
|||
|
|
public float Force {
|
|||
|
|
get => force;
|
|||
|
|
set => force = value;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private List<Arrow> arrowPool;
|
|||
|
|
private bool isJumping;
|
|||
|
|
private bool isReloaded;
|
|||
|
|
private Arrow arrowPrefab;
|
|||
|
|
|
|||
|
|
private float bonusForce;
|
|||
|
|
private float bonusDamage;
|
|||
|
|
private float bonusHealth;
|
|||
|
|
|
|||
|
|
private UICharacterController controller;
|
|||
|
|
|
|||
|
|
private static readonly int Speed = Animator.StringToHash("Speed");
|
|||
|
|
private static readonly int IsGrounded = Animator.StringToHash("isGrounded");
|
|||
|
|
private static readonly int StartJump = Animator.StringToHash("StartJump");
|
|||
|
|
private static readonly int StartFall = Animator.StringToHash("StartFall");
|
|||
|
|
private static readonly int Shoot = Animator.StringToHash("Shoot");
|
|||
|
|
|
|||
|
|
#region Singletone
|
|||
|
|
public static PlayerController Instance { get; set; }
|
|||
|
|
#endregion
|
|||
|
|
|
|||
|
|
public void InitUIController(UICharacterController uiController) {
|
|||
|
|
controller = uiController;
|
|||
|
|
controller.Jump.onClick.AddListener(CheckJump);
|
|||
|
|
controller.Fire.onClick.AddListener(CheckShoot);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void Awake() {
|
|||
|
|
Instance = this;
|
|||
|
|
IsEnd = false;
|
|||
|
|
ReloadTimer = 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void Start() {
|
|||
|
|
isReloaded = false;
|
|||
|
|
arrowPool = new List<Arrow>();
|
|||
|
|
for (var i = 0; i < arrowsCount; i++) {
|
|||
|
|
var arrowTemp = Instantiate(arrow, arrowSpawnPoint);
|
|||
|
|
arrowPool.Add(arrowTemp);
|
|||
|
|
arrowTemp.gameObject.SetActive(false);
|
|||
|
|
}
|
|||
|
|
buffReceiver.OnBuffChanged += ApplyBafs;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void ApplyBafs() {
|
|||
|
|
var forceBuff = buffReceiver.Buffs.Find(t => t.type == BuffType.Force);
|
|||
|
|
var damageBuff = buffReceiver.Buffs.Find(t => t.type == BuffType.Damage);
|
|||
|
|
var armorBuff = buffReceiver.Buffs.Find(t => t.type == BuffType.Armor);
|
|||
|
|
bonusForce = forceBuff?.additiveBonus ?? 0;
|
|||
|
|
bonusHealth = armorBuff?.additiveBonus ?? 0;
|
|||
|
|
_health.SetHealth((int) bonusHealth);
|
|||
|
|
bonusDamage = damageBuff?.additiveBonus ?? 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void Update() {
|
|||
|
|
if (isReloaded) {
|
|||
|
|
ReloadTimer += Time.deltaTime;
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
#if UNITY_EDITOR
|
|||
|
|
if (Input.GetKeyDown(KeyCode.Space)) {
|
|||
|
|
CheckJump();
|
|||
|
|
}
|
|||
|
|
#endif
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Update is called once per frame
|
|||
|
|
private void FixedUpdate() {
|
|||
|
|
if (!IsEnd) {
|
|||
|
|
Move();
|
|||
|
|
if (transform.position.y < minimalHeight) {
|
|||
|
|
SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
if (Input.GetKey(KeyCode.R)) {
|
|||
|
|
SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// private void OnTriggerEnter2D(Collider2D other) {
|
|||
|
|
// if (other.gameObject.CompareTag("Finish")) {
|
|||
|
|
// if (!isEnd) {
|
|||
|
|
// isEnd = true;
|
|||
|
|
// }
|
|||
|
|
// }
|
|||
|
|
// }
|
|||
|
|
|
|||
|
|
private void CheckShoot() {
|
|||
|
|
m_Animator.SetTrigger(Shoot);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void Move() {
|
|||
|
|
m_Animator.SetBool(IsGrounded, m_GroundDetection.isGrounded);
|
|||
|
|
if (!isJumping && !m_GroundDetection.isGrounded) {
|
|||
|
|
m_Animator.SetTrigger(StartFall);
|
|||
|
|
}
|
|||
|
|
isJumping = isJumping && !m_GroundDetection.isGrounded;
|
|||
|
|
direction = Vector3.zero;
|
|||
|
|
#if UNITY_EDITOR
|
|||
|
|
if (Input.GetKey(KeyCode.A)) {
|
|||
|
|
direction = Vector3.left;
|
|||
|
|
m_SpriteRenderer.flipX = true;
|
|||
|
|
}
|
|||
|
|
if (Input.GetKey(KeyCode.D)) {
|
|||
|
|
direction = Vector3.right;
|
|||
|
|
m_SpriteRenderer.flipX = false;
|
|||
|
|
}
|
|||
|
|
#endif
|
|||
|
|
if (controller.Left.IsPressed) {
|
|||
|
|
direction = Vector3.left;
|
|||
|
|
m_SpriteRenderer.flipX = true;
|
|||
|
|
}
|
|||
|
|
if (controller.Right.IsPressed) {
|
|||
|
|
direction = Vector3.right;
|
|||
|
|
m_SpriteRenderer.flipX = false;
|
|||
|
|
}
|
|||
|
|
direction *= speed;
|
|||
|
|
direction.y = m_Rigidbody2D.velocity.y;
|
|||
|
|
m_Animator.SetFloat(Speed, Mathf.Abs(direction.x));
|
|||
|
|
m_Rigidbody2D.velocity = direction;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private Arrow GetArrowFromPool() {
|
|||
|
|
if (arrowPool.Count > 0) {
|
|||
|
|
var arrowTemp = arrowPool[0];
|
|||
|
|
arrowPool.Remove(arrowTemp);
|
|||
|
|
arrowTemp.gameObject.SetActive(true);
|
|||
|
|
arrowTemp.transform.parent = null;
|
|||
|
|
arrowTemp.transform.position = arrowSpawnPoint.transform.position;
|
|||
|
|
return arrowTemp;
|
|||
|
|
}
|
|||
|
|
return Instantiate(arrow, arrowSpawnPoint.position, Quaternion.identity);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public void ReturnArrowToPool(Arrow arrowTemp) {
|
|||
|
|
if (!arrowPool.Contains(arrowTemp)) {
|
|||
|
|
arrowPool.Add(arrowTemp);
|
|||
|
|
}
|
|||
|
|
arrowTemp.transform.parent = arrowSpawnPoint;
|
|||
|
|
arrowTemp.transform.position = arrowSpawnPoint.transform.position;
|
|||
|
|
arrowTemp.GetComponent<Rigidbody2D>().constraints = RigidbodyConstraints2D.FreezePositionY;
|
|||
|
|
arrowTemp.gameObject.SetActive(false);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public void ShowArrowBeforeShoot() {
|
|||
|
|
var tmpPos = arrowSpawnPoint.position;
|
|||
|
|
var position = tmpPos;
|
|||
|
|
position = new Vector3(m_SpriteRenderer.flipX ? position.x - 0.75f: position.x, position.y, position.z);
|
|||
|
|
arrowSpawnPoint.position = position;
|
|||
|
|
arrowPrefab = GetArrowFromPool();
|
|||
|
|
arrowPrefab.SetImpulse(Vector2.right, 0, 0, this);
|
|||
|
|
arrowPrefab.transform.rotation = Quaternion.Euler(0, m_SpriteRenderer.flipX ? 180 : 0, 0);
|
|||
|
|
arrowSpawnPoint.position = tmpPos;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public void ShootArrow() {
|
|||
|
|
arrowPrefab.GetComponent<Rigidbody2D>().constraints = RigidbodyConstraints2D.None;
|
|||
|
|
arrowPrefab.SetImpulse(Vector2.right, m_SpriteRenderer.flipX ? -force * shootForce : force * shootForce, (int) bonusDamage, this);
|
|||
|
|
isReloaded = true;
|
|||
|
|
StartCoroutine(nameof(Reload));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private IEnumerator Reload() {
|
|||
|
|
isReloaded = true;
|
|||
|
|
yield return new WaitForSeconds(reloadTime);
|
|||
|
|
isReloaded = false;
|
|||
|
|
ReloadTimer = 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public void CheckJump() {
|
|||
|
|
if (m_GroundDetection.isGrounded) {
|
|||
|
|
Jump();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public void Jump() {
|
|||
|
|
m_Rigidbody2D.velocity = Vector2.zero;
|
|||
|
|
m_Rigidbody2D.AddForce(Vector2.up * (force + bonusForce), ForceMode2D.Impulse);
|
|||
|
|
m_Animator.SetTrigger(StartJump);
|
|||
|
|
isJumping = true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
}
|