• Как конкатенировать текст из разных ячеек?

    EveningEugene
    @EveningEugene
    Unity-разраб
    =CONCATENATE(A3; "@"; A4; " "; A5; " "; A6)
    62b5c6c2a6c11310293561.png
    Ответ написан
  • Как сделать так, чтобы бот запретил писать сообщения в группе?

    EveningEugene
    @EveningEugene
    Unity-разраб
    1. Научиться ботом отслеживать любые сообщения пользователей.
    2. Научиться удалять сообщения.
    3. Научиться выдавать разные командные кнопки в зависимости от полномочий в группе.
    4. Научиться сохранять состояние по команде.
    5. Научиться проверять состояние.
    6. Объединить всё вышеописанное в единую фичу.
    Ответ написан
    Комментировать
  • Как сделать такой занос у 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-разраб
    Простейшее, что приходит в голову:
    Для каждого предмета делим цену ящика на цену предмета - получаем "вес" предмета.
    UPD:
    Для каждого предмета умножаем его вес на соотношение цены ящика к цене предмета. Например ящик - 50р, предмет 10р, значит вес*(50/10).

    Суммируем все веса.
    Делим 100 на сумму весов - получаем вероятность за единицу веса.
    Для каждого предмета умножаем его вес на вероятность за единицу веса - получаем вероятность выпадения этого предмета из ящика. Суммарная вероятность - 100%.
    Вы пишите
    шанс выпадения каждой вещи в зависимости от цены ящика

    А саму зависимость вы не описали. Как именно шанс должен зависеть от цены? То есть можно что угодно придумать и это не будет правильным или неправильным. Просто один из бесчисленных вариантов.
    Ответ написан
  • Как оптимизировать изменение размера камеры?

    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-разраб
    Каждая песня - это объект, а его просмотры - это одно из полей/свойств. Song.Views
    List<Song> songs;
    songs = songs.OrderBy(s => s.Views);
    //используйте OrderByDescending для порядка по убыванию
    Ответ написан
  • Функция swap заменить максимальные и минимальные значения массивов?

    EveningEugene
    @EveningEugene
    Unity-разраб
    Вызывая Swap() вы меняете местами значения в переменных maxA и maxB, но этим вы никак не модифицируете массивы, так как int - значимый тип, а не ссылочный.

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

    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
    Ответ написан