Zastosowanie GUI.Box()
.
Jeśli potrzebujesz tylko prostokąta 2D, najlepszym rozwiązaniem jest GUI. Utwórz nowy GUIStyle, używając prostego prostokąta jako tekstury (wnętrze prostokąta powinno być oczywiście przezroczyste), ustaw jego Border
wartość, aby nie była rozciągnięta, i wywołaj GUI.Box(new Rect(...),"",myGuiStyle);
.
Możesz użyć Camera.WorldToScreenPoint
metody, jeśli chcesz zarysować coś we współrzędnych świata (tj. 3D), pamiętaj tylko, że we współrzędnych świata Unity y przebiega od dołu do góry, aw GUI y od góry do dołu.
Przykład kodu:
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);
}
Poniżej znajduje się podejście inne niż shader.
Pomyśl o swoim polu 2d jako o niczym więcej niż czterech liniach, gdzie każda linia jest rozciągnięta tylko w jednym wymiarze (pozostałe dwa wymiary są przekrojem krawędzi). To tak, jakbyś budował pudełko w prawdziwym życiu, gdzie składasz ze sobą różne długości drewna, które mają taki sam rozmiar przekroju.
Mając to na uwadze, możesz opracować Komponent, powiedzmy
BoxBuilder
, który po podłączeniu do GameObject tworzy i zarządza czterema potomnymi GameObjectami. Każdy obiekt gry podrzędnej jest jedną z krawędzi pudełka i może być po prostu sześcianem 3d rozciągniętym tylko w jednym wymiarze. Zwidth
iheight
określonymBoxBuilder
poziomie, można obliczyć niezbędną pozycjonowanie i niejednorodnej skalę czterech krawędziach potomnych. To będzie dużopos.x=w/2
,pos.y=h/2
, ...,scale.x=h
,scale.y=w
, itd rodzaj kodu.Chociaż uważam, że prosisz tylko o 2D, zauważ, że ten sam pomysł można zastosować w razie potrzeby do ramek 3d, gdzie
BoxBuilder
teraz musi utworzyć i zarządzać 12 krawędziami podrzędnymi, ale ponownie skalować tylko każdą krawędź w jednym lokalnym wymiarze.źródło
Prostym sposobem jest użycie modułu cieniującego z dwoma przejściami: pierwsze przejście wykorzystuje moduł cieniujący wierzchołek do nieznacznego skalowania obiektu, a moduł cieniujący piksele do pokolorowania go jednolitym kolorem dopasowanym do koloru, który ma mieć kontur, oraz wtedy drugie przejście wykonuje normalne renderowanie.
źródło
Miałem ten sam problem z tworzeniem konspektu, tyle że musiałem stworzyć „obrys” dla kostki 3d i znalazłem nowy sposób na zrobienie tego, czego nigdzie indziej nie widziałem online.
Na poniższym obrazku są dwa kształty z konturami. Ten po prawej to sześcian zbudowany z LineRenderer, który tworzy płaskie ściany, które zawsze zwracają się w stronę użytkownika. Uważam tę metodę za super glitchy, z pojawiającymi się przypadkowymi „pociągnięciami”, które naśladują trójkąty tworzące twarz.
Ten po lewej to moja „innowacja”, w której 12 oddzielnych, chudych kostek tworzy coś, co wygląda jak kontur. Aby zmienić rozmiar „obrysu” w konspekcie, muszę zwiększyć / zmniejszyć rozmiary dwóch boków każdej z 12 chudych kostek. Działa to również w przypadku konturów 2d. Po prostu zastosuj materiał, aby zmienić kolor i voila!
Na tym obrazie widać szczegół struktury tego sześcianu. Wszystko to można było utworzyć w czasie wykonywania, ale zrobiłem to ręcznie i użyłem go jako prefabrykatu.
źródło
Obecnie mam do czynienia z tym samym problemem, a moje rozwiązanie jest dokładnie tym, co sugerują DuckMaestro i Raven Dreamer - Mają skrypt, który tworzy w czasie wykonywania 4 obiekty potomne, z których każdy reprezentuje bok granicy i dołącza do każdego z nich renderery linii.
W moim przypadku musiałem ciągle zmieniać rozmiar ramki, aby utrzymać ją wokół mojego obiektu (siatka tekstowa [która korzysta z renderera siatki] dla niestandardowego pola tekstowego), więc przy każdej aktualizacji robiłem to:
AlterBorder()
po prostu uzyskuje dostęp do odpowiedniego mechanizmu renderującego linie (określonego przez pierwszy parametr) i ustawia odpowiednio jego początek i koniec na pierwszy i drugi wektor.Zauważ, że użyłem
renderer
jako odniesienia dla rozmiaru, ale oczywiście możesz użyć dowolnego prostokąta, o ile x, y jest lewym górnym rogiem.Z tego, co mogę powiedzieć, działa to naprawdę dobrze, wygląda świetnie w grze, ponieważ mogę z łatwością przesuwać graniczy obiekt we wszystkich 3 osiach (nawet go obracać, a ponieważ renderery linii zawsze są skierowane w stronę kamery, nie wygląda to dziwnie) i jest nie trudne do wdrożenia.
źródło