跳至正文
版本:bleeding-edge 🩸

事件指南

关于事件你需要了解的一切。

类事件​

在 nanos world 中,玩家或实体执行的所有操作都可以通过事件来获取。

最基本的事件例子是 Spawn(生成)。每当实体生成时,都会触发 Spawn 事件。

订阅类事件​

使用 :Subscribe() 方法注册事件非常简单直接。例如,我们想在有玩家加入服务器时获得通知:

Server/Index.lua
Player.Subscribe("Spawn", function(player)
Console.Log(player:GetName() .. " has joined!")
end)
信息

Most events are triggered on both Client and Server sides, only a few exceptions which are indicated by the Availability icons in each event.

Preventing Actions​

Some events are triggered before something happens, and allow you to cancel it by returning false. They usually start with Attempt, such as AttemptEnterVehicle:

Server/Index.lua
-- Only allows Characters from team 1 to drive vehicles
Character.Subscribe("AttemptEnterVehicle", function(character, vehicle, seat_index)
if (seat_index == 0 and character:GetTeam() ~= 1) then
return false
end
end)

退订类事件​

Currently there are two ways of unsubscribing from events:

信息

注意: 退订事件将始终只会注销在你当前 Package 中注册的事件。

退订所有事件​

-- 这将注销在此 Package 中注册的所有 Player 的 "Spawn" 事件
Player.Unsubscribe("Spawn")

退订特定的事件回调​

-- 提前声明回调函数
function OnSpawnPlayer(player)
Console.Log(player:GetName() .. " has joined!")
end

-- 订阅事件并传入回调
Player.Subscribe("Spawn", OnSpawnPlayer)

-- 再次订阅同一个事件
Player.Subscribe("Spawn", function(player)
Console.Log(player:GetName() .. " has joined again!")
end)

-- 仅退订第一个回调
Player.Unsubscribe("Spawn", OnSpawnPlayer)

-- 这将继续触发 "player has joined again",但不再触发
-- "player has joined"
提示

Subscribe returns the callback you passed, so you can also unsubscribe anonymous functions later:

local my_callback = Player.Subscribe("Spawn", function(player) end)
Player.Unsubscribe("Spawn", my_callback)

实体事件​

在 nanos world 中,你也可以为特定实体注册事件。这样一来,只有当该特定实体成为事件触发原因时,才会触发回调。

订阅实体事件​

Server/Index.lua
-- Spawns a Character
local my_character = Character(Vector(0, 0, 100), Rotator(), "nanos-world::SK_Male")

my_character:Subscribe("EnterVehicle", function(self, vehicle)
-- my_character entered vehicle
end)
提示

请注意,一旦实体被销毁,为该实体注册的所有事件都会自动注销!

退订实体事件​

Currently there are two ways of unsubscribing from events:

信息

注意: 退订事件将始终只会注销在你当前 Package 中注册的事件。

退订所有实体事件​

-- 这将注销在此 Package 中注册的该特定 Character 的所有 "EnterVehicle" 事件
my_character:Unsubscribe("EnterVehicle")

退订特定实体事件回调​

-- 提前声明回调函数
function OnCharacterEnteredVehicle(character, vehicle)
-- 进入了载具!
end

-- 订阅事件并传入回调
my_character:Subscribe("EnterVehicle", OnCharacterEnteredVehicle)

-- 再次订阅同一个事件
my_character:Subscribe("EnterVehicle", function(character, vehicle)
-- 再次进入了载具!
end)

-- 仅退订第一个回调
my_character:Unsubscribe("EnterVehicle", OnCharacterEnteredVehicle)

自定义事件​

在 nanos world 中,可以定义和调用自定义事件。技术文档请参考 Events 静态类。

自定义事件是由用户创建的事件,你可以向所有其他 Package 订阅或调用这些事件。 There are two kinds of them:

Local Events​

Local events stay on the same side (server or client) and reach every Package on that side. Use Events.Call() to trigger them and Events.Subscribe() to listen:

Server/Index.lua
-- In any Package
Events.Subscribe("RoundStarted", function(round_number)
Console.Log("Round %d started!", round_number)
end)

-- In any other Package (or the same one)
Events.Call("RoundStarted", 1)

Remote Events​

Remote events travel through the network, from the client to the server or from the server to clients. Listen to them with Events.SubscribeRemote():

Server/Index.lua
-- On the server, the first parameter is always the Player who sent it
Events.SubscribeRemote("BuyItem", function(player, item_name)
Console.Log("%s wants to buy %s", player:GetName(), item_name)

-- Answers only to that Player
Events.CallRemote("ItemBought", player, Reliability.Reliable, item_name)
end)
Client/Index.lua
Events.SubscribeRemote("ItemBought", function(item_name)
Console.Log("I bought %s!", item_name)
end)

-- Sends it to the server
Events.CallRemote("BuyItem", Reliability.Reliable, "medkit")

The server can also send events to a list of Players with CallRemotePlayers, to everyone with BroadcastRemote, or only to Players in a radius or dimension with BroadcastRemoteInRadius and BroadcastRemoteDimension.

A few important things to keep in mind:

  • Reliability: Reliability.Reliable guarantees the event arrives, in order. Reliability.Unreliable is cheaper but can be lost, use it for events sent very often (e.g. every Tick) where only the latest one matters.
  • Entities can be passed as parameters, they arrive as the same entity on the other side (as long as it exists there).
  • Local and remote are separate: Events.Subscribe doesn't receive remote events and Events.SubscribeRemote doesn't receive local ones.
  • Never trust the client: a player can send any remote event with any parameters, always validate them on the server. See the Never Trust the Client guide.
提示

Entities also have their own remote events, which are triggered on a specific entity. See :CallRemoteEvent() and :BroadcastRemoteEvent().