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...
사용자 정의 리소스 형식 로더
소개
ResourceFormatLoader는 파일 자산을 로드하기 위한 팩토리 인터페이스입니다. 리소스는 기본 컨테이너입니다. 동일한 파일 경로에서 다시 로드를 호출하면 이전에 로드된 리소스가 참조됩니다. 당연히 로드된 리소스는 상태 비저장이어야 합니다.
이 가이드는 독자가 C++ 모듈과 Godot 데이터 유형을 만드는 방법을 알고 있다고 가정합니다. 그렇지 않은 경우 이 가이드를 참조하세요: C++에서 커스텀 모듈
참조
무엇을 위해?
다양한 파일 형식에 대한 새로운 지원 추가
오디오 형식
비디오 형식
기계 학습 모델
그렇지 않은가?
래스터 이미지
ImageFormatLoader는 이미지를 로드하는 데 사용해야 합니다.
참조
ResourceFormatLoader 만들기
각 파일 형식은 데이터 컨테이너와 ``ResourceFormatLoader``로 구성됩니다.
ResourceFormatLoaders는 Godot의 새로운 확장을 지원하는 데 필요한 모든 메타데이터를 반환하는 클래스입니다. 클래스는 형식 이름과 확장 문자열을 반환해야 합니다.
또한 ResourceFormatLoaders는 load 함수를 사용하여 파일 경로를 리소스로 변환해야 합니다. 리소스를 로드하려면 ``load``가 데이터 직렬화를 읽고 처리해야 합니다.
#pragma once
#include "core/io/resource_loader.h"
class ResourceFormatLoaderJson : public ResourceFormatLoader {
GDCLASS(ResourceFormatLoaderJson, ResourceFormatLoader);
public:
virtual RES load(const String &p_path, const String &p_original_path, Error *r_error = NULL);
virtual void get_recognized_extensions(List<String> *r_extensions) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
};
#include "resource_loader_json.h"
#include "resource_json.h"
RES ResourceFormatLoaderJson::load(const String &p_path, const String &p_original_path, Error *r_error) {
Ref<JsonResource> json = memnew(JsonResource);
if (r_error) {
*r_error = OK;
}
Error err = json->load_file(p_path);
return json;
}
void ResourceFormatLoaderJson::get_recognized_extensions(List<String> *r_extensions) const {
if (!r_extensions->find("json")) {
r_extensions->push_back("json");
}
}
String ResourceFormatLoaderJson::get_resource_type(const String &p_path) const {
return "Resource";
}
bool ResourceFormatLoaderJson::handles_type(const String &p_type) const {
return ClassDB::is_parent_class(p_type, "Resource");
}
ResourceFormatSaver 만들기
리소스를 편집하고 저장하려면 ``ResourceFormatSaver``를 구현할 수 있습니다.
#pragma once
#include "core/io/resource_saver.h"
class ResourceFormatSaverJson : public ResourceFormatSaver {
GDCLASS(ResourceFormatSaverJson, ResourceFormatSaver);
public:
virtual Error save(const String &p_path, const RES &p_resource, uint32_t p_flags = 0);
virtual bool recognize(const RES &p_resource) const;
virtual void get_recognized_extensions(const RES &p_resource, List<String> *r_extensions) const;
};
#include "resource_saver_json.h"
#include "resource_json.h"
#include "scene/resources/resource_format_text.h"
Error ResourceFormatSaverJson::save(const String &p_path, const RES &p_resource, uint32_t p_flags) {
Ref<JsonResource> json = memnew(JsonResource);
Error error = json->save_file(p_path, p_resource);
return error;
}
bool ResourceFormatSaverJson::recognize(const RES &p_resource) const {
return Object::cast_to<JsonResource>(*p_resource) != NULL;
}
void ResourceFormatSaverJson::get_recognized_extensions(const RES &p_resource, List<String> *r_extensions) const {
if (Object::cast_to<JsonResource>(*p_resource)) {
r_extensions->push_back("json");
}
}
커스텀 데이터 유형 만들기
Godot는 코어 유형 또는 관리되는 리소스 내에 적절한 대체품이 없을 수 있습니다. Godot는 기계 학습 모델과 같은 추가 바이너리 형식을 이해하려면 새로 등록된 데이터 유형이 필요합니다.
어떻게 작동하는 지의 예제입니다:
#pragma once
#include "core/io/json.h"
#include "core/variant_parser.h"
class JsonResource : public Resource {
GDCLASS(JsonResource, Resource);
protected:
static void _bind_methods() {
ClassDB::bind_method(D_METHOD("set_dict", "dict"), &JsonResource::set_dict);
ClassDB::bind_method(D_METHOD("get_dict"), &JsonResource::get_dict);
ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "content"), "set_dict", "get_dict");
}
private:
Dictionary content;
public:
Error load_file(const String &p_path);
Error save_file(const String &p_path, const RES &p_resource);
void set_dict(const Dictionary &p_dict);
Dictionary get_dict();
};
#include "resource_json.h"
Error JsonResource::load_file(const String &p_path) {
Error error;
FileAccess *file = FileAccess::open(p_path, FileAccess::READ, &error);
if (error != OK) {
if (file) {
file->close();
}
return error;
}
String json_string = String("");
while (!file->eof_reached()) {
json_string += file->get_line();
}
file->close();
String error_string;
int error_line;
JSON json;
Variant result;
error = json.parse(json_string, result, error_string, error_line);
if (error != OK) {
file->close();
return error;
}
content = Dictionary(result);
return OK;
}
Error JsonResource::save_file(const String &p_path, const RES &p_resource) {
Error error;
FileAccess *file = FileAccess::open(p_path, FileAccess::WRITE, &error);
if (error != OK) {
if (file) {
file->close();
}
return error;
}
Ref<JsonResource> json_ref = p_resource.get_ref_ptr();
JSON json;
file->store_string(json.print(json_ref->get_dict(), " "));
file->close();
return OK;
}
void JsonResource::set_dict(const Dictionary &p_dict) {
content = p_dict;
}
Dictionary JsonResource::get_dict() {
return content;
}
고려사항
일부 라이브러리는 IO 처리와 같은 특정 공통 루틴을 정의하지 않을 수 있습니다. 따라서 Godot 호출 번역이 필요합니다.
예를 들어 다음은 FileAccess 호출을 ``std::istream``로 변환하는 코드입니다.
#include "core/io/file_access.h"
#include <istream>
#include <streambuf>
class GodotFileInStreamBuf : public std::streambuf {
public:
GodotFileInStreamBuf(FileAccess *fa) {
_file = fa;
}
int underflow() {
if (_file->eof_reached()) {
return EOF;
} else {
size_t pos = _file->get_position();
uint8_t ret = _file->get_8();
_file->seek(pos); // Required since get_8() advances the read head.
return ret;
}
}
int uflow() {
return _file->eof_reached() ? EOF : _file->get_8();
}
private:
FileAccess *_file;
};
참조
새 파일 형식 등록
Godot는 ResourceLoader 핸들러로 ``ResourcesFormatLoader``를 등록합니다. 핸들러는 ``load``가 호출될 때 자동으로 적절한 로더를 선택합니다.
void register_json_types();
void unregister_json_types();
#include "register_types.h"
#include "core/class_db.h"
#include "resource_loader_json.h"
#include "resource_saver_json.h"
#include "resource_json.h"
static Ref<ResourceFormatLoaderJson> json_loader;
static Ref<ResourceFormatSaverJson> json_saver;
void register_json_types() {
ClassDB::register_class<JsonResource>();
json_loader.instantiate();
ResourceLoader::add_resource_format_loader(json_loader);
json_saver.instantiate();
ResourceSaver::add_resource_format_saver(json_saver);
}
void unregister_json_types() {
ResourceLoader::remove_resource_format_loader(json_loader);
json_loader.unref();
ResourceSaver::remove_resource_format_saver(json_saver);
json_saver.unref();
}
참조
GDScript에 로드
다음 내용으로 ``demo.json``라는 파일을 저장하고 프로젝트의 루트 폴더에 배치합니다.
{
"savefilename": "demo.json",
"demo": [
"welcome",
"to",
"godot",
"resource",
"loaders"
]
}
다음과 같은 주의 사항이 있습니다:
extends Node
@onready var json_resource = load("res://demo.json")
func _ready():
print(json_resource.get_dict())