Unity3d에서 외곽선을 어떻게 그릴 수 있습니까?


13

임의의 높이의 사각형을 강조하려고합니다. 가장 쉬운 방법은 사각형을 나타내는 별도의 "상자"gameobject를 만드는 것입니다.

MeshRenderer + Transparent Texture와 LineRenderer를 사용하여 사각형의 네 점을 설명했습니다. 둘 다 매우 만족스럽지 않습니다.

여기에 이미지 설명을 입력하십시오

(오른쪽의 스케일 된 큐브 가운데에 선 렌더러가 있음)

이것에 대해 올바른 길은 무엇입니까? 왼쪽 사각형과 같은 것을 얻으려고합니다. 내가 선택한 4 점을 통해 고정 너비의 간단한 둘레입니다.

답변:


8

사용하십시오 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);
}

내가 실수하지 않는 한 GUI.Box ()는 항상 장면의 모든 객체 위에 그려 집니까? 게임 오브젝트 뒤에 또는 부분적으로 GUI 요소를 가질 수 있습니까?
Raven Dreamer

예, GUI는 항상 다른 객체 뒤에 그려집니다. GUI 위에 별도의 카메라를 렌더링하는 데 사용할 수있는 해킹이 있지만 다소 다루기 어렵습니다.
Nevermind

이 답변은 필요한 것을 얻었지만 일반적인 경우에는 더 나은 방법이 있기를 희망하여 지금 열어두고 있습니다.
레이븐 드리머

코드 샘플 추가 편집을 수락하고 GUI-y-down-down 버그를 수정했습니다.
Nevermind

1

아래는 셰이더가 아닌 접근 방식입니다.

2d 상자를 4 개의 선으로 생각하십시오. 각 선은 한 차원으로 만 늘어납니다 (다른 두 차원은 모서리의 단면입니다). 이것은 단면적이 동일한 나무의 가변 길이를 서로 연결하는 실생활에서 상자를 만드는 것과 매우 비슷합니다.

이를 염두에두고 BoxBuilderGameObject에 연결될 때 4 개의 자식 GameObject를 만들고 관리 하는 Component를 구성 할 수 있습니다 . 각 하위 게임 개체는 상자 가장자리 중 하나이며 단순히 한 차원으로 확장되는 3D 큐브 일 수 있습니다. A의 widthheight정의 BoxBuilder수준, 당신은 네 아이 가장자리의 필요한 위치 및 비 균일 한 크기를 계산할 수 있습니다. 그것은 많은 것 pos.x=w/2, pos.y=h/2, ..., scale.x=h, scale.y=w, 등 종류 코드.

2 차원 만 요구한다고 생각하지만 필요한 경우이 동일한 아이디어를 3d 상자에 적용 할 수 있습니다.이 경우 BoxBuilder12 개의 자식 가장자리를 만들고 관리해야하지만 각 가장자리를 하나의 로컬 차원으로 만 스케일링해야합니다.


실행 가능하지만 너무 복잡합니다.
Nevermind

나는 이런 식으로해야 할 일을했을 경우에, 나는 간단하게 4 라인 렌더러 ... 사용하십시오
레이븐 드리머

그러나 이것은 깊이를 올바르게 처리합니다.
DuckMaestro

1

간단한 방법은 패스가 두 개인 셰이더를 사용하는 것입니다. 첫 번째 패스는 정점 셰이더를 사용하여 객체를 약간 확대하고 픽셀 셰이더를 사용하여 윤곽선에 원하는 색상과 일치하는 단색으로 채색합니다. 두 번째 패스는 일반 렌더링을 수행합니다.


무슨 의미인지 더 잘 설명하기 위해 코드 예제를 제공해 주시겠습니까?
Raven Dreamer

이것은 원점이 기하학적 중심에있는 볼록한 객체 (사각형과 같은)에 대해서만 작동합니다.
rootlocus

1

3D 큐브에 대한 "스트로크"를 작성해야한다는 점을 제외하고는 윤곽을 작성하는 데 동일한 문제가 있었으며 온라인에서 다른 곳에서는 보지 못한 새로운 방법을 찾았습니다.

아래 이미지에는 윤곽선이있는 두 가지 모양이 있습니다. 오른쪽에있는 것은 LineRenderer로 구성된 큐브로, 항상 사용자쪽으로 향하는 평평한면을 만듭니다. 얼굴을 구성하는 삼각형을 흉내 낸 임의의 "스트로크"가 나타나는이 방법은 매우 결함이있는 것으로 나타났습니다.

왼쪽에있는 것은 윤곽선처럼 보이는 12 개의 분리 된 스키니 큐브가있는 "혁신"입니다. 개요에서 "스트로크"의 크기를 변경하려면 12 개의 스키니 큐브 각각의 양면 크기를 늘리거나 줄여야합니다. 이것은 2D 아웃 라인에도 적용됩니다. 재료를 적용하여 색상과 짜잔을 변경하십시오!

두 가지 개요

이 이미지에서이 큐브의 세부 구조를 볼 수 있습니다. 이것은 모두 런타임에 만들 수는 있지만 수동으로 만들어 조립식으로 사용했습니다.

세부 묘사


0

나는 현재 같은 문제에 직면하고 있으며 내 솔루션은 정확히 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 축에서 경계선이있는 객체를 쉽게 움직일 수 있기 때문에 게임에서 멋지게 보입니다 (회전하더라도 라인 렌더러가 항상 카메라를 향하기 때문에 이상하게 보이지 않습니다). 구현하기가 어렵지 않습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.