Godot在Godot中模仿实现接口功能

Posted 张学徒

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Godot在Godot中模仿实现接口功能相关的知识,希望对你有一定的参考价值。

Godot 3.4.2

在接口节点中写下方法后,如果父节点没有实现这个方法,则会进行提示,运行时则会进行断定并提示(断言)。

NodeInterface.gd

#============================================================
#	Node Interface
#============================================================
#  节点需要实现的功能
#============================================================
# @datetime: 2022-3-15 19:46:31
#============================================================
tool
class_name NodeInterface
extends Node


## 角色对应的接口节点
const ObjectNodeMap := 


export(Array, String) var excluede_list : Array


onready var host = get_parent()



#============================================================
#   Set/Get
#============================================================
##  获取对象的节点接口
## (如果想要获取一个节点的这个接口则直接进行 NodeInterface.get_role_interface(节点对象)
##  进行获取这个节点的接口列表)
static func get_role_interface(object: Object) -> Array:
	if ObjectNodeMap.has(object):
		return ObjectNodeMap[object]
	return []


func __get_no_exists_method__() -> Array:
	host = get_parent()
	# 这个节点所拥有的方法
	var list = (get_script() as Script).get_script_method_list()
	var data = 
	for method_data in list:
		var method = method_data['name']
		data[method] = null
	# 排除的方法
	var exclude_method := [
		"_ready", "_exit_tree", "get_role_interface", "_init",
		"__get_no_exists_method__", "_get_configuration_warning"
	]
	exclude_method.append_array(excluede_list)
	for method in exclude_method:
		data.erase(method)
	# 判断host是否存在这些方法
	var no_exists := []
	for method in data:
		if not host.has_method(method):
			no_exists.append(method)
	return no_exists



#============================================================
#   内置
#============================================================
func _init():
	if not ObjectNodeMap.has(host):
		ObjectNodeMap[host] = []
	ObjectNodeMap[host].append(self)


func _ready():
	if not Engine.editor_hint:
		var list = __get_no_exists_method__()
		assert(list.size() == 0, "host 没有实现 %s 方法!" % str(list))


func _exit_tree():
	ObjectNodeMap.erase(host)


func _get_configuration_warning():
	var list = __get_no_exists_method__()
	if list.size() > 0:
		return "host 没有实现 %s 方法!" % str(list)
	return ""

以上是接口的基类,如果想让父节点实现一些方法,比如我想让player节点实现 move attack 等方法,则继承上面脚本,并写下如下代码

tool
class_name PlayerInterface
extends NodeInterface


func move():
	host.move()


func attack():
	host.attack()

创建一个如下结构的节点,并扩展 NodeInterface 节点为上面的代码内容

节点如果没有实现上面那些方法,则会提示,点击黄色警示按钮显示未实现的方法的内容

运行则报错提示

如果我给 Player 加上这两个方法,则提示取消

以上是关于Godot在Godot中模仿实现接口功能的主要内容,如果未能解决你的问题,请参考以下文章

Godot在 Godot 中使用代理模式将一些通用的功能封装起来

Godot FunctionTree 功能树 简单使用教程

Godot FunctionTree 功能树 简单使用教程

Godot Shader笔记:着色器材质ShaderMaterial

Godot 2D 和 3D 游戏引擎

Godot 2D 和 3D 游戏引擎