Godot菜单脚本,只用传入字典数据即可创建多级菜单
Posted 张学徒
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Godot菜单脚本,只用传入字典数据即可创建多级菜单相关的知识,希望对你有一定的参考价值。
Godot 3.5 rc2
将脚本挂载到一个 HBoxContainer
或 VBoxContainer
节点上
下面 test()
方法即是一个示例,可以扩展脚本重写 _menu_pressed()
方法操作点击的菜单项,或者连接 menu_pressed
信号进行对点击的菜单进行操作
#=====================================================
# 菜单列表
#=====================================================
# 类似 test() 脚本中的菜单结构,可以生成不断嵌套的菜单
#=====================================================
class_name MenuList
extends BoxContainer
func _ready():
test()
func test():
init_menu(
"File": [
"Open", "Save", "Save As",
"Export": [
"Export",
"Export as..."
]
],
"Edit": [
"Undo",
"number": [
"1",
"2",
"3",
],
"item_02": [
"a",
"b",
"c",
"d": [1, 2, 3, 4],
]
,
],
)
signal menu_pressed(id, path)
var idx := -1
var popup_menu_map :=
var popup_item_path_map :=
#=====================================================
# Set/Get
#=====================================================
## 获取弹窗菜单
func get_popup_menu(path: String) -> PopupMenu:
return popup_menu_map[path] as PopupMenu
#=====================================================
# 自定义方法
#=====================================================
## 初始化菜单
func init_menu(data: Dictionary):
call_deferred("add_menu", data)
## 添加菜单项
func add_menu(menu_data, popup : PopupMenu = null, parent_label: String = ""):
idx += 1
if popup != null:
# Dictionary
if menu_data is Dictionary:
for key in menu_data:
add_menu(
menu_data[key]
, popup
, parent_label.plus_file(key)
)
# Array
elif menu_data is Array:
for item in menu_data:
add_menu(item, popup, parent_label)
# String
else:
# 添加子菜单
create_menu(parent_label, popup)
# 添加菜单项
var sub_popup := get_popup_menu(parent_label)
var label : String = str(menu_data)
if not label.begins_with("-"):
popup_item_path_map[idx] = parent_label + "/" + label
sub_popup.add_item(label, idx)
else:
sub_popup.add_separator()
else:
for key in menu_data:
var menu = MenuButton.new()
menu.switch_on_hover = true
menu.text = str(key)
add_child(menu)
parent_label = "/" + key
__popup_item_data__(parent_label, menu.get_popup())
add_menu(menu_data[key], menu.get_popup(), parent_label)
## 创建菜单
func create_menu(menu_path: String, to_menu: PopupMenu = null):
if menu_path == "":
return
if not popup_menu_map.has(menu_path):
var arr : Array = menu_path.split("/")
var last_menu : PopupMenu = to_menu
for idx in range(1, arr.size()):
var label : String = arr[idx]
var sub_path = "/".join(arr.slice(0, idx))
if not popup_menu_map.has(sub_path):
var item_label = sub_path.right( sub_path.find_last("/") ).trim_prefix("/")
var temp_popup = PopupMenu.new()
temp_popup.name = item_label
__popup_item_data__(sub_path, temp_popup)
last_menu.add_child(temp_popup)
last_menu.add_submenu_item( item_label, item_label )
last_menu = get_popup_menu(sub_path)
## 点击菜单
func _menu_pressed(idx: int, path: String):
printt(idx, path)
pass
#=====================================================
# 连接信号
#=====================================================
# 弹窗菜单路径
func __popup_item_data__(path: String, popup: PopupMenu):
popup_menu_map[path] = popup
if not popup.is_connected("id_pressed", self, "__popup_id_pressed__"):
popup.connect("id_pressed", self, "__popup_id_pressed__")
# 点击菜单连接信号
func __popup_id_pressed__(id: int):
_menu_pressed(id, popup_item_path_map[id])
emit_signal("menu_pressed", id, popup_item_path_map[id])
以上是关于Godot菜单脚本,只用传入字典数据即可创建多级菜单的主要内容,如果未能解决你的问题,请参考以下文章