Làm cách nào tôi có thể vẽ phác thảo trong Unity3d?


13

Tôi đang cố gắng làm nổi bật một hình chữ nhật có chiều cao tùy ý. Tôi nghĩ cách dễ nhất để làm điều này là tạo ra một trò chơi "hộp" riêng biệt phác thảo hình chữ nhật.

Tôi đã thử với cả GridRenderer + Texture trong suốt và LineRenderer để phác thảo bốn điểm của hình chữ nhật. Không phải là rất thỏa đáng.

nhập mô tả hình ảnh ở đây

(Trình kết xuất đường thẳng ở giữa, khối được chia tỷ lệ ở bên phải)

Cách đúng đắn để đi về điều này là gì? Tôi đang cố gắng để có được một cái gì đó giống như hình chữ nhật bên trái - một chu vi đơn giản có chiều rộng cố định thông qua bốn điểm tôi chọn.

Câu trả lời:


8

Sử dụng GUI.Box().

Nếu bạn chỉ cần một hình chữ nhật 2D, GUI là cách để đi. Tạo GUIStyle mới bằng cách sử dụng một hình chữ nhật đơn giản làm kết cấu (dĩ nhiên bên trong hình chữ nhật phải trong suốt), thiết lập Bordergiá trị của nó để nó không bị kéo dài và gọi GUI.Box(new Rect(...),"",myGuiStyle);.

Bạn có thể sử dụng Camera.WorldToScreenPointphương thức nếu bạn muốn phác thảo một cái gì đó theo tọa độ thế giới (ví dụ 3D), chỉ cần nhớ rằng trong tọa độ thế giới của Unity y đi từ dưới lên trên và trong GUI y đi từ trên xuống dưới.

Mã ví dụ:

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);
}

Trừ khi tôi nhầm, GUI.Box () sẽ luôn được vẽ trên đầu của bất kỳ đối tượng nào trong cảnh? Có thể có một phần tử GUI phía sau hoặc một phần phía sau một trò chơi không?
Raven Dreamer

Có, GUI luôn được vẽ sau các đối tượng khác. Có một hack mà bạn có thể sử dụng để kết xuất một camera riêng trên đỉnh GUI, nhưng nó hơi khó sử dụng.
Nevermind

Câu trả lời này đã cho tôi những gì tôi cần, nhưng hiện tại tôi vẫn đang mở nó với hy vọng rằng có một cách tốt hơn để làm điều này trong trường hợp chung.
Raven Dreamer

Tôi đã chấp nhận bản chỉnh sửa thêm mẫu mã của bạn và đã sửa lỗi GUI-y-lộn ngược trong đó.
Không bao giờ

1

Dưới đây là một cách tiếp cận không shader.

Hãy nghĩ về hộp 2d của bạn là không có gì nhiều hơn bốn dòng, trong đó mỗi dòng được kéo dài chỉ trong một chiều (hai chiều còn lại là mặt cắt ngang của cạnh). Điều này giống như khi bạn xây dựng một chiếc hộp trong đời thực, nơi bạn đang ghép các chiều dài khác nhau của gỗ mà tất cả đều có cùng kích thước mặt cắt ngang.

Với ý nghĩ đó, bạn có thể nghĩ ra một Thành phần, giả sử BoxBuilder, khi được gắn vào GameObject, sẽ tạo và quản lý bốn GameObject con. Mỗi đối tượng trò chơi trẻ em là một trong các cạnh hộp của bạn và có thể chỉ đơn giản là một khối lập phương 3d được kéo dài chỉ trong một chiều. Với một mức widthheightđược xác định BoxBuilder, bạn có thể tính toán vị trí cần thiết và tỷ lệ không đồng nhất của bốn cạnh con. Nó sẽ là rất nhiều pos.x=w/2, pos.y=h/2, ..., scale.x=h, scale.y=wvv loại mã.

Mặc dù tôi tin rằng bạn chỉ yêu cầu 2-d, lưu ý rằng ý tưởng tương tự này có thể được áp dụng cho các hộp 3d nếu cần, trong đó BoxBuilderbây giờ phải tạo và quản lý 12 cạnh con, nhưng chỉ mở rộng mỗi cạnh theo một chiều cục bộ.


