Files
Gnome-s-Bounty/Assets/Scripts/Utilities/Character.cs
T
2026-06-22 21:09:22 +03:00

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;
}
}
}