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.
Checking the stable version of the documentation...
다음 예제에서:
더 보기
자세한 설명은 프로젝트 내보내기 를 참고하세요.
때때로 :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
private void SaveFile(string content)
{
using var file = FileAccess.Open("/Path/To/File.txt", FileAccess.ModeFlags.Write);
file.StoreString(content);
}
private string LoadFile()
{
using var file = FileAccess.Open("/Path/To/File.txt", FileAccess.ModeFlags.Read);
string content = file.GetAsText();
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")
// Load an image of any format supported by Godot from the filesystem.
var image = Image.LoadFromFile(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.GenerateMipmaps();
GetNode<TextureRect>("TextureRect").Texture = ImageTexture.CreateFromImage(image);
// Save the loaded Image to a PNG image.
image.SavePng("/Path/To/File.png");
// Save the converted ImageTexture to a PNG image.
GetNode<TextureRect>("TextureRect").Texture.GetImage().SavePng("/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)
GetNode<AudioStreamPlayer>("AudioStreamPlayer").Stream = AudioStreamOggVorbis.LoadFromFile(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()
var videoStreamTheora = new VideoStreamTheora();
// File extension is ignored, so it is possible to load Ogg Theora videos
// that have a `.ogg` extension this way.
videoStreamTheora.File = "/Path/To/File.ogv";
GetNode<VideoStreamPlayer>("VideoStreamPlayer").Stream = videoStreamTheora;
// VideoStreamPlayer's Autoplay property won't work if the stream is empty
// before this property is set, so call `Play()` after setting `Stream`.
GetNode<VideoStreamPlayer>("VideoStreamPlayer").Play();
씬
Godot는 편집기와 내보낸 프로젝트 모두에서 glTF 2.0에 대한 최고 수준의 지원을 제공합니다. class_gltfdocument`와 :ref:`class_gltfstate`를 함께 사용하면 Godot는 내보낸 프로젝트에 glTF 파일을 텍스트(`.gltf``) 및 바이너리(.glb) 형식으로 로드하고 저장할 수 있습니다. 바이너리 형식은 작성 속도가 더 빠르고 크기도 작으므로 선호되지만 텍스트 형식은 디버깅이 더 쉽습니다.
Godot 4.3부터, FBXDocument 및 FBXState 클래스를 사용하여 런타임에 FBX 장면을 로드할 수도 있습니다(저장할 수는 없음). 이를 수행하는 코드는 glTF와 동일하지만 아래 코드 샘플에서 GLTFDocument 및 GLTFState``의 모든 인스턴스를 ``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)
// 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 gltfDocumentLoad = new GltfDocument();
var gltfStateLoad = new GltfState();
var error = gltfDocumentLoad.AppendFromFile("/Path/To/File.gltf", gltfStateLoad);
if (error == Error.Ok)
{
var gltfSceneRootNode = gltfDocumentLoad.GenerateScene(gltfStateLoad);
AddChild(gltfSceneRootNode);
}
else
{
GD.PrintErr($"Couldn't load glTF scene (error code: {error}).");
}
// Save a new glTF scene.
var gltfDocumentSave = new GltfDocument();
var gltfStateSave = new GltfState();
gltfDocumentSave.AppendFromScene(gltfSceneRootNode, gltfStateSave);
// The file extension in the output `path` (`.gltf` or `.glb`) determines
// whether the output uses text or binary format.
// `GltfDocument.GenerateBuffer()` is also available for saving to memory.
gltfDocumentSave.WriteToFilesystem(gltfStateSave, 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)
string path = "/Path/To/Font.ttf";
var fontFile = new FontFile();
if (
path.EndsWith(".ttf", StringComparison.OrdinalIgnoreCase)
|| path.EndsWith(".otf", StringComparison.OrdinalIgnoreCase)
|| path.EndsWith(".woff", StringComparison.OrdinalIgnoreCase)
|| path.EndsWith(".woff2", StringComparison.OrdinalIgnoreCase)
|| path.EndsWith(".pfb", StringComparison.OrdinalIgnoreCase)
|| path.EndsWith(".pfm", StringComparison.OrdinalIgnoreCase)
)
{
fontFile.LoadDynamicFont(path);
}
else if (path.EndsWith(".fnt", StringComparison.OrdinalIgnoreCase) || path.EndsWith(".font", StringComparison.OrdinalIgnoreCase))
{
fontFile.LoadBitmapFont(path);
}
else
{
GD.PrintErr("Invalid font file format.");
}
if (!fontFile.Data.IsEmpty())
{
// If font was loaded successfully, add it as a theme override.
GetNode<Label>("Label").AddThemeFontOverride("font", fontFile);
}
ZIP 아카이브
Godot는 ZIPReader 및 ZIPPacker 클래스를 사용하여 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()
// Load an existing ZIP archive.
var zipReader = new ZipReader();
zipReader.Open(path);
string[] files = zipReader.GetFiles();
// The list of files isn't sorted by default. Sort it for more consistent processing.
Array.Sort(files);
foreach (string file in files)
{
GetNode<ItemList>("ItemList").AddItem(file);
// Make folders disabled in the list.
GetNode<ItemList>("ItemList").SetItemDisabled(-1, file.EndsWith('/'));
}
// Save a new ZIP archive.
var zipPacker = new ZipPacker();
var error = zipPacker.Open(path);
if (error != Error.Ok)
{
GD.PrintErr($"Couldn't open path for saving ZIP archive (error code: {error}).");
return;
}
// Reuse the above ZIPReader instance to read files from an existing ZIP archive.
foreach (string file in zipReader.GetFiles())
{
zipPacker.StartFile(file);
zipPacker.WriteFile(zipReader.ReadFile(file));
zipPacker.CloseFile();
}
zipPacker.Close();