Hoàn toàn khả thi, nhưng CÁCH quá phức tạp.
Không bao giờ bắt đầu

Nếu tôi phải làm theo cách này, tôi chỉ cần sử dụng trình kết xuất 4 dòng ...
Raven Dreamer

Điều này không xử lý đúng chiều sâu tuy nhiên.
DuckMaestro

1

Một cách đơn giản là sử dụng Shader có hai Pass: Pass đầu tiên sử dụng shader đỉnh để tăng tỷ lệ cho đối tượng một chút và sử dụng pixel shader để tô màu cho nó thành màu phù hợp với màu bạn muốn phác thảo, và sau đó Pass thứ hai thực hiện kết xuất thông thường.


Bạn có thể đưa ra một ví dụ mã để giải thích rõ hơn ý của bạn?
Raven Dreamer

Điều này sẽ chỉ hoạt động cho các đối tượng lồi (như hình chữ nhật) có nguồn gốc ở trung tâm hình học của nó.
rootl Focus

1

Tôi gặp vấn đề tương tự khi tạo một phác thảo, ngoại trừ tôi cần tạo "nét vẽ" cho khối lập phương 3d và tìm ra một cách mới để làm điều đó mà tôi chưa thấy ở bất kỳ nơi nào khác trên mạng.

Trong hình dưới đây có hai hình với đường viền. Cái bên phải là một khối lập phương được xây dựng với LineRenderer, nó xây dựng các mặt phẳng luôn hướng về phía người dùng. Tôi thấy phương pháp này siêu rối, với những "nét" ngẫu nhiên xuất hiện bắt chước các hình tam giác tạo nên khuôn mặt.

Cái bên trái là sự đổi mới của tôi, với 12 khối hình riêng biệt, tạo ra một hình dáng giống như một bản phác thảo. Để thay đổi kích thước của đường nét đột phá trong phác thảo, tôi cần tăng / giảm kích thước của hai cạnh của mỗi khối trong số 12 khối. Điều này cũng sẽ làm việc cho phác thảo 2d. Chỉ cần áp dụng một vật liệu để thay đổi màu sắc và thì đấy!

hai đề cương khác nhau

Trong hình ảnh này, bạn có thể thấy một chi tiết về cấu trúc của khối này. Tất cả điều này có thể được tạo ra trong thời gian chạy nhưng tôi đã làm nó bằng tay và sử dụng nó như một prefab.

chi tiết


0

Tôi hiện đang đối mặt với cùng một vấn đề và giải pháp của tôi chính xác là những gì DuckMaestro và Raven Dreamer đã đề xuất - Có một kịch bản tạo ra 4 đối tượng con trong thời gian chạy, mỗi đối tượng đại diện cho một bên của đường viền và gắn trình kết xuất đường truyền cho mỗi đối tượng.

Trong trường hợp của tôi, tôi cần liên tục thay đổi kích thước đường viền để giữ nó xung quanh đối tượng của mình (Lưới văn bản [sử dụng trình kết xuất lưới] cho trường văn bản tùy chỉnh) vì vậy mọi cập nhật tôi đã làm điều này:


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() chỉ cần truy cập trình kết xuất dòng thích hợp (được chỉ định bởi tham số đầu tiên) và đặt bắt đầu và kết thúc của nó thành vectơ thứ nhất và thứ hai tương ứng.

Lưu ý rằng tôi đã sử dụng rendererlàm tham chiếu cho kích thước của mình, nhưng rõ ràng bạn có thể sử dụng bất kỳ hình chữ nhật nào, miễn là x, y là góc trên cùng bên trái.

Từ những gì tôi có thể nói điều này hoạt động rất tốt, trông rất tuyệt trong trò chơi vì tôi có thể dễ dàng di chuyển vật thể có viền xung quanh theo cả 3 trục (Ngay cả khi xoay nó, và vì các trình kết xuất dòng luôn đối diện với máy ảnh, nó trông không lạ), và không khó để thực hiện.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.