Задать вопрос

Кто нибудь может помочь оценить код (связку) на C# для игры на Unity?

Новичок и с кодом не работал.Хотелось бы просто услышать мнение, советы и т.д. Скорее всего до конца это не работает как надо, но мы стараемся, честно)
Это скрипт ИИ. Намешано дофига всего). Задача бежать в сторону Обелиска, остановиться и атаковать, если в поле зрения попадается игрок, то бежит к нему и атакует. Первый раз пробовал ссылаться и на переменные и методы из других скриптов и работал с параметрами).
public class EnemyAIwithFOV : MonoBehaviour
{
    [Header("Переменные для настройки баланса")]
    public attackEvent attackEvent;
    [Space]
    [Header("Абсолютное обноружение")]
    [Range(1, 3)] public int minDistance = 1;
    [Header("Настройка дистанции атаки")]
    [Range(0, 20)] public float attackRadius = 10;
    [Header("Настройка дистанции обзора")]
    [Range(1, 40)] public float sightRadius = 16;
    [Header("Настройка угла обзора")]
    [Range(0, 360)] public int fieldOfViewAngle = 60; // угол обзора
    private int absoluteSign = 2;
    [Header("Цели для выбора приоритета")]
    public Transform primaryTarget;
    public Transform secondaryTarget;
    [Header("Атрибуты")]
    public NavMeshAgent nav;
   
    [Header("Цели")]
   
    [Header("Текущая цель")]
    [SerializeField] private Transform currentTarget;
    [Header("Лист персонажей находящихся в радиусе")]
    [SerializeField] private List<Transform> targetsInRange = new List<Transform>();
    [Header("Лист персонажей находящихся в видимости")]
    [SerializeField] private List<Transform> targetsInSight = new List<Transform>();
    public Animator EnemyAnim;
    public bool attack;
    public bool attackPlayer;
    public bool attackStella;
    public void SearchTargetPosition()
    {
        Collider[] hitColliders = Physics.OverlapSphere(transform.position, attackRadius);
        foreach (Collider hitCollider in hitColliders)
        {
            if (hitCollider.CompareTag("Enemy") || hitCollider.CompareTag("Player"))
            {
                targetsInRange.Add(hitCollider.transform);
            }
        }
    }
    private void Start()
    {
        EnemyAnim = GetComponent<Animator>();
        nav = GetComponent<NavMeshAgent>();
        SearchTargetPosition();
        attack = false;
        attackPlayer = false;
        attackStella = false;
    }
    
    public void Attack()
    {
        StartCoroutine("AttackWithTime");
        
        EnemyAnim.SetTrigger("Attack");
    }
    public IEnumerator AttackWithTime()
    {
        yield return new WaitForSeconds(0.8f);
        int attackTarget = attackEvent.targetToDamage;
        attackEvent.AttackEnemy(attackTarget);
        yield return new WaitForSeconds(1.6f);
    }
    private void Update()
    {
        absoluteSign = minDistance;
        Collider[] hitColliders = Physics.OverlapSphere(transform.position, attackRadius);
        foreach (Collider hitCollider in hitColliders)
        {
            if (hitCollider.CompareTag("Enemy") || hitCollider.CompareTag("Player"))
            {
                Transform target = hitCollider.transform;
                Vector3 targetDirection = (target.position - transform.position).normalized;
                if (currentTarget != null && Vector3.Distance(nav.transform.position, currentTarget.position) <= attackRadius)
                {
                    nav.isStopped = true;
                    EnemyAnim.SetBool("nav.isStoped", nav.isStopped);
                }
                else
                {
                    nav.isStopped = false;
                    EnemyAnim.SetBool("nav.isStoped", nav.isStopped);
                }
                foreach (Collider enemy in hitColliders)
                {
                    if (enemy.CompareTag("Player") && currentTarget == CompareTag("Player"))
                    {
                        attack = true;
                        attackPlayer = true;
                        Attack();
                    }
                    else
                    {
                        attack = false;
                        attackPlayer = false;
                        attackStella = false;
                        StartCoroutine("AttackWithTime");
                    }
                    if (enemy.CompareTag("Enemy") && currentTarget == CompareTag("Enemy"))
                    {
                        attack = true;
                        attackStella = true;
                        Attack();
                    }
                    else
                    {
                        attack = false;
                        attackPlayer = false;
                        attackStella = false;
                        StartCoroutine("AttackWithTime");
                    }
                    
                    transform.LookAt(new Vector3(currentTarget.position.x, transform.position.y, currentTarget.position.z));
                    
                }
            }
        }
        if (currentTarget == null || !targetsInRange.Contains(currentTarget))
        {
            currentTarget = GetNewTarget();
        }
        if (currentTarget != null && Vector3.Distance(transform.position, currentTarget.position) >= minDistance)
        {
            TransformNavMesh();
        }
        targetsInSight.Clear();
        Collider[] targetsInViewRadius = Physics.OverlapSphere(transform.position, sightRadius);
        Collider[] targetInAbsolutRadius = Physics.OverlapSphere(transform.position, absoluteSign);
        foreach (Collider targetCollider in targetInAbsolutRadius) 
        {
            if (targetCollider.CompareTag("Player"))
            {
                targetsInSight.Add(targetCollider.transform);
            }
        }
        foreach (Collider targetCollider in targetsInViewRadius)
        {
            if (targetCollider.CompareTag("Enemy") || targetCollider.CompareTag("Player"))
            {
                Transform target = targetCollider.transform;
                Vector3 targetDirection = (target.position - transform.position).normalized;
                float targetDistance = Vector3.Distance(transform.position, target.position);
                if (targetDistance <= sightRadius && Vector3.Angle(transform.forward, targetDirection) < fieldOfViewAngle / 2 || targetDistance <= absoluteSign) 
                {
                    RaycastHit hit;
                    Debug.DrawLine(transform.position, target.position);
                    if (Physics.Raycast(transform.position, targetDirection, out hit, targetDistance))
                    {
                        if (hit.transform == target)
                        {
                            targetsInSight.Add(target);
                        }
                    }
                }
            }
        }
        if (secondaryTarget != null && targetsInSight.Contains(secondaryTarget) && !targetsInSight.Contains(primaryTarget))
        {
            currentTarget = secondaryTarget;
        }
        else if (currentTarget == secondaryTarget && !targetsInSight.Contains(secondaryTarget))
        {
            currentTarget = primaryTarget;
        }
        if (currentTarget != null && Vector3.Distance(transform.position, currentTarget.position) > sightRadius)
        {
            currentTarget = null;
        }
    }
    private Transform GetNewTarget()
    {
        Transform newTarget = null;
        if (primaryTarget != null)
        {
            newTarget = primaryTarget;
        }
        if (secondaryTarget != null && targetsInSight.Contains(secondaryTarget))
        {
            newTarget = secondaryTarget;
        }
        if (newTarget == null && targetsInRange.Count > 0)
        {
            newTarget = targetsInRange[Random.Range(0, targetsInRange.Count)];
        }
        return newTarget;
    }
    public void TransformNavMesh()
    {
        nav.SetDestination(currentTarget.transform.position);
    }
}

