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(); if (rigidBody2D != null) { _collider2D = GetComponent(); rigidBody2D.constraints = RigidbodyConstraints2D.FreezeRotation; } else { rigidBody = GetComponent(); _capsuleCollider = GetComponent(); 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().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().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; } } }