我正在尝试在go中实现一个行为树,而我正在努力解决它的组合功能。基本上,我需要在下面实现Tick()
来调用嵌入它所定义的方法。
以下是behavior.go
:
type IBehavior interface {
Tick() Status
Update() Status
}
type Behavior struct {
Status Status
}
func (n *Behavior) Tick() Status {
fmt.Println("ticking!")
if n.Status != RUNNING { n.Initialize() }
status := n.Update()
if n.Status != RUNNING { n.Terminate(status) }
return status
}
func (n *Behavior) Update() Status {
fmt.Println("This update is being called")
return n.Status
}
这里是嵌入的Behavior
结构:
type IBehaviorTree interface {
IBehavior
}
type BehaviorTree struct {
Behavior
Root IBehavior
}
func (n *BehaviorTree) Update() Status {
fmt.Printf("Tree tick! %#v\n", n.Root)
return n.Root.Tick()
}
使这个例子更多的文件是有道理的:
type ILeaf interface {
IBehavior
}
type Leaf struct {
Behavior
}
这一个:
type Test struct {
Leaf
Status Status
}
func NewTest() *Test {
return &Test{}
}
func (n Test) Update() Status {
fmt.Println("Testing!")
return SUCCESS
}
以下是其用法示例:
tree := ai.NewBehaviorTree()
test := ai.NewTest()
tree.Root = test
tree.Tick()
我希望通过打印这个树正常打勾:
ticking!
Tree tick!
但相反,我得到了:
ticking!
This update is being called
有人可以帮我解决这个问题吗?
编辑:添加了一些额外的文件来说明问题。另外,我不理解downvotes。我有一个诚实的问题。我本来应该问一些对我有意义的问题吗?
答案 0 :(得分:2)
此处的问题是您的BehaviorTree结构未定义Tick()
。因此,当您致电tree.Tick()
时,没有定义直接方法,因此它会调用嵌入式Tick()
结构的提升Behavior
方法。那个Behavior
struct 不知道BehaviorTree
是什么!在Go的嵌入式伪继承风格中,“子”类型没有他们"父母的概念# 34;,也没有任何参考或访问它们。使用嵌入类型作为接收器调用嵌入式方法,而不是嵌入结构。
如果您需要预期的行为,则需要在Tick()
类型上定义BehaviorTree
方法,并使用该方法调用自己的Update()
方法(然后调用sub { {1}}或Tick()
方法(如果您愿意)。例如:
Update()
答案 1 :(得分:0)
正如Volker所说
Go绝对没有继承的概念(嵌入不是继承),你根本不能在Go中做父/子的东西。重新设计
据我所知,你想要的是一个使用接口多次执行相同任务的功能。
func Tick(n IBehavior) Status {
fmt.Println("ticking!")
if n.Status != RUNNING { n.Initialize() }
status := n.Update()
if n.Status != RUNNING { n.Terminate(status) }
return status
}
当然,Initialize必须在界面中。