Ответы пользователя по тегу Unity
  • Как научить ботов учитывать гравитацию планеты при стрельбе?

    @0x131315
    По поводу скрипта - он странный:
    1) Он работает только для обьектов, которые участвуют в столкновениях.
    2) Он не учитывает дистанцию до центрального тела, только его массу, и работает только для случаев, когда дистанция между противниками в тысячи раз меньше дистанции до центрального тела, т.е. более-менее точен где-то на задворках звездной системы, вдали от звезды. На более ближних дистанциях начинает безбожно врать.
    3) Он наполняет обьектами массив, который не особо нужен скрипту для работы, который нигде не очищается. Это - утечка памяти.
    4) Его можно прикладывать только к одному телу - центральному. Иначе это умножает утечку памяти и сильно расходует процессор. В некоторых случаях его можно заменить триггером. И часто его оптимизируют, вызывая раз в несколько десятков кадров, а не каждый кадр. Также пишут, что указание маски слоя в Physics.OverlapSphere повышает эффективность работы.

    По поводу утечки.
    Не знаю тонкостей unity, не могу сказать точно, насколько она серьезна. Но возможны два варианта:
    1) обьект скрипта пересоздается каждый кадр, и время от времени устаревшие экземпляры собирает сборщик мусора.
    Тогда утечка равна размеру массива помноженному на количество кадров в секунду и на таймаут сборщика мусора.
    При условии, что скрипт используется только на одном обьекте (надеюсь ты не додумался применить его ко всем обьектам?), для 1000 обьектов в сцене, 60фпс и 10 секундном таймауте сборщика мусора, утечка составит 5..50Мб - именно столько памяти игра будет отьедать впустую, никуда не используя, только на один экземпляр этого скрипта.
    Если скрипт применен к 10 обьектам, утечка увеличится до 50..500Мб.
    А если обьектов 1000?
    Так и рождаются игры, которые требуют 16Гб оперативки.
    Это не говоря о бесполезной трате процессорных ресурсов: если по глупости применить скрипт ко всем обьектам, эффективно работать он будет только на одном, но жрать память и процессор будет за всех.
    На 1000 обьектах потребление процессора этим скриптом увеличится в 1000000 раз: 1000 скриптов должны будут каждый обработать по 1000 обьектов.
    Так рождаются игры, которые требуют топовое железо.
    Всего 2 легкие ошибки с одним скриптом (далеко не основным) - и такой потенциал! :)
    2) Используется один экземпляр скрипта, он не пересоздается каждый вызов.
    Тогда обьем массива каждую секунду умножается на фпс, пока массив не забьет всю память.
    И сборщик мусора тут не поможет, т.к. скрипт существует пока существует основной обьект, т.е. пока загружен уровень - всю игровую сессию.
    Для тех же условий утечка в первую секунду составит 0,5..5Мб, и каждую секунду будет увеличиваться на столько же. За час игры утечка составит от 2 до 20Гб, в зависимости от размера структур.
    Утечка процессора останется той же, что и в первом варианте.

    Твой вариант походу первый, иначе бы скрипт отработал ровно один раз, и гравитация после первого кадра пропала: массив используется для проверки тел, к которым еще не прикладывалась гравитация.
    А это не так - раз есть постоянная ошибка, гравитация работает дольше одного кадра.
    Кстати, проверка эта лишняя, в документации ее нет.

    По поводу ошибок прицеливания: введи поправки на гравитацию при прицеливании.
    Не факт, что это тебе поможет, все-таки скрипт у тебя кривой, и непонятно правильно ли ты его используешь - каковы максимальные дистанции между противниками, каковы минимальные дистанции от противников до центрального тела, каков размер центрального тела, как создаются снаряды (независимыми или привязанными к тому, кто выстрелил), как задается их скорость (постоянная или относительно скорости выстрелившего), какова скорость снаряда и цели.
    Но самое простое:
    dy=g*t*t/2
    t=l/v
    dy - величина смещения снаряда гравитацией на текущей дистанции
    g - величина гравитации, локальная (вблизи точки выстрела). В твоем скрипте гравитация постоянна, не зависит от координат, и равна массе центрального тела, значит вместо g можно подставить массу центрального тела.
    t - время полета снаряда
    l - прямая дистанция до противника.
    v - глобальная скорость снаряда (относительно мира).
    Ограничения:
    Локальная гравитация неприменима, если дистанция сравнима с расстоянием до центрального тела - там нужен дополнительный учет кривизны поля гравитации. Гравитация в разных точках пути снаряда будет разная, а это сильно снизит точность, особенно на больших дистанциях - на много порядков.
    Прямая дистанция неприменима, если дистанция сравнима с расстоянием до центрального тела - там нужен дополнительный учет кривизны поля гравитации. Дистанция будет не прямой, а дугой, и значит снаряд пройдет больше расстояния, лететь будет дольше, и поправка нужна больше.
    Если время полета больше нескольких секунд, придется учитывать влияние гравитации на скорость снаряда. Снаряд будет ускоряться или замедляться гравитацией, а значит точность с дистанцией начнет быстро падать.
    Если скорость цели сравнима со скоростью снаряда - придется учитывать, что цель движется. Пока снаряд летит в точку прицеливания, быстрая цель оттуда уже убежит, и точность никакой не будет.
    Ответ написан