为什么在将Handles.ArrowHandleCap添加到一行时没有绘制ArrowHandleCap?

时间:2019-06-29 00:25:23

标签: c# unity3d

我正在使用编辑器窗口,也许是问题所在吗?

这个想法是,当连接两个节点时,也要在结束位置制作一个箭头,以显示连接流向。

在屏幕快照中,当我连接两个节点(例如,Window 0至Window 1)时 因此,在窗口1附近的行的末尾应该有一个箭头,指示窗口0已连接到窗口1,因此流是从窗口0到窗口1的。

但是它没有绘制任何ArrowHandleCap。

我不介意在终点位置绘制另一个简单的白色箭头,但目前根本不起作用。根本不画箭头。

Nodes

这是我的编辑器窗口代码:

using UnityEngine;
using UnityEditor;
using System.Collections.Generic;
using UnityEditor.Graphs;
using UnityEngine.UI;

public class NodeEditor : EditorWindow
{
    List<Rect> windows = new List<Rect>();
    List<int> windowsToAttach = new List<int>();
    List<int> attachedWindows = new List<int>();

    int tab = 0;
    float size = 10f;

    [MenuItem("Window/Node editor")]
    static void ShowEditor()
    {
        const int width = 600;
        const int height = 600;

        var x = (Screen.currentResolution.width - width) / 2;
        var y = (Screen.currentResolution.height - height) / 2;

        GetWindow<NodeEditor>().position = new Rect(x, y, width, height);
    }


    void OnGUI()
    {
        Rect graphPosition = new Rect(0f, 0f, position.width, position.height);
        GraphBackground.DrawGraphBackground(graphPosition, graphPosition);

        int selected = 0;
        string[] options = new string[]
        {
     "Option1", "Option2", "Option3",
        };
        selected = EditorGUILayout.Popup("Label", selected, options);

        if (windowsToAttach.Count == 2)
        {
            attachedWindows.Add(windowsToAttach[0]);
            attachedWindows.Add(windowsToAttach[1]);
            windowsToAttach = new List<int>();
        }

        if (attachedWindows.Count >= 2)
        {
            for (int i = 0; i < attachedWindows.Count; i += 2)
            {
                DrawNodeCurve(windows[attachedWindows[i]], windows[attachedWindows[i + 1]]);
            }
        }

        BeginWindows();

        if (GUILayout.Button("Create Node"))
        {
            windows.Add(new Rect(10, 10, 200, 40));
        }

        for (int i = 0; i < windows.Count; i++)
        {
            windows[i] = GUI.Window(i, windows[i], DrawNodeWindow, "Window " + i);
        }

        EndWindows();
    }


    void DrawNodeWindow(int id)
    {
        if (GUILayout.Button("Attach"))
        {
            windowsToAttach.Add(id);
        }

        GUI.DragWindow();
    }


    void DrawNodeCurve(Rect start, Rect end)
    {
        Vector3 startPos = new Vector3(start.x + start.width, start.y + start.height / 2, 0);
        Vector3 endPos = new Vector3(end.x, end.y + end.height / 2, 0);
        Vector3 startTan = startPos + Vector3.right * 50;
        Vector3 endTan = endPos + Vector3.left * 50;
        Color shadowCol = new Color(255, 255, 255);

        for (int i = 0; i < 3; i++)
        {// Draw a shadow
            //Handles.DrawBezier(startPos, endPos, startTan, endTan, shadowCol, null, (i + 1) * 5);
        }

        Handles.DrawBezier(startPos, endPos, startTan, endTan, Color.white, null, 5);
        Handles.color = Handles.xAxisColor;
        Handles.ArrowHandleCap(0, endPos, Quaternion.LookRotation(Vector3.right), size, EventType.Repaint);
    }
}

1 个答案:

答案 0 :(得分:0)

问题在于箭头始终位于后面后面,例如Window 0,因为您总是在DrawNodeWindow之后致电DrawNodeCurve

之所以会这样,是因为箭头总是从endPos开始向右绘制,长度为{size,所以您以后总是将其覆盖在窗口上……您必须更改

// move your endpos to the left by size 
var endPos = new Vector3(end.x - size, end.y + end.height / 2 , 0);

为了使它在实际size位置之前还剩end.x个像素。

enter image description here

enter image description here

但是,正如您所看到的,它仍然很小,因为它通常用于在3D空间中显示箭头-不使用像素坐标..您可能需要调整圆角或使用完全不同的东西。


例如只是使用GUI.DrawTexture而不是给定的Arrow sprite?

// assign this as default reference via the Inspector for that script
[SerializeField] private Texture2D aTexture;

// ...

// since the drawTexture needs a rect which is not centered on the height anymore
// you have to use endPos.y - size / 2 for the Y start position of the texture
GUI.DrawTexture(new Rect(endPos.x, endPos.y - size / 2, size, size), aTexture, ScaleMode.StretchToFill);

就像在注释中提到的Unity中所有序列化字段一样,您已经可以为脚本本身引用默认资产(与对MonoBehaviours这样的每个实例相反),因此选择了NodeEditor脚本后,只需引用一个下载的箭头纹理

enter image description here

如果使用白色箭头作为纹理,则仍可以使用

更改其颜色
var color = GUI.color;
GUI.color = Handles.xAxisColor;
GUI.DrawTexture(new Rect(endPos.x, endPos.y - size / 2, size, size), aTexture, ScaleMode.StretchToFill);
GUI.color = color;

结果

enter image description here


P.S .:用于示例的箭头图标:https://iconsplace.com/red-icons/arrow-icon-14,您可以在下载图标之前直接在该页面上更改颜色;)