Загрузка данных


using System.Diagnostics;
using System.Collections.Generic;
using UnityEngine;
using TMPro;

public class WalkEnemyController : MonoBehaviour
{
    public GameObject player;
    public TextMeshProUGUI livesText;
    public int enemyLive;
    public float distanceToPlayer;
    public float attackDistance;

    public float leftPoint;
    public float rightPoint;
    public float waitTimeLifePoint;
    public float waitTimeRightPoint;

    private Dictionary<int, (string type, float value)> moveScript = new Dictionary<int, (string, float)>();
    private Stopwatch waitStartTime = new Stopwatch();
    private int currentStep;
    private int currentDirection;
    private (string type, float value) currentType;

    private float speed = 10f;
    private float attackSpeed = 15f;
    private float xScale;

    private Rigidbody2D rb;
    private Animator anim;
    void Start()
    {
        FillMovingScriptList();
        FillStartDirection();

        rb = GetComponent<Rigidbody2D>();
        anim = transform.GetChild(0).GetComponent<Animator>();
        xScale = transform.localScale.x;
        enemyLive = (enemyLive > 0) ? enemyLive : 3;
        livesText.text = "HP: " + enemyLive;
    }
    void FillMovingScriptList()
    {
        moveScript[0] = ("Move", rightPoint = transform.position.x + ((rightPoint != 0) ? rightPoint : 10));
        moveScript[1] = ("Wait", waitTimeRightPoint = (waitTimeRightPoint != 0) ? waitTimeRightPoint : 2);
        moveScript[2] = ("Move", leftPoint = transform.position.x - ((leftPoint != 0) ? leftPoint : 10));
        moveScript[3] = ("Wait", waitTimeLifePoint = (waitTimeLifePoint != 0) ? waitTimeLifePoint : 2);
        
        distanceToPlayer = (distanceToPlayer > 0) ? distanceToPlayer: 12f;
        attackDistance = (attackDistance > 0) ? attackDistance : 5f;
    }
    void FillStartDirection()
    {
        currentStep = 0;
        currentType.type = "Walk";
        currentDirection = 1;
    }
    void Update()
    {
        if (!CanUpdate())
            return;
        if (anim.GetBool("Attack"))
        {
            CheckAttackTimeOut();
            return;
        }
            CheckPlayerDistation();
        if (currentType.type == "Attack")
            PlayAttackScript();
        else
            PlayMoveScript();
    }
    bool CanUpdate()
    {
        if (anim.GetBool("Damage"))
            return false;
        if (enemyLive == 0)
        {
            Destroy(transform.gameObject);
        }
        return true;
    }
    void CheckPlayerDistation()
    {
        float distance = player.transform.position.x - transform.position.x;
        if (Mathf.Abs(distance) <= distanceToPlayer)
            currentType = (type: "Attack", value: player.transform.position.x);
        else if (currentType.type != "Walk")
            FillStartDirection();
    }
    void PlayAttackScript()
    {
        float distation = currentType.value - transform.position.x;
        float point = (distation > 0) ? ((currentType.value <= moveScript[0].value) ? 
            currentType.value - attackDistance : moveScript[0].value) : 
            ((currentType.value >= moveScript[2].value) ? currentType.value + attackDistance : moveScript[2].value);

        currentDirection = (distation > 0) ? 1 : -1;
        if ((currentDirection > 0) ? (transform.position.x >= point) : (transform.position.x <= point))
        {
            transform.localScale = new Vector3(xScale * currentDirection, transform.localScale.y);
            anim.SetBool("Run", false);
            if (Mathf.Abs(distation) <= attackDistance)
            {
                anim.SetBool("Attack", true);
            }
            else
                anim.SetBool("Attack", false);
            return;
        }
        Move();
    }
    void CheckAttackTimeOut()
    {
        if (anim.GetCurrentAnimatorStateInfo(0).normalizedTime >= 1)
            anim.SetBool("Attack", false);

    }
    void PlayMoveScript()
    {
        if (moveScript[currentStep].type == "Move")
            MoveEnemyToScriptPoint();
        else if (moveScript[currentStep].type == "Wait")
            EnemyWaitOnPoint();
    }
    void MoveEnemyToScriptPoint()
    {
        if ((currentDirection > 0) ? (transform.position.x >= moveScript[currentStep].value) : (transform.position.x <= moveScript[currentStep].value))
        {
            anim.SetBool("Run", false);
            ChangeWalkState();
            return;
        }
        Move();
    }
    void Move()
    {
        float current_speed = (currentType.type == "Attack") ? attackSpeed : speed;
        transform.localScale = new Vector3(xScale * currentDirection, transform.localScale.y);
        livesText.transform.localScale = new Vector3(currentDirection, livesText.transform.localScale.y);
        rb.velocity = new Vector2(currentDirection * current_speed, rb.velocity.y);
        SetAnimationProperties();
    }
    void EnemyWaitOnPoint()
    {
        if (waitStartTime.Elapsed.TotalSeconds >= moveScript[currentStep].value)
        {
            waitStartTime.Stop();
            ChangeWalkState();
        }
    }
    void ChangeWalkState()
    {
        currentStep = (currentStep < moveScript.Count - 1) ? currentStep + 1 : 0;
        if (moveScript[currentStep].type == "Wait")
            waitStartTime.Restart();
        if (moveScript[currentStep].type == "Move")
            currentDirection *= -1;
    }
    private void SetAnimationProperties()
    {
        anim.SetBool("Run", rb.velocity.x != 0);
        anim.SetBool("Damage", false);
        anim.SetBool("Attack", false);
    }
    void OnTriggerEnter2D(Collider2D collider)
    {
        if (!collider.IsTouching(transform.GetComponent<CapsuleCollider2D>()))
            return;
        if (collider.gameObject.name == "DeathPit")
            enemyLive = 0;
        if (collider.gameObject.name == "DamageZone" && !anim.GetBool("Damage"))
        {
            enemyLive--;
            anim.SetBool("Damage", true);
            int damageDirection = ((transform.position.x - collider.transform.position.x) > 0) ? 1 : -1;
            rb.velocity = new Vector2(25f * damageDirection, 50f);
            livesText.text = "HP: " + enemyLive;
        }
    }
    private void OnCollisionEnter2D(Collision2D collision)
    {
        if (collision.gameObject.layer == LayerMask.NameToLayer("Ground") && anim.GetBool("Damage"))
            anim.SetBool("Damage", false);
    }
}