219 lines
6.3 KiB
C#
219 lines
6.3 KiB
C#
using System.Linq;
|
|
using System;
|
|
using UnityEngine;
|
|
|
|
public abstract class Character : MonoBehaviour
|
|
{
|
|
[SerializeField]
|
|
protected Animator _animator;
|
|
[SerializeField]
|
|
private Transform _visualRoot;
|
|
[SerializeField]
|
|
private float _movementSpeed = 1.5f;
|
|
|
|
[SerializeField]
|
|
private LayerMask _mapLayer;
|
|
|
|
private Rigidbody rigidBody;
|
|
private Rigidbody2D rigidBody2D;
|
|
private Collider2D _collider2D;
|
|
private CapsuleCollider _capsuleCollider;
|
|
private float _lastFlipTime;
|
|
private const float FlipCooldown = 0.12f;
|
|
protected bool _isOnBridge;
|
|
private bool _isOnLadder = false;
|
|
|
|
protected bool _isFalling;
|
|
protected bool _facingRight = true;
|
|
|
|
protected bool isCanGoDown = false;
|
|
protected bool isCanClimbUp=false;
|
|
public bool IsAllowVertical { get; set; }
|
|
protected bool isAllowRight = true;
|
|
protected bool isAllowLeft = true;
|
|
private Vector2 _cellSize;
|
|
|
|
public event EventHandler OnCharacterDeath;
|
|
|
|
public void Init()
|
|
{
|
|
rigidBody2D = GetComponent<Rigidbody2D>();
|
|
if (rigidBody2D != null)
|
|
{
|
|
_collider2D = GetComponent<Collider2D>();
|
|
rigidBody2D.constraints = RigidbodyConstraints2D.FreezeRotation;
|
|
}
|
|
else
|
|
{
|
|
rigidBody = GetComponent<Rigidbody>();
|
|
_capsuleCollider = GetComponent<CapsuleCollider>();
|
|
if (rigidBody != null)
|
|
{
|
|
rigidBody.constraints = RigidbodyConstraints.FreezeRotation;
|
|
}
|
|
}
|
|
|
|
_cellSize = new Vector2(0.6f, 1f);
|
|
|
|
if (_visualRoot == null)
|
|
{
|
|
if (_animator != null && _animator.transform != transform)
|
|
{
|
|
_visualRoot = _animator.transform;
|
|
}
|
|
else if (transform.childCount > 0)
|
|
{
|
|
_visualRoot = transform.GetChild(0);
|
|
}
|
|
else
|
|
{
|
|
_visualRoot = transform;
|
|
}
|
|
}
|
|
|
|
if (_animator != null)
|
|
{
|
|
_animator.applyRootMotion = false;
|
|
}
|
|
}
|
|
|
|
private const float MovementFlipThreshold = 0.1f;
|
|
|
|
protected void MoveTo(float inputHorizontal, float inputVertical)
|
|
{
|
|
_isFalling = false;
|
|
float h_movement = inputHorizontal;
|
|
|
|
if (Mathf.Abs(h_movement) > MovementFlipThreshold)
|
|
{
|
|
if (Time.time - _lastFlipTime > FlipCooldown)
|
|
{
|
|
if (h_movement > 0 && !_facingRight || h_movement < 0 && _facingRight)
|
|
{
|
|
FlipCharacter();
|
|
_lastFlipTime = Time.time;
|
|
}
|
|
}
|
|
}
|
|
|
|
SetWalkingAnimation(Mathf.Abs(h_movement) > Mathf.Epsilon);
|
|
|
|
//_isOnLadder = block.ElementSO.ElementType == MapElementType.Ladder;
|
|
|
|
if (IsAllowVertical)
|
|
{
|
|
if (rigidBody2D != null)
|
|
{
|
|
rigidBody2D.gravityScale = 0f;
|
|
float v_movement = inputVertical;
|
|
SetClimbingAnimation(v_movement != 0);
|
|
rigidBody2D.velocity = new Vector2(h_movement * _movementSpeed, v_movement * _movementSpeed);
|
|
}
|
|
else if (rigidBody != null)
|
|
{
|
|
rigidBody.useGravity = false;
|
|
float v_movement = inputVertical;
|
|
SetClimbingAnimation(v_movement != 0);
|
|
rigidBody.velocity = new Vector2(h_movement * _movementSpeed, v_movement * _movementSpeed);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (rigidBody2D != null)
|
|
{
|
|
rigidBody2D.gravityScale = 1f;
|
|
rigidBody2D.velocity = new Vector2(h_movement * _movementSpeed, rigidBody2D.velocity.y);
|
|
}
|
|
else if (rigidBody != null)
|
|
{
|
|
rigidBody.useGravity = true;
|
|
rigidBody.velocity = new Vector3(h_movement * _movementSpeed, rigidBody.velocity.y, 0f);
|
|
}
|
|
}
|
|
// else
|
|
// {
|
|
// _isFalling = true;
|
|
// _isOnLadder = false;
|
|
// }
|
|
|
|
|
|
if (_isOnLadder || _isOnBridge)
|
|
{
|
|
//_body.gravityScale = 0;
|
|
}
|
|
else
|
|
{
|
|
//_body.gravityScale = 1;
|
|
}
|
|
// if (_isFalling)
|
|
// {
|
|
// _body.linearVelocity = new Vector2(0, _body.linearVelocity.y);
|
|
// SetWalkingAnimation(false);
|
|
|
|
// if (block?.ElementSO.ElementType == MapElementType.Ladder)
|
|
// {
|
|
// _body.linearVelocity = Vector2.zero;
|
|
// _isOnLadder = true;
|
|
// }
|
|
// }
|
|
|
|
}
|
|
|
|
protected void Death()
|
|
{
|
|
OnCharacterDeath?.Invoke(this,EventArgs.Empty);
|
|
}
|
|
|
|
private bool CanClimbUp()
|
|
{
|
|
// var rayCastHit = Physics2D.Raycast(_capsuleCollider.bounds.center, Vector2.down, _capsuleCollider.size.y / 2,_mapLayer);
|
|
// if(rayCastHit)
|
|
// if(rayCastHit.collider.transform.GetComponent<MapElement>().ElementSO.ElementType==MapElementType.Ladder)
|
|
// {
|
|
// return true;
|
|
// }
|
|
return false;
|
|
}
|
|
|
|
// private bool CanGoDown()
|
|
// {
|
|
// var rayCastHit = Physics2D.RaycastAll(_capsuleCollider.bounds.center, Vector2.down, 0.5f, _mapLayer);
|
|
// var isNoladder = rayCastHit.Any(x => x.collider.transform.GetComponent<MapElement>().ElementSO.ElementType != MapElementType.Ladder);
|
|
// foreach (var hit in rayCastHit)
|
|
// {
|
|
// Debug.DrawLine(hit.point, hit.point + hit.normal.normalized * 0.2f, isNoladder? Color.blue: Color.red);
|
|
// }
|
|
|
|
// if (isNoladder)
|
|
// {
|
|
// return false;
|
|
// }
|
|
|
|
// return true;
|
|
// }
|
|
|
|
protected abstract void SetWalkingAnimation(bool isWalking);
|
|
protected abstract void SetClimbingAnimation(bool isClimbing);
|
|
|
|
private void FlipCharacter()
|
|
{
|
|
_facingRight = !_facingRight;
|
|
|
|
var flipTarget = _visualRoot != null ? _visualRoot : transform;
|
|
var localScale = flipTarget.localScale;
|
|
localScale.x = Mathf.Abs(localScale.x) * (_facingRight ? 1f : -1f);
|
|
flipTarget.localScale = localScale;
|
|
|
|
if (rigidBody2D != null)
|
|
{
|
|
rigidBody2D.angularVelocity = 0f;
|
|
}
|
|
else if (rigidBody != null)
|
|
{
|
|
rigidBody.angularVelocity = Vector3.zero;
|
|
}
|
|
}
|
|
|
|
|
|
}
|