使用 FunctionTree 快速开发角色功能
在 test 文件夹中有个 test01 示例,可进入参考查看
添加一个 KinematicBody2D
节点,选中点击添加节点,搜索 FunctionRoot
点击添加。添加后选中 FunctionRoot
,右侧将会出现一列可添加的节点列表,双击添加 Blackboard(已更改为 Reference
类型,下方请忽略这个节点)、Standard
、Custom
节点,如下图所示
场景根节点更名为 Player
,创建一个 player 文件夹,保存场景到里面。
选中 Standard
节点,添加 Actions
节点,然后选中 Actions
节点,双击添加右侧节点列表中的 Move
节点
选中 Custom
节点,添加 Controllers
节点,然后选中 Controllers
节点,双击添加 CustomFunction
节点
双击场景树中的 CustomFunction
节点,重命名为 CMove
,意为 Control Move(控制移动),然后在编辑器最右侧检查器面板中给这个脚本扩展一下
在代码编辑视图中按下 Ctrl + Alt + Shift + S
,或者点击代码编辑上的代码菜单(这个是我自己的一个脚本插件添加上的,默认没有这个),如下图,然后弹出重写函数弹窗,勾选 _process_input
方法,点击 OK 按钮
生成如下代码:
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 小图标拖拽到场景中
还差一点,给场景根节点 Player 添加一个脚本,并写入如下代码
extends KinematicBody2D
export var move_speed : int = 300
onready var root = $FunctionRoot
func _ready():
# 设置移动速度
root.get_property().move_speed = move_speed
让我们按下 F6 ,进行运行当前场景,按下小键盘进行移动
选中场景树中的 Actions
节点,双击添加 TurnTo
节点,选中 Controllers
节点,双击右侧 CustomFunction
添加节点,并重命名为 CTurnTo
,选中这个 CTurnTo
节点,在编辑器最右侧检查器面板中进行扩展脚本
在代码编辑视图中按下 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 运行当前场景,按小键盘让角色移动到场景中,鼠标移动一下查看是否进行了旋转
选中 Standard
节点,添加 Skills
节点,然后选中 Skills
节点,双击添加右侧节点列表中的 Sprint
节点,选中 Sprint
节点,修改 duration
属性持续时间设为 0.5
秒
添加键位映射,添加鼠标的映射,添加 click
,
设置为鼠标左键点击
Godot 的 Input 类获取 click
事件,就代表要获取鼠标点击的事件,点击 关闭
按钮
选中场景树中的 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 运行当前场景,点击鼠标,看看节点是否进行了冲刺
跟上面创建角色相同,创建如下节点(只要选中节点的父节点,场景树旁的面板会显示出其可选子节点),先 Ctrl + A
选中 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 图像大小。
场景节点如下:
现在给 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
添加一个 CollisionShape2D
,CollisionShape2D
设置一个 RectangleShape2D
,调整其大小
然后按 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 下的节点的功能。如此进行分类。如下流程图所示
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
功能树根节点 _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 下的节点的功能。
每个 Layer 都是一个功能类别的分类,Actions 是动作层,Skills 是技能层等等,每个层下面都是一个具体功能的节点。使用 register_layer
方法注册层节点到全局数据中
执行具体的功能逻辑,调用这个节点的 control
方法进行使用这个节点的功能。使用 register_function
方法注册层节点到全局数据中。
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。