Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The "abort_tree " signal may have the wrong target object #21

Closed
MadFlyFish opened this issue Apr 28, 2021 · 7 comments
Closed

The "abort_tree " signal may have the wrong target object #21

MadFlyFish opened this issue Apr 28, 2021 · 7 comments

Comments

@MadFlyFish
Copy link

MadFlyFish commented Apr 28, 2021

As you can see in the screenshot bellow, what you want to abort may be the "BehaviorTree" node, but actually in my case it can raise an error, because the real "owner" is "ai_test" node and it doesn't have any "abort( )" function. :)

image
image

@kagenash1
Copy link
Owner

It would be best if you create the behavior tree as a separate scene, that way it will have the correct target object.
But anyway I will find a way around this so they can be created locally as well, thank you for reporting!

@MadFlyFish
Copy link
Author

Yep, actually I am creating the behavior tree as a separate scene, but the root node isn't the BehaviorTree node.
in my case , using owner.get_node("BehaviorTree") as the target object would solve this problem. : )

@kagenash1
Copy link
Owner

If the Behavior Tree is a separate scene, then the owner WILL be the root node.

@MadFlyFish
Copy link
Author

I create the behavior tree scene by Xmind2Json, which uses recursion in the main processing function and as a result the root node isn't the BehaviorTree node... LOL
Maybe I should refactor it

class_name BtreeHandler
extends Reference

管理ai相关的处理,如从json生成行为树

var json_files_path:String = "res://resource/data/ai/" # ai json 目录
var config_ai_path:String = "res://addons/behavior_tree/src/" # ai节点类目录
var data_ai:Dictionary # ai配置
var root:Node # 根节点

func _init():
data_ai = load("res://resource/data/config/config.gd").new().config_ai.data_ai # 因为这是在tool模式下,所以autoload是无法访问到的。

生成行为树PackedScene至特定目录

func create_tree_scene():
var file_handler = FileHandler.new() # 复用文件管理类
var files = file_handler.show_files("res://resource/data/ai") # 返回路径下的全部文件绝对路径(不包含文件夹)

for file in files:
	if ".json" in file and not ".import" in file: # 筛选json文件
		var file_name = file.split("/")[file.split("/").size() - 1] # 获取json文件命,包括后缀
		var node = Node.new() # 生成根节点
		node.name = file_name.split(".")[0].capitalize().replace(" ", "") # 命名为json的同名节点,去掉.json后缀,并且转换为Pacal模式
		creat_tree_nodes(file_name, node) # 对根节点生成完整的行为树

		var packed_scene = PackedScene.new() # 创建PackedScene对象
		packed_scene.pack(node) # 打包至PackedScene
		ResourceSaver.save("res://resource/btree/" + file_name.split(".")[0] + ".tscn", packed_scene) # 保存为本地文件
		print("保存成功:" + file_name.split(".")[0] + ".tscn")

生成行为树和黑板

func creat_tree_nodes(json_file_name:String, mount:Node):
# 生成黑板
var black_board = Blackboard.new()
black_board.name = "BlackBoard"
mount.add_child(black_board)
root = mount
black_board.owner = root

# 根据json和目标挂载点生成行为树
var json_file = File.new() # 新建文件类
json_file.open(json_files_path + json_file_name, File.READ) # 读取json文件
var json_string = json_file.get_as_text() # json转换为字符串
var json_result = JSON.parse(json_string) # 解析json字符串,转换为列表或者字典,此处是列表
var dict_result = json_result.result[0]["topic"] # 取得要处理的字典,等同于json_result.result[0].topic
creat_tree_by_dict(dict_result, mount)

根据json转成的dict和挂载点生成行为树(递归部分)

func creat_tree_by_dict(result:Dictionary, mount:Node):
var class_info_list:Array = result["title"].split("\n") # 用换行符切割字符串,返回列表
if result.has("note"): # 把笔记部分也考虑进来
class_info_list.append_array(result["note"].split("\n"))

var class_id:String = class_info_list[0] # 类名key
var script_path:String = config_ai_path + data_ai[class_id]["folder"] + data_ai[class_id]["script_name"]
var node = load(script_path).new() # 生成节点
mount.add_child(node) # 挂载节点
node.owner = root # 设置owner,否则保存为packScene将无法包含子节点
node.name = class_id # 命名节点

var class_member_list:Array = class_info_list.slice(1,class_info_list.size())
for member in class_member_list:
	var member_list:Array = member.split("=") # 储存成员-值对
	node.set(member_list[0], member_list[1]) # 为树节点成员赋值
# 递归处理
if result.has("topics"):
	for i in result["topics"]:
		creat_tree_by_dict(i, node)

@kagenash1
Copy link
Owner

kagenash1 commented Apr 28, 2021

Oh ok. That's because nodes added at runtime do not have a owner unless set explicitly.
But don't worry, I already found a very simple solution and I will push the fix soon. :

@kagenash1
Copy link
Owner

Fixed by #22

@MadFlyFish
Copy link
Author

Oh ok. That's because nodes added at runtime do not have a owner unless set explicitly.
But don't worry, I already found a very simple solution and I will push the fix soon. :

Brilliant solution ^_^

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants