Attention: Here be dragons

This is the latest (unstable) version of this documentation, which may document features not available in or compatible with released stable versions of Godot.

다음 예제에서:

더 보기

자세한 설명은 프로젝트 내보내기 를 참고하세요.

때때로 :ref:`팩, 패치 및 모드 내보내기 <doc_exporting_pcks>`는 플레이어가 프로젝트에서 사용자 생성 콘텐츠를 로드할 수 있도록 하려는 경우 이상적이지 않습니다. 사용자는 Godot에서 가져온 리소스가 포함된 Godot 편집기를 통해 PCK 또는 ZIP 파일을 생성해야 합니다.

런타임 파일 로드 및 저장에 대한 사용 사례의 예는 다음과 같습니다.

  • 코드에서 리소스 불러오기

  • 사용자가 제공한 오디오 트랙을 로드하고 게임 내 라디오 방송국에서 재생합니다.

  • glTF 또는 FBX로 내보낼 수 있는 3D DCC로 디자인할 수 있는 사용자 정의 레벨 또는 3D 모델 로드(런타임에 Godot에 의해 저장된 glTF 장면 포함).

  • 메뉴 및 HUD에 사용자가 제공한 글꼴을 사용합니다.

  • 여러 파일을 포함할 수 있지만 다른 응용 프로그램에서 쉽게 읽을 수 있는 파일 형식(ZIP)을 저장/로드합니다.

  • 다른 게임이나 프로그램에서 만든 파일을 로드하거나 Godot로 만들지 않은 다른 게임의 게임 데이터 파일도 로드합니다.

런타임 파일 로딩을 :ref:`HTTP 요청 <doc_http_request_class>`과 결합하여 인터넷에서 직접 리소스를 로드할 수 있습니다.

경고

프로젝트의 일부인 리소스를 로드하기 위해 이 런타임 로딩 접근 방식을 사용하지 마십시오. 이는 효율성이 낮고 Godot의 리소스 처리 기능(예: 번역 다시 매핑)의 이점을 허용하지 않기 때문입니다. 자세한 내용은 :ref:`doc_import_process`를 참조하세요.

더 보기

이 문서 외에 여러가지 Godot 데모 프로젝트들도 살펴보면 좋습니다.

일반 텍스트 및 바이너리 파일

Godot의 FileAccess 클래스는 읽고 쓰기 위해 파일 시스템의 파일에 액세스하는 방법을 제공합니다:

func save_file(content):
    var file = FileAccess.open("/path/to/file.txt", FileAccess.WRITE)
    file.store_string(content)

func load_file():
    var file = FileAccess.open("/path/to/file.txt", FileAccess.READ)
    var content = file.get_as_text()
    return content

사용자 정의 바이너리 형식(예: Godot에서 지원하지 않는 파일 형식 로드)을 처리하기 위해 class_FileAccess`는 정수, 부동 소수점, 문자열 등을 읽고 쓰는 여러 가지 방법을 제공합니다. 이러한 FileAccess 메서드의 이름은 ``get_```store_``로 시작됩니다.

바이너리 파일 읽기에 대해 더 많은 제어가 필요하거나 파일의 일부가 아닌 바이너리 스트림을 읽어야 하는 경우 class_PackedByteArray`는 일련의 바이트를 정수, 부동 소수점, 문자열 등으로 디코딩/인코딩하는 여러 가지 도우미 메서드를 제공합니다. 이러한 PackedByteArray 메서드의 이름은 ``decode_```encode_``로 시작됩니다. :ref:`doc_binary_serialization_api`도 참조하세요.

메인 이미지(mainImage)

이미지의 Image.load_from_file 정적 메서드는 파일 확장자를 기반으로 한 형식 감지부터 디스크에서 파일 읽기까지 모든 것을 처리합니다.

오류 처리나 추가 제어(예: SVG가 로드되는 배율 변경)가 필요한 경우 파일 형식에 따라 다음 방법 중 하나를 사용하세요.

다음 방법을 사용하여 런타임에 Godot에 의해 여러 이미지 형식을 저장할 수도 있습니다:

to_buffer 접미사가 있는 메서드는 이미지를 파일 시스템 대신 PackedByteArray에 저장합니다. 이는 이미지를 파일 시스템에 쓰지 않고도 네트워크를 통해 또는 ZIP 아카이브로 보내는 데 유용합니다. 이렇게 하면 I/O 사용률을 줄여 성능을 높일 수 있습니다.

참고

로드된 이미지를 3D 표면에 표시하는 경우 멀리서 볼 때 텍스처가 거칠어 보이지 않도록 :ref:`Image.generate_mipmaps <class_Image_method_generate_mipmaps>`을 호출해야 합니다. 이는 :ref:`다운샘플링 시 앨리어싱 감소 <doc_multiple_solutions_reducing_aliasing_on_downsampling>`에 대한 지침을 따를 때 2D에서도 유용합니다.

이미지를 로드하고 TextureRect 노드에 표시하는 예(:ref:`class_ImageTexture`로 변환 필요):

# Load an image of any format supported by Godot from the filesystem.
var image = Image.load_from_file(path)
# Optionally, generate mipmaps if displaying the texture on a 3D surface
# so that the texture doesn't look grainy when viewed at a distance.
#image.generate_mipmaps()
$TextureRect.texture = ImageTexture.create_from_image(image)

# Save the loaded Image to a PNG image.
image.save_png("/path/to/file.png")

# Save the converted ImageTexture to a PNG image.
$TextureRect.texture.get_image().save_png("/path/to/file.png")

효과 추가하기

Godot는 런타임에 Ogg Vorbis, MP3, WAV 오디오 로딩을 지원합니다. .ogg 확장자를 가진 모든 파일이 Ogg Vorbis 파일은 아닙니다. 일부는 Ogg Theora 비디오이거나 Ogg 컨테이너 내에 Opus 오디오를 포함할 수 있습니다. 이 파일은 Godot에서 오디오 파일로 올바르게 로드되지 않습니다.

AudioStreamPlayer 노드에 Ogg Vorbis 오디오 파일을 로드하는 예:

$AudioStreamPlayer.stream = AudioStreamOggVorbis.load_from_file(path)

VideoStreamPlayer 노드에 Ogg Theora 비디오 파일을 로드하는 예:

var video_stream_theora = VideoStreamTheora.new()
# File extension is ignored, so it is possible to load Ogg Theora videos
# that have a `.ogg` extension this way.
video_stream_theora.file = "/path/to/file.ogv"
$VideoStreamPlayer.stream = video_stream_theora

# VideoStreamPlayer's Autoplay property won't work if the stream is empty
# before this property is set, so call `play()` after setting `stream`.
$VideoStreamPlayer.play()

Godot는 편집기와 내보낸 프로젝트 모두에서 glTF 2.0에 대한 최고 수준의 지원을 제공합니다. class_gltfdocument`와 :ref:`class_gltfstate`를 함께 사용하면 Godot는 내보낸 프로젝트에 glTF 파일을 텍스트(`.gltf``) 및 바이너리(.glb) 형식으로 로드하고 저장할 수 있습니다. 바이너리 형식은 작성 속도가 더 빠르고 크기도 작으므로 선호되지만 텍스트 형식은 디버깅이 더 쉽습니다.

Godot 4.3부터, FBXDocumentFBXState 클래스를 사용하여 런타임에 FBX 장면을 로드할 수도 있습니다(저장할 수는 없음). 이를 수행하는 코드는 glTF와 동일하지만 아래 코드 샘플에서 GLTFDocumentGLTFState``의 모든 인스턴스를 ``FBXDocument``FBXState``로 바꿔야 합니다.

glTF 씬을 로드하고 해당 루트 노드를 씬에 추가하는 예:

# Load an existing glTF scene.
# GLTFState is used by GLTFDocument to store the loaded scene's state.
# GLTFDocument is the class that handles actually loading glTF data into a Godot node tree,
# which means it supports glTF features such as lights and cameras.
var gltf_document_load = GLTFDocument.new()
var gltf_state_load = GLTFState.new()
var error = gltf_document_load.append_from_file("/path/to/file.gltf", gltf_state_load)
if error == OK:
    var gltf_scene_root_node = gltf_document_load.generate_scene(gltf_state_load)
    add_child(gltf_scene_root_node)
else:
    show_error("Couldn't load glTF scene (error code: %s)." % error_string(error))

# Save a new glTF scene.
var gltf_document_save := GLTFDocument.new()
var gltf_state_save := GLTFState.new()
gltf_document_save.append_from_scene(gltf_scene_root_node, gltf_state_save)
# The file extension in the output `path` (`.gltf` or `.glb`) determines
# whether the output uses text or binary format.
# `GLTFDocument.generate_buffer()` is also available for saving to memory.
gltf_document_save.write_to_filesystem(gltf_state_save, path)