public class attackEvent : MonoBehaviour
{
public healthBar healthBar;
public healthStella healthStella;
public float minDamage;
public float maxDamage;
public float curretDamage;
public EnemyAIwithFOV enemyScript;
public bool attackPlayer;
public bool attackStella;
public int targetToDamage;
public void Start()
{
attackPlayer = false;
attackStella = false;
}
public void Update()
{
CheckTargetForDamage();
}
public void CheckTargetForDamage()
{
if (enemyScript.attack == true && enemyScript.attackPlayer == true)
{
attackPlayer = true;
}
else attackPlayer = false;
if (enemyScript.attack == true && enemyScript.attackStella == true)
{
attackStella = true;
}
else attackStella = false;
if (attackPlayer)
{
targetToDamage = 1;
Debug.Log("Враг бьет игрока");
}
if (attackStella)
{
targetToDamage = 2;
Debug.Log("Враг бьет обелиск");
}
if (!attackPlayer && !attackStella)
{
targetToDamage = 0;
Debug.Log("Враг никого не бьет");
}
}
public void Damage(float minDamage, float maxDamage, out float curretDamage)
{
curretDamage = Random.Range(minDamage, maxDamage);
}
public void SetDamage()
{
Damage(minDamage, maxDamage, out curretDamage);
}
public void AttackEnemy(int whoToBeat)
{
SetDamage();
if (whoToBeat == 1)
{
healthBar.GetDamage();
}
if (whoToBeat == 2)
{
healthStella.GetDamage();
}
}
}

В нем он проверяет кого бьет противник и так же присваивает для цели "типо" индекс (возможно это можно было реализовать через массивы, но я пока плохо в них разбираюсь) и генерируется случайный урон
И после из этого скрипта все отправляется в показатели здоровья целей.
  • Вопрос задан
  • 152 просмотра
Подписаться 1 Средний 4 комментария
Решения вопроса 2
GavriKos
@GavriKos Куратор тега Unity
Из за такого выравнивания это читать невозможно.
Ответ написан
@OwDafuq
1) Зачем вы сразу лезете в Unity, если не знаете даже основ C#? Без знаний основ вы не сделаете "крутой код";
2) Форматирование - жесть, присоединяюсь к GavriKos, прочитать что-либо нереально;

Смысл данных площадок не в том, чтобы научить вас правильно/красиво/etc. писать код, а чтобы помочь разобраться в какой-то конкретной ошибке в вашем коде, с аудитом кода вам не сюда :)
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@alexanderfandeev
Для начала - хорошо. Я бы не слушал "мастеров", которые из-за своей лени и нежелании в чем-то разобраться сразу осуждают. Когда я писал свой первый проект для устройства на работу, в коде было намного больше неточностей и глупостей в плане написания кода и его правильности. В любом случае, если код работает, и результат тот, который Вы ожидаете, значит всё хорошо написано. С опытом придет понимание. Главное, - это не бросать и развиваться дальше.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы