Files
netease-modsdk-wiki/docs/mconline/15-玩法组件教程/10-模组SDK初步/4-监听事件并创建组件逻辑.md
boybook 760c2dd9ad 2.6
2025-12-01 20:59:16 +08:00

123 lines
4.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
front: https://nie.res.netease.com/r/pic/20211104/69055361-2e7a-452f-8b1a-f23e1262a03a.jpg
hard: 进阶
time: 20分钟
---
# 监听事件并创建组件逻辑
现在我们已经创建好了一个服务端系统,我们来尝试向这个系统中添加逻辑。
在添加逻辑之前我们需要手动将系统在主模组文件中注册。我们仿照之前看到的示例将额外API的`RegisterSystem`函数写在`@Mod.InitServer()`装饰器下的方法中。
```python
@Mod.InitServer()
def DemoTutorialModServerInit(self):
serverApi.RegisterSystem("DemoTutorialMod", "Server", "Script_DemoTutorialMod.DemoTutorialServerSystem.DemoTutorialServerSystem")
```
## 监听实体受伤事件
我们回到服务端系统文件`DemoTutorialServerSystem.py`中。我们一起尝试做一个简单的事件监听,比如,监听实体(活动对象)收到伤害的事件。
通过查阅API文档我们得到了控制实体受到伤害的事件`ActorHurtServerEvent`,其字面意思为“活动对象受伤服务端事件”。我们通过该系统本身的`ListenForEvent`方法来注册这个事件监听。我们在`__init__`方法的末尾加入我们的监听注册函数,同时在该类中定义一个新的方法,比如名为`OnActorHurtServer`,将该方法作为回调函数绑定到事件上。
```python
def __init__(self, namespace, systemName):
ServerSystem.__init__(self, namespace, systemName)
self.ListenForEvent(serverApi.GetEngineNamespace(), serverApi.GetEngineSystemName(), "ActorHurtServerEvent", self, self.OnActorHurtServer)
```
这样,我们便完成了实体受伤的监听。当实体受到伤害时,`DemoTutorialServerSystem`实例的`OnActorHurtServer`方法将会运行。
## 在事件内触发击退逻辑
我们希望不仅仅是监听该事件,更要在事件发生时执行一些逻辑,比如更改受击实体的击退属性。
我们通过查阅API文档得知`action`组件(`mod.server.component.actionCompServer`)具备更改击退逻辑的方法`SetMobKnockback`。所以我们使用引擎组件工厂创建一个`action`引擎组件,然后调用它的设置击退的方法做到一些逻辑,比如我们想增加击退的威力。我们在`OnActorHurtServer`中写入如下内容。
```python
def OnActorHurtServer(self, args):
comp = serverApi.GetEngineCompFactory().CreateAction(args["entityId"])
comp.SetMobKnockback(0.1, 0.1, 10.0, 1.0, 1.0)
```
![](./images/11.4_set_knockback.png)
这样,我们便成功更改了击退的威力。我们将完整的修改过的代码展示在此处。首先是`modMain.py`
```python
# -*- coding: utf-8 -*-
from mod.common.mod import Mod
import mod.server.extraServerApi as serverApi
import mod.client.extraClientApi as clientApi
@Mod.Binding(name="DemoTutorialMod", version="0.0.1")
class DemoTutorialMod(object):
def __init__(self):
@Mod.InitServer()
def DemoTutorialModServerInit(self):
serverApi.RegisterSystem("DemoTutorialMod", "Server", "Script_DemoTutorialMod.DemoTutorialServerSystem.DemoTutorialServerSystem")
@Mod.DestroyServer()
def DemoTutorialModServerDestroy(self):
pass
@Mod.InitClient()
def DemoTutorialModClientInit(self):
pass
@Mod.DestroyClient()
def DemoTutorialModClientDestroy(self):
pass
```
然后是`DemoTutorialServerSystem.py`
```python
# -*- coding: utf-8 -*-
import mod.server.extraServerApi as serverApi
ServerSystem = serverApi.GetServerSystemCls()
class DemoTutorialServerSystem(ServerSystem):
def __init__(self, namespace, systemName):
ServerSystem.__init__(self, namespace, systemName)
self.ListenForEvent(serverApi.GetEngineNamespace(), serverApi.GetEngineSystemName(), "ActorHurtServerEvent", self, self.OnActorHurtServer)
def OnActorHurtServer(self, args):
comp = serverApi.GetEngineCompFactory().CreateAction(args["entityId"])
comp.SetMobKnockback(0.1, 0.1, 10.0, 1.0, 1.0)
# ScriptTickServerEvent的回调函数会在引擎tick的时候调用1秒30帧被调用30次
def OnTickServer(self):
"""
Driven by event, One tick way
"""
pass
# 这个Update函数是基类的方法同样会在引擎tick的时候被调用1秒30帧被调用30次
def Update(self):
"""
Driven by system manager, Two tick way
"""
pass
def Destroy(self):
self.UnListenForEvent(serverApi.GetEngineNamespace(), serverApi.GetEngineSystemName(), "ActorHurtServerEvent", self, self.OnActorHurtServer)
```
![](./images/11.4_in-game.gif)
进入游戏测试,便可以发现`SetMobKnockback`更改击退属性“诚不我欺”。