Godot4 プロジェクト設定に保存した独自の項目の値を辞書変数に得る実装例

無料・軽快な 2D / 3D 用のゲームエンジン Godot Engine 4 で、プロジェクトごとの設定を管理するプロジェクト設定から、指定した項目の値を辞書変数に格納するスクリプト例と実行結果を紹介します。

プロジェクト設定のオーバーライドや、小数を読み込んだ際の誤差についても紹介します。

※ GodotEngine 4.3 を使用しています。.NET 版ではありません。
※スクリプトは自己責任でご利用ください。

プラグインによるツールメニューとサブメニューの追加

独自の項目をプロジェクト設定に保存する処理を実装した関数は、作成したプラグインによって追加したツールメニューのサブメニューを選択することで呼び出されます。

プラグインとツールメニュー・サブメニューの追加の方法については以下の記事を参照してください。

独自項目を保存するサブメニュー Save について

独自項目を保存するサブメニュー Save については以下の記事を参照してください。

プロジェクト設定の項目の値を辞書変数に得るスクリプト例

以下のスクリプトを、以下の記事で作成したプラグインの gd スクリプトに貼り付けて保存します。

上記の記事で紹介している手順で、追加したツールメニューのサブメニューを選択すると、_on_submenu_id_pressed 関数( 57 行目)が呼び出され、サブメニューのどの項目かを id で判別して、対応する関数を呼び出します。

@tool
extends EditorPlugin

## ProjectSettings の「ユーザ名/アドオン名/セクション名/キー」の読み書きを Dictionary 型を用いて行う関数とそのテストです。
## EditorInterface の機能はエディタ上で利用できます。
## ProjectSettings の機能を含む関数を実行するために、プラグインとしてこのスクリプトを追加して
## ツールメニュー(「プロジェクト」→「ツール」)から、これが追加したメニューを選択してください。

## 追加するメニューアイテムの表示名です。
const tool_menu_item_name: StringName = "Study ProjectSettings By Dictionary"
## メニューアイテムに追加するサブメニューアイテムの項目名と ID の配列です。
const tool_submenu_item_info_array = [
	{"name": "Save", "id": 0},
	{"name": "Set Initial Value", "id": 1},
	{"name": "Load", "id": 2},
	{"name": "Clear", "id": 3},
]
## サブメニューのリソースです。
var submenu: PopupMenu = null

## テストでアクセスする ProjectSettings の name の要素です。
## テストでは、 EDITOR_SETTINGS_PATH + EDITOR_SETTINGS_SECTION + key を name とします。
const PROJECT_SETTINGS_PATH = "sclib/fit_font_size/"
const PROJECT_SETTINGS_SECTION = "scale_correction_value/"


## プラグインの初期化処理を定義します。
## プラグイン (プロジェクト設定ダイアログ>プラグイン>有効) を有効にした直後や、プラグインが有効な状態のプロジェクトを開いた際に呼び出されます。
func _enter_tree():
	if submenu == null:
		# サブメニュー用のポップアップメニューに項目名とその ID を追加します。
		submenu = PopupMenu.new()
		for info in tool_submenu_item_info_array:
			submenu.add_item(info.name, info.id)
		# 選択されたシグナル発生時に呼び出す関数を設定します。
		submenu.id_pressed.connect(_on_submenu_id_pressed)
		# ツールメニュー(「プロジェクト」→「ツール」)にメニューアイテムとそのサブメニューを追加します。
		add_tool_submenu_item(tool_menu_item_name, submenu)
	
	return


## プラグインの後片付けの処理を定義します。
## プラグインを無効 (プロジェクト設定ダイアログ>プラグイン>有効) にした直後や、プラグインが有効な状態でプロジェクトを閉じた際に呼び出されます。
func _exit_tree():
	# ツールメニュー(「プロジェクト」→「ツール」)に追加したメニューアイテムを削除します。
	remove_tool_menu_item(tool_menu_item_name)
	# サブメニューのリソースを解放します。
	if submenu != null:
		submenu.queue_free()
		submenu = null
	return


## プラグインで追加したツールメニューのサブメニューを選択した際に呼び出される関数です。
## [param id] は、選択されたサブメニューの項目の ID です。
func _on_submenu_id_pressed(id):
	print("_on_submenu_id_pressed called. id = ", id)
	print(tool_submenu_item_info_array[id].name, " pressed.")
	
	# id が指すツールメニューのサブメニューに対応した処理を実行します。
	match id:
		0:	# Save
			test_save_editor_settings_section_from_dictionary()
		1:	# Set Initial Value
			test_set_editor_settings_section_initial_value_from_dictionary()
		2:	# Load
			test_load_project_settings_section_to_dictionary()
		3:	# Clear
			test_erase_project_settings_section_from_dictionary()
		_:
			push_warning("id is unknown.")
	return

## [method save_project_settings_section_from_dictionary] のテスト関数です。
func test_save_editor_settings_section_from_dictionary():
	# セクション内に保存されるデータです。
	var dic_save = {}
	dic_save["Label"] = 0.9
	dic_save["Button"] = 1.0
	
	# 辞書のデータ群を、指定した EditorSettings ファイルのセクションに保存します。
	# ファイルが存在しない場合は作成し、存在する場合は辞書の要素ごとに上書きします。
	print("save_project_settings_section_from_dictionary call")
	save_project_settings_section_from_dictionary(
		PROJECT_SETTINGS_PATH, PROJECT_SETTINGS_SECTION, dic_save)
	
	return


## 指定した ProjectSettings の path (例:「ユーザ名/アドオン名」)のセクションに、辞書型のデータを保存します。
## 辞書の要素のキーは、EditorSettings.set_settings の name 引数、値は value 引数に対応します。
##
## [param path] と [param section] を連結した base_path に、
## 辞書の要素キーを付け加えた name に対して value を設定します。
##
## [param path] に "user_name/addon_name/" を指定して、
## [param section] に "section_name/" を設定すると
## ユーザ名、アドオン名、セクション名を / で区切った後にキーを加えた name に value を設定します。
func save_project_settings_section_from_dictionary(
	path: String, section: String, dic: Dictionary) -> void:
	
	# 設定を保存する name のキーの1つ前までの階層の文字列を作成します。
	var base_path := path + section
	
	# 辞書変数の要素ごとに EditorSettings に保存します。
	for key in dic.keys():
		# name の最後には、辞書変数のキーを追加します。
		var project_settings_name: String = base_path + key
		ProjectSettings.set_setting(project_settings_name, dic[key])
	
	return


func test_erase_project_settings_section_from_dictionary():
	# セクション内に保存されるデータです。
	var array_erase_keys = ["Label", "Button"]
	
	# 辞書のデータ群を、指定した EditorSettings ファイルのセクションの
	# 各設定値の初期値に設定します。
	print("erase_project_settings_section_from_dictionary call")
	erase_project_settings_section_from_dictionary(
		PROJECT_SETTINGS_PATH, PROJECT_SETTINGS_SECTION, array_erase_keys)
	
	return


## ProjectSettings の項目を削除します。
## 削除することでエディタが正常に動作しなくなる危険性があるので注意してください。
## [param path] + [param section ] + [param erase_keys] の各要素で連結した文字列
## の name に一致する項目を削除します。
func erase_project_settings_section_from_dictionary(
	path: String, section: String, erase_keys: Array = []
) -> void:
	
	# 設定を保存する name のキーの1つ前までの階層の文字列を作成します。
	var base_path := path + section
	
	# 辞書変数の要素ごとに EditorSettings から値を取得します。
	for key in erase_keys:
		# name の最後には、辞書変数のキーを追加します。
		var project_settings_name: String = base_path + key
		print("erase_project_settings_section_from_dictionary, project_settings_name = ", project_settings_name)
		# name と同じ項目があれば、それを削除します。
		if ProjectSettings.has_setting(project_settings_name) == true:
			# 指定した name の設定値を削除します。
			ProjectSettings.set_setting(project_settings_name, null)
			print(project_settings_name, " を ProjectSettings から削除しました。")
		else:
			print(project_settings_name, " は ProjectSettings にありませんでした。")
	return


## [method set_editor_settings_section_initial_value_from_dictionary] のテスト関数です。
func test_set_editor_settings_section_initial_value_from_dictionary():
	# セクション内に保存されるデータです。
	var dic_initial = {}
	dic_initial["Label"] = 0.98
	dic_initial["Button"] = 0.95
	
	# 辞書のデータ群を、指定した EditorSettings ファイルのセクションの
	# 各設定値の初期値に設定します。
	print("set_editor_settings_section_initial_value_from_dictionary call")
	set_editor_settings_section_initial_value_from_dictionary(
		PROJECT_SETTINGS_PATH, PROJECT_SETTINGS_SECTION, dic_initial)
	
	return


## ProjectSettings の項目の初期値を指定します。
## これは ProjectSettings の Revert ボタンが押されたときなどに用いられます。
## 存在しない項目については処理しません。
func set_editor_settings_section_initial_value_from_dictionary(
	path: String, section: String, initial_values: Dictionary = {}
) -> void:
	
	# 設定を保存する name のキーの1つ前までの階層の文字列を作成します。
	var base_path := path + section
	
	# 辞書変数の要素ごとに EditorSettings から値を取得します。
	for key in initial_values.keys():
		# name の最後には、辞書変数のキーを追加します。
		var project_settings_name: String = base_path + key
		print("set_initial_values, project_settings_name = ", project_settings_name)
		if ProjectSettings.has_setting(project_settings_name) == true:
			# 初期値を設定します。
			ProjectSettings.set_initial_value(project_settings_name, initial_values[key])
			print("set_initial_value project_settings_name = ", project_settings_name, 
			", initial_value = ", initial_values[key])
		else:
			print("set_initial_value project_settings_name = ", project_settings_name, 
			" は存在しません。 ")
	
	return


## load_project_settings_section_to_dictionary のテスト関数です。
func test_load_project_settings_section_to_dictionary():
	# 取得するキーを設定します。
	var key_array = ["Label", "Button", "OptionButton", "CheckButton"]
	
	# デフォルト値を設定します。
	var default_values := {}
	default_values["Label"] = 0.5
	default_values["OptionButton"] = 0.8
	
	# 指定した EditorSettings ファイルのセクションを読み込み、辞書として取得します。
	print("load_editor_settings_section_to_dictionary call")
	var dic: Dictionary = load_project_settings_section_to_dictionary(
		PROJECT_SETTINGS_PATH, PROJECT_SETTINGS_SECTION, key_array, default_values)
	
	# 読み込んだ辞書の内容を出力します。
	var str_dic: String = ScUtil.to_pretty_print_string(dic)
	print(str_dic)

	return


## 指定した ProjectSettings の path (例:「ユーザ名/アドオン名」)のセクションを辞書型で取得します。
## [param path] と [param section] については [method save_project_settings_section_from_dictionary] を
## 参照してください。
func load_project_settings_section_to_dictionary(
	path: String, section: String, key_array: Array, default_values: Dictionary = {}
) -> Dictionary:
	var dic := {}
	
	# 設定を保存する name のキーの1つ前までの階層の文字列を作成します。
	var base_path := path + section
	
	var default_keys = default_values.keys()
	# 辞書変数の要素ごとに EditorSettings から値を取得します。
	for key in key_array:
		# name の最後には、辞書変数のキーを追加します。
		var project_settings_name: String = base_path + key
		
		# 本関数内でデフォルト値を設定していない、かつ、name の設定が存在しない場合は警告を出力します。
		# それ以外は、辞書変数に設定値を格納します。
		if ProjectSettings.has_setting(project_settings_name) == false:
			if key in default_keys:
				dic[key] = default_values[key]
			else:
				push_warning("study_project_settings_by_dictionary.gd:" +
					"load_project_settings_section_to_dictionary:" +
					"ProjectSettings.has_setting(project_settings_name) == false, " +
					"project_settings_name = ", project_settings_name)
		else:
			dic[key] = ProjectSettings.get_setting(project_settings_name)
	
	return dic

今回は、サブメニュー Loadを選択した際に、プロジェクト設定に指定した項目を辞書変数に取得するテスト関数 test_load_project_settings_section_to_dictionary( 198 行目)を呼び出します。

そのテスト関数の内部では、配列変数に指定した項目群をプロジェクト設定から辞書変数に取得する load_project_settings_section_to_dictionary 関数( 222 行目)を呼び出します。

その関数内で、初期値を設定する項目存在することを has_setting 関数で確認した後に、 辞書の要素ごとに get_setting 関数を使用( 247 行目)して、プロジェクト設定に保存した独自の項目に初期値を設定しています。

項目が存在しなくても、引数 default_values 辞書変数のキーと一致すれば、その値を戻り値の辞書変数に格納( 240 行目)します。

bool has_setting(name: String) const 

Returns true if a configuration value is present.

構成値が存在する場合は true を返します。

Note: In order to be be detected, custom settings have to be either defined with set_setting(), or exist in the project.godot file. This is especially relevant when using set_initial_value().

注: 検出されるためには、カスタム設定が set_setting() で定義されているか、project.godot ファイルに存在している必要があります。これは、set_initial_value() を使用する場合に特に関係します。

ProjectSettings — Godot Engine (stable) documentation in English #has_setting と Google 翻訳

Variant get_setting(name: String, default_value: Variant = null) const

Returns the value of the setting identified by name. If the setting doesn’t exist and default_value is specified, the value of default_value is returned. Otherwise, null is returned

名前で識別された設定の値を返します。設定が存在せず、default_value が指定されている場合は、default_value の値が返されます。それ以外の場合は、null が返されます

print(ProjectSettings.get_setting("application/config/name"))
print(ProjectSettings.get_setting("application/config/custom_description", "No description specified."))

Note: This method doesn’t take potential feature overrides into account automatically. Use get_setting_with_override() to handle seamlessly.

注: この方法では、機能のオーバーライドの可能性は自動的に考慮されません。シームレスに処理するには get_setting_with_override() を使用します。

See also has_setting() to check whether a setting exists.

設定が存在するかどうかを確認するには、has_setting() も参照してください。

ProjectSettings — Godot Engine (stable) documentation in English #get_setting と Google 翻訳

オーバーライドの値を考慮する取得関数について

get_setting_with_override では、オーバーライドを考慮した値を取得します。
オーバーライドは、プロジェクトフォルダ直下に override.cfg ファイルによって定義できます。
※動作確認はしていません。

Variant get_setting_with_override(name: StringName) const 

Similar to get_setting(), but applies feature tag overrides if any exists and is valid.

get_setting() と似ていますが、機能タグのオーバーライドが存在し、有効であればそれを適用します。

Example: If the setting override "application/config/name.windows" exists, and the following code is executed on a Windows operating system, the overridden setting is printed instead:

ProjectSettings — Godot Engine (stable) documentation in English #get_setting_with_override と Google 翻訳

Overriding: Any project setting can be overridden by creating a file named override.cfg in the project’s root directory. This can also be used in exported projects by placing this file in the same directory as the project binary. Overriding will still take the base project settings’ feature tags in account. Therefore, make sure to also override the setting with the desired feature tags if you want them to override base project settings on all platforms and configurations.

オーバーライド: プロジェクトのルート ディレクトリに override.cfg という名前のファイルを作成することで、プロジェクト設定をオーバーライドできます。このファイルをプロジェクト バイナリと同じディレクトリに配置することで、エクスポートされたプロジェクトでも使用できます。オーバーライドでは、基本プロジェクト設定の機能タグが引き続き考慮されます。したがって、すべてのプラットフォームと構成の基本プロジェクト設定をオーバーライドする場合は、目的の機能タグでも設定をオーバーライドしてください。

ProjectSettings — Godot Engine (stable) documentation in English と Google 翻訳

get_setting_with_override_and_custom_features は、機能タグによって指定したプラットフォームについてのオーバーライドを適用した値を取得します。
※動作確認はしていません。

Variant get_setting_with_override_and_custom_features(name: StringName, features: PackedStringArray) const 

Similar to get_setting_with_override(), but applies feature tag overrides instead of current OS features.

get_setting_with_override() と似ていますが、現在の OS 機能の代わりに機能タグのオーバーライドを適用します。

ProjectSettings — Godot Engine (stable) documentation in English #get_setting_with_override_and_custom_features と Google 翻訳

Feature tags: Project settings can be overridden for specific platforms and configurations (debug, release, …) using feature tags.

機能タグ: 機能タグを使用して、特定のプラットフォームおよび構成 (デバッグ、リリースなど) のプロジェクト設定をオーバーライドできます。

ProjectSettings — Godot Engine (stable) documentation in English と Google 翻訳

テスト

前述のスクリプトのプロジェクト設定の項目の値を辞書変数に取得する関数を、サブメニューから呼び出して、プロジェクト設定の項目の値と比較します。

サブメニュー Save (日本語表示は保存) を選択して、独自項目をプロジェクト設定に保存します。

	var dic_save = {}
	dic_save["Label"] = 0.9
	dic_save["Button"] = 1.0
Godot4 プロジェクト設定に保存した独自の項目の値を辞書変数に得る実装例1
_on_submenu_id_pressed called. id = 0
Save pressed.
save_project_settings_section_from_dictionary call

プロジェクト設定ダイアログに、独自のセクション・項目表示されました。
プロジェクト設定ダイアログは、メニュー「プロジェクト」→「プロジェクト設定」で開きます。

Godot4 プロジェクト設定に保存した独自の項目の値を辞書変数に得る実装例2

プロジェクト設定ダイアログで、 Button の項目の値を保存した 1 の値から 0.777 に変更します。

Godot4 プロジェクト設定に保存した独自の項目の値を辞書変数に得る実装例3
scale_correction_value/Button を設定

project.godot ファイルにも反映されました。
# 後述する浮動小数のずれがないため、おそらく値は文字列として保存されていると思います。

[sclib]

fit_font_size/scale_correction_value/Label=0.9
fit_font_size/scale_correction_value/Button=0.777

サブメニュー Load (日本語表示は読み込み)を選択して、今回紹介した関数プロジェクト設定独自項目の値を辞書変数読み込んだ結果を出力します。

Godot4 プロジェクト設定に保存した独自の項目の値を辞書変数に得る実装例4

プロジェクト設定に存在しない項目かつ引数 default_values にもない項目は、黄色の警告文で指定された項目が見つからないというメッセージが表示されました。

プロジェクト設定存在しないけれど、引数 default_values にあった OptionButton の項目は、その defualt_values[“OptionButton”] の値が戻り値の辞書変数に格納されました。

他の2つの項目はプロジェクト設定存在している値が取得されています。
プロジェクト設定ダイアログで変更した Button の値(0.777)も取得されています。

  core/variant/variant_utility.cpp:1112 - study_project_settings_by_dictionary.gd:load_project_settings_section_to_dictionary:ProjectSettings.has_setting(project_settings_name) == false, project_settings_name = sclib/fit_font_size/scale_correction_value/CheckButton
_on_submenu_id_pressed called. id = 2
Load pressed.
load_editor_settings_section_to_dictionary call
{
	"Label": 0.9,
	"Button": 0.77700000000186,
	"OptionButton": 0.8
}

0.777 は、辞書変数に格納したあとの出力では、0.77700000000186 で表示されました。
また下記の print 文で小数第 20 位までを指定すると0.77700000000000002000 と表記されます。

print("Raw: ", "%.20f" % float_value)

小数は扱う関数で丸め方などが異なるので、実装する機能に応じ有効桁数を設定してそれ以降は切り捨てるなどの処理が必要かもしれません。

まとめ

参照サイト Thank You!

記事一覧 → Compota-Soft-Press

コメント

Ads Blocker Image Powered by Code Help Pro

お願い - Ads Blocker Detected

このサイトは広告を掲載して運営しています。

ポップアップを閉じて閲覧できますが、よろしければ

このサイト内の広告を非表示にする拡張機能をオフにしていただけませんか?

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

We have detected that you are using extensions to block ads. Please support us by disabling these ads blocker.

タイトルとURLをコピーしました