Как сделать перемещение объекта в unity

Обновлено: 07.07.2024

Всем доброго времени суток. Я к вам хочу обратиться за помощью: мне надо плавно переместить объект в начало сцены не зависимо от его расположения (желательно ещё и с вращением), а как сделать - понять не могу. Искал в интернете - не находил.
Заранее спасибо! (Использую Unity 2018.2.3f1)

Передвижение объекта в определённую точку
Здравствуйте , подскажите пожалуйста со скриптом который в методе старт будет узнавать координаты.

Плавное передвижение в точку клика
Есть объект который должен переместиться в точку куда попал луч. Но объект перемещается только во.

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

Передвижение объекта
Подскажите плиз Вводятся 3 числа. A, B, N. A - движение вперед, B - движение назад, N -.

Решение

Спасибо, то что нужно!

Кстати, а поворот также плавно можно сделать?

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

Передвижение объекта в игре
В моей игре объект(бот) передвигаеться с помощью таймера(pygame.time.set_timer()) каждые 10.


Замкнутое передвижение объекта
Я новичёк в unity3d скажу сразу. Хочу сделать чтобы объект двигался вправо влево по оси x.


Передвижение объекта по плоскости
Доброго времени суток, не могу найти нормального ответа по счет следующего: Почему функция.

Передвижение объекта по координатам
Привет. Есть такая часть кода private: System::Void startToolStripMenuItem_Click(System::Object^ .

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

В прошлой статье было небольшое введение в принцип работы Bolt и основы визуального программирования. В этой же попробуем небольшой платформер сделать и затронем основные аспекты.

​Поработаем с силами, рейкастами и затронем тему модульности и переиспользования компонентов.


Цикл статей

​Туториалы можно скачать бесплатно с Гитхаба. Каждый туториал будет отдельной папкой в проекте. Конкретно этот туториал будет лежать в директории Assets/Tutorials/02 — Platformer.

Оглавление

Подготовка

Накидаем простенькую сцену с платформами и шипами. Я использовал редактор Тайлов, но это могут быть и обычные спрайты с колайдерами на них. Добавляем в иерархию GameObject игрока.


В инспекторе добавляем к объекту компонент Flow Machine.


Нажимаем Edit Graph и приступает к настройке графа.

Движение персонажа

Мы хотим, чтобы персонаж двигался влево и вправо в зависимости от горизонтальной оси ввода, для которой предварительно настроены сочетания клавиш A и D на клавиатуре или левый джойстик на контроллере. Когда вы идёте влево, возвращается -1 , а когда вправо, то +1 . Скорость движения зададим в переменной.

Для начала можно зайти в настройки и задать необходимое управление в Edit > Project Settings > Input Manager, если не нравятся дефолтные настройки.


Теперь добавим переменную, откуда будем читать скорость. В инспектора объекта игрока добавим переменную в компоненте Veriables. Подробнее можно почитать в документации.

Далее, собственно, нам нужно получить горизонтальную ось ввода. Мы можем сделать это с помощью блока Get Axis.

Новый узел будет полупрозрачным. Так Unity нам сообщает, что они пока нигде не используется. Этот эффект можно отключить на панели отжав пункт Dim.


Далее мы хотим на основании инпута вычислить итоговое значение скорости. Для этого нужно считать значение переменной Speed, созданной ранее, перемножить со значением с инпута и записать в новую переменную.

  1. От выхода узла GetAxis тащим указатель и создаём узел Multiply.
  2. От второго входа нового узла тянем указатель и создаём узел для чтения переменной Variables > Object > Get Object Variable.
  3. Выбираем там Speed.
  4. Выход узла Multiply соединяем с новым узлом Variables > Graph -> Set Graph Variable.
  5. Дадим новой переменной имя Movement.
  6. Соединяем управляющий вход с Update.

Каждый кадр (событие Update) мы получаем значение инпута по оси X в диапозоне [-1;1], домножаем на скорость и сохраняем в переменную Movement.

Теперь нужно задать компоненту Rigidbody 2D персонажа скорость. Скорость состоит из двух составляющих — по осям X и Y, которые пакуются в Vector2 .

  1. Добавляем узел Get Variable для получения Movement из предыдущего шага.
  2. Это передаёт на вход X координате новой ноде Vector2.
  3. А в Y передаём считанную Y координату из текущей скорости (Codebase > Unity Engine > Rigidbody 2D -> Get Velocity).
  4. Полученный вектор передаём на вход узлу для установки нового значения скорости (Codebase > Unity Engine > Rigidbody 2D -> Set Velocity).

Остаётся теперь связать выход узла по установке Movement со входом узла, устанавливающего скорость.

Ну и заодно сгруппируем узлы. Это делается выделением с зажатой клавишей Ctrl .

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

  1. Если двигаемся вправо (значение Movement больше 0), значение Scale должно быть положительным.
  2. Если движемся влево (значение Movement меньше 0), значение Scale должно быть отрицательным.
  3. Если стоим на месте (значение Movement равно 0), то ничего не делаем.

Значение Y и Z оставляем как есть.


Если запустить редактор, то увидим, что спрайт персонажа отзеркаливается в зависимости от направления движения.

Но сейчас персонаж просто скользит. Хотелось бы сделать анимацию движения.

Анимация

Возьмём готовые спрайты и анимации из примера проекта Penny Pixel.

Если открыть аниматор, то нас там пока интересует всего 2 анимации: айдловая и бега. Если посмотреть на переход для анимации бега, то заметим, что оно зависит от скорости по оси X. Нам всего лишь нужно это значение передавать аниматору.

Ну и флажок grounded пока в true выставим, чтобы не запускалась анимация полёта.


На графе, как я уже сказал, нам нужно всего лишь передать значение скорости аниматору и записать в переменную velocityX.


Остаётся только соединить с остальным графом и запустить.

Следующим шагом добавим возможность прыгать.

Придание силы объекту для прыжка

  1. Добавим глобальную переменную для силы прыжка и назовём JumpPower.
  2. Events > Input, а там On Button Input.
  3. Вместе со считанной силой прыжка передаём в Codebase > Unity Engine > Rigidbody 2D > Add Force (Force, Mode).

Если запустить, то по нажатию на Space персонаж будет прыгать. Но есть одна проблема…

Во-первых, нету анимации прыжка. Во-вторых, если, находясь в воздухе, снова нажать Space, то персонаж прыгнет ещё раз. А нам бы этого не хотелось.

Создадим новый слой и назначим его платформам.


Необходимо дописать логику по проверке, находится ли персонаж на земле. Один из способов — рейкасты. Будем выпускать лучи вниз на небольшое расстояние, чтобы проверить, сталкиваются ли они с платформой. Проверять как раз по этому слою будем.

Переиспользование логики

Так как эта проверку нужна в двух местах, то выделим всю логику в отдельный юнит Assets > Create > Bolt > Flow Macro.

Для каста использовать будем CircleCast . Хотя это не так принципиально.

  1. Получаем позицию текущую.
  2. Делаем рейкаст по слою Platform, направляя вниз с радиусом 2 и дальностью 2.
  3. Результат получаем в отдельную ноду.
  4. Делаем проверку на то, было ли столкновение.
  5. Результат проверки столкновения луча с платформой пишем в bool переменную IsGrounded на выход.

Теперь в графе персонажа нужно немного изменить узлы, обрабатывающие прыжок.

  1. Перетаскиваем на граф персонажа граф GroundCheck.
  2. Добавляем ветвление.
  3. Соединяем с узлом, задающим силу.

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

Точно также добавим проверку к анимации.


Теперь, если персонаж в воздухе, будет проигрываться соответствующая анимация.

Хотелось бы как-то визуализировать дебажную информацию для отладки.

Отладка и OnDrawGizmos

Было бы неплохо как-то визуализировать рейкаст. Как минимум, хочется видеть, как далеко он бьёт. Для этого можно воспользоваться событием OnDrawGizmos , которое позволяет в редакторе рисовать отладочную информацию.

В нашем случае просто будет рисовать линию. Увеличим дальность луча до 50 и добавим соответствующие узлы для отрисовки линии.

  1. Вытаскиваем информацию о текущем положении.
  2. Создаём Vecto3 на основе X и Z координаты. Эта позиция будет конечной при отрисовки линии.
  3. Рейкаст мы делаем вниз, поэтому в Y координату вписываем Y координату текущего положения персонажа с за вычетом дальности луча.
  4. Добавляем ивент, который каждый кадр рисует информацию.
  5. На вход узла по отрисовке в начальную координату передаём текущее положение персонажа, а конечной точкой будет новое вычисленное значение позиции.

Ещё нужно в Scene View включить отображение Gizmos.


Теперь запустим и посмотрим.

Увеличив дальность проверки для рейкаста мы дали возможно персонажу прыгать даже в воздухе.

В следующей статье поработаем с окнами и сделаем экран смерти персонажа с перезапуском сцены.

Если хотите поддержать выход статей, сделать это можно одним из способов.

Создание объекта, контролируемого игроком, требует наличия определенных элементов: спрайт, способ управления им и способ его взаимодействия с игровым миром. Рассмотрим этот процесс шаг за шагом и начнем, пожалуй, со спрайта. Вот изображение, которое мы будем использовать:

  1. Скорируйте картинку в папку "Textures"
  2. Создайте новый спрайт и назовите его "Player"
  3. Настройте спрайт так, чтобы он отображался в свойстве "Sprite" компонента "Sprite Renderer"

Если у вас возникли проблемы, обратитесь к предыдущему уроку. Мы проделали точно такие же действия для фона и "реквизита".

  1. Поместите игрока в слой "2 - Foreground"
  2. Измените масштаб на (0.2, 0.2, 1)

Теперь несколько слов о компонентах. Мы только что говорили о компоненте "Sprite Renderer". Если вы еще не заметил, объект игры состоит из нескольких компонентов, видимых в панели "Инспектор".

По умолчанию пустой объект игры выглядит так:

Компоненты пустого игрового объекта

Этот объект имеет только один компонент: Transform . Этот компонент является обязательным и не может быть отключен или удален. Вы можете добавить к объекту столько компонентов, сколько захотите. Например, скрипты добавляются в качестве компонента. Большинство компонентов может быть включено или отключено пока существует объект.

Включить компонент игрового объекта

(Вы можете нажать на галочку чекбокса, чтобы отключить его. Вы можете щелкнуть правой кнопкой мыши на компоненте, чтобы вернуть прежнее свойство, удалить его и т.д.

Компоненты могут взаимодействовать с другими компонентами. Если объект имеет сомпонент, который требуется другому компоненту объекта для работы, вы можете просто перетащить весь объект внутрь этого компонента, и тогда компонент сам найдет все, что ему нужно.

Sprite Renderer является компонентом, который способен отображать спрайт-текстуру. Теперь, когда мы узнали о концепции компонента, давайте добавим один к игроку!

Добавляем бокс-коллайдер (Box Collider)

Нажмите на кнопку "Добавить компонент" объекта игрока. Выберите "Box Collider 2D". Вы можете увидеть коллайдер в редакторе "Сцена" зрения и настройки его размера в "Инспекторе" в поле "Размер" (Size).

Существует еще один способ редактирования бокс-коллайдера. Выберите игровой объект с помощью бокс-коллайдера и зажмите клавишу shift на клавиатуре. Вы увидите, что на бокс-коллайдере (зеленый прямоугольник ) появились четыре маленьких рычажка. Перетащите один из них, чтобы изменить форму бокс-коллайдера. Будьте осторожны, синий прямоугольник представляет собой компонент Transform вашего игрового объекта, а не коллайдер.

Мы будем устанавливать размер коллайдера равным (10, 10) .

Это слишком много для настоящего шмапа, но все же меньше, чем спрайт:

Хитбокс игрока

В настоящее время, этого вполне достаточно.

Совет: Если вы планируете создать шмап, вам придется уделить много времени настройке хитбоксов – они должны точно соответствовать маленькому элементу внутри игрового спрайта. Вы также можете изменить такой параметр коллайдера, как shape – например, с помощью "Circle Collider 2D". Благодаря Unity, его поведение при этом не меняется, но это позволяет немного улучить геймплей.

Сохраним объект игрок как префаб. Теперь у вас есть базовую сущность игрока!

Добавляем спрайт игрока

2D полигональный коллайдер

Если вы хотите супер точный и произвольный формы хитбокс, воспользуйтесь компонентом Unity "Полигоннальный коллайдер 2D" (Polygon Collider 2D). Эффект от этого будет незначительный, но зато вы получите такую форму, какую вы хотите.

"Polygon Collider 2D" похож на остальные коллайдеры: вы можете изменять форму с помощью мышки в режиме "Scene". Для удаления точки зажмите cmd или ctrl , а чтобы отрегулировать положение точки или добавить ее в форму коллайдера, используйте shift

Магия Rigidbody

Последний компонент, необходимый для добавления на нашего игрока: "Rigidbody 2D". Это поможет физическому движку правильно задействовать объект в игровом пространстве. Более того, это позволит вам использовать столкновения в скрипте.

  1. Выберите объект Player в "Hierarchy".
  2. Добавьте компонент "Rigidbody 2D".

Теперь, нажмите кнопку "играть" и смотрите, что у нас вышло:

Корабль падает! И как падает! Передвайте привет нашей любимой силе тяжести. По мере того, как сменяются кадры с заранее заданной гравитацией и rigidbodies прибавляет объекту массы, корабль притягивается к нижней части экрана.

По-умолчанию, ускорние свободного падения в Unity равно 9.81 , т.е. мы имеем дело с земной гравитацией.

Гравитация может быть использована в любой игре, но нам она не нужна. К счастью, гравитацию на Rigidbody можн легко отключить. Просто установите "гравитационный масштаб" равным нулю. Вот и все, корабль снова летит. Не забудьте поставить галочку в окошке "Fixed Angles", чтобы предотвратить вращение корабля, обусловленное такой физикой.

Настройки твердого тела игрока

Перемещение игрока

"Sync MonoDevelop Project": Это подменю немного странное.Во-первых, невозможно изменить имя, даже если сменить редактора.
Мы также рекомендуем использовать это меню при создании первого скрипта, так как Unity создаст решения и привяжет их к библиотекам Unity (для Visual Studio, Xamarin Studio или MonoDevelop).
Если вместо этого вы просто откроете скрипт, компилятор вашего IDE, скорее всего, зарегистрирует определенные ошибки, не Unity. Это не имеет значения, потому что вам не придется использовать его напрямую, но функция автоматического завершения объектов Unity не помешает.

По умолчанию в скрипте уже прописаны методы Start и Update . Вот краткий список наиболее часто используемых функций:

  • Awake() вызывается один раз, когда объект создается. По сути аналог обычной функции-конструктора.
  • Start() выполняется после Awake() . Отличается тем, что метод Start() не вызывается, если скрипт не включен (remember the checkbox on a component in the "Inspector").
  • Update() выполняется для каждого кадра in the main game loop.
  • FixedUpdate() вызывается каждый раз через определеннок число кадров. Вы можете вызывать этот метод вместо Update() когда имеете дело с физикой ("RigidBody" и др.).
  • Destroy() вызывается, когда объект уничтожается. Это ваш последний шанс, чтобы очистить или выполнить код.

У вас также есть некоторые функции для обработки столкновений:

  • OnCollisionEnter2D(CollisionInfo2D info) выполняется, когда коллайдер объекта соприкасается с другим коллайдером.
  • OnCollisionExit2D(CollisionInfo2D info) выполняется, когда коллайдер объекта не соприкасается ни с одним другим коллайдером.
  • OnTriggerEnter2D(Collider2D otherCollider) выполняется, когда коллайдер объекта соприкасается с другим коллайдером с пометкой "Trigger".
  • OnTriggerExit2D(Collider2D otherCollider) выполняется, когда коллайдер объекта перестает соприкасаться с коллайдером, помеченным как "Trigger".

Итак, с теорией покончено, пора в бой. Или нет, погодите еще немного: обратите внимание, что почти все, о чем мы говорили с вами имеет, суффикс "2D". Box Collider 2D , a Rigidbody 2D , OnCollisionEnter2D , OnTriggerEnter2D и т.д. Эти новые компоненты или методы появились с Unity 4.3. Используя их, вы работаете с физическим движком, встроенным в Unity 4.3, для 2D-игр (на основе Box2D) вместо движка для 3D-игр (PhysX). Два движка имеют аналогичные концепции и объекты, но они не работают точно так же. Если вы начинаете работать с одним (например, Box2D для 2D-игр), придерживаqntcm его. Именно поэтому мы используем все объекты или методы с суффиксом "2D".

В скрипт для нашего игрока мы добавим несколько простых элементов управления, а именно: клавиши со стрелками, которые будут перемещать корабль.

Поясню цифры в комментариях к коду:

  1. Сначала определим публичную переменную, которая будет отображаться в окне "Инспектор". Это скорость, используемая для корабля.
  2. Сохраним движение для каждого кадра.
  3. Используем дефолтную ось, которую можно отредактировать в "Edit" -> "Project Settings" -> "Input". При этом мы получим целые значения между [-1, 1] , где 0 будет означать, что корабль неподвижен, 1 - движение вправо, -1 - влево.
  4. Умножим направление на скорость.
  5. Изменим скорость rigidbody. Это даст движку команду к перемещению объекта. Сделаем это в FixedUpdate() , предназначенном для всего, что связано с физикой.

Теперь добавим скрипт к игровому объекту. Для этого перетащите скрипт из окна "Проект" (Project) на игровой объект в "Иерархии" (Hierarchy). Вы также можете нажать на "Add Component" и добвить его вручную.

Попробуйте настроить скорость: нажмите на игрока, измените значения скорости в "Инспекторе", и посмотрите что из этого получится.

Инспектор для сценария

Будьте осторожны: изменения параметров, сделанные во время, игры теряются, когда вы ее остановите! Инспекторе - это отличный инструмент для настройки геймплея, но запомните или запишите, что вы делали, если хотите сохранить изменения. Этот же трюк подходит, если вы хотете проверить что-то новое, но не хотите вносить изменения в реальный проект.

Первый враг

Теперь добавим неприятелей, стремящихся уничтожить наш корабль. Пусть им будет зловещий спрут, названный "Poulpi":

Poulpi Sprite

Создадим новый спрайт. Для этого:

  1. Скопируйте картинку в папку "Textures".
  2. Создайте новый спрайт, используя это изображение.
  3. Измените свойство "Масштаб" (Scale) в разделе Трансформирование (Transform) на (0.4, 0.4, 1) .
  4. Добавьте "Box Collider 2D" размером (4, 4) .
  5. Add a "Rigidbody 2D" with a "Gravity Scale" of 0 and "Fixed Angles" ticked.

Сохраните префаб и. вуаля!

Спрайт врага в Unity

Скрипт

Теперь напишем простенький скрипт, отвечающий за движение осьминога в определенном направлении. Для этого создайте новый скрипт, назвав его "MoveScript".

Модульность обеспечивается системой на основе компонентов Unity. Это отличный способ отделить друг от друга скрипты с различными функциями. Конечно, вы можете написать один гигантский скрипт с большим количеством параметров. Это ваш выбор, но я настоятельно не рекомендую вам делать это.

Скопируем некоторые части кода, который мы написали в «PlayerScript" для движения персонажа. We will add another designer (a public member you can alter in the "Inspector") variable for the direction:

Прикрепите скрипт к осьминогу. Нажмите "Play" и убедитесь, что спрут движется так, как показано на рисунке ниже:

Если вы будете перемещать игрока перед врагом, оба спрайта столкнутся. Они просто заблокируют друг друга, так как мы еще не определили их поведение при столкновении.

Вы узнали, как добавить игрока, движущегося с помощью клавиатуры. Также, мы создали врага с зачаточным AI. Теперь мы хотим иметь возможность уничтожить его! А для этого, нам нужны боеприпасы, которые мы создадим в следующем уроке 2D игра на Unity. Подробное руководство. Часть 3.

Я просматриваю несколько разных руководств по Unity, и способ перемещения игрового объекта в каждом из них немного отличается.

Каковы плюсы и минусы каждого из этих методов и какой из них предпочтительнее для ролевой игры от первого лица?

Что-то, что я заметил, это то, что приложенная сила напоминает колесные транспортные средства, в то время как положение меняет образ ходьбы/бега.

Ответы 2

  1. Rigidbody.MovePosition(m_Rigidbody.position + movement);
  1. Rigidbody.AddForce(15 * Time.deltaTime, 0, 0, ForceMode.VelocityChange);

Это заставит объект ускоряться, поэтому он не будет двигаться с постоянной скоростью (это из-за второго закона Ньютона, Сила = масса * ускорение). Кроме того, если у вас есть другая сила, действующая в противоположном направлении, эта сила может быть нейтрализована, и объект вообще не будет двигаться.

  1. Transform.transform.position = playerTransform.position + cameraOffset;

Это позволит телепортировать объект. Никакого плавного перехода, никакого взаимодействия с какими-либо силами, уже находящимися в игре, только мгновенная смена позиции.

Твердые тела и скорости/физика

Единственный раз, когда я лично использовал систему твердых тел, был при реализации моего собственного боиды (поведение стаи), так как вам нужно вычислить несколько отдельных векторов и применить их все к юниту.

Это вычисляет вектор движения к цели для вас, используя физическую систему, поэтому на скорость и движение объекта все еще может влиять сопротивление, угловое сопротивление и так далее.

Я полагаю, что эта конкретная функция является оболочкой Rigidbody.AddForce .

  • Хорошо, если вы стремитесь к реалистичным физическим реакциям.

Немного неудобно использовать, если все, чего вы пытаетесь достичь, — это перемещение объекта из точки А в точку Б.

  • Иногда ошибочное значение параметра, установленное где-то слишком высоко (например, Mass > 10000000), может привести к действительно странным ошибкам в поведении, которые может быть довольно сложно определить и смягчить.

Примечания: Rigidbody при столкновении с другим Rigidbody будет отскакивать друг от друга в зависимости от настроек физики.

На них также влияет гравитация. В основном они пытаются имитировать объекты из реальной жизни, но иногда бывает сложно приручить объекты и заставить их делать именно то, что вы хотите.

И Rigidbody.AddForce в основном такой же, как и выше, за исключением того, что вы сами вычисляете вектор.

Так, например, чтобы получить вектор к цели, вы должны сделать

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

Поскольку гораздо проще заставить вещи вести себя так, как вы хотите, если, конечно, вы не стремитесь к физическому реализму!

Интерполяция позиции единиц

  • Возможно, сначала это немного странно для понимания, но гораздо проще заставить объекты двигаться так, как вы хотите.
  • Если вам нужны реалистичные реакции на воздействующие объекты, вам придется проделать большую часть работы самостоятельно. Но иногда это предпочтительнее, чем использовать физическую систему, а не пытаться, как я уже говорил ранее, приручить ее.

Вы бы использовали эту технику, скажем, в игре Pokemon, вы не останавливаетесь в Pokemon и ждете, пока пепел перестанет скользить или ударится о стену и неконтролируемо отскочит назад.

Читайте также: