216 lines
6.0 KiB
C#
216 lines
6.0 KiB
C#
using System;
|
|
using UnityEngine;
|
|
using UnityEngine.Tilemaps;
|
|
|
|
public abstract class Character : MonoBehaviour
|
|
{
|
|
[SerializeField]
|
|
protected Animator _animator;
|
|
[SerializeField]
|
|
private float MovementSpeed = 1.5f;
|
|
[SerializeField]
|
|
protected GameObject _bonesSide;
|
|
[SerializeField]
|
|
protected GameObject _bonesBack;
|
|
[SerializeField]
|
|
protected GameObject _spawnPoint;
|
|
[SerializeField]
|
|
protected Tilemap _tileMap;
|
|
|
|
[SerializeField]
|
|
private LayerMask _mapLayer;
|
|
|
|
|
|
|
|
private Rigidbody2D _body;
|
|
private CapsuleCollider2D _capsuleCollider;
|
|
protected bool _isOnBridge;
|
|
protected bool _isOnLadder = false;
|
|
protected bool _isFalling;
|
|
protected bool _facingRight = true;
|
|
|
|
|
|
protected bool isAllowVertical = true;
|
|
protected bool isAllowRight = true;
|
|
protected bool isAllowLeft = true;
|
|
private Vector2 _cellSize;
|
|
|
|
private void Start()
|
|
{
|
|
_body = GetComponent<Rigidbody2D>();
|
|
_capsuleCollider = GetComponent<CapsuleCollider2D>();
|
|
|
|
_cellSize = new Vector2(_tileMap.cellSize.x, _tileMap.cellSize.y);
|
|
}
|
|
|
|
protected void Spawn()
|
|
{
|
|
transform.position = _spawnPoint.transform.position;
|
|
}
|
|
|
|
protected void MoveTo(float inputHorizontal, float inputVertical)
|
|
{
|
|
var downBlock = GetMapElement(Vector2.down);
|
|
|
|
if (downBlock == MapElementType.Water)
|
|
{
|
|
Death();
|
|
}
|
|
|
|
_isOnBridge = downBlock == MapElementType.Bridge && !_isFalling;
|
|
GetMapElement(Vector2.up);
|
|
if (downBlock == MapElementType.Wall || _isOnLadder || _isOnBridge || downBlock == MapElementType.BreakableWall)
|
|
{
|
|
var leftCheck = GetMapElement(Vector2.left);
|
|
var rightCheck = GetMapElement(Vector2.right);
|
|
|
|
//print($"LeftCheck:{leftCheck} right:{rightCheck}");
|
|
|
|
isAllowLeft = !(leftCheck == MapElementType.Wall || leftCheck == MapElementType.BreakableWall);
|
|
isAllowRight = !(rightCheck == MapElementType.Wall || rightCheck == MapElementType.BreakableWall);
|
|
|
|
isAllowVertical = false;
|
|
_isFalling = false;
|
|
float h_movement = inputHorizontal;
|
|
|
|
if (h_movement > 0 && !_facingRight || h_movement < 0 && _facingRight)
|
|
{
|
|
FlipCharacter();
|
|
}
|
|
|
|
SetWalkingAnimation(h_movement != 0);
|
|
;
|
|
_isOnLadder = GetMapElement(Vector2.zero) == MapElementType.Ladder || downBlock == MapElementType.Ladder;
|
|
|
|
if (_isOnLadder)
|
|
{
|
|
float v_movement = inputVertical;
|
|
isAllowVertical = true;
|
|
|
|
SetClimbingAnimation(v_movement != 0);
|
|
_body.velocity = new Vector2(h_movement * MovementSpeed, v_movement * MovementSpeed);
|
|
|
|
}
|
|
else
|
|
{
|
|
_body.velocity = new Vector2(h_movement * MovementSpeed, _body.velocity.y);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
_isFalling = true;
|
|
}
|
|
|
|
|
|
if (_isOnLadder || _isOnBridge)
|
|
{
|
|
_body.gravityScale = 0;
|
|
}
|
|
else
|
|
{
|
|
_body.gravityScale = 1;
|
|
}
|
|
if (_isFalling)
|
|
{
|
|
_body.velocity = new Vector2(0, _body.velocity.y);
|
|
SetWalkingAnimation(false);
|
|
|
|
if (downBlock == MapElementType.Ladder)
|
|
{
|
|
_body.velocity = Vector2.zero;
|
|
_isOnLadder = true;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
private void Death()
|
|
{
|
|
OnDeath();
|
|
|
|
}
|
|
|
|
|
|
private MapElementType GetMapElement(Vector3 direction)
|
|
{
|
|
var bounds = _capsuleCollider.bounds.min;
|
|
|
|
//var cell = _tileMap.WorldToCell(bounds + direction);
|
|
//Vector2 cell2d = new Vector2(cell.x + 0.5f, cell.y + 0.3f);
|
|
Vector2 cellSize = new Vector2(0.9f,0.8f);
|
|
|
|
var playerBounds = _capsuleCollider.bounds.min;
|
|
playerBounds += new Vector3(0.01f, 0.01f);
|
|
|
|
|
|
DrawBounds(playerBounds, cellSize, Color.cyan);
|
|
|
|
playerBounds = playerBounds + direction;
|
|
|
|
var raycastHit = Physics2D.BoxCast(playerBounds, cellSize, 0f, Vector3.forward, .01f, _mapLayer);
|
|
|
|
|
|
|
|
MapElementType returnValue;
|
|
Color color = Color.red;
|
|
if (raycastHit)
|
|
{
|
|
var mapElement = raycastHit.transform.GetComponent<MapElement>();
|
|
if (!mapElement.IsEnabled)
|
|
{
|
|
color = Color.white;
|
|
returnValue = MapElementType.Empty;
|
|
}
|
|
else
|
|
{
|
|
returnValue = mapElement.ElementSO.ElementType;
|
|
|
|
switch (returnValue)
|
|
{
|
|
case MapElementType.Wall:
|
|
color = Color.green;
|
|
break;
|
|
case MapElementType.Ladder:
|
|
color = Color.yellow;
|
|
break;
|
|
case MapElementType.BreakableWall:
|
|
color = Color.magenta;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
returnValue = MapElementType.Empty;
|
|
}
|
|
DrawBounds(playerBounds, cellSize, color);
|
|
|
|
return returnValue;
|
|
}
|
|
|
|
private static void DrawBounds(Vector2 cell2d, Vector2 cellSize, Color color)
|
|
{
|
|
Debug.DrawLine(cell2d, cell2d + new Vector2(cellSize.x, 0), color);
|
|
Debug.DrawLine(cell2d + new Vector2(cellSize.x, 0), cell2d + new Vector2(cellSize.x, cellSize.y), color);
|
|
Debug.DrawLine(cell2d, cell2d + new Vector2(0, cellSize.y), color);
|
|
Debug.DrawLine(cell2d + new Vector2(0, cellSize.y), cell2d + new Vector2(cellSize.x, cellSize.y), color);
|
|
}
|
|
|
|
protected abstract void OnDeath();
|
|
protected abstract void SetWalkingAnimation(bool isWalking);
|
|
protected abstract void SetClimbingAnimation(bool isClimbing);
|
|
|
|
|
|
|
|
private void FlipCharacter()
|
|
{
|
|
Vector3 currentScale = gameObject.transform.localScale;
|
|
currentScale.x *= -1;
|
|
gameObject.transform.localScale = currentScale;
|
|
|
|
_facingRight = !_facingRight;
|
|
}
|
|
|
|
|
|
}
|