Аватар в мире гравитации
У нас есть живущий сам по себе мир. Давайте добавим интерактива и создадим собственную проекцию в этот мир. Пусть это будет космический корабль сравнимый по размерам с планетой. Хотелось бы сделать что-то более реалистичное и маленькое, но есть несколько препятствий для этого, во первых, из-за ограничений в вычислительной точности компьютера, в одной сцене адекватно физически взаимодействовать не могут гигантские звёзды и крошечные космические корабли. Поэтому, обычно в играх прибегают к разным хитростям чтобы создать у игрока ощущение реальности мира. В нашем случае пришлось бы модели планет и звёзд подменять разными заменителями в зависимости от расстояния, например, если корабль в космосе, то солнце можно представить в виде сферы, а если на земле, то в виде круга на небе.
Как будет выглядеть результат глазами игрока:
Игрок сможет управлять кораблём, с видом от третьего лица, при этом старый ракурс на мир будет в отдельном окошке по принципу миникарты.
Чтобы получить такой результат выполните следующие шаги: Добавьте к UI объект Image, установите свойство Color как белый цвет.
Переименуйте его как BorderImage, он послужит нам в качестве контура для миникарты. Установите его свойство Anchor как на картинке:
Это свойство указывает на то каким образом будет задаваться позиция, в данном случае позиция будет задаваться относительно правого нижнего угла. Куда бы не стал двигаться правый нижний угол родителя(в данном случае угол интерфейса) этот компонент будет сохранять расстояние указанное в свойствах Pos X Pos Y, установите эти свойства в 0. Это будет означать что опорная точка этого объекта будет точно в позиции левого нижнего угла. Сама опорная точка(Pivot point) задаётся чуть ниже:
Установите свойства Width и Height в 256, Pivot X в 1, Pivot Y в 0. Опорная точка выставляется относительно объекта, позиция (0;0) означает левый нижний угол объекта, а (1;1) правый верхний. Опорная точка работает точно так же как и в пакетах 3D моделирования, все трансформации производятся относительно этой точки, т.е. если мы будем вращать по оси Z, то картинка будет вращаться вокруг этой точки. Поправьте PosX и PosY, т.к. изменение точки опоры не меняет фактического положения объекта, а заново вычисляет PosX и PosY.
Теперь создайте потомком BorderImage объект типа RawImage и переименуйте его в MinimapRawImage.
Установите свойства объекта в соответствии с картинкой. Заметьте свойство Anchor теперь другое, этот вид Anchor позволяет задать расстояние до каждого края и сохранять его, т.е. если родитель будет менять свой размер, то этот потомок будет повторять все изменения с заданным отступом. И последним создайте потомком MinimapRawImage объект Text и задайте следующие свойства:
PosX и PosY не имеют значения, т.к. мы будем менять эти параметры кодом. После создания всех элементов интерфейса должно получится что-то такое:
Теперь, чтобы вывести картинку с камеры на миникарту надо в окне Project создать текстуру в которую будет осуществляться рендер, задайте её имя Minimap:
После создания надо указать камере, что именно в эту текстуру надо осуществлять ренедер:
И последний шаг в настройке ренедера миникарты, установите эту же текстуру в качестве картинки для MinimapRawImage.
Теперь давайте приступим к созданию корабля. Создайте в окне Hierarchy новый пустой объект и назовите его GiantShip, добавьте к нему кубик и назовите его Geometry. Так же потомком создайте новую камеру и ParticleSystem:
Переименуйте систему частиц в Smoke. И задайте свойства в соответствии со скриншотом:
Кубик геометрии можете настроить по своему вкусу чтобы он был примерно в два раза меньше земли. Учтите, что коллайдеры потомков GiantShip будут участвовать в коллизиях. Добавьте так же к GiantShip компонент Rigidbody, не забудьте снять галочку Use gravity. Настройка сцены закончена. Чтобы всё заработало надо создать скрипт и изменить пару старых.
Это тот скрипт, что в прошлых уроках был прикреплён к камере общего вида. Теперь в нём одно новое открытое поле и его надо заполнить ссылкой на текстовый объект.
Заметьте, что в коде раньше было Screen.width, а теперь camera.pixelWidth, дело в том, что теперь эта камера осуществляет рендер не во весь экран, а только в размер рендер-текстуры. Соответственно надо и все значения изменить под этот нюанс.
Этот скрипт изменился только в тех местах, где раньше было Screen.width/Screen.height.
Этот скрипт отвечает за управление кораблём. Добавьте его как компонент к GiantShip. Заметьте, что данный класс унаследован от CelestialBody, что автоматически добавляет влияние гравитации на него. Ещё один интересный момент в том, что нажатие кнопок на клавиатуре не влияет напрямую на физическое тело корабля, а всё влияние осуществляется внутри FixedUpdate.
Теперь у нас есть мир, который живёт и развивается, и наш аватар в нём, которым мы можем управлять. Если врезаться в землю, то можно даже изменить её траекторию.