• Как получать переменную из другого скрипта Unity в update?

    @hermer29
    ООП это не методология отрубающая руки, это способ строить сложные программы проще. Нужно объединить MovePlatform и PlatformSpeed в класс Platform, тут же все проблемы уйдут, пусть и работают с общим полем speed
    Ответ написан
    Комментировать
  • Что является более оптимизированным Timer или WaitForSeconds?

    @hermer29
    Бессмысленный вопрос, надо над задачей думать, задача оптимизации это тоже задача, она возникает когда появляется потребность.

    А так да, по идее собственный счетчик меньше должен памяти жрать
    Ответ написан
    Комментировать
  • Как переписать в linq?

    @hermer29
    Перепишу сюда так чтобы из глаз не текла кровь:
    var wordOccurrences = new Dictionary<string, int>();
    foreach (var word in filteredWords.Select(x => x.ToLower())
    {
        if(wordOccurrences.ContainsKey(word))
        {
            wordOccurrences[word] = wordOccurrences[word] + 1;
            continue;
        }
        wordOccurrences[word] = 1;
    }
    return wordOccurrences;

    Максимум ток Select. Предполагая что filteredWords это список или массив string. По определению задачи: если в фильтрованном списке со словами есть слово которое есть в словаре, мы увеличиваем значение по ключу на единицу (по умолчанию 0). Если слово не встречается в словаре, то устанавливаем в счётчик 1. Очевидно, что задача не решение проблемы, это просто задача по приколу. По моему, лучше всего читается то что я выше написал, linq тут реально только усложнит, использование метода ForEach читается хуже чем цикл foreach в ситуации условной логики. Чтобы не вступать с преподом в конфликт можно сунуть ему вот это:
    var wordOccurrences = new Dictionary<string, int>();
    var filteredLower = filteredWords.Select(x => x.ToLower());
    // Преполагаем что не встречающиеся слова в словаре имеют значение 1
    // На этом этапе предположим что все слова - не встречающиеся
    foreach (var word in wordOccurrences.Keys)
    {
        wordOccurrences[word] = 1;
    }
    
    foreach (var word in filteredLower.Where(x => wordOccurrences.ContainsKey(x)))
    {
        // Те слова, что всё таки встречаются мы начинаем инкрементить
        // Однако счёт не начинается с единицы по определению задачи, поэтому пропускаем первое увеличение
        if(wordOccurrences[word] == 1)
            continue;
        wordOccurrences[word]++;
    }
    return wordOccurrences;
    Ответ написан
    Комментировать
  • Сделал движение через new Vector3, и, вроде бы все нормально, но задался вопросом - а можно так вообще?

    @hermer29
    Важный принцип: забей на оптимизацию пока это не станет проблемой, структуры хранятся в стеке, так шо они очистятся в конце этого контекста. При таком присвоении просто происходит копирование. Чаще всего в таких простых ситуациях самое очевидное решение правильное - если не появляются проблемы с производительностью значит ты сделал всё верно (можно научиться отлаживать профайлером, все вопросы тут же отпадут)

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

    @hermer29
    Вкачивать можно в разные ветки:
    * Профпригодность - способность решать задачи. Находишь самую часто встречающуюся механику из первых 10 игр в плей маркете и думаешь как её реализовать, гуглишь об этом, запоминаешь как реализовать, запоминаешь с какими проблемами столкнулся. Кроме механики, берешь первую попавшуюся не слишком сложную по времени игру и делаешь её от начала до конца, воруя ассеты из интернета - вот это вообще супер метод.
    * Способность искать новое, анализировать какие у тебя проблемы и что может их решить - оно сильнее всего прокачивается опытом (ты можешь попасть в хорошую организацию, в которой есть наработанный рабочий опыт, который они сохраняют, тогда ты быстро станешь носителем этого опыта и очень быстро будешь расти). Вот недавно на опыте, делаешь web gl игру. Сделал билд, отправил тестеру - он просит сделать фичи для тестирования, забиваешь на то что он говорит - билд идёт минут 10-20 + заливать, не хочешь время тратить, + билд блокирует разработку, издатель скорее хочет готовый проект. Скидываешь билд, издатель вносит правки, правишь, скидываешь билд и так раз 10. Эту проблему решает CI/CD, ты даёшь команду на билд и дальше разрабатываешь. То есть важно анализировать, что новое может повысить твою эффективность?
    * Смежные области - иногда чтобы стать лучшим разработчиком достаточно разбираться в какой то смежной области. К примеру основы геймдизайна, графики, понимание бизнес процессов, веб программирования (в наше время веб игр очень актуально)
    Надо понимать закон мёрфи, если что-то плохое может случиться, то оно обязательно случится. Иногда в важном месте не сделав интерфейс вместо класса, и сделав к примеру ситуацию где от этого класса в разных контекстах хотят разные вещи, ты попадёшь в ловушку. Или к примеру заказчик попросил вырезать фичу, а ты взял и всё удалил вместо того чтобы добавить тумблер - молодец, теперь надо запускать редактор кода и вспоминать где ты что закомментил. Тоже самое с использованием гита
    Ответ написан
    Комментировать
  • Трясёт персонажа, что делать?

    @hermer29
    Автор описал решение: "Всё починил, написал transform.rotation = Quaternion.LookRotation(new Vector3(_joystick.Horizontal* _moveSpeed, 0, _joystick.Vertical * _moveSpeed));", с которым я не согласен. velocity лучше не менять руками в таких ситуациях, достаточно использовать MovePosition. Есть такой вариант, что автор использовал в FixedUpdate прямую установку скорости, а Rigidbody прибавлял к скорости реакцию поверхности с силой трения сразу после этого. С MovePosition ты не игнорируешь работу модуля физики, а говоришь ему "Передвинь пожалуйста персонажа туда"
    Ответ написан
    Комментировать
  • Как отправить http запрос c одного приложения на другое на одном компьютере?

    @hermer29
    Есть HttpClient и HttpListener классы. А ещё есть ссылка на урок у ms
    Ответ написан
    Комментировать
  • Оптимально ли я сделал управление в 2D платформере?

    @hermer29
    Прежде всего большинство Ваших задач здесь может решать Rigidbody2D. Для понимания, Rigidbody - это система которая реализует физические явления в движке и она подходит для практически любых ситуаций - если станете большим специалистом то может быть найдете решение получше. Обратите внимание, что движение, ускорение свободного падения и столкновение это физические процессы. Для начинающего лучший курс по физике в Unity.

    Вы можете реализовать прыжок, коллизию (столкновения) и движение через Rigidbody.

    [RequireComponent(typeof(Rigidbody2D), typeof(SpriteRenderer))]
    public class Player : MonoBehaviour
    {
        [SerializeField, Min(1)] private float _speed = 1;
        [SerializeField, Min(1)] private float _jumpForce = 1;
        [SerializeField] private LayerMask _ground;
        
        private Rigidbody2D _body;
        private SpriteRenderer _player;
    
        private void Start()
        {
            _body = GetComponent<Rigidbody2D>();
            _player = GetComponent<SpriteRenderer>();
        }
        
        private void Update()
        {
            var horizontal = GetHorizontalInput();
            var jump = Input.GetKey(KeyCode.W);
    
            if(jump && IsGrounded())
                Jump();
            
            Move(horizontal);
            Animate();
        }
    
        private float GetHorizontalInput()
        {
            return Input.GetAxis("Horizontal");
        }
    
        private bool IsGrounded()
        {
            return Physics2D.OverlapArea(
                GroundCheck.bounds.min, 
                GroundCheck.bounds.max, 
                _ground);
        }
    
        private void Move(float input)
        {
            var deltaDistance = Time.deltaTime * _speed;
            var deltaPosition = transform.position.x + (deltaDistance * input);
            _body.MoveDirection(new Vector2(deltaPosition, 0));
        }
    
        private void Jump()
        {
            _body.AddForce(Vector3.up * _jumpForce)
        }
    
        private void Animate()
        {
            var velocity = _body.velocity.normalized;
            if (velocity.x < 0)
            {
                sr.flipX = true;
            }
            else if (velocity.x > 0)
            {
                sr.flipX = false;
            }
        }
    }


    В чём разница между Rigidbody.MovePosition и Transform.Translate? Rigidbody управляет физическими явлениями, т.е. трение с поверхностями (когда мы движемся мы трёмся коллайдером), столкновениями и физикой во время прыжка. Когда мы движемся в препятствие и движемся с помощью Rigidbody.MovePosition физический движок замечает, что мы двигаемся в препятствие ну и симулирует реакцию поверхности, ну и мы не проваливаемся в коллайдер за счёт этого. Transform.Translate напрямую меняет позицию объекта, ему довольно безразлична физика и столкновения, он просто меняет позицию, и как вы могли заметить, он может изменить позицию прямо в препятствие.
    Резюмируя: Transform.Translate хорош когда нас не волнуют столкновения: UI-анимации, движение облаков, перемещение препятствий на которые ничто не влияет физически. В остальных случаях Rigidbody.MovePosition.

    Остальные детали,
    * Если используем GetComponent значит надо гарантировать наличие компонента через RequireComponent. Когда компонентов становится больше, а ты такие вещи не предусмотрел однажды ты можешь словить 100+ Null reference exception в консоль
    * Параметрам можно установить минимальные возможные значения через атрибут Min, таким образом случайно нельзя будет допустить неверное поведение
    * Стирай изначальные комментарии и явно пиши private на методах, таким образом читается быстрее, лишнее внимание переводить не придётся
    * gameObject.GetComponent не обязательно, можно просто GetComponent
    * Вместо Update уместнее FixedUpdate. Разница в том, что FixedUpdate ВСЕГДА вызывается каждый определенный промежуток времени, в отличие от Update. В курсе наверху описывается почему так лучше, и разница между FixedUpdate и Update.
    * Проверять нахождение на земле где-то читал предлагали с помощью рейкаста, стоит помнить что любой физический метод имеет 2D версию, которая тебе лучше подходит
    * Научись придерживаться одного и того же стиля во всём своём коде
    * Метод должен быть глаголом или словосочетанием с глаголом
    Ответ написан
  • Vk api secure.addAppEvent пример?

    @hermer29
    Можно использовать любой программный http клиент. Пример на php с библиотекой Guzzle:
    <?php
    require __DIR__ . 'relative/path/to/autoload.php';
     
    $access_token = "your-app-access-token";
    $api_version = '5.95';
    $user_id = 1234567; // User id
    $activity_id = 1; // Completed level
    $value = 3; //level 3
    $client = new GuzzleHttp\Client();
     
    $request_url = "https://api.vk.com/method/secure.addAppEvent"
        ."?access_token=$access_token&"
        ."v=$api_version&"
        ."user_id=$user_id&"
        ."activity_id=$activity_id&"
        ."value=$value";
     
    $response = $client -> request('GET', $request_url);
     
    echo $response -> getBody();


    Этот код будет выглядеть примерно точно также в любом языке. Альтернативно можно найти vk sdk для нужной вам платформы или языка. Также у вас могут быть ошибки связанные с тем что вы слабо поняли, что в документации вк написали. У меня к примеру проблема, api отвечает:

    Permission to perform this action is denied: cannot add points to not verified app


    Жду от поддержки подтверждение о том, что это потому что использован сервисный ключ от приложения, которое не прошло модерацию
    Ответ написан
    Комментировать