using Assets.Scripts.Enums;
|
using Assets.Scripts.Helpers;
|
using System;
|
using System.Linq;
|
using UnityEngine;
|
using UnityEngine.InputSystem;
|
|
[RequireComponent(typeof(Rigidbody2D))]
|
public class PlayerController : MonoBehaviour
|
{
|
public float moveSpeed = 5f;
|
public float maxFallSpeed = -20f;
|
public float maxFallSpeedDamge = -10f;
|
private float maxFallSpeedCurrent = 0f;
|
Vector2 moveInput;
|
|
[NonSerialized]
|
public Rigidbody2D rb;
|
[NonSerialized]
|
public Damageable health;
|
|
BoxCollider2D boxCollider;
|
Animator animator;
|
Animator animator_rotor;
|
public GameObject rotorGO;
|
TouchingDirections touchingDirections;
|
|
// Time it takes to drill
|
[SerializeField]
|
private float drillingTime = 1f;
|
private float timeSinceDrill = 0f;
|
private bool drillToPosition;
|
private Vector3 drillTilePosition;
|
private Vector3 drillOriginalPosition;
|
|
[SerializeField]
|
private bool _isMoving;
|
public bool IsMoving
|
{
|
get { return _isMoving; }
|
private set
|
{
|
_isMoving = value;
|
animator.SetBool(AnimationStrings.Player.isMoving, value);
|
}
|
}
|
|
[SerializeField]
|
private bool _isFlying;
|
public bool IsFlying
|
{
|
get { return _isFlying; }
|
private set
|
{
|
_isFlying = value;
|
animator.SetBool(AnimationStrings.Player.isFlying, value);
|
animator_rotor.SetBool(AnimationStrings.Player.isFlying, value);
|
}
|
}
|
public bool IsDrilling
|
{
|
get { return IsDrillingDown || IsDrillingLeftRight; }
|
set
|
{
|
if (value)
|
{
|
Debug.Assert(false, "Can't set IsDrilling this way, use IsDrillingLeftRight or IsDrillingDown!");
|
}
|
if (IsDrillingDown)
|
{
|
IsDrillingDown = false;
|
}
|
if (IsDrillingLeftRight)
|
{
|
IsDrillingLeftRight = false;
|
}
|
}
|
}
|
[SerializeField]
|
private bool _isDrillingLeftRight;
|
public bool IsDrillingLeftRight
|
{
|
get { return _isDrillingLeftRight; }
|
set
|
{
|
_isDrillingLeftRight = value;
|
animator.SetBool(AnimationStrings.Player.isDrillingLeftRight, value);
|
animator_rotor.SetBool(AnimationStrings.Player.isFlying, false);
|
if (value)
|
{
|
animator.speed = 1 / drillingTime;
|
}
|
else
|
{
|
animator.speed = 1f;
|
}
|
}
|
}
|
[SerializeField]
|
private bool _isDrillingDown;
|
public bool IsDrillingDown
|
{
|
get { return _isDrillingDown; }
|
set
|
{
|
_isDrillingDown = value;
|
animator.SetBool(AnimationStrings.Player.isDrillingDown, value);
|
animator_rotor.SetBool(AnimationStrings.Player.isFlying, false);
|
if (value)
|
{
|
animator.speed = 1 / drillingTime;
|
}
|
else
|
{
|
animator.speed = 1f;
|
}
|
}
|
}
|
|
private bool _isFacingRight = true;
|
|
public bool IsFacingRight
|
{
|
get { return _isFacingRight; }
|
set
|
{
|
if (_isFacingRight != value)
|
{
|
transform.localScale *= new Vector2(-1, 1);
|
}
|
_isFacingRight = value;
|
}
|
}
|
|
public bool CanMove
|
{
|
get
|
{
|
return animator.GetBool(AnimationStrings.canMove) && !PauseMenu.GameIsPaused && !IsDrilling;
|
}
|
}
|
|
private void OnEnable()
|
{
|
CharacterEvents.characterDrillingToPosition += (DrillingToPosition);
|
//CharacterEvents.characterDrillingToPositionAbort += (DrillingToPositionAbort);
|
}
|
|
private void OnDisable()
|
{
|
CharacterEvents.characterDrillingToPosition -= (DrillingToPosition);
|
//CharacterEvents.characterDrillingToPositionAbort -= (DrillingToPositionAbort);
|
}
|
|
private void Awake()
|
{
|
rb = GetComponent<Rigidbody2D>();
|
animator = GetComponent<Animator>();
|
animator_rotor = rotorGO.GetComponent<Animator>();
|
touchingDirections = GetComponent<TouchingDirections>();
|
health = GetComponent<Damageable>();
|
boxCollider = GetComponent<BoxCollider2D>();
|
if (SaveSystem.isGameLoaded)
|
{
|
LoadPlayer();
|
}
|
}
|
|
private void LoadPlayer()
|
{
|
SaveDataPlayer save = SaveSystem.LoadPlayer();
|
health.MaxHealth = save.maxHealth;
|
health.Health = save.health;
|
transform.position = VectorHelper.ConvertToVector3(save.position);
|
rb.velocity = VectorHelper.ConvertToVector2(save.velocity);
|
}
|
|
private void FixedUpdate()
|
{
|
if (CanMove)
|
{
|
if (moveInput.y == 0)
|
{
|
if (rb.velocity.y <= maxFallSpeed)
|
{
|
// max fall speed, dont accelerate more
|
rb.velocity = new Vector2(moveInput.x * moveSpeed, maxFallSpeed);
|
}
|
else
|
{
|
// normal fall
|
rb.velocity = new Vector2(moveInput.x * moveSpeed, rb.velocity.y);
|
}
|
}
|
else
|
{
|
if (rb.velocity.y < 0 && moveInput.y > 0)
|
{
|
// falling but moving upwards
|
rb.velocity = new Vector2(moveInput.x * moveSpeed, (moveInput.y * moveSpeed) + rb.velocity.y);
|
}
|
else
|
{
|
// moving upwards no falling
|
rb.velocity = new Vector2(moveInput.x * moveSpeed, (moveInput.y * moveSpeed));
|
}
|
}
|
if (touchingDirections.IsGrounded)
|
{
|
if (maxFallSpeedCurrent < maxFallSpeedDamge)
|
{
|
TakeFallDamage(Math.Abs((int)maxFallSpeedCurrent));
|
maxFallSpeedCurrent = 0;
|
}
|
}
|
else if (IsFlying)
|
{
|
maxFallSpeedCurrent = rb.velocity.y;
|
}
|
else
|
{
|
if (maxFallSpeedCurrent > rb.velocity.y)
|
{
|
maxFallSpeedCurrent = rb.velocity.y;
|
}
|
}
|
if (touchingDirections.IsGrounded && moveInput.y < 0 && !IsDrilling)
|
{
|
//IsDrilling = true;
|
Drill(DrillDirection.Down);
|
}
|
|
if (touchingDirections.IsGrounded && moveInput.x != 0 && !IsDrilling)
|
{
|
if (touchingDirections.IsAtWallLeft && moveInput.x < 0)
|
{
|
Drill(DrillDirection.Left);
|
}
|
else if (touchingDirections.IsAtWallRight && moveInput.x > 0)
|
{
|
Drill(DrillDirection.Right);
|
}
|
}
|
}
|
if (IsDrilling)
|
{
|
rb.velocity = Vector2.zero;
|
if (drillToPosition)
|
{
|
if (timeSinceDrill < drillingTime)
|
{
|
gameObject.transform.position = Vector3.Lerp(drillOriginalPosition, drillTilePosition, timeSinceDrill / drillingTime);
|
//Debug.Log("drillTilePosition: " + drillTilePosition);
|
//Debug.Log("timeSinceDrill: " + timeSinceDrill);
|
timeSinceDrill += Time.deltaTime;
|
}
|
else
|
{
|
boxCollider.enabled = true;
|
IsDrilling = false;
|
drillToPosition = false;
|
timeSinceDrill = 0;
|
}
|
}
|
}
|
}
|
|
public void OnMove(InputAction.CallbackContext context)
|
{
|
moveInput = context.ReadValue<Vector2>();
|
|
IsMoving = moveInput.x != 0;
|
|
IsFlying = (moveInput.y != 0);
|
|
SetFacingDirection(moveInput);
|
if (IsDrilling)
|
{
|
IsMoving = false;
|
IsFlying = false;
|
//moveInput = Vector2.zero;
|
}
|
}
|
|
private void Drill(DrillDirection drillDirection)
|
{
|
ContactPoint2D[] contactPoints = new ContactPoint2D[1];
|
//rb.GetContacts(contactPoints);
|
switch (drillDirection)
|
{
|
case DrillDirection.Left:
|
touchingDirections.wallHitsLeft[0].collider.GetContacts(contactPoints);
|
break;
|
case DrillDirection.Right:
|
touchingDirections.wallHitsRight[0].collider.GetContacts(contactPoints);
|
break;
|
case DrillDirection.Down:
|
touchingDirections.groundHits[0].collider.GetContacts(contactPoints);
|
break;
|
default:
|
Debug.Assert(false, "Add DrillDirection here!");
|
break;
|
}
|
//Debug.Log(contactPoints[0].otherRigidbody?.gameObject.name);
|
if (contactPoints.Any(x => x.otherRigidbody?.name == "Tilemap"))
|
{
|
CharacterEvents.characterDrill.Invoke(contactPoints.Single(x => x.otherRigidbody?.name == "Tilemap"), drillDirection);
|
}
|
}
|
|
private void DrillingToPosition(Vector3 tilePosition, DrillDirection drillDirection)
|
{
|
boxCollider.enabled = false;
|
switch (drillDirection)
|
{
|
case DrillDirection.Left:
|
case DrillDirection.Right:
|
IsDrillingLeftRight = true;
|
break;
|
case DrillDirection.Down:
|
IsDrillingDown = true;
|
break;
|
default:
|
Debug.Assert(false, "Add DrillDirection here!");
|
break;
|
}
|
//Debug.Log("DrillingToPosition() called");
|
//Debug.Log(gameObject.transform.position);
|
drillToPosition = true;
|
drillTilePosition = tilePosition;
|
//Debug.Log("drillTilePosition: " + drillTilePosition);
|
drillOriginalPosition = gameObject.transform.position;
|
//Debug.Log("drillOriginalPosition: " + drillOriginalPosition);
|
}
|
//private void DrillingToPositionAbort()
|
//{
|
// IsDrilling = false;
|
// //Debug.Log("DrillingToPosition() called");
|
// //Debug.Log(gameObject.transform.position);
|
// drillToPosition = false;
|
// //drillTilePosition = null;
|
// //Debug.Log("drillTilePosition: " + drillTilePosition);
|
// drillOriginalPosition = gameObject.transform.position;
|
// //Debug.Log("drillOriginalPosition: " + drillOriginalPosition);
|
//}
|
|
//private void DrillLeftOrRight()
|
//{
|
// ContactPoint2D[] contactPoints = new ContactPoint2D[1];
|
// touchingDirections.wallHits[0].collider.GetContacts(contactPoints);
|
// CharacterEvents.characterDrillLeftOrRight.Invoke(contactPoints[0]);
|
//}
|
|
private void SetFacingDirection(Vector2 moveInput)
|
{
|
if (moveInput.x > 0 && !IsFacingRight)
|
{
|
IsFacingRight = true;
|
}
|
else if (moveInput.x < 0 && IsFacingRight)
|
{
|
IsFacingRight = false;
|
}
|
}
|
|
public void TakeDamage(int damage)
|
{
|
health.Hit(damage);
|
}
|
|
public void TakeFallDamage(int fallDamage)
|
{
|
TakeDamage(fallDamage);
|
}
|
|
//public void OnRun(InputAction.CallbackContext context)
|
//{
|
// if (context.started) // Button pressed
|
// {
|
// _isRunning = true;
|
// }
|
// else if (context.canceled) // Button released
|
// {
|
// _isRunning = false;
|
// }
|
|
//}
|
}
|