1 Star 4 Fork 2

Apprentice / FunctionTree

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README
MIT

Godot 功能树

项目地址:Apprentice/FunctionTree (gitee.com)

使用 FunctionTree 快速开发角色功能

示例教程

在 test 文件夹中有个 test01 示例,可进入参考查看

添加基本节点

添加一个 KinematicBody2D 节点,选中点击image-20211218102323185添加节点,搜索 FunctionRoot 点击添加。添加后选中 FunctionRoot ,右侧将会出现一列可添加的节点列表,双击添加 Blackboard(已更改为 Reference 类型,下方请忽略这个节点)、StandardCustom 节点,如下图所示

image-20211217154403609image-20211217154627633

场景根节点更名为 Player,创建一个 player 文件夹,保存场景到里面。

image-20211217155013008

添加移动功能

选中 Standard 节点,添加 Actions 节点,然后选中 Actions 节点,双击添加右侧节点列表中的 Move 节点

image-20211217155152539image-20211217155323059

选中 Custom 节点,添加 Controllers 节点,然后选中 Controllers 节点,双击添加 CustomFunction 节点

image-20211217160027116image-20211217155947332

双击场景树中的 CustomFunction 节点,重命名为 CMove,意为 Control Move(控制移动),然后在编辑器最右侧检查器面板中给这个脚本扩展一下

image-20211217160240822image-20211217160312606image-20211217160434998

在代码编辑视图中按下 Ctrl + Alt + Shift + S ,或者点击代码编辑上的代码菜单(这个是我自己的一个脚本插件添加上的,默认没有这个),如下图,然后弹出重写函数弹窗,勾选 _process_input 方法,点击 OK 按钮

image-20211217160556680image-20211217160706498

生成如下代码:

image-20211217160813976
extends "res://addons/function_tree/src/custom/CustomFunction.gd"


#(override)
func _process_input(arg0):
	._process_input(arg0)
	pass

重写 _process_input ,获取用户输入,根据玩家按下的键盘控制节点移动

extends "res://addons/function_tree/src/custom/CustomFunction.gd"


#(override)
func _process_input(arg0):
    # 获取用户输入(下面四个是小键盘上的按键,按下进行控制)(这个是Godot3.4中的方法)
	var dir = Input.get_vector("ui_left","ui_right","ui_up","ui_down")
    # 获取 Move 功能节点,操控其移动
	get_function("Move").control(dir)

我们将文件系统中 icon.png ,Godot 小图标拖拽到场景中

image-20211217161419330

还差一点,给场景根节点 Player 添加一个脚本,并写入如下代码

extends KinematicBody2D


export var move_speed : int = 300


onready var root = $FunctionRoot


func _ready():
	# 设置移动速度
	root.get_property().move_speed = move_speed

让我们按下 F6 ,进行运行当前场景,按下小键盘进行移动

image-20211217161926811

添加旋转功能

选中场景树中的 Actions 节点,双击添加 TurnTo 节点,选中 Controllers 节点,双击右侧 CustomFunction 添加节点,并重命名为 CTurnTo,选中这个 CTurnTo 节点,在编辑器最右侧检查器面板中进行扩展脚本

image-20211217162054356image-20211217163151935image-20211217163248410

在代码编辑视图中按下 Ctrl + Alt + Shift + S ,或者点击代码编辑上的代码菜单,弹出窗口中勾选 _process_input ,点击 OK,写入控制旋转代码,让节点随着鼠标位置进行旋转,脚本代码如下

extends "res://addons/function_tree/src/custom/CustomFunction.gd"


#(override)
func _process_input(arg0):
	# 获取鼠标的全局位置
	var mouse_pos = (host as Node2D).get_global_mouse_position()
	# 旋转到鼠标位置
	get_function("TurnTo").control(mouse_pos)

按下 F6 运行当前场景,按小键盘让角色移动到场景中,鼠标移动一下查看是否进行了旋转

image-20211217164019273

添加技能

选中 Standard 节点,添加 Skills 节点,然后选中 Skills 节点,双击添加右侧节点列表中的 Sprint 节点,选中 Sprint 节点,修改 duration 属性持续时间设为 0.5

image-20211217164259530image-20211217164420223

添加键位映射,添加鼠标的映射,添加 click

image-20211217164828831image-20211217164924667

设置为鼠标左键点击

image-20211217165219027

Godot 的 Input 类获取 click 事件,就代表要获取鼠标点击的事件,点击 关闭 按钮

image-20211217165233744image-20211217165247386

选中场景树中的 Controllers 节点,双击右侧 CustomFunction 添加节点,并重命名为 CSprint,选中这个 CSprint 节点,在编辑器最右侧检查器面板中进行扩展脚本,重写 _process_input 方法,控制 Sprint 技能的使用 ,脚本代码如下

extends "res://addons/function_tree/src/custom/CustomFunction.gd"


#(override)
func _process_input(arg0):
	if Input.is_action_pressed("click"):
		# 获取鼠标的全局位置
		var mouse_pos = (host as Node2D).get_global_mouse_position()
		# 操作 Sprint 方法,冲刺到鼠标位置
		get_function("Sprint").control(mouse_pos)

按下 F6 运行当前场景,点击鼠标,看看节点是否进行了冲刺img


横版游戏角色教程

跟上面创建角色相同,创建如下节点(只要选中节点的父节点,场景树旁的面板会显示出其可选子节点),先 Ctrl + A

  • FunctionRoot
    • Blackboard
    • Standard
      • Actions
        • PlatformMove(平台游戏移动)
        • Gravity(重力)
        • Jump(跳跃)
    • Custom
      • Controllers

选中 Controllers 节点,双击添加 CustomFunction,重命名为 CMove,并扩展脚本,脚本代码如下:

extends "res://addons/function_tree/src/custom/CustomFunction.gd"


#(override)
func _process_input(arg0):
	var d = Input.get_action_strength("ui_right") - Input.get_action_strength("ui_left")
	if d:
		get_function("Move").control(Vector2(d, 0))

然后选中场景根节点,添加 CollisionShape2D 节点,再将 icon.png 图标拖拽到场景中,给 CollisionShape2D 节点添加一个 RectangleShape2D 碰撞形状,设置成添加的 icon 图像大小。

场景节点如下:

image-20211217201319275

现在给 Player 节点添加脚本,脚本代码如下

extends KinematicBody2D


export var move_speed : int = 300
export (float, 0, 1.0) var gravity : float = 0.7
export var max_gravity : int = 2000
export var jump_height : int = 700


onready var root = $FunctionRoot


func _ready():
	root.property.move_speed = move_speed
	root.property.gravity = gravity
	root.property.max_gravity = max_gravity
	root.property.jump_height = jump_height

可以将角色移动到场景中间,现在按下 F6 运行当前场景,就可以看到角色一直下坠

再在上面添加一个 StaticBody2D ,给 StaticBody2D 添加一个 CollisionShape2DCollisionShape2D 设置一个 RectangleShape2D,调整其大小

image-20211217202117987

然后按 F6 运行当前场景,按下小键盘左右键,可以进行左右移动

现在给他添加跳跃控制,点击 Controllers 节点,场景树节点右侧面板双击添加一个 CustomFunction 节点,重命名为 CJump,并扩展脚本,脚本代码如下:

extends "res://addons/function_tree/src/custom/CustomFunction.gd"


#(override)
func _process_input(arg0):
	if (Input.is_action_pressed("ui_up")
		&& host.is_on_floor()
	):
		get_function("Jump").control()

最基本的横版游戏角色的功能就做出来了,其中还有爬墙,多级跳跃等功能,快上手试试吧 ;)


经过这个简单的教程之后,不知你对这个插件是否有了兴趣?现在我将介绍一下这个插件的一个制作思路。分为 Standard 类的节点和 Custom 类的节点。将通用功能放在 Standard 类下的节点,将各种各样的逻辑和操作写在 Custom 类的节点下,在 Custom 下的节点中调用 Standard 下的节点的功能。如此进行分类。如下流程图所示

graph TD
Root(根节点)-->Standard(标准节点)
Root(根节点)-->Custom(自定义节点)
Standard-->Layer1(标准节点层1)
Standard-->Layer...(标准节点层...)

Custom-->CustomLayer(自定义节点层...)

Layer1-->Function1(标准功能子节点...)
Layer1-->Function2(标准功能子节点...)

CustomLayer-->CustomFunction(自定义功能子节点...)
CustomLayer-->CustomFunction1(自定义功能子节点...)

插件介绍

方法和属性

blackboard 属性或 get_blackboard() 方法获取黑板,黑板中记录有整个功能树的全局数据

property 属性或 get_property() 方法获取全局属性

enabled 属性或 get_enabled() 方法获取全局功能可用性属性

注册为功能节点:register_function(名称),注册后可使用 get_function 方法进行获取这个节点

获取功能层节点:get_layer(注册的功能节点名)

获取功能节点:get_function(注册的功能节点名)

执行功能节点的功能:get_function(注册的功能节点名).control(传入的数据)

节点

不要动态的增减节点,因为场景运行后 FunctionRoot 根节点会扫描一遍子节点并记录,子节点也会注册到数据中,增减节点会出现问题。

有两个类别节点:Standard、Custom。 Standard 下的节点是标准节点,不进行扩展脚本,只修改属性连接信号,Custom 下的节点是自定义节点,必须要进行扩展脚本才有功能。这两个类别节点下是各个功能层节点,用以对功能进行划分。

FunctionRoot

FunctionRoot 功能树根节点 _ready() 时会先遍历得到所有子功能节点,然后给这些节点设置基本属性,调用节点的初始化方法,执行步骤如下

  • _init_data > _init_node > _init_finished

子节点的 _process_physics_process 都是 false,不会执行,需要重写 _process_input_process_execute_process_finish 方法进行使用,执行顺序为

  • _process_input > _process_execute > _process_finish
  • _process_input 先接收用户输入
  • _process_execute 进行执行所有功能
  • _process_finish 对执行完成后进行一些处理

Standard 与 Custom 下的节点的区别

Standard 类下方的子节点尽量都不要重写(如果你了解这个节点的执行逻辑的话,也可以扩展脚本,但不建议这样做)

Custom 类下方的子节点都要进行重写才能使用其功能,否则其只有逻辑,没有功能没有效果

Standard 下的节点提供功能,节点只进行属性的设置,增加功能节点;在 Custom 下的节点中进行扩展脚本调用 Standard 下的节点的功能。

Layer 节点

每个 Layer 都是一个功能类别的分类,Actions 是动作层,Skills 是技能层等等,每个层下面都是一个具体功能的节点。使用 register_layer 方法注册层节点到全局数据中

Function 节点

执行具体的功能逻辑,调用这个节点的 control 方法进行使用这个节点的功能。使用 register_function 方法注册层节点到全局数据中。

MIT License Copyright (c) 2021 Apprentice Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

简介

Godot 的行为功能相关插件 展开 收起
其他
MIT
取消

发行版

暂无发行版

贡献者

全部

近期动态

加载更多
不能加载更多了
其他
1
https://gitee.com/LaoDie1/function-tree.git
git@gitee.com:LaoDie1/function-tree.git
LaoDie1
function-tree
FunctionTree
master

搜索帮助