Использование GUI.Box()
.
Если вам нужен только двухмерный прямоугольник, лучше всего использовать GUI. Создайте новый GUIStyle, используя простой прямоугольник в качестве текстуры (конечно, внутренняя часть прямоугольника должна быть прозрачной), установите его Border
значение так, чтобы оно не растягивалось, и вызовите GUI.Box(new Rect(...),"",myGuiStyle);
.
Вы можете использовать Camera.WorldToScreenPoint
метод, если хотите нарисовать что-то в мировых координатах (например, в 3D), просто помните, что в мировых координатах Unity y движется снизу вверх, а в GUI y движется сверху вниз.
Пример кода:
void OnGUI()
{
//top left point of rectangle
Vector3 boxPosHiLeftWorld = new Vector3(0.5f, 12, 0);
//bottom right point of rectangle
Vector3 boxPosLowRightWorld = new Vector3(1.5f, 0, 0);
Vector3 boxPosHiLeftCamera = Camera.main.WorldToScreenPoint(boxPosHiLeftWorld);
Vector3 boxPosLowRightCamera = Camera.main.WorldToScreenPoint(boxPosLowRightWorld);
float width = boxPosHiLeftCamera.x - boxPosLowRightCamera.x;
float height = boxPosHiLeftCamera.y - boxPosLowRightCamera.y;
GUI.Box(new Rect(boxPosHiLeftCamera.x, Screen.Height - boxPosHiLeftCamera.y, width, height),"", highlightBox);
}
Ниже приведен не шейдерный подход.
Представьте, что ваш 2-мерный прямоугольник представляет собой не более чем четыре линии, где каждая линия растянута только в одном измерении (два других измерения являются поперечным сечением края). Это очень похоже на то, как если бы вы собирали коробку в реальной жизни, где вы складываете куски различной длины, которые имеют одинаковый размер поперечного сечения.
Имея это в виду, вы можете разработать, скажем
BoxBuilder
, Компонент, который при подключении к GameObject создает и управляет четырьмя дочерними объектами GameObject. Каждый дочерний игровой объект является одним из ребер вашего бокса и может быть просто трехмерным кубом, растянутым только в одном измерении. Сwidth
иheight
определенномBoxBuilder
уровне, можно рассчитать необходимое позиционирование и неравномерную шкалу четырех детей края. Это будет многоpos.x=w/2
,pos.y=h/2
, ...,scale.x=h
,scale.y=w
и т.д. вид кода.Хотя я полагаю, что вы запрашиваете только
BoxBuilder
двумерные изображения , обратите внимание, что эту же идею можно применить к трехмерным блокам, если это необходимо, где теперь необходимо создать и управлять 12 дочерними ребрами, но опять же только масштабировать каждое ребро в одном локальном измерении.источник
Простой способ - использовать шейдер с двумя проходами: первый проход использует вершинный шейдер, чтобы немного увеличить масштаб объекта, и использует пиксельный шейдер, чтобы закрасить его до сплошного цвета, соответствующего цвету, который должен иметь контур, и затем второй проход делает обычный рендеринг.
источник
У меня была такая же проблема при создании контура, за исключением того, что мне нужно было создать «обводку» для 3d-куба, и я нашел новый способ сделать это, чего я не видел нигде в Интернете.
На изображении ниже есть две фигуры с очертаниями. Правый - это куб, построенный с помощью LineRenderer, который строит плоские грани, которые всегда обращены к пользователю. Я нашел этот метод супер глючным, со случайными «штрихами», которые имитируют треугольники, составляющие лицо.
Слева - мое «новшество» с 12-ю отдельными тощими кубиками, создающими то, что выглядит как контур. Чтобы изменить размер «обводки» в контуре, мне нужно увеличить / уменьшить размеры двух сторон каждого из 12 тощих кубов. Это также будет работать для двухмерных контуров. Просто примените материал, чтобы изменить цвет и вуаля!
На этом изображении вы можете увидеть детали структуры этого куба. Все это может быть создано во время выполнения, но я сделал это вручную и использовал его в качестве сборного.
источник
В настоящее время я сталкиваюсь с той же проблемой, и мое решение - именно то, что предложили DuckMaestro и Raven Dreamer: иметь скрипт, создающий 4 дочерних объекта во время выполнения, каждый из которых представляет сторону границы, и прикреплять к ним средства визуализации линий.
В моем случае мне нужно было постоянно изменять размер границы, чтобы она оставалась вокруг моего объекта (текстовая сетка [которая использует средство визуализации сетки] для настраиваемого текстового поля), поэтому при каждом обновлении я делала это:
AlterBorder()
просто обращается к соответствующему средству рендеринга строки (указанному первым параметром) и устанавливает его начало и конец для первого и второго вектора соответственно.Обратите внимание, что я использовал в
renderer
качестве ссылки для размера, но, очевидно, вы можете использовать любой прямоугольник, если х, у верхний левый угол.Из того, что я могу сказать, это работает очень хорошо, отлично смотрится в игре, потому что я могу легко перемещать свой ограниченный объект вокруг по всем 3 осям (даже поворачивать его, и так как линейные рендеры всегда смотрят в камеру, это не выглядит странно), и это не сложно реализовать.
источник