Unity/개발연습

[Unity] Behaviour Tree Editor 제작기 - 3

민트초밥 2024. 8. 30. 11:48

노드들이 이런 형태가 되길 원했고, 구현을 성공 하긴 했지만 다른 문제가 발생하여 결국 포기했다.

 

 

 

 

 

문제의 원인

 

노드는 Experimental.GraphView.Node를 상속받도록 만들었다.

노드안에 내용들은 container들이 감싸고 있고 아래와 같은 구조로 되어있다.

 

 

 

 

container 구성을 변경할 순 없어서 (아예 없는 건 아니지만... 방법은 아래에)

mainContainer.Clear() 함수를 이용해서 기존의 mainContainer를 삭제하고 새로운 container를 만들어서 원하는 레이아웃으로 구성되게 만들었다.

 

그 결과 처음 이미지처럼 input과 output 사이에 tilte이 오도록 만들 수 있었다.

 

여기까진 큰 문제가 없어보였는데 문제는 에셋에 변경사항이 생기거나 유니티를 재시작할 때 발생했다.

 

 

 

 

 

원인을 검색해보니까 mainContainer를 Clear 하고 새로운 container를 추가하는 과정이 에디터상에서 제대로 출력이 안 되는 현상이 발생할 수도 있다고 한다. (feat. ChatGPT)

 

그래서 깔끔하게 포기....

 

 

 

 

"다른 방법"

 

근본적인 구성을 변경해서 문제를 해결할 수 있긴하다.

 

Node 클래스를 보면 Node.uss와 Node.uxml을 사용하는데 이 중 Node.uxml이 Node내의 UI 구성을 담당하고 있어서 이 파일을 사용하지 않고 새로운 uxml 파일을 만들어서 대체하면 된다.

 

 

 

이런 식으로??

public BehaviourNodeView(BehaviourNode inNode) : base ("newUxmlPath.uxml")

 

 

 

 

하지만 uxml이나 uss파일을 만들고 수정하는 건 UIToolkit을 이용해야 하는데 이것까지 익히기엔 시간이...

그리고 아래 영상을 봤는데 기존 UGUI를 사용하지 않고 UIToolkit을 사용해야 하는 이유를 찾지 못하기도 했다.

 

 

 


 

 

최종적으로 기본 레이아웃을 따르지만, Node의 기능에 맞게 input, output port를 다르게 설정했다.

 

 

public class BehaviourNodeView : UnityEditor.Experimental.GraphView.Node
{
    public Port inputPort;
    public Port outputPort;
    public BehaviourNode behaviourNode;

    public string guid;

    public BehaviourNode Node { get; private set; }


    public BehaviourNodeView(BehaviourNode inNode)
    {
        Node = inNode;

        style.width = 200;
        StyleColor inputColor = new Color(0.2f, 0.2f, 0.2f, 1f);

        // 체크박스 삭제
        var collapseButton = titleContainer.Q("collapse-button");
        if (collapseButton != null)
        {
            collapseButton.RemoveFromHierarchy();
        }

        if (Node is RootNode)
        {
            outputPort = AddOutputPort(Port.Capacity.Single);
        }
        else if (Node is CompositeNode)
        {
            inputColor = new Color(129f / 255f, 44f / 255f, 27f / 255f, 1f);

            inputPort = AddInputPort(Port.Capacity.Single);
            outputPort = AddOutputPort(Port.Capacity.Multi);
        }
        else if (Node is DecoratorNode)
        {
            inputColor = new Color(0f / 255f, 132f / 255f, 43f / 255f, 1f);

            inputPort = AddInputPort(Port.Capacity.Single);
            outputPort = AddOutputPort(Port.Capacity.Multi);
        }
        else if (Node is ActionNode)
        {
            inputColor = new Color(23f / 255f, 64f / 255f, 165f / 255f, 1f);

            inputPort = AddInputPort(Port.Capacity.Single);
        }
        else
        {
            Debug.LogError($"{nameof(BehaviourNodeView)} : Node Error {typeof(Node)}");
        }

        title = Node.GetType().Name;

        titleContainer.style.backgroundColor = inputColor;
        titleContainer.style.justifyContent = Justify.Center;

        var titleLabel = titleContainer.Q<Label>("title-label");
        if (titleLabel != null)
            titleLabel.style.color = Color.white;

        inputContainer.Add(inputPort);
        outputContainer.Add(outputPort);

        RefreshExpandedState();
        RefreshPorts();
    }


    private Port AddInputPort(Port.Capacity portCapacity)
    {
        Port inputPort = InstantiatePort(Orientation.Horizontal, Direction.Input, portCapacity, typeof(float));
        inputPort.portName = "Input";

        return inputPort;
    }


    private Port AddOutputPort(Port.Capacity portCapacity)
    {
        Port outputPort = InstantiatePort(Orientation.Horizontal, Direction.Output, portCapacity, typeof(float));
        outputPort.portName = "Output";

        return outputPort;
    }
}

 

 

 

 

GitHub - mintchobab/Unity_Practice_Editor

Contribute to mintchobab/Unity_Practice_Editor development by creating an account on GitHub.

github.com

 

반응형