Ответы пользователя по тегу C#
  • Как десериализовать массив именных объектов в именно объекте посредством Unity JsonUtility?

    @Ente
    Unity developer
    1) Не используй стандартный JSON от Unity - он ужасен, он не работает с уровнем вложенности большим, чем 1.
    2) Newtonsoft гораздо лучше, сама команда Unity включила его в свои packages.
    3) Чтобы считать класс в JSON, тебе нужно создать его с атрибутом [Serializable]. Также обрати внимание, что не все базовые классы/структуры в Unity могут быть сериализованы. Например, могут возникнуть проблемы с Vector3, кое где может потребовать написать свой класс для этого.
    Ответ написан
    Комментировать
  • Как лучше написать?

    @Ente
    Unity developer
    61dac9c0087d2865358929.jpeg
    Решарпер предлагает использовать второй вариант и его можно считать авторитетом в плане оформления.
    В плане производительности разницы нет, это всего лишь оформление кода и ситуаций когда нужно было бы менять порядок просто нету.
    Ответ написан
    Комментировать
  • Как сделать рандомный спавн нескольких объектов в 1 скрипте?

    @Ente
    Unity developer
    Почему неиграбельно? Создай один префаб - это будет главный образец для метеоритов. Затем создай наследованные префабы от него и дай им уникальные характеристики, например размер, спрайт, какие-то настройки скриптов. Затем создай один скрипт MeteorSpawner. Затем можешь набросать несколько скриптов и каждому выставить уникальные значения, либо разделить на разные GameObject'ы.

    [SerializeField] private GameObject prefab;
    [SerializeField] private Vector2 minPos;
    [SerializeField] private Vector2 maxPos;
    [SerializeField] private Vector2 spawnRate;
    
    private IEnumerator Start()
    {
         while (true)
         {
              yield return new WaitForSeconds(Random.Range(spawnRate.x, spawnRate.y));
              var pos = new Vector2(Random.Range(min.x, max.x), Random.Range(min.y, max.y));
              Instantiate(prefab, pos, Quaternion.identity);
         }
    }
    Ответ написан
    1 комментарий
  • Как задать движение по кривой Безье при старте приложения?

    @Ente
    Unity developer
    Воспользуйся бесплатным плагином из стора - Bézier Path Creator. В нем уже встроены и построение, и нахождение любого положения на кривой и прочие полезные фичи.
    Ответ написан
    Комментировать
  • Как исправить ошибку в коде C#?

    @Ente
    Unity developer
    WheelCollider убери
    Ответ написан
    Комментировать
  • Как сделать чтобы Player наносил урон Enemy?

    @Ente
    Unity developer
    Сделай себе два скрипта, первый будет для всех объектов в игре, которые обладают здоровьем, это могут быть персонажи (твой игрок, враги), предметы (двери, стены и т.п.)

    У этих объектов будет скрипт, назовем его Health.cs

    [SerializedField] private int hitpoints = 100;
    public Action<int, int> OnChange;
    
    public void Change(int amount)
    {
               hitpoints += amount;
               OnChange?.Invoke(hitpoints, amount);
    }


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

    Второй скрипт - Damage.cs. Он будет работать на триггерах в Unity, и когда объекты пересекаются между собой, то происходит вызов функции урона, например, если персонаж встанет в огонь, его затронет пуля или меч. Само собой нужно проставить им триггеры нужного размера, как объекту с уроном, так и тому, кому наносится урон + поставить правильно матрицу коллизий, чтобы OnTriggerEnter2D не затрагивал другие объекты, которые не являются его целью.

    [SerializedField] private int amount = -10;
    public Action<int> OnDamage;
    
    private void OnTriggerEnter2D(Collider2D collider)
    {
          collider.gameObject.GetComponent<Health>().Change(amount);
          OnDamage?.Invoke(amount);
    }
    Ответ написан
    21 комментарий
  • Как изменять массово свойства элементам?

    @Ente
    Unity developer
    Создаешь скрипт AlphaChanger.cs, в нем такой код

    private SpriteRenderer spriteRenderer; //Кэшируем компонент
    [SerializeField] private float speed = 1; //Скорость фейдинга
            
    private void Awake()
    {
    	spriteRenderer = GetComponent<SpriteRenderer>();
    }
    
    public void Show()
    {
    	StartCoroutine(SetVisibility(1));
    }
    
    public void Hide()
    {
    	StartCoroutine(SetVisibility(0));
    }
    
    private IEnumerator SetVisibility(float finish)
    {
    	var color = spriteRenderer.color;
    	while (true)
    	{
    		color.a = Mathf.MoveTowards(color.a, finish, speed * Time.deltaTime);
    		spriteRenderer.color = color;
    		if (color.a == finish) break;
    		yield return null;
    	}
    }


    Вешаешь этот скрипт на все спрайты, которые будут фейдится. Если нужно вызвать его у детей gameobjecta, заводишь еще один скрипт AlphaChangerManager, в нем пишешь такие функции.

    private AlphaChanger[] alphaChangers; //Кэшируем компоненты детей
    private void Awake()
    {
    	alphaChangers = GetComponentsInChildren<AlphaChanger>();
    }
    
    public void ShowAll()
    {
    	alphaChangers.ForEach(a => a.Show());
    }
    
    public void HideAll()
    {
    	alphaChangers.ForEach(a => a.Hide());
    }


    Преимущество в том, что можно вызвать как и отдельный фейд у любого спрайта, так и все сразу, через общий скрипт
    Ответ написан
    Комментировать
  • Как сделать индикатор заполнения в Unity, при нажатии кнопки?

    @Ente
    Unity developer
    Создаешь два gameobjecta - один с кнопкой, второй со слайдером. У слайдера выключаешь возможность управлять через мышь и убираешь лишние элементы, чтобы получился слайдер с заполнением. Выставляешь MinMax = 0, 1;

    Затем заводишь скрипт ProgressBar.cs и вешаешь на Slider.

    [SerializeField] private Button activationButton;
    [SerializeField] private Slider progressSlider;
    [SerializeField] private float speed = 1;
    
    private void OnEnable()
    {
         activationButton.onClick.AddListener(Press);
    }
    
    private void OnDisable()
    {
         activationButton.onClick.RemoveListener(Press);
    }
    
    private void Press()
    {
        activationButton.onClick.RemoveListener(Press);
        StartCoroutine(Loop());
        IEnumerator Loop()
        {
            for (var i=progressSlider.value; i<1f; i+= Time.deltaTime * speed)
            {
                 progressSlider.value = i;
                 yield return null;
            }
        }
    }
    Ответ написан
    7 комментариев
  • Как передать позицию объекта скрипту, который висит на другом объекте без занесения в инспектор?

    @Ente
    Unity developer
    Сделай себе скрипт MovementSyncer.cs и пропиши в нем такой код
    [SerializedField] private bool isLeader; //переменная указывает, что данный объект лидер, а остальные повторяют
    [SerializedField] private string category; //переменная для разделения объектов на категории, например категория "синие", "красные"
    private MovementSyncer leader; //переменная для кеширования лидера на старте
    
    private void Awake() 
    {
        //найди объект-лидер для данной категории
        leader= FindObjectsOfType<MovementSyncer>().First(ms => ms.category == category && ms.isLeader);
    }
    
    private void Update()
    {
        if (isLeader) return; //пропускаем себя, еcли лидер
        transform.position = leader.transform.position;
    }
    Ответ написан
    2 комментария