221 lines
6.0 KiB
C#
221 lines
6.0 KiB
C#
using System.Linq;
|
|
using UnityEngine;
|
|
|
|
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]
|
|
private LayerMask _mapLayer;
|
|
|
|
|
|
|
|
private Rigidbody2D _body;
|
|
private CapsuleCollider2D _capsuleCollider;
|
|
protected bool _isOnBridge;
|
|
private 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(0.6f, 1f);
|
|
}
|
|
|
|
protected void Spawn()
|
|
{
|
|
transform.position = _spawnPoint.transform.position;
|
|
}
|
|
|
|
protected void MoveTo(float inputHorizontal, float inputVertical)
|
|
{
|
|
var block = GetMapElement();
|
|
|
|
if (block?.ElementSO.ElementType == MapElementType.Water)
|
|
{
|
|
Death();
|
|
}
|
|
|
|
_isOnBridge = block?.ElementSO.ElementType == MapElementType.Bridge && !_isFalling;
|
|
|
|
if (block)
|
|
{
|
|
isAllowVertical = false;
|
|
_isFalling = false;
|
|
float h_movement = inputHorizontal;
|
|
|
|
if (h_movement > 0 && !_facingRight || h_movement < 0 && _facingRight)
|
|
{
|
|
FlipCharacter();
|
|
}
|
|
|
|
SetWalkingAnimation(h_movement != 0);
|
|
|
|
_isOnLadder = block.ElementSO.ElementType == MapElementType.Ladder;
|
|
|
|
if (_isOnLadder)
|
|
{
|
|
float ladderCenterDistance = Mathf.Abs(transform.position.x - block.transform.position.x);
|
|
|
|
float v_movement = inputVertical;
|
|
isAllowVertical = ladderCenterDistance < 0.3f;
|
|
|
|
|
|
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;
|
|
_isOnLadder = false;
|
|
}
|
|
|
|
|
|
if (_isOnLadder || _isOnBridge)
|
|
{
|
|
_body.gravityScale = 0;
|
|
}
|
|
else
|
|
{
|
|
_body.gravityScale = 1;
|
|
}
|
|
if (_isFalling)
|
|
{
|
|
_body.velocity = new Vector2(0, _body.velocity.y);
|
|
SetWalkingAnimation(false);
|
|
|
|
if (block?.ElementSO.ElementType == MapElementType.Ladder)
|
|
{
|
|
_body.velocity = Vector2.zero;
|
|
_isOnLadder = true;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
private void Death()
|
|
{
|
|
OnDeath();
|
|
|
|
}
|
|
|
|
|
|
private MapElement GetMapElement()
|
|
{
|
|
|
|
var playerBounds = _capsuleCollider.bounds.center;
|
|
|
|
var collider = BoxCast(playerBounds, _cellSize, 0f, Vector3.forward, .01f, _mapLayer);
|
|
Color color = Color.red;
|
|
MapElement mapElement = null;
|
|
if (collider.Length > 0)
|
|
{
|
|
var elements=collider.Select(x=>x.transform.GetComponent<MapElement>());
|
|
mapElement = elements.Where(x => x.ElementSO.ElementType == MapElementType.Ladder).FirstOrDefault();
|
|
if(mapElement == null)
|
|
{
|
|
mapElement = elements.First();
|
|
}
|
|
}
|
|
|
|
return mapElement;
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
static public Collider2D[] BoxCast(Vector2 origin, Vector2 size, float angle, Vector2 direction, float distance, int mask)
|
|
{
|
|
//RaycastHit2D hit = Physics2D.BoxCast(origin, size, angle, direction, distance, mask);
|
|
var collider = Physics2D.OverlapBoxAll(origin, size, angle, mask);
|
|
//Setting up the points to draw the cast
|
|
Vector2 p1, p2, p3, p4, p5, p6, p7, p8;
|
|
float w = size.x * 0.5f;
|
|
float h = size.y * 0.5f;
|
|
p1 = new Vector2(-w, h);
|
|
p2 = new Vector2(w, h);
|
|
p3 = new Vector2(w, -h);
|
|
p4 = new Vector2(-w, -h);
|
|
|
|
Quaternion q = Quaternion.AngleAxis(angle, new Vector3(0, 0, 1));
|
|
p1 = q * p1;
|
|
p2 = q * p2;
|
|
p3 = q * p3;
|
|
p4 = q * p4;
|
|
|
|
p1 += origin;
|
|
p2 += origin;
|
|
p3 += origin;
|
|
p4 += origin;
|
|
|
|
Vector2 realDistance = direction.normalized * distance;
|
|
p5 = p1 + realDistance;
|
|
p6 = p2 + realDistance;
|
|
p7 = p3 + realDistance;
|
|
p8 = p4 + realDistance;
|
|
|
|
|
|
//Drawing the cast
|
|
Color castColor = collider.Length > 0 ? Color.red : Color.green;
|
|
Debug.DrawLine(p1, p2, castColor);
|
|
Debug.DrawLine(p2, p3, castColor);
|
|
Debug.DrawLine(p3, p4, castColor);
|
|
Debug.DrawLine(p4, p1, castColor);
|
|
|
|
Debug.DrawLine(p5, p6, castColor);
|
|
Debug.DrawLine(p6, p7, castColor);
|
|
Debug.DrawLine(p7, p8, castColor);
|
|
Debug.DrawLine(p8, p5, castColor);
|
|
|
|
Debug.DrawLine(p1, p5, Color.grey);
|
|
Debug.DrawLine(p2, p6, Color.grey);
|
|
Debug.DrawLine(p3, p7, Color.grey);
|
|
Debug.DrawLine(p4, p8, Color.grey);
|
|
|
|
//collider
|
|
//if (hit)
|
|
//{
|
|
// var color = hit.point.x > origin.x ? Color.yellow : Color.cyan;
|
|
// Debug.DrawLine(hit.point, hit.point + hit.normal.normalized * 0.2f, color);
|
|
//}
|
|
|
|
return collider;
|
|
}
|
|
}
|