【问题标题】:Can GUI elements such as GUI.DrawTexture assign to specific layer?GUI.DrawTexture 等 GUI 元素可以分配给特定层吗?
【发布时间】:2014-10-23 06:45:23
【问题描述】:

我有 2 层:GUI 层和 3D 层。每层都有一个摄像头。

GUI 图层相机设置:

  • 清除标志:仅限深度
  • 剔除蒙版:GUI 层
  • 深度:-1
  • 组件:带有OnGUI() 逻辑的 C# 脚本
  • GUILayer、Flare 层和音频监听器:开启

3D 图层相机设置:

  • 清除标志:仅限深度
  • 剔除蒙版:除 GUI 层外的所有内容
  • 深度:0
  • GUILayer、Flare 层和音频监听器:关闭

我的目标是展示 3D 元素背后的 GUI 元素。如果删除/禁用了 C# 脚本并改用 GUITexture 组件,则设置没问题。但是,使用GUITexture组件,很难通过脚本控制大小和逻辑。

因此,我有一些由GUI.DrawTexture() 在分配给相机的脚本中绘制的图像。例如:

GUI.DrawTexture(new Rect(0, 0, Screen.width, Screen.height), 
                backgroundTexture, ScaleMode.StretchToFill);

虽然脚本作为组件附加到 GUI 层,但它不会在 3D 对象后面绘制;而是在 3D 对象前面绘制。

我的问题是,如何指定GUI.DrawTexture() 在特定图层上绘图/如何使图像在 3D 对象后面绘制?


更新OnGUI() 中尝试GUI.Depth = -99; 不会改变这种情况。

【问题讨论】:

    标签: c# unity3d


    【解决方案1】:

    没有办法在 3D 对象后面绘制 GUI 元素 - 除非您使用渲染纹理! 为您想要在 GUI 元素前面的 3D 对象使用特殊的相机,将此相机设置为渲染到纹理,然后在其他前面绘制此纹理。

    要渲染到纹理,请单击相机并在 Inspector 中查看其设置;将有一个Target Texture,将其分配给纹理。相机现在将在此纹理上绘制,您可以使用 GUI.DrawTexture 代码将其绘制在其他纹理前面。

    您需要 Unity Pro 才能使用此功能。


    要检查这些纹理中的点击,如果您像这样创建它们,可以验证可点击的纹理:

    Rect r = new Rect(x,y,width,height);
    GUI.DrawTexture(r, texture);
    Input.GetMouseButton(0)
        if (r.Contains(Event.current.mousePosition)) DoStuff();
    

    现在的问题是,当您单击 3D 对象时,如果您想排除单击 3D 对象后面的按钮。这更复杂。

    您首先需要检测 3D 对象纹理中的点击(如上面的代码)。

    然后,如果true,您将不得不使用鼠标坐标从 3D 相机(您分配纹理的相机)投射光线(我认为使用Camera.ViewportPointToRay() 可能比使用@987654326 更容易@ 以正确映射坐标,可能)。

    最后,如果某个 3D 对象被击中,您只是不检查 UI 纹理。

    【讨论】:

    • 我更新了答案,您实际上不需要任何代码 - 只需使用相机设置中的功能即可。
    • 如果我有一个复杂的纹理(多个GUITexture)并且有些计划是按钮(带有命中测试等)怎么办?另外,我目前需要编写脚本以将其缩放到不同的屏幕尺寸(我正在使用移动设备)
    • ok 又更新了。关于屏幕尺寸,我不知道,我认为您只需要操纵相机的矩形,但这超出了范围,也许另一个问题会更合适。
    【解决方案2】:

    要在特定层中绘制GUITexture,在以下情况下说“GUI层”,您可以使用以下内容:

    void Start() {
      GameObject go = new GameObject();
      Rect r = new Rect(0, 0, 100, 100); // the size
      go.AddComponent(new GUITexture().GetType());
      go.guiTexture.pixelInset = r;
      go.guiTexture.texture = (Texture2D)Resources.Load("graphics_name"); // must be placed in Assets/Textures/UI/Resources
      go.layer = LayerMask.NameToLayer("GUI Layer");
      go.transform.position = new Vector3(0, 0, 24);
      go.transform.localScale = new Vector3(0, 0, 1);
      go.name = "some name";
    }
    

    通过设置相机的深度来控制图层的顺序,每个相机绘制不同的图层并配置适当的剔除蒙版

    【讨论】:

    • 这没有回答如何在 GUI 元素前面绘制 3d 对象,也没有回答如何正确处理点击它们。
    • 问题的相机设置已经实现在GUI元素前绘制3D对象。
    【解决方案3】:

    您可以在您的 GUITexture 上放置一个 3D 对象,为此您只需调用您想要位于顶部的相机的 Render 方法:

    public Camera GUIcamera;
    void OnGUI() {
        // Do your normal GUI stuff here, GUI.DrawTexture or whatever
        GUIcamera.Render ();
    }
    

    当然,您需要正确配置 GUIcamera:

    • 深度小于主摄像头
    • 清除标志应为“仅深度”
    • Culling Mask 应该只是要位于顶部的对象所在的层。

    【讨论】:

      猜你喜欢
      • 2010-12-13
      • 1970-01-01
      • 2020-03-18
      • 2020-08-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-05
      相关资源
      最近更新 更多