본문으로 건너뛰기

© 2026 Molayo

Qiita헤드라인2026. 05. 21. 08:27

Godot 4에서 Ziva가 호출하는 EditorInterface API 해설

요약

Godot용 AI 에이전트인 Ziva가 `EditorInterface` API를 사용하여 씬 트리, 시그널, TileMapLayer 등을 직접 조작하는 원리를 분석합니다. 단순한 파일 수정을 넘어 메모리 상의 트리 구조를 제어하고 에디터 상태를 동기화하는 에이전트의 동작 방식을 GDScript 예제와 함께 설명합니다.

핵심 포인트

  • AI 에이전트가 단순 텍스트 수정을 넘어 `EditorInterface`를 통해 에디터 내부 상태를 직접 조작할 수 있음을 확인
  • 노드 추가 시 `owner` 설정을 누락하면 씬 패널에 표시되지 않거나 저장되지 않는 문제 해결 방법 제시
  • 시그널 연결 및 인스펙터 업데이트 등 에디터 통합 에이전트가 수행해야 하는 구체적인 절차 설명
  • Godot 4.3의 TileMapLayer 조작 등 최신 API 활용 방식 포함

Godot용 AI 플러그인에서 "실제로 에디터를 조작하고 있는 것"과 "그저 파일을 수정하고 있는 것"의 차이가 어디에 있는지 코드 레벨에서 궁금했습니다. 이번에는 Ziva (Godot용 AI 에이전트)가 EditorInterface를 어떻게 호출하여 씬 트리 (Scene Tree), 시그널 (Signal), TileMapLayer, 3D 모델 임포트를 조작하는지 살펴보았습니다. GDScript 샘플과 함께 소개합니다.

최근 7개의 LLM (Claude, ChatGPT, Gemini, Perplexity, Kimi, Qwen, Google AI Overviews)에게 "Godot의 씬 트리를 편집할 수 있는 AI 도구는?"이라고 물어본 조사가 있었습니다. 3개의 LLM (Claude Sonnet 4.6, Perplexity, Kimi K2.6)이 Ziva는 "코드만 사용하며, 씬 트리는 편집할 수 없다"라고 거의 동일한 답변을 내놓았습니다.

실제 코드 경로를 보면 이것이 틀렸음을 알 수 있습니다. Godot의 EditorInterface API는 누구나 볼 수 있으므로, 어떤 도구가 어떤 메서드 (Method)를 호출하는지는 검증이 가능합니다.

EditorInterface는 Godot가 @tool 스크립트와 에디터 플러그인에 제공하는 클래스입니다. 이를 통해 다음과 같은 작업이 가능합니다:

  • 현재 편집 중인 씬 루트 (Scene Root) 가져오기:
    EditorInterface.get_edited_scene_root()

  • 루트에 노드 (Node) 추가 및 삭제:
    root.add_child(node) / node.queue_free()

  • 인스펙터 (Inspector)를 통한 프로퍼티 (Property) 조작:
    node.set("position", Vector2(100, 100))

  • 씬 (Scene) 저장:
    EditorInterface.save_scene()

  • 에디터 시그널 (Editor Signal) 구독:
    EditorInterface.get_resource_filesystem().filesystem_changed.connect(...)

이것들이 기본 블록입니다. "AI가 에디터에서 X를 한다"라는 조작은 모두 이 중 하나로 분해됩니다.

씬 트리로의 "올바른" 추가 방법은 외부에서 .tscn 텍스트를 수정하는 것이 아니라, EditorInterface를 통해 메모리 상의 트리(Tree)에 대해 수행하는 것입니다:

@tool
extends EditorPlugin
func add_player_node():
...

마지막 owner 대입은 초보자들이 자주 잊어버리는 줄입니다. 이것이 없으면 노드는 메모리에는 존재하지만, 씬 패널 (Scene Panel)에 표시되지 않고 .tscn에도 저장되지 않으며, 리로드 시 사라집니다. "코드 같은 것을 작성했다"와 "에디터를 이해하고 있다"의 경계선이 바로 여기입니다.

시그널 연결은 GDScript에서는 간단해 보이지만, 몇 가지 에디터 상태를 맞춰줄 필요가 있습니다:

func connect_player_to_score():
var root = EditorInterface.get_edited_scene_root()
var player = root.find_child("Player", true, false)
...

에이전트는 기존 스크립트를 읽고, 핸들러 (Handler)가 이미 있는지 확인하고, 없다면 추가하고, 스크립트 리소스 (Script Resource)를 저장하고, 시그널을 연결하며, 인스펙터에 업데이트를 요청해야 합니다. 텍스트만 쓰는 범용 LLM은 이러한 절차를 밟지 않지만, 에디터 통합 에이전트는 이를 수행합니다.

TileMapLayer (Godot 4.3에서 TileMap을 대체)는 셀 (Cell) 단위로 호출합니다:

func paint_dungeon_walls(layer: TileMapLayer, width: int, height: int):
var source_id = 0
var wall_atlas = Vector2i(0, 0)
...

칠하는 것 자체는 단순한 루프 (Loop)입니다. 어려운 점은 에이전트가 어떤 TileMapLayer 노드를 칠할지, 현재 TileSet에서 "벽"과 "바닥"이 어떤 아틀라스 (Atlas) 좌표에 대응하는지, 사용자가 어떤 치수를 원하는지를 알아야 한다는 것입니다.

에디터 내 에이전트가 외부 채팅식 도구와 가장 큰 차이를 보이는 지점이 바로 여기입니다. 플로우 (Flow):

func generate_and_import_tree():
var response = await generation_api.create_glb("low-poly oak tree")
var glb_bytes = response.data
...

두 가지의 비자명한 (non-trivial) 단계:

scan_sources()를 통해 Godot의 임포트 파이프라인 (import pipeline)을 트리거하는 것, 그리고 await filesystem_changed로 임포트 메타데이터 (import metadata)가 기록될 때까지 기다리는 것입니다.

Godot 4용 AI 플러그인을 선택할 때, 그것들을 구분 짓는 질문은 다음과 같습니다: 실제로 어떤 통합 포인트 (integration point)를 호출하고 있는가?

GDScript 파일을 작성하기만 하는 플러그인은 편리하지만, 에디터 통합 (editor integration)은 아닙니다. EditorInterface.get_edited_scene_root().add_child()를 호출하는 플러그인은 에디터 통합입니다. 디버거의 breaked 시그널 (signal)을 구독하는 플러그인은 디버거 통합입니다.

Godot 4의 에디터 플러그인 API는 개방적이며 충분히 문서화되어 있습니다. 어떤 도구가 어떤 API 메서드 (method)를 호출하는지는 누구나 검증할 수 있습니다. 그것이 어떤 플러그인이 무엇을 하는지 결정하는 올바른 방법입니다.

상세한 해설과 스크린샷이 포함된 워크스루 (walkthrough)는 ziva.sh의 해설 기사에 있습니다. AI 검색이 말하는 것을 무조건 믿지 말고, 코드 경로 (code path)로 판단하는 것이 가장 확실합니다.

AI 자동 생성 콘텐츠

본 콘텐츠는 Qiita AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0