如何在Unity3d中绘制轮廓?


13

我正在尝试突出显示任意高度的矩形。我认为最简单的方法是创建一个单独的“盒子”游戏对象来勾勒出矩形。

我同时尝试了MeshRenderer +透明纹理和LineRenderer来勾勒出矩形的四个点。两者都不是很令人满意。

在此处输入图片说明

(线渲染器在中间,缩放的立方体在右侧)

解决这个问题的正确方法是什么?我正在尝试获得类似于左侧矩形的东西-通过选择的四个点来固定宽度的简单周长。

Answers:


8

使用GUI.Box()

如果只需要2D矩形,则GUI是必经之路。使用一个简单的矩形作为纹理(当然,矩形的内部应该是透明的)创建一个新的GUIStyle,设置其Border值以使其不被拉伸,然后调用GUI.Box(new Rect(...),"",myGuiStyle);

Camera.WorldToScreenPoint如果要在世界坐标系(即3D)中绘制轮廓,则可以使用method,只要记住在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之上渲染单独的相机,但这有点笨拙。
没关系

这个答案满足了我的需求,但我现在暂时不公开它,希望在一般情况下有更好的方法可以做到这一点。
Raven Dreamer

我接受了您的编辑添加代码示例,并修复了其中的GUI-y-up-down-bug。
没关系

1

下面是一种非着色方法。

将您的2d框想像成只有四条线,其中每条线仅在一个维度上拉伸(其他两个维度是边的横截面)。这就像您要在现实生活中构造一个盒子时一样,将不同长度的具有相同横截面尺寸的木材拼合在一起。

考虑到这一点,您可以设计一个Component,例如BoxBuilder,将其附加到GameObject时,可以创建和管理四个子GameObject。每个子游戏对象都是盒子边缘之一,并且可以只是一个仅在一个维度上拉伸的3d立方体。使用widthheight定义的BoxBuilder级别,您可以计算四个子边缘的必要定位和不均匀比例。这将是一个很大的pos.x=w/2pos.y=h/2,... scale.x=hscale.y=w等的代码排序。

尽管我相信您只要求2-d,但是请注意,如果需要,可以将相同的想法应用于3d框,BoxBuilder现在3d框必须创建和管理12个子边,但同样只能在一个局部维度上缩放每个边。


可行,但方法太复杂。
没关系

如果我必须这样做,我将只使用4个线渲染器...
Raven Dreamer

但这确实可以处理深度。
DuckMaestro

1

一种简单的方法是使用具有两个遍的着色器:第一个遍使用顶点着色器稍微扩展对象,并使用像素着色器将其着色为与您希望轮廓具有的颜色匹配的纯色,以及然后第二遍通过常规渲染。


您可以举一个代码示例来更好地解释您的意思吗?
Raven Dreamer

这仅适用于原点位于其几何中心的凸对象(如矩形)。
rootlocus

1

除了创建3D立方体的“笔画”,我发现创建轮廓时遇到了同样的问题,并且找到了一种在网上看不到的新方法。

在下图中,有两个带有轮廓的形状。右边的一个是使用LineRenderer构造的多维数据集,该多维数据集生成始终面向用户的平面。我发现此方法超级故障,出现了随机的“笔触”,模仿了构成面部的三角形。

左边的是我的“创新”,其中包含12个单独的瘦立方体,它们构成了轮廓。要更改轮廓中“笔画”的大小,我需要增加/减小12个瘦立方体中每个立方体的两侧的大小。这也适用于二维轮廓。只需应用一种材料即可更改颜色和瞧!

两种不同的轮廓

在此图像中,您可以看到此多维数据集的详细结构。所有这些都可以在运行时创建,但是我手工制作并将其用作预制件。

详情


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个轴移动边框对象(即使旋转它,并且因为线渲染器始终面对镜头,所以看起来也不奇怪),并且不难实施。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.