其实最后我发现这是自己一个比较粗心的问题造成的。还是老套路,我先贴代码,描述问题:
//从XML加载UI
UIElement@ layoutRoot = ui.LoadLayout(cache.GetResource("XMLFile", "UI/SelectCharacterUI.xml"));
//获取UI中的Button对象
Button@ createRoleButton = layoutRoot.GetChild("CreateRoleButton");
//挂载对象:Button的Released事件
SubscribeToEvent(createRoleButton, "Released", "HandleCreateRoleReleased");
void HandleCreateRoleReleased(StringHash eventType, VariantMap& eventData)
{
Print("I'm coming");
}
很明显,我就是想点击一个button,执行一个语句而已。然后点击后没有反应,事件未触发。
然后,请看我的UI结构:
我的button在第三层。
我发现当把第二层window去掉后就好了。
我也不绕圈子了,请把
Button@ createRoleButton = layoutRoot.GetChild("CreateRoleButton");
改成:
Button@ createRoleButton = layoutRoot.GetChild("CreateRoleButton", true);
然后管你Button在第几层,都么有问题了。至于原因,我们看下GetChild的定义与源码:
Node* Node::GetChild(StringHash nameHash, bool recursive) const
{
for (Vector<SharedPtr<Node> >::ConstIterator i = children_.Begin(); i != children_.End(); ++i)
{
if ((*i)->GetNameHash() == nameHash)
return *i;
if (recursive)
{
Node* node = (*i)->GetChild(nameHash, true);
if (node)
return node;
}
}
return 0;
}
那个bool参数就是递归的意思了,也就是说我没有填写这个参数时,默认的是false,也就是说,我的getchild只是查找了第一层window下的UI,当然没有找到我的BUTTON了,所以就是空的,挂载事件当然失败了。
哎,没脸见人了,我应该一开始就注意这个参数的。曾经看到过这个参数,忽略了。
相关话题:其实我们也可以在挂载事件时不填写第一个参数:sender,那么也就不需要用getchild把那个BUTTON找出来了。也就是说直接用
SubscribeToEvent("Released", "HandleCreateRoleReleased");
只不过我们在事件中做下判断就好了:
void HandleCreateRoleReleased(StringHash eventType, VariantMap& eventData)
{
UIElement@ button = eventData["Element"].GetPtr();
if(button.name == "CreateRoleButton")
{
Print("I'm coming");
}
}