Ответы пользователя по тегу Unity
  • Как войти в Unity Hub?

    @Ezekiel4
    Охотник на пиратов и сборщик монолитов
    Процесс следующий. Unity Hub отправляет браузеру по умолчанию запрос, тот заходит на сайте в аккаунт и возвращает из браузера в хаб обратно ответ.
    Если не открылся браузер - у вас слишком суровные настройки антивируса или брандмауэра, а может браузера вообще нет/не настроен (но как вы бы тогда хаб скачали?). Если открылся, но хаб не отреагировал, возможно, хаб не до конца инициализирован. Такое бывает в Windows с процессами время от времени. Зайдите в диспетчер задач и уберите тупо все процессы, связанные с Unity, после чего перезапустите и попробуйте снова.
    Если не помогло, пишите в комменты версию Unity Hub, название браузера и название+версия ОС, подумаем ещё.
    Ответ написан
    3 комментария
  • Как реализовать движение по диагональной лестнице 2d?

    @Ezekiel4
    Охотник на пиратов и сборщик монолитов
    1) Почему нахождение на лестнице не вызывает остановку анимации падения?
    Вангую на персонаже висит скругленный коллайдер - это от него. Прикол в том, что даже если вам кажется, что персонаж не движется, в Rigidbody2D со скруглённым коллайдером при условии, что вы стоите скруглённой частью на острие или другом круге, то постоянно возникает небольшое ускорение вниз, которое фейлит ваше условие:
    if (rb.velocity.y < 0f && !onGround)
    {
    	animator.SetBool("isFall", true);
    }
    
    if (rb.velocity.y == 0) // вот это вот условие
    {
    	animator.SetBool("isFall", false);
    }

    По идее, должно хватить условия "onGround":
    animator.SetBool("isFall", !onGround);

    2) Почему прыжок с лестницы выше, чем с земли?
    Высота разная, потому что вы применяете к персонажу именно силу, ведь она напрямую учитывается в пересчётах. Более того, высота может быть другой, если вы будете прыгать ещё от углов, стоя на месте или скользя вниз или вверх.
    Есть много решений, вот два рандомных:
    1. Обнулить вертикальную часть вектора velocity перед применением силы:
    void Jump() {
    	if (Input.GetKeyDown(KeyCode.Space) && onGround && !jumpLock) {
    		rb.velocity = new Vector2(rb.velocity.x, 0);
    		rb.AddForce(new Vector2(0f, jumpForce));
    	}
    }

    2. Вообще заменить силу на мгновенное изменение скорости:
    void Jump() {
    	if (Input.GetKeyDown(KeyCode.Space) && onGround && !jumpLock) {
    		rb.velocity = new Vector2(rb.velocity.x, jumpForce);
    	}
    }


    3) Почему персонаж скатывается с угла?
    Потому что стоит скругленной частью на угле. Замените коллайдер. Можете взять квадрат и слегка скруглить края, чтобы при горизонтальном движении не ударялся о стыки текстур (если такая проблема у вас вдруг вообще возникнет).
    Типа такого
    641258084edd0441102905.png
    Ответ написан
  • При нажатии на UI.Button сделать так, чтобы была возможность управления камерой, кто знает???

    @Ezekiel4
    Охотник на пиратов и сборщик монолитов
    Не видя пруфов могу лишь сказать попробовать поместить кнопку по иерархии внутри канваса ниже чем элемент, отвечающий за управление камерой. Если не поможет совет, пишите в коменты подумаем ещё
    Ответ написан
    Комментировать
  • Как сделать вращение по оси X на Rigibody?

    @Ezekiel4
    Охотник на пиратов и сборщик монолитов
    Трясётся потому, что у вас камера внутри иерархии игрока и она считайте дважды пересчитывается, сначала иерархией, потом скриптом. Попробуйте сделать так - создайте пустую точку на месте, где должна была бы крепиться камера и сделайте в LateUpdate привязку координат камер к этому якорю. А поворот через вектор transform.forward.
    Ответ написан
  • Почему у персонажа в Unity при столкновении с врагом не отнимается последняя жизнь?

    @Ezekiel4
    Охотник на пиратов и сборщик монолитов
    На курсах обычно дают один из двух вариантов:

    1) Из текущего здоровья отнимают дельту и затем проверяют, не упало ли здоровье в условие:
    public int healthCurrent;
    
    public void OnHealthChanged(int healthDelta)
    	healthCurrent -= healthDelta;
    	// update health bar
    	if (healthCurrent <= 0) {
    		// death
    	}
    }

    В этом варианте у вас может быть ошибка в условии. Например в примере ниже реально можно попасть в ситуацию, когда персонаж стал бессмертным:
    public int healthCurrent;
    
    public void OnHealthChanged(int healthDelta)
    	if (healthCurrent > 0) {
    		healthCurrent -= healthDelta;
    		// update health bar
    		if (healthCurrent < 0) {
    			// death
    		}
    	}
    }

    2) Через Mathf.Clamp:
    public int healthCurrent;
    public int healthMaximum;
    
    public void OnHealthChanged(int healthDelta)
    	healthCurrent = Mathf.Clamp(healthCurrent - healthDelta, 0, healthMaximum);
    	// update health bar
    	if (healthCurrent == 0) {
    		// death
    	}
    }


    В этом варианте помимо неправильного условия также можно случайно ошибиться в аргументах функции Clamp и вместо 0 указать 1, а проверять будет именно 0.
    Ответ написан
  • Как сделать, чтобы при запуске игры не было видно курсор?

    @Ezekiel4
    Охотник на пиратов и сборщик монолитов
    Сам Unity не убирает курсор, а просто его прячет. Если вы резко двинете мышью, то можете заметить, как выделяются элементы под курсором за пределами окна сцены и Unity вообще. А если вы будете транслировать экран через Zoom или Google Meet, то заметите, что курсор на трансляции виден.

    Эту проблему можно решить, написав дополнительное расширение редактора, но обычно с этим не парятся, так как в игре всё работает как часы. Будет это работать примерно следующим образом:
    1) Используя EditorApplication.playModeStateChanged вы можете отследить момент входа в PlayMode
    2) Используя Cursor вы можете узнать координаты курсора, а затем скрыть указатель и залочить его позицию
    А при выходе из PlayMode показать и разблокировать. Чтобы разделить функционал можно использовать платформо-зависимую компиляцию, типа:
    public void HideCursor() {
    
    #if UNITY_EDITOR
    
    	// hide & lock using Cursor class
    
    #else
    
    	Cursor.lockState = CursorLockMode.Locked;
    
    #endif
    
    }
    Ответ написан
    Комментировать
  • Как отзеркалить 2D персонажа?

    @Ezekiel4
    Охотник на пиратов и сборщик монолитов
    Обычно для этого достаточно развернуть рут объект игрока по oY. Типа такого:
    public class PlayerController : MonoBehaviour {
    
    	// ...
    
    	private void Update() {
    		float xInput = Input.GetAxisRaw("Horizontal");
    
    		if (xInput != 0)
    			transform.localEulerAngles = new Vector3(0, xInput > 0 ? 0 : 180, 0);
    
    		// ...
    	}
    
    	// ...
    
    }


    PS. С этим у вас может возникнуть новая проблема - если вы следите камерой за игроком, вложив её по иерархии, тогда камеру тоже развернёт и визуально ничего не поменяется. Если у вас такое будет - вынесите её из иерархии игрока и напишите скрипт, который будет синхронизировать oX/oY координаты игрока с камерой.
    Ответ написан
    Комментировать
  • Как заставить так чтобы камера двигалась сама в UNITY при параллакс эффекте?

    @Ezekiel4
    Охотник на пиратов и сборщик монолитов
    Вам так или иначе нужно какое-то событие, например, "игрок сместился" или "прошёл один кадр" или что-то ещё. Если у вас игра типа террарии, где параллакс опирается на движение игрока, то вместо слушания клавиш можете сделать как-то так:
    1) Запоминаем где игрок
    2) Смотрим, насколько далеко он сместился от этой точки
    3) Смещаем слои фона на эквивалентные величины

    Если же эффект автоматический, как в раннерах, то всё ещё проще:
    1) Отсчитываем паузу (таймер, обновление экрана или что-то ещё)
    2) Смещаем слои фона на величины их скорости движения
    Ответ написан
    Комментировать
  • Почему соотношение сторон в юнити неправильное после билда игры?

    @Ezekiel4
    Охотник на пиратов и сборщик монолитов
    В канвасе есть компонент Canvas Scaler. Настройте его следующим образом:
    6405e02a8224d397628725.png
    Ответ написан
    1 комментарий
  • Почему низкий фпс при большом количестве CharacterController?

    @Ezekiel4
    Охотник на пиратов и сборщик монолитов
    Почему - потому что много объектов. В юнити потребление ресурсов никогда не росло линейно к количеству объектов. Одно накладывается на другое. Столь большое количество активных объектов нестандартная ситуация, потому тут нет шаблонного эффективного решения. На ум приходит попытаться оптимизировать код или написать свой контроллер, но при таких числах оно вам даст едва ли 20 фпс.

    Идеальное решение этой задачи довольно сложное, но если вы не прочь пободаться с математикой и логикой, то можете попробовать. Первая итерация этой системы заключается в создании пула выключенных объектов, откуда вы достаёте и расставляете видимые объекты, и куда прячете, когда их не видно. Для каждого объекта считается его траектория движения и по таймеру вы можете вычислить его местоположение в любой момент времени. Следующим шагом можно покрыть всю карту небольшими зонами, для каждой из которых назначить проходимость. Например, терновый куст или крутой подъём должны нормально так затормозить. И при рассчёте местоположения персонажа на пути учитывать эти зоны.

    Другой вопрос, а будет ли в игре реально тысяча объектов? Это такой стресс-тест? Или это усреднённое значение и реально их может быть и полторы? Я это к тому, что если тысяча не предел, то, возможно, придётся писать что-то ещё более сложное, чем система выше.
    Ответ написан
    2 комментария
  • Как сделать Хватание предметов как в People Playground на Unity?

    @Ezekiel4
    Охотник на пиратов и сборщик монолитов
    Есть как минимум два способа это сделать - через иерархию и через суставы. Вы даже без кода можете попробовать руками дать персонажу вещь, сделав её дочерней к ладони и покрутить рукой. Фокус в том, что дочерние объекты повторяют все модификации местоположения и поворота родительского. Нечто похожее делают и суставы, но плюс суставов в том, что их можно разбить, т.е. как бы выбить вещь из руки при достаточном внешнем усилии (отстрелить нож из руки в шутере, например).
    Можно ещё тупо поместить все возможные вещи в руки прямо со старта, в редакторе, а затем их просто выключить и включать как объекты при необходимости, но, надеюсь, вы так делать не будете, потому что это кринж, что бы парни с ютуба вам об этом не говорили.

    Среди первых видосов на ютубе по вашему запросу вот два примера:
    1) Как можно сделать: https://www.youtube.com/watch?v=pzaxC-P3sgs
    2) Как делать не нужно: https://www.youtube.com/watch?v=zEfahR66Pa8

    Код вам не напишут не из вредности, есть слишком много ньюансов, которые относятся к конкретной реализации механики в разных играх. Ну и дело это не на пять минут. Возможно, вы сможете найти что-то похожее на ваш запрос среди дополнений на unity asset store или его аналоге. Ну или обратиться на тот же фриланс.
    Ответ написан
    Комментировать
  • Не входит в аккаунт unity. Как исправить?

    @Ezekiel4
    Охотник на пиратов и сборщик монолитов
    Сначала удостоверьтесь, что браузер по-умолчанию имеет активную сессию на сайте юнити. Затем через диспетчер задач остановите все процессы, которые хоть как-то связаны с Unity. Перезапустите хаб и попробуйте ещё раз нажать кнопку входа и подождите пару секунд. Если всё равно глухо, проверьте настройки брандмауэра и антивируса. Они умеют блокировать такие действия. Глухо всё равно - пишите в коменты, подумаем ещё.
    Ответ написан
    Комментировать
  • Хватит ли моего компьютера для разработки игр?

    @Ezekiel4
    Охотник на пиратов и сборщик монолитов
    Требования различаются от версии к версии, также зависят от разрабатываемого проекта и уровня его оптимизации. У меня есть ноут 2011 года, там видеокарта интегрированная в проц, сам проц i5 3 поколения (2 ядра, 4 потока), озу 6 гб. На версии 2020* ноута с головой хватает на разработку гиперказуалок, 2д платформеров, шутеров и песочниц. 3д тянет не очень. На этом же ноуте чистая версия 2021 лагает даже до начала разработки проекта.

    Если с вашими характеристиками вы столкнулись с лагами, то одно из двух - либо проблема с редактором, либо вы плохо/не оптимизировали проект.
    Ответ написан
    Комментировать
  • Как удалить Audio Listener для остальных игроков кроме себя?

    @Ezekiel4
    Охотник на пиратов и сборщик монолитов
    Ну тут есть два варианта - либо вы удаляете компоненту AudioListener с камеры всех, кто удовлетворяет условию:
    using Photon.Pun;
    using UnityEngine;
    
    public class FixAudioListener : MonoBehaviour {
    
    	// заполнить ссылки в инспекторе до старта игры
    	public AudioListener listener;
    	public PhotonView photonView;
    
    	private void Start() {
    		if (!photonView.IsMine)
    			Destroy(listener); // удалить компоненту с камеры
    	}
    }


    Или вы руками его удаляете до старта игры, а на старте помещаете на камеру игрока:
    using Photon.Pun;
    using UnityEngine;
    
    public class FixAudioListener : MonoBehaviour {
    
    	// заполнить ссылку в инспекторе до старта игры
    	public PhotonView photonView;
    
    	private void Start() {
    		if (photonView.IsMine)
    			AddComponent<AudioListener>(); // добавить компоненту на камеру
    	}
    }


    С точки зрения логики, логичнее второй вариант, ибо в первом юнити сначала его создаст, а потом поудаляет почти у всех. А во втором он создаст компоненту лишь раз.
    Ответ написан
  • Как проигрывать звук только на определенном расстоянии (Photon)?

    @Ezekiel4
    Охотник на пиратов и сборщик монолитов
    В AudioSource есть свойство Spatial Blend, которое определяет пространственное распространение.
    Крайнее левое положение - это чистый 2D звук. Такой звук играет одинаково по всей сцене. Идеально для фоновой музыки в играх и интерфейса.
    Крайнее правое, в свою очередь, чистый 3D звук, дальность распространения которого вы и определили.
    Промежуточные состояния, это нечто среднее (зависит от зелёной полосы на графике в разделе 3D Sound Settings).

    Вам нужно поставить в крайнее правое положение.
    63f268e6e4ebe824615264.png
    Ответ написан
    Комментировать
  • Здравствуйте у меня ошибка cs0115 в строке 25. Делал скрипт по видео уроку,как её исравить не нашёл. Попробовал к MonoBehaviour добавить PunCallbacks?

    @Ezekiel4
    Охотник на пиратов и сборщик монолитов
    В следующий раз оберните код внутрь тега Code и приводите весь код полностью (включая импорт). А вообще, проблема кроется вот здесь:
    public override void OnJoinedRoom()
    Заключается она вот в чём. Оператор override служит для переопределения метода. Берётся метод у родительского класса и меняется в дочернем, таким образом (в вашем случае) сам фреймворк знает о таком методе, а вы туда можете написать то, что вам хочется.
    Но в данном случае ни MonoBehaviour, ни один из классов, от которых всё это дело наследуется, не имеет в распоряжении метода заданной сигнатуры, значит и переопределять нечего.

    Скорее всего, проблема решится, когда вы в 7 строке
    public class PUN : MonoBehaviour
    Замените MonoBehaviour на MonoBehaviourPunCallbacks.
    Ответ написан
  • Как сделать плавным прыжок С# unity?

    @Ezekiel4
    Охотник на пиратов и сборщик монолитов
    Главный вопрос в том, что вы подразумеваете под плавностью прыжка?

    Вы можете задать траектории прыжка с помощью AnimationCurve и в IEnumerator плавно применять нужные силы или смещения - таким образом у вас будет удобный внешний интерфейс, где вы сможете сделать просто что угодно.
    Вот тут пример, как такое можно сделать - https://www.youtube.com/watch?v=zprbOhxHPXE

    С другой стороны, возможно, сейчас ваш прыжок ведёт себя как-то не так. Не видя остального кода, могу лишь предположить, что, например, персонаж прыгает аномально быстро, почти телепортируясь, а падает крайне медленно. Если у вас всё действительно так, то проблема не в прыжке, а в движении, а точнее вертикальной его координате. Возможно, вы используете что-то типа:
    rb.velocity = Vector2.right * xInput * movementSpeed;

    или
    rb.velocity = new Vector2(xInput * movementSpeed, 0);

    Если я угадал, то тут проблема в обнулении Y координаты движения. Типа вы перегружаете X, что даёт движение, а всё Y движение обнуляется (гравитация, прыжок). Можно сделать вот так:
    rb.velocity = new Vector2(xInput * movementSpeed, rb.velocity.y);


    Непрошенный совет

    Пробовал разные способы которые нашёл в интернете, умножение на Time.deltaTime, пробовав изменить импульс на Time.deltaTime, отслеживал нажатие в FixedUpdate() вместо Update() и используя Time.FixedDeltaTime. Впрочем, ни один из способов не увенчался успехом. Подскажите как исправить данную проблему?

    1. Параметр Time.deltaTime - это временной промежуток между последним и текущим кадром. Умножая на него, например, скорость, вы говорите коду, что хотите сделать привязку скорости не к кадрам (столько-то метров за кадр), а к секундам (столько же метров, но уже за секунду). Это довольно удобно, когда вы делаете физическую симуляцию игре.
    2. У прыжка есть два режима (Force и Impulse). Force обычно используется для продолжительных воздействий. Например, с её помощью можно реализовать занос в гонках. А Impulse нужна для разового приложения силы - разгон пули, удар по мячу, прыжок, и т.д.
    3. Функция отслеживания нажатий. Используйте для этого всегда Update, вместо FixedUpdate. Дело в том, что класс Input предоставляет информацию, которая опирается именно на период обновления экрана (ему соответствует Update). Например, вот в этом кадре вы нажали пробел и продолжаете удерживать кнопку вправо. FixedUpdate же лучше использовать для применения постоянных сил (вроде движения).
    Просто из-за разного периода работы вполне может быть такая ситуация, что ваш ввод просто потеряется или, наоборот, данные о нём останутся на следующую итерацию приложения сил, когда игрок уже перестал нажимать. Чтобы переносить данные между ними, воспользуйтесь полем класса.

    Вот примерно так будет выглядеть простое движение с Rigidbody2D:
    using UnityEngine;
    
    [RequireComponent(typeof(Rigidbody2D))]
    [DisallowMultipleComponent]
    public class PlayerMovementDemo : MonoBehaviour {
    
    	private Rigidbody2D _Controller;
    	private float _MovementInput;
    
    	public float movementSpeed;
    	public float jumpingForce;
    	[Space(10)]
    	public Transform groundCheckPoint;
    	public float groundCheckDistance;
    	public LayerMask groundIdentity;
    
    	private void Start() {
    		_Controller = GetComponent<Rigidbody2D>();
    	}
    
    	private void Update() {
    		_MovementInput = Input.GetAxis("Horizontal");
    
    		if (Input.GetButtonDown("Jump") && IsGrounded())
    			_Controller.AddForce(Vector2.up * jumpingForce, ForceMode2D.Impulse);
    	}
    
    	private void FixedUpdate() {
    		_Controller.velocity = new Vector2(_MovementInput * movementSpeed, _Controller.velocity.y);
    	}
    
    	private bool IsGrounded() {
    		return Physics2D.OverlapCircle(groundCheckPoint.position, groundCheckDistance, groundIdentity);
    	}
    }

    Ответ написан
    Комментировать
  • Почему в unity анимация не прекращается?

    @Ezekiel4
    Охотник на пиратов и сборщик монолитов
    На переходе от ноды получения урона к пустой уберите условия и включите галочку Has Exit Time.
    63f1e2b80acd8608650604.png
    Ответ написан
    Комментировать
  • Почему прыжок не стаёт меньше от уменьшения значения?

    @Ezekiel4
    Охотник на пиратов и сборщик монолитов
    Скорее всего, произошла следующая ситуация. Вы создали скрипт и добавили его на сцену потестить. После этого вы пробовали менять параметр jumpForce в коде, но в инспекторе объекта в Unity осталось старое значение. То, что вы пишете тут - для скрипта это как значения по дефолту, попробуйте в инспекторе поменять.
    Ответ написан
    Комментировать
  • Как сделать смену персонажа по Dropdown в Unity3D?

    @Ezekiel4
    Охотник на пиратов и сборщик монолитов
    Вам достаточно представить своих персонажей в виде чисел (номер 1 такой-то, номер 9 такой-то и т.д.). Объединив их в массив или список, вы сможете легко пользоваться событием выпадающего списка.

    Вот пример, как это может быть реализовано в коде. Публичный метод привязать к событию выпадающего списка.
    using UnityEngine;
    
    public class CharacterSelection : MonoBehaviour {
    
    	public GameObject[] characters;
    
    	private void Start() {
    		OnSelected(0);
    	}
    
    	public void OnSelected(int elementId) {
    		for (int i = 0; i < characters.Length; i++)
    			characters.SetActive(i == elementId);
    	}
    }
    Ответ написан
    Комментировать