참고

glTF 씬을 로드할 때 텍스처와 같은 외부 리소스가 올바르게 로드될 수 있도록 *기본 경로*를 설정해야 합니다. 파일에서 로드할 때 기본 경로는 파일이 포함된 폴더로 자동 설정됩니다. 버퍼에서 로딩할 때, Godot가 이 경로를 추론할 수 있는 방법이 없기 때문에 이 기본 경로는 수동으로 설정되어야 합니다.

기본 경로를 설정하려면 GLTFDocument.append_from_buffer.

정면 뷰

:ref:`FontFile.load_dynamic_font <class_FontFile_method_load_bitmap_font>`은 다음 글꼴 파일 형식을 지원합니다: TTF, OTF, WOFF, WOFF2, PFB, PFM

반면에 :ref:`FontFile.load_bitmap_font <class_FontFile_method_load_bitmap_font>`는 `BMFont <https://www.angelcode.com/products/bmfont/>`__ 형식(.fnt 또는 .font)을 지원합니다.

추가적으로, :ref:`doc_using_fonts_system_fonts`에 대한 Godot의 지원을 사용하여 시스템에 설치된 모든 글꼴을 로드하는 것이 가능합니다.

파일 확장자에 따라 자동으로 글꼴 파일을 로드한 다음 이를 Label 노드에 테마 재정의로 추가하는 예:

var path = "/path/to/font.ttf"
var path_lower = path.to_lower()
var font_file = FontFile.new()
if (
        path_lower.ends_with(".ttf")
        or path_lower.ends_with(".otf")
        or path_lower.ends_with(".woff")
        or path_lower.ends_with(".woff2")
        or path_lower.ends_with(".pfb")
        or path_lower.ends_with(".pfm")
):
    font_file.load_dynamic_font(path)
elif path_lower.ends_with(".fnt") or path_lower.ends_with(".font"):
    font_file.load_bitmap_font(path)
else:
    push_error("Invalid font file format.")

if not font_file.data.is_empty():
    # If font was loaded successfully, add it as a theme override.
    $Label.add_theme_font_override("font", font_file)

ZIP 아카이브

Godot는 ZIPReaderZIPPacker 클래스를 사용하여 ZIP 아카이브 읽기 및 쓰기를 지원합니다. 이는 Godot의 "PCK/ZIP 내보내기" 기능으로 생성된 파일을 포함한 모든 ZIP 파일을 지원합니다(이 파일에는 원본 프로젝트 파일이 아닌 가져온 Godot 리소스가 포함되지만).

참고

Godot가 :ref:`추가 데이터 팩 <doc_exporting_pcks>`으로 내보낸 PCK 또는 ZIP 파일을 로드하려면 :ref:`ProjectSettings.load_resource_pack <class_ProjectSettings_method_load_resource_pack>`을 사용하세요. 이러한 접근 방식은 추가 데이터 팩과 원활하게 상호 작용할 수 있도록 하기 때문에(가상 파일 시스템) DLC에 선호됩니다.

이 ZIP 아카이브 지원은 런타임 이미지, 3D 씬 및 오디오 로딩과 결합되어 사용자가 PCK/ZIP 파일을 생성하기 위해 Godot 편집기를 거치지 않고도 원활한 모딩 경험을 제공할 수 있습니다.

ItemList 노드의 ZIP 아카이브에 있는 파일을 나열한 다음 여기에서 읽은 내용을 새 ZIP 아카이브에 쓰는 예(기본적으로 아카이브 복제):

# Load an existing ZIP archive.
var zip_reader = ZIPReader.new()
zip_reader.open(path)
var files = zip_reader.get_files()
# The list of files isn't sorted by default. Sort it for more consistent processing.
files.sort()
for file in files:
    $ItemList.add_item(file, null)
    # Make folders disabled in the list.
    $ItemList.set_item_disabled(-1, file.ends_with("/"))

# Save a new ZIP archive.
var zip_packer = ZIPPacker.new()
var error = zip_packer.open(path)
if error != OK:
    push_error("Couldn't open path for saving ZIP archive (error code: %s)." % error_string(error))
    return

# Reuse the above ZIPReader instance to read files from an existing ZIP archive.
for file in zip_reader.get_files():
    zip_packer.start_file(file)
    zip_packer.write_file(zip_reader.read_file(file))
    zip_packer.close_file()

zip_packer.close()