Ответы пользователя по тегу Unity
  • Как сделать такой занос у Rigidbody2D?

    EveningEugene
    @EveningEugene
    Unity-разраб
    Во-первых, вам нужно уяснить разницу между физическим и не физическим движениями и понимать какие методы на что влияют. У вас изначально движение реализовано через физику, то есть вы придаёте объекту физический импульс и в конечном счёте это влияет на rg.velocity - именно он является итоговым вектором движения объекта.

    А теперь, в контексте вышесказанного, задумайтесь, что вы пытались сделать своим первым несработавшим способом? Просто попытались повернуть объект в пространстве, никак не изменив вектор движения.

    Во втором способе вы уже догадались применить правильный метод, но почему-то не догадались заглянуть в его документацию, чтобы узнать, а как его нужно правильно применять. Нет, вместо этого вы решили закинуть аргументы наугад, надеясь, что это заработает так, как вы хотите.
    А правильно так (пример взят прямиком из документации):
    Quaternion deltaRotation = Quaternion.Euler(m_EulerAngleVelocity * Time.fixedDeltaTime);
    m_Rigidbody.MoveRotation(m_Rigidbody.rotation * deltaRotation);

    , где m_EulerAngleVelocity - это вектор, содержащий в себе угол поворота для каждой из осей. Если ваш объект движется в плоскости XY, то вращать нужно вокруг оси Z:
    m_EulerAngleVelocity = new(0, 0, rotatePower);
    И не забудьте включить интерполяцию в компоненте rb объекта в инспекторе.

    Предвосхищая ваш дальнейший геймдизайнерский вопрос, скажу - где-то в этом коде вы должны сбрасывать скорость объекта в зависимости от eulerDelta, который вам не помешает самому придумать, как реализовать.
    Ответ написан
    Комментировать
  • Где найти такой скрипт контроллер top down?

    EveningEugene
    @EveningEugene
    Unity-разраб
    Совсем вкратце и обобщённо:
    Сначала отключаешь поворот персонажа за курсором, пускай смотрит туда, куда бежит.
    Потом к анимации бега подключаешь анимацию поворота корпуса. В юнити можно смешивать несколько анимаций одновременно - это отдельна задача, отдельные туториалы. Например гугли анимацию поворота головы в зависимости от взгляда, там поймёшь как это к корпусу применить. Придётся тестить на виде от третьего лица.
    Но поворот корпуса, конечно же, ограничен условными 75 градусов в каждую сторону. Вот в коде ты и проверяешь на эти самые 75 градусов разницу между векторами направления движения и направления курсора. Если больше 75 - значит переключаешь анимацию бега прямо на анимацию бега влево-вправо или даже назад, если смотришь вообще в противоположную сторону. Ну там нюансы уже по ходу дела поймёшь.
    Итог - 4(5) анимаций: бег вперёд, влево-вправо, назад, поворот корпуса.
    Ответ написан
    1 комментарий
  • Можете ли вы дать идею для реализации AI?

    EveningEugene
    @EveningEugene
    Unity-разраб
    Есть функция Vector2.SignedAngle, которая возвращает угол между двумя векторами. Причём эта версия Возвращает значения от -180 до 180. В зависимости от того значение меньше или больше нуля вам и нужно поворачивать направо или на лево, если вообще нужно поворачивать. И вот это "нужно ли поворачивать" - это вовсе не "угол равен 0", а какие-то небольшие отклонения от нуля.
    Уделяйте больше времени чтению документации, задача очень простая. Вам уже сказали, что тут простая векторная математика, а значит идёте и исследуете документацию по Vector2
    Ответ написан
    6 комментариев
  • Как откалибровать направление модели?

    EveningEugene
    @EveningEugene
    Unity-разраб
    Вообще-то, у вас всё работает в точности, как в туториале. Просто у вас есть лазер-прицел, и поэтому у вас наглядно, что линия не совпадает с курсором. А у туториала этой линии нет, поэтому не так очевидно.
    А вот почему такое несовпадение - тоже всё очевидно. Вы делаете рейкаст из камеры в землю, потом точку попадания какбы подымаете от земли вертикально вверх на уровень глаз и уже туда проводится линия прицела. Но по факту, в трёхмерном пространстве, линия проходит ровно над тем местом, куда показывает курсор. Если бы вы не бездумно копировали код, а вчитывались и в голове питались визуализировать, что действительно делает код, вы бы и сами это поняли. Чтобы увидеть наглядно - представьте себе (или даже временно реализуйте), что линии исходит не из глаз, а из ног - на уровне пола. Тогда линия будет совпадать с курсором.
    Из туториала
    62ab02d706891030882769.png


    Кстати, в зомбоиде так работает прицел - жутко бесит, неудобно, сбивает с толку.
    Ответ написан
    2 комментария
  • Почему не работает смена локализации (языка) игры?

    EveningEugene
    @EveningEugene
    Unity-разраб
    Вы читаете какой сейчас язык внутри класса LocalisationSystem из статической переменной public static Language language. Значит и менять нужно тоже её, а не создавать где-то в другом месте новую, которую никто нигде не читает.
    public void ClickButtonRussian()
    {
        LocalisationSystem.language = Language.Russian;
    }
    Ответ написан
    4 комментария
  • Как оптимизировать изменение размера камеры?

    EveningEugene
    @EveningEugene
    Unity-разраб
    У вас есть динамические переменные sceneWidth, Screen.width, Screen.height, а значит запускать этот код можно не каждый апдейт, а только тогда, когда изменяются эти переменные. Выносите код в отдельный метод и вызываете его при каждом изменении этих переменных. У Screen наверняка есть событие, которое умеет сообщать об изменениях размера экрана, подписываете на него метод. sceneWidth можно превратить в свойство, которое в set также будет вызывать этот метод.
    Ответ написан
    Комментировать
  • Как исправить ошибку при использовании "Custom Editors" и List?

    EveningEugene
    @EveningEugene
    Unity-разраб
    Вы декларировали список, но не создали его.
    public List<AList> aLists = new List<AList>();
    //или
    public List<AList> aLists = new();


    UPD:
    Так как он у вас паблик в MonoBehavior, то видимо, предполагается, что он должен наполняться в инспекторе.
    Ответ написан
    1 комментарий
  • Как поменять изображение у кнопки через скрипт?

    EveningEugene
    @EveningEugene
    Unity-разраб
    Вот у вас есть кнопка, которая реагирует на клик. Как она реагирует? Вызывает новое окно, где есть список смайлов. Как вызывает? Очевидно, через вызов какого-то метода, например, OpenSmileMenu(). Так вот, пускай этот метод имеет параметр Action<Sprite>. Что должно передаваться? Ссылка на метод класса кнопки по которому кликнули, который принимает в себя спрайт и этот спрайт уже применяет к изображению кнопки.
    private void UpdateSprite(Sprite sprite){
      spriteRenderer.sprite = sprite;
    }
    Что происходит в OpenSmileMenu(Action<Sprite> callback)? В нём мы этот колбек прибавляем к событию: SmileChoosed += callback;
    Далее. Что происходит при нажатие на смайл? Очевидно, вызывается обработчик клика. Что он делает?
    private void OnClick(Button button){
      callback?.Invoke(button.GetComponent<SpriteRenderer>().sprite);
      CloseSpriteMenu();
    }
    Ответ написан
    5 комментариев
  • Как менять угол наклона камеры в центре и в нужном направлении?

    EveningEugene
    @EveningEugene
    Unity-разраб
    EDIT с учётом, что выяснилось, что игра в 3д-изометрии.

    Есть некая точка, в которую всегда смотрит камера. И это та самая точка, вокруг которой должна вращаться камера, назовём её фокусом. Создай emptyObject на сцене и размести где-то чуть выше плоскости земли. Камеру размести на сцене так, как она должна изначально быть расположена относительно этой точки (главное, чтобы её x-координата была нулевой, важно в скрипте далее). С поворотом самой камеры в сцене париться сильно не надо, его мы назначим в Start() с помощью LookAt().
    Далее сделай камеру дочерней относительно фокуса, а в классе камеры заведи приватное поле под фокус и в инспекторе передай туда объект фокуса. А также заводим поля для настраиваемых скоростей.
    [SerializeField] private Transform _focus;
    [SerializeField] private float rotationSpeed = 1;
    [SerializeField] private float moveSpeed = 1;
    private void Start(){
      //
      tramsform.LookAt(_focus);
      //
    }

    Таким образом, если есть фича мгновенного переноса фокуса камера на удалённые объекты, то нужно двигать только сам фокус на тот объект, а камера будет уже двигаться сама, так как дочерняя.

    Далее поворот и движение якобы камеры, на самом деле фокуса, а камера меняет положение уже как дочерний объект
    private void RotateCamera()
        {
            if (Input.GetMouseButton(1))
            {
                float mouseMove = Input.GetAxis("Mouse X") * rotationSpeed;
                _focus.Rotate(0, mouseMove, 0); //-mouseMove для инвертирования
                Debug.Log("Rotation " + mouseMove.ToString());
            }
        }
    
        private void MoveCamera()
        {
            if (Input.GetMouseButton(0))
            {
                Vector3 mouseMove = new Vector3(Input.GetAxis("Mouse X"), 0, Input.GetAxis("Mouse Y")) * moveSpeed;
                _focus.Translate(mouseMove, Space.Self); //-mouseMove для инвертирования
                Debug.Log("Moving " + mouseMove.ToString());
            }
        }


    Только сейчас понял, что то, что вы называли "центром камеры", и есть фокус, куда она смотрит.
    Ответ написан
  • Как сделать вращение в заданном диапозоне?

    EveningEugene
    @EveningEugene
    Unity-разраб
    var TempBlood = Instantiate(Blood, transform.position, Quaternion.AngleAxis(Random.Range(-60, 60), Vector3.forward));

    Vector3.forward означает вращение вокруг оси z. Подойдёт, если игра в 2d. Если 3d, то сами замените на то, что нужно. Уточняйте в каком пространстве ваша игра, 2d или 3d.
    Ответ написан
    Комментировать
  • Как удалять дубликат объекта после перезапуска уровня?

    EveningEugene
    @EveningEugene
    Unity-разраб
    ChekingLVL checkingLvl = (ChekingLVL)FindObjectOfType(typeof(ChekingLVL));
    if (!checkingLvl) Instantiate(checkingLvlPrefab);
    Ответ написан
    Комментировать
  • Какое лучше использовать передвижение в 2д-платформере?

    EveningEugene
    @EveningEugene
    Unity-разраб
    Translate() перемещает объекты без проверки на столкновения. То есть, предметы не будут останавливаться при визуальном столкновении со стенами и прочем, а просто проходить сквозь, даже без вызова методов типа OnCollisionEnter() и прочее.

    Второй нефизический способ - это модификация transform.position напрямую.

    Если тебе нужно, чтоб персонаж прыгал, падал, отталкивался от стен, сам толкал блоки и т.д. - то тебе нужны физические способы, потому что перечисленные штуки и есть суть физического движения.

    _rb.AddForce() - позволяет прикладывать силы к физическому объекту, а физ.движок сам обсчитает, как именно это повлияет на конечный вектор скорости объекта.

    _rb.velocity (это свойство, а не функция, как вы написали) - редактирование вектора движения напрямую. Задаёшь конечный вектор скорости, а физический движок уже двигает объект.
    Ответ написан
    Комментировать
  • Как правильно измерить расстояние между объектом А и Б?

    EveningEugene
    @EveningEugene
    Unity-разраб
    float distance = (a.transform.position - b.transform.position).magnitude;
    
    float distance = (new Vector3(a.transform.position.x, 0, a.transform.position.z) - new Vector3(b.transform.position.x, 0, b.transform.position.z)).magnitude; //без учёта Y
    Ответ написан
  • Как сделать движение куба с вращением?

    EveningEugene
    @EveningEugene
    Unity-разраб
    Вот в этом видео понятно и с визуализацией объясняется, как это реализовать. Да, по-английски, но это всего полторы минуты и с визуализацией. Конкретного кода с решением нет, но сам принцип становится понятен.
    Ответ написан
    1 комментарий
  • Почему не загружается сцена из кода?

    EveningEugene
    @EveningEugene
    Unity-разраб
    Edited: Тебе буквально в ошибке написали, что нужно сделать. File -> Build Settings -> Перетащить новую сцену в окно -> Поставить галочку напротив этой сцены game.
    Ответ написан
    4 комментария
  • Что значит ошибка не присвоен объект?

    EveningEugene
    @EveningEugene
    Unity-разраб
    Судя по твоему коду, смею предположить, в это поле ты должен был через инспектор назначить объект, который служит маркером позиции, в которой должен появиться создаваемый экземпляр bullet.
    Ответ написан
    2 комментария
  • Как реализовать механику поворота?

    EveningEugene
    @EveningEugene
    Unity-разраб
    Если вам нужен мгновенный поворот машинки, то вам подойдёт Transform.LookAt
    Если нужен плавный во времени поворот, то вдобавок ещё и это Vector3.RotateTowards. Туда можно передавать и Vector2.

    UPD: LookAt для 2д не годится, предложил по сути на основании догадки, так как в 3д работало. Но за 2 минуты нагуглил рабочий способ по запросу "unity 2d rotate sprite {принять гугловское автодополнение запроса} towards mouse":
    float angle = Mathf.Atan2(target.position.y - transform.position.y, target.position.x - transform.position.x) * Mathf.Rad2Deg;
                transform.rotation = Quaternion.Euler(new Vector3(0, 0, angle));

    Лично создал тестовый проект - проверил, работает. Важный нюанс - спрайт машинки должен быть повёрнут по умолчанию вправо,
    пример:
    628b6652f239e206690280.png

    Вывод: учитесь гуглить. Это азы. С плавным, не мгновенным, поворотом разберётесь сами.

    UPD2: Хотя, всё же спрайт не обязательно должен быть повёрнут вправо. Просто учитывайте, что приведённый код предназначен для повёрнутых направо. Если ваши спрайты изначально нарисованы передом вверх то просто вычтите 90 из angle. Или прибавьте 90, если спрайт почему-то повёрнут вниз. Но самое главное, если вы используете несколько разных спрайтов - то у них у всех должна быть одинаковая изначальная ориентация.
    transform.rotation = Quaternion.Euler(new Vector3(0, 0, angle));// спрайт, повёрнутый вправо
    transform.rotation = Quaternion.Euler(new Vector3(0, 0, angle - 90));// спрайт, повёрнутый вверх
    transform.rotation = Quaternion.Euler(new Vector3(0, 0, angle + 90));// спрайт, повёрнутый вниз
    Ответ написан
  • Operator '==' cannot be applied to operands of type 'Collider[]' and 'bool'???

    EveningEugene
    @EveningEugene
    Unity-разраб
    У вас в классе есть переменная public bool ButtonOn;
    А также внутри метода Update есть переменная с таким же именем, но другим типом Collider[] ButtonOn;
    Когда в методе Update вы делаете сравнение if (ButtonOn == true), подразумевается именно локальная переменная Collider[] ButtonOn. То есть, вы пытаетесь сравнить Collider[] с bool. Либо меняйте название локальной переменной либо пишите так if (this.ButtonOn == true), тогда будет использоваться внешняя переменная класса.
    Рекомендую почитать про области видимости. А ещё при добавления кода в пост используйте тег
    <code lang="cs">
    //your code
    </code>
    Ответ написан
    1 комментарий