2017-05-13 11 views
0

Unity에서 사용자 정의 노드 편집기 창을 구성 중이며 과 같은 다양한 리소스를 살펴 보았습니다. GUI.Box을 사용하여 노드 창을 구성합니다.GUI 컨트롤이있는 Unity3D 드래그 가능한 GUI.Box

이 방법은 훌륭합니다. 원하는대로이 창을 드래그 할 수는 있지만, 일단 GUI.Box에 컨트롤을 추가하면, 내가 작성한 Drag() 함수를 덮어 쓰게하고 싶습니다.

다음은 문제의 예입니다. 수직 슬라이더를 위로 움직이면 상자 전체가 끌어옵니다.

Vertical Slider issues

GUI.Box를 사용하여이 문제를 해결할 수있는 방법이 있나요, 아니면 함께 GUI.Window으로 돌아 가야 내장 된 GUI.DragWindow()?

EditorMouseInput.cs :

private bool ActionLeftMouseDown() 
{ 
    mouseDownNode = editor.GetSelectedNode(Input.current.mousePosition); 

    if (mouseDownNode == null) 
     editor.StartMovingEditorCanvas(); 
    else 
     mouseDownNode.IsSelected = true; 
} 

BaseNodeEditor.cs :

public BaseNode GetSelectedNode(Vector2 mousePos) 
{ 
    foreach (BaseNode node in Nodes) 
    { 
     if (node.WindowRect.Contains(mousePos)) 
      return node; 
    } 
    return null; 
} 

public void Drag(Vector2 delta) 
{ 
    if (!MoveEditorMode && !ConnectionMode) 
    { 
     foreach (BaseNode node in Nodes) 
     { 
      node.Drag(delta); 
     } 
    } 

BaseNode.cs 여기

내가 사용하고 코드의 단순화 된 버전입니다 :

수직 슬라이더는 파생 된 점프 노드 클래스에 추가됩니다. 슬라이더를 구성 헬퍼 클래스의 추출 :

Vector2 pos = node.WindowRect.position + rect.position * GridSpacing; 
value = GUI.VerticalSlider(new Rect(pos, rect.size * GridSpacing), value, maxValue, minValue); 

이 내가 원하는 것을하지 않는 이유를 내가 볼 수 있지만, 나는 그것이 GUI 컨트롤을 제공 가야의 일부가 아닌 방법을 모른다 GUI.Box.

어떤 도움이나 제안, 심지어 다른 출처에 대한 찔림조차도 크게 감사 할 것입니다 - 나는 내 머리 속에 존재하는 모든 검색어를 사용했다고 생각합니다!

편집 - 해결 : 나를 위해이 문제를 해결해 주신 Kleber에게 감사드립니다. 다른 사람이이 문제와 비슷한 문제를 겪는 경우, GUI 컨트롤이 왼쪽 마우스 클릭 이벤트를 자동으로 사용한다는 것을 깨달았습니다. 슬라이더를 클릭하면 상자에 클릭이 전달되었는지 확인할 수 없습니다.

내가해야 할 일은 Node 클래스에서 IsSelected 및 IsDragged 플래그를 분리하고 mouseUp에서 IsDragged를 지우는 것입니다. 원래는 IsSelected를 사용하여 드래그를 활성화하고 선택한 플래그를 표시했습니다 (여러 노드를 선택하고 한 번에 드래그 할 수 있음).

답변

1

아주 복잡한 튜토리얼이므로 완전히 읽지는 않았지만 문제는 MouseDrag 감지로 보입니다. 글쎄, 기본적으로 Box 내부의 GUI 요소를 클릭 할 때 이벤트 전파를 중지하고 싶습니다. 이렇게하려면 사용자가 구성 요소 중 하나에서 마우스를 끌 때마다

번으로 전화를 겁니다.당신이 언급 한 자원을 사용하여

, 나는 Node 클래스를 변경하고 같이 끝나는 Draw() 방법 내부 슬라이더를 추가 :

public void Draw() { 
    inPoint.Draw(); 
    outPoint.Draw(); 
    GUI.Box(rect, title, style); 
    GUI.BeginGroup(rect); 
    _value = GUI.HorizontalSlider(new Rect(20, 0, 50, 20), _value, 100, -100); 
    GUI.EndGroup(); 
} 

First example

은 당신이 할 수있는 또 한가지 방법을 변경하다 너는 창문을 그려. 여기 내가 최신 유니티 버전 (5.6)에서 테스트 한 것을 간단한 예제 :

private void OnGUI() { 
    GUI.Box(_rect, string.Empty); 
    GUI.BeginGroup(_rect); 

    _value = GUI.VerticalSlider(new Rect(145, 100, 20, 100), _value, 100, -100); 
    GUI.EndGroup(); 

    var e = Event.current; 
    if (e.type == EventType.MouseDrag && _rect.Contains(e.mousePosition)) { 
     _rect.x += e.delta.x; 
     _rect.y += e.delta.y; 
     Repaint(); 
    } 
} 

당신이 볼 수 있듯이,이 예제가 제대로 작동하기 위해 Event.current.Use() 필요하지 않습니다.

Second example

+0

응답 해 주셔서 감사합니다. 내 문제는 슬라이더 컨트롤 (또는 모든 컨트롤)이 상자에 존재하지 않는다는 점에서 Event.current.Use()가 확실히 작동하지만, 맨 위에 그려져 있습니다. 또한 GUI 컨트롤을 내장하고있어 클릭, 선택, 끌기 등의 이벤트를 볼 수 없습니다. – Aspekt

+1

'Event.current'는'OnGUI()'에서만 액세스 할 수 있으므로 IMGUI 시스템에서만 사용할 수 있습니다. 보낸 리소스에는'ProcessEvents()'메소드의 매개 변수로 보내진'Event.current'의 사용이 있습니다. 내가 할 수있는 다른 솔루션을 추가하여 내 대답을 편집했습니다. – Kleber

+1

첫째로 나는이 것에 당신의 시간을 걸리기를위한 거대한 감사를주고 싶다. 나는 문제를 알아 냈습니다. 생각에 약간의 변화가 있었고 당신은 분명히 저에게 다가 갈 수있었습니다. mouseup에서 선택을 지우지 않은 단일 MouseEventHandler 스크립트 (여러 상자 선택 가능)가있었습니다. 컨트롤이 자동으로 이벤트를 사용한다는 것을 알지 못해 잘못된 위치를 찾고있었습니다. 상자를 드래그하면 슬라이더를 끌 때 선택한 채로 남아있었습니다. – Aspekt