Задать вопрос
  • Почему зомби (NavMesh) стоят некоторое время а потом идут к цели?

    @DrRen7
    Ad1yar,
    Ну как вариан это все можно чутка оптимизировать

    targets.AddRange(manager.turrets);
            mainBase = manager.mainBase;
            player = manager.btr.transform;
            if (targets.Count != 0) target = targets[Random.Range(0, targets.Count)];
            else target = null;
            btr = player.GetComponent<BTR>();

    это все можно в менеджере сделать к ниму обраться и получить все с него.
    добавь в конце Start
    _agent.SetDestination(_target.position);
    Менеджер уже задан или собирается? если собирается попробуй собрать не в старте а в Awake.
    И попробуй target подебажить
  • Почему зомби (NavMesh) стоят некоторое время а потом идут к цели?

    @DrRen7
    Ad1yar, ну достаточно спорно зачем, по сути такое можно использовать если у тебя объект все должен делать одно действие, но в данном случаи у тебя одни боты будут идти другие стоять третьи атаковать, и уже у них у всех разный по длине список действий. Если тебе надо условно 1 апдейт и 1000 зомби и оптимизацию смотри Entities(DOTS). Если хочешь оптимизировать проект смотри на пуллер объектов, и Корутины можно update игнорировать и включать их, выключать что то не нужно.

    Синь скрипт на поиск таргета, а то обычно они должны тупить когда их очень много
  • Как решить ошибку build в unity?

    @DrRen7
    varfnik,
    Попробуй сбилдить только пустую сцену с условно крутящимся кубом
    private void Update()
     {
         transform.rotation *= Quaternion.Euler(transform.rotation.x + 150f*Time.deltaTime, 0, 0);
     }
    }

    если она не сбилдится то проблема с настройками компилятора
    если все будет норм то ищи ошибку в проекте, там условно может быть кнопка на которой есть скрипт который был удален и тд
  • Как решить ошибку build в unity?

    @DrRen7
    varfnik, 66433e6dcbca9118238086.png
    вот такую ошибку выдает?
  • Почему зомби (NavMesh) стоят некоторое время а потом идут к цели?

    @DrRen7
    Ad1yar,
    Во первых я поменял смысл когда враг идет. Если нет цели он стоит и ищет цель, если он подходит к цели он пытается ударить. Получается у нас приоритет это дойти по цели а не в проверки тех кто нас окружает.

    Во вторых надо сделать нормальное древо анимации, по сути ходьба бег и стояние на месте ничем не отличаются кроме скорости движения, Получается делаем в аниматоре переменную флот идл->ходьба->бег меняем через флот. Ну атака будет из идла идти , если есть смерть это прерывание.

    Ну это самый базовый скрипт, плюс чутка оптимизации. Плюс ещё вопрос как у тебя получается target
  • Как решить ошибку build в unity?

    @DrRen7
    varfnik,
    так если не помогло идешь в папку
    b:\\unity\2022.3.11f\editor\data\playbackengines\AndroidPlayer\SDK\building-tools
    там будет папка номерная заходишь в папку ищешь файл source.properties в файле строчка Rkg.Revision="___"
    В общем надо чо бы цифры в этой строке совпадали в цифровой папкой, лучше папку переименовать
  • Почему зомби (NavMesh) стоят некоторое время а потом идут к цели?

    @DrRen7
    Ad1yar, главное ещё агента настроить
    using System.Collections;
    using UnityEngine;
    using UnityEngine.AI;
    
    public class BaseAi : MonoBehaviour
    {
        float _currentHeal;
        NavMeshAgent _agent;
        Coroutine _MoveTo;
        Coroutine _TargetSearch;
    
        float _speed;
        [SerializeField] float _walkSpeed=5f;
        Transform _target;
        LayerMask _targetMask;
        bool _IsAlive;
        Animator _animator;
        private void Start()
        {
            _IsAlive = true;
            _agent = GetComponent<NavMeshAgent>();
            _animator = GetComponent<Animator>();
            _TargetSearch = StartCoroutine(TargetSearch());
        }
    
        IEnumerator TargetSearch() //там свой способ для поиска используй, это просто для примера
        {
            while (true)
            {
                Collider[] colliders = Physics.OverlapSphere(transform.position, 25f, _targetMask);
                if (colliders.Length != 0)
                {
                    _target = colliders[Random.Range(0, colliders.Length)].transform;
                }
                yield return new WaitForSeconds(0.5f);
            } 
        }
    
        void SearchOff()
        {
            StopCoroutine(_TargetSearch);
            _TargetSearch= null;
        }
        void BrainOff()
        {
            StopCoroutine(_MoveTo);
            _MoveTo = null;
        }
        private void Update()
        {
            if (_IsAlive)
            {
                if (_target == null && _TargetSearch == null) _TargetSearch = StartCoroutine(TargetSearch());
                if (_target != null && _TargetSearch != null) SearchOff();
                if (_target != null && _MoveTo == null) _MoveTo = StartCoroutine(WalkTo());
                if (_target == null && _MoveTo != null) BrainOff();
    
    
                _animator.SetFloat("MoveSpeed", _agent.speed); // переключать анимацию мы будем через скорость самого зомби 
            }
    
        }
    
        IEnumerator WalkTo()
        {
            while (true)
            {
                _agent.SetDestination(_target.position);
                if (_agent.remainingDistance! > _agent.stoppingDistance) TryAttack();
                if(_agent.remainingDistance>15f) yield return new WaitForSeconds(0.8f); //SetDestination ресурсоемкая команда
                else yield return new WaitForSeconds(0.2f);                            //делаем бота более распоропнее, чем ближе он подходит 5 раз в секунду вероятно тож много 
    
            }
        }
    
        void TryAttack()
        {
            _agent.speed = 0f;
            _animator.SetTrigger("Attack");
            Invoke("RetrigetAttack", 0.5f); //отжатие триггера на атаку, лучше сделать через анимацию, а так надо поставить примерное время анимации удара
            Collider[] colliders = Physics.OverlapSphere(transform.position+transform.up+transform.forward*0.5f, 1.5f, _targetMask);
            foreach (Collider collider in colliders)
            {
                switch (collider.tag) // можно сделать проще повесить на все элементы скрипт Heals и брать только его 
                {
                    case "Player":
                        if (collider.TryGetComponent(out Mover btr))     //у меня тут свои скрипты будут 
                        {
                            btr.TakeDamage(Random.Range(25, 35));
                        }
                        break;
                    case "Turret":
                        if (collider.TryGetComponent(out Turret turret))
                        {
                            turret.TakeDamage(Random.Range(20, 30));
                        }
                        break;
                    case "Base":
                        if (collider.TryGetComponent(out Base Mybase))
                        {
                            Mybase.TakeDamage(Random.Range(70, 90));
                        }
                }
            }
            
    
        }
    
        public void RetrigetAttack() //триггер его можну отдажть через анимацию или коррутину
        {
            _animator.ResetTrigger("Attack");
            _agent.speed = _walkSpeed;
        }
    
    
        public void TakeDamage(float damage)
        {
            _currentHeal -= damage;
            if (_currentHeal! > 0) Die();
        }
        void Die()
        {
    
            _IsAlive = false;
            if(_TargetSearch!=null) SearchOff();
            if(_MoveTo!=null)BrainOff();
            _agent.enabled = false;
            _animator.SetTrigger("Die");
    
        }
    }
  • Почему зомби (NavMesh) стоят некоторое время а потом идут к цели?

    @DrRen7
    Щас попробуй что нить накидать, я только не понимаю зачем тут коррутина.

    плюс есть не значимые места типо
    foreach (Collider coll in colliders)
                        {
                            if (coll != null)


    или
    if (hp > 0)
                {

    да и выдавать одинаковую(по смыслу) анимацию через булиен тож такое
  • Как можно исправить поворот ракет?

    @DrRen7
    Блок с ракетами стоит нормально, а трансформ самих ракет какой? вероятно блок сделан был в юнити а потом скинут трансформ, но ракеты получили новый трансформ родительский-дочерний. В общем трансформ самих ранет надо на 0 оставить, ну оффсет по позициям только оставить
  • Как решить ошибку build в unity?

    @DrRen7
    Проект в гейммоде запускается? Не английских названий/файлов по пути нету?
  • (Unity2D)Вопрос по Перемещению префабов при спавне?

    @DrRen7
    22Alex22,
    ну так собственно а как новый враг получает точки куда идти?
    Попробуй подебажить посмотреть а если у него финальная точка и таргет точка.
    Вероятно в старте надо создать запрос на поиск трансформа всех точек, ну условно точкам накинуть таг и найти по тагу
  • (Unity2D)Вопрос по Перемещению префабов при спавне?

    @DrRen7
    Как трансформ куда идти получаешь?
  • Не сохраняется переменная в Unity через PlayerPrefs?

    @DrRen7
    NattRiy1,
    Ну у тебя вместо присвоения переменных они создают заново, и Start у тебе ещё раз создает skin1, что со сути уже должно быть ошибкой, потому у как уже есть глобальный skin1 и не даль скомпилироваться
    Просто такое подсвечивает и сразу пишет что это не верно, поэтому в глаза и не кидается) особенно когда код без тега)
  • Не сохраняется переменная в Unity через PlayerPrefs?

    @DrRen7
    ой да я даж не всматривался) с переменными совсем беда.... хотя странно что это получилось запустить должна была быть ошибка
  • Как сделать так чтобы объект шёл рандомно от объекта к объекту?

    @DrRen7
    Ost234,
    Просто на объект все будет работь.
    Если есть навмешь, но к объекту надо добавить агента то тогда уже движение будет не
    void MoveToPlayer()
        {
            transform.position = Vector3.MoveTowards(transform.position, _playerPos.position, _speed * Time.deltaTime);
        }


    а будет
    void MoveToPlayer()
        {
            agent.SetDestination(_playerPos.position);
        }
  • Не сохраняется переменная в Unity через PlayerPrefs?

    @DrRen7
    Ну тадо тогда посидеть по дебагать, когда данные перестают записываться считываться.
    Есть еще вариант немного все изменить те не на прямую работать с PlayerPrefs а через условно другой скрипт который будет хранить переменные. Условно при старте он возьмет все значение(из PlayerPrefs) и ты будешь работать со значениями в этом скрипте, а когда надо просто то сохранить все значения
  • Если переносить объект и держать долгое время и скидывать то он падает очень быстро. C# Что делать?

    @DrRen7
    matikYT, Ну тогда все проще скинь Velocity.у Rigidbody (а то она накапливается) перед падением плюс еще надо поставить интерполяцию(у Rigidbody) что бы при объект не проходил через коллайдер при большой скоростью
  • Как лучше хранить и доставать ресурсы в unity?

    @DrRen7
    Ну класс Item ты создаешь в папке с проектом и его заполняешь потом кидаешь в общую базу (ItemHolder выше), а там уже делаешь с различные списки и поиски.
    Ну я создаю персонажа условно
    using UnityEngine;
    
    public class Player : MonoBehaviour
    {
        [Header("PlayerAnker")]
        [SerializeField] Transform _armorPos;
        [SerializeField] Transform _weaponPos;
        [SerializeField] Transform _helmetPos;
    
        ItemHolder _ItemBase;
    
        [Header("inventory")]
        Item _helmetItem;
        Item _weaponItem;
        Item _armorItem;
    
        private void Start()
        {
            _ItemBase = GameObject.FindGameObjectWithTag("GameMaster").GetComponent<ItemHolder>();
            NewSword();
        }
    
        void NewSword()
        {
            _weaponItem = _ItemBase._allITemList[0]; //<= ну условно у меня там есть метод для получение нужного меча
            EquipItem(_weaponItem, _weaponPos);
        }
    
        void EquipItem(Item item,Transform pos)
        {
            item.ReOpenItem(pos);
        }
    }


    Ну и по сути все Item это asset , и в них хранятся ссылки на спрайты и без условного ReOpenItem это просто адрес что то типо такого
    _sprites:
      - {fileID: 10913, guid: 0000000000000000f000000000000000, type: 0}

    Замысел в том что это хорошо все масштабируется, тебе же нужны не только внешний вид но и статы это все тоже можно получить через наследование там у брони защита или урон у оружия.
    Ну и с иконками все для инвентаря работает так же, написать метод что вытащит их Item сплайт для инвентаря
  • Как лучше хранить и доставать ресурсы в unity?

    @DrRen7
    Varhelm,
    А понял тебе просто надо распаковать scriptableObject в gameObject щас подумаю с 2д я особо не знаком щас что нить попробуй по быстрому накидать

    using UnityEngine;
    
    public class Item : ScriptableObject
    {
        public enum ObjType
        {
            HeavyArmor, LightArmor, Swords, Stuffs
        }
        public int _id;
        public string _name;
        public ObjType _Objtype;
        public Sprite[] _sprites;
        public Sprite icon;
    
    
        public virtual void ReOpenItem(Transform pos)
        {
    
            GameObject openObj =new GameObject();
            openObj.transform.position = pos.position;
            openObj.transform.name = _name;
            for (int i=0; i< _sprites.Length; i++)
            {
                GameObject sonObj = new GameObject();
                sonObj.transform.SetParent(openObj.transform);
                sonObj.transform.localPosition = Vector2.zero; //?
                sonObj.AddComponent<SpriteRenderer>().sprite = _sprites[i];
                sonObj.transform.name = "Sprite " + (i + 1);
            }
    
        }
    }

    Ну сейчас по идеи объект должен открыться в том месте где укажешь, для оптимизации можно сделать что объект создается 1 раз а потом просто меняют имя и спрайты если надо то делает ещё дочерние объекты или их удаляет
  • NullReferenceException: Object reference not set to an instance of an object?

    @DrRen7
    ian77, Текст это просто компонент как коллайдер и прочее создаешь пустой объект и добавляешь компонент текст
    662e330ebdae6672962592.png