事件系统介绍
Nibiru Studio的事件系统提供了一系列类,用于在不同对象间传递事件消息。
NEventSystem
NEventSystem是Nibiru Studio的事件系统统一分发入口。我们在使用事件系统时需要将需要进行事件派发的类继承UserEventListener以获得事件监听功能,然后在初始化组件类时需要获取事件调度器并将类注册到事件调度器中,在需要发送事件时调用事件发送接口即可。
| 接口名称 | 返回值 | 接口含义 |
|---|---|---|
| NEventDispatcherPtr GetEventDispatcher(); | void | 获取事件分发器 |
| SendEvent(Event* evt); | void | 发送事件 |
| AddListener(EventListener* listener); | void | 添加事件监听 |
继承监听器后,我们可以给事件赋值,并添加上监听器,类似如下代码所示:
cpp
class temp_API temp : public NComponent, UserEventListenercpp
void temp::Start()
{
OnUserEvent = [](const UserEvent& evt) {
NDebug::Log("has done"); return true;
};
auto Dispatcher = NEventSystem::GetEventDispatcher();
Dispatcher->AddEventListener(this);
}
void temp::Update()
{
NEventSystem::SendEvent(new UserEvent());
}NEventDispatcher
| 接口名称 | 返回值 | 接口含义 |
|---|---|---|
| AddEventListener(EventListener* listener); | void | 添加事件监听器 |
| RemoveEventListener(EventListener* listener); | void | 移除事件监听器 |
| RemoveEventListenerImmediately(EventListener* listener); | void | 立即移除事件监听器 |
| DispatchEvent(Event* event); | void | 发送事件 |
自定义事件UserEvent
Nibiru Studio的事件系统支持各种类型的事件,并可在开发者编写的自定义输入模块中进一步自定义它们。 Standalone平台输入模块和触摸输入模块支持的事件由接口提供,通过实现该接口即可在 Component上实现这些事件。如果配置了有效的事件系统,则会在正确的时机调用事件。下面以鼠标左键按在名为cube的模型上时,将模型名为cone的模型像X移动10个单位作为示例:
Cube模型添加cube组件脚本
cpp
void cube::Update()
{
// Called every frame if actor is enabled.
//监控鼠标左键是否按下
if (NInput::GetMouseButtonDown(MouseButton::Left))
{
Ray ray = NCamera::GetCurrent()->GetScreenToWorldRay(NInput::GetMousePosition());
SceneQueryResult queryResult;
if (NPhysics::RayCastQuery(ray, queryResult))
{
//取出射线方向上的第一个结果
auto hit = queryResult.entries[0];
//若模型名为Cube
if ("Cube" == hit.actor->GetName())
{
UserEvent* userEvent = UserEvent::NewInstance();
userEvent->SetIntValue(1);
userEvent->SetStringValue("Number");
userEvent->sender = this;
NEventSystem::SendEvent(userEvent);
}
}
}
}Cone模型添加cone组件脚本
cpp
//类需要继承用户自定义的UserEventListener
class Cone_API Cone: public NComponent, UserEventListener
{
//忽略其他组件模版
//声明一个回调函数,以及两个成员变量
public:
//变量与返回值固定不可修改,函数名可以修改
bool OnUserEventCallBack(const UserEvent& evt);
private:
bool m_ReceivedEvent = false;
//因为回调的变量为const,若要使用事件的非const函数,必须传给一个非const对象
UserEvent m_ReceiverEvent;
}cpp
//类需要继承用户自定义的UserEventListener
void Cone::Awake()
{
// Called when the scene loads the object or when the script is added to the object, the actor is activated for the first time
//回调函数指针赋值
OnUserEvent = [this](const UserEvent& evt) { return OnUserEventCallBack(evt); };
//添加监听事件
NEventSystem::AddListener(dynamic_cast<UserEventListener*>(this));
}
void Cone::Update()
{
// Called every frame if actor is enabled.
if (m_ReceivedEvent)
{
//获取传递的值
//int num = m_ReceiverEvent.GetIntValue();
//std::string name = m_ReceiverEvent.GetStringValue();
NActorPtr act = NActorManager::GetActor("Cone");
if (act)
{
NTransformComponentPtr transCom = act->GetComponent<NTransformComponent>();
if (transCom)
{
Vector3 vec = transCom->GetLocalPosition();
vec += Vector3(10.f, 0.f, 0.f);
transCom->SetLocalPosition(vec);
}
}
m_ReceivedEvent = false;
}
}
void Cone::OnDestroy()
{
// When the component deleted
//需要移除监听
NEventSystem::GetEventDispatcher()->RemoveEventListenerImmediately(dynamic_cast<UserEventListener*>(this));
}
bool Cone::OnUserEventCallBack(const UserEvent& evt)
{
m_ReceivedEvent = true;
m_ReceiverEvent = evt;
return true;
}
