답변:
사용하십시오 GUI.Box()
.
2D 직사각형 만 필요한 경우 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);
}
아래는 셰이더가 아닌 접근 방식입니다.
2d 상자를 4 개의 선으로 생각하십시오. 각 선은 한 차원으로 만 늘어납니다 (다른 두 차원은 모서리의 단면입니다). 이것은 단면적이 동일한 나무의 가변 길이를 서로 연결하는 실생활에서 상자를 만드는 것과 매우 비슷합니다.
이를 염두에두고 BoxBuilder
GameObject에 연결될 때 4 개의 자식 GameObject를 만들고 관리 하는 Component를 구성 할 수 있습니다 . 각 하위 게임 개체는 상자 가장자리 중 하나이며 단순히 한 차원으로 확장되는 3D 큐브 일 수 있습니다. A의 width
와 height
정의 BoxBuilder
수준, 당신은 네 아이 가장자리의 필요한 위치 및 비 균일 한 크기를 계산할 수 있습니다. 그것은 많은 것 pos.x=w/2
, pos.y=h/2
, ..., scale.x=h
, scale.y=w
, 등 종류 코드.
2 차원 만 요구한다고 생각하지만 필요한 경우이 동일한 아이디어를 3d 상자에 적용 할 수 있습니다.이 경우 BoxBuilder
12 개의 자식 가장자리를 만들고 관리해야하지만 각 가장자리를 하나의 로컬 차원으로 만 스케일링해야합니다.
간단한 방법은 패스가 두 개인 셰이더를 사용하는 것입니다. 첫 번째 패스는 정점 셰이더를 사용하여 객체를 약간 확대하고 픽셀 셰이더를 사용하여 윤곽선에 원하는 색상과 일치하는 단색으로 채색합니다. 두 번째 패스는 일반 렌더링을 수행합니다.
3D 큐브에 대한 "스트로크"를 작성해야한다는 점을 제외하고는 윤곽을 작성하는 데 동일한 문제가 있었으며 온라인에서 다른 곳에서는 보지 못한 새로운 방법을 찾았습니다.
아래 이미지에는 윤곽선이있는 두 가지 모양이 있습니다. 오른쪽에있는 것은 LineRenderer로 구성된 큐브로, 항상 사용자쪽으로 향하는 평평한면을 만듭니다. 얼굴을 구성하는 삼각형을 흉내 낸 임의의 "스트로크"가 나타나는이 방법은 매우 결함이있는 것으로 나타났습니다.
왼쪽에있는 것은 윤곽선처럼 보이는 12 개의 분리 된 스키니 큐브가있는 "혁신"입니다. 개요에서 "스트로크"의 크기를 변경하려면 12 개의 스키니 큐브 각각의 양면 크기를 늘리거나 줄여야합니다. 이것은 2D 아웃 라인에도 적용됩니다. 재료를 적용하여 색상과 짜잔을 변경하십시오!
이 이미지에서이 큐브의 세부 구조를 볼 수 있습니다. 이것은 모두 런타임에 만들 수는 있지만 수동으로 만들어 조립식으로 사용했습니다.
나는 현재 같은 문제에 직면하고 있으며 내 솔루션은 정확히 DuckMaestro와 Raven Dreamer가 제안한 것입니다. 런타임에 4 개의 자식 객체를 만드는 스크립트가 있습니다. 각 객체는 테두리의 한면을 나타내고 각 라인 렌더러를 연결합니다.
필자의 경우 객체 주위에 테두리를 유지하기 위해 테두리의 크기를 끊임없이 조정해야했습니다 (사용자 정의 텍스트 필드에 [메시 렌더러를 사용하는 텍스트 메쉬]) 모든 업데이트마다 다음과 같이했습니다.
float width = Mathf.Max(renderer.bounds.size.x + paddingX * 2, minWidth);
float x = renderer.bounds.center.x - width / 2;
float height = renderer.bounds.size.y + paddingY * 2;
float y = renderer.bounds.center.y - height / 2;
AlterBorder(0, new Vector3(x - thickness / 2, y, 0), new Vector3(x + width + thickness / 2, y, 0)); //Bottom edge going left to right
AlterBorder(1, new Vector3(x + width, y + thickness / 2, 0), new Vector3(x + width, y + height - thickness / 2, 0)); //Right edge going bottom to top
AlterBorder(2, new Vector3(x + width + thickness / 2, y + height, 0), new Vector3(x - thickness / 2, y + height, 0)); //Top edge going right to left
AlterBorder(3, new Vector3(x, y + height - thickness / 2, 0), new Vector3(x, y + thickness / 2, 0)); //Left edge going top to bottom
AlterBorder()
적절한 라인 렌더러 (첫 번째 매개 변수로 지정)에 액세스하고 시작과 끝을 각각 첫 번째와 두 번째 벡터로 설정합니다.
renderer
크기에 대한 참조로 사용 했지만 x, y가 왼쪽 상단 모서리 인 한 사각형을 사용할 수 있습니다.
내가 실제로 말할 수있는 것에서, 3 축에서 경계선이있는 객체를 쉽게 움직일 수 있기 때문에 게임에서 멋지게 보입니다 (회전하더라도 라인 렌더러가 항상 카메라를 향하기 때문에 이상하게 보이지 않습니다). 구현하기가 어렵지 않습니다.