example
example

教程 FiveM 小白从零开发教程 02:认识各种事件(服务端事件,客户端事件,回调,cb,以及客户端与服务端传值,以及回调的用法)

FiveM 小白从零开发教程 02:认识各种事件(服务端事件,客户端事件,回调,cb,以及客户端与服务端传值,以及回调的用法)

欢迎回到 FiveM 开发教程系列的第二篇。在上一节中,我们了解了基本的开发环境设置。这一节中,我们将深入探讨 FiveM 中的各种事件机制,包括服务端事件、客户端事件、回调函数(callback)、`cb` 的用法,以及如何在客户端和服务端之间传递数据。

目录

1. 什么是事件?
2. 服务端事件
3. 客户端事件
4. 客户端与服务端之间的数据传递
5. 回调函数的用法
6. 实战示例
7. 总结

[a name=section1][/a]
1. 什么是事件?

在编程中,**事件**是指在程序运行过程中发生的动作或情况,可以由用户操作、系统行为或其他外部因素触发。在 FiveM 中,事件机制用于在客户端和服务端之间传递信息和触发动作。

为什么使用事件?

- 解耦:事件机制使代码更加模块化,客户端和服务端可以各自处理自己的逻辑。
- 异步通信:允许在不同的环境中异步地传递信息,而不需要立即得到响应。
- 可扩展性:通过事件,可以方便地添加新的功能,而不影响现有的代码结构。

[a name=section2][/a]
2. 服务端事件

2.1 注册服务端事件

在服务器脚本(通常是 server.lua)中,可以使用
代码:
RegisterNetEvent
来注册一个服务端事件。

lua:
RegisterNetEvent('myServerEvent')
AddEventHandler('myServerEvent', function(data)
    print('Received data from client: ' .. data)
    -- 在这里处理接收到的数据
end)

2.2 触发服务端事件

服务端事件通常由客户端触发,使用
代码:
TriggerServerEvent
函数。

客户端脚本(client.lua):

lua:
TriggerServerEvent('myServerEvent', 'Hello Server!')

[a name=section3][/a]
3. 客户端事件

3.1 注册客户端事件

在客户端脚本中,使用
代码:
RegisterNetEvent
来注册客户端事件。

lua:
RegisterNetEvent('myClientEvent')
AddEventHandler('myClientEvent', function(data)
    print('Received data from server: ' .. data)
    -- 在这里处理接收到的数据
end)

3.2 触发客户端事件

客户端事件通常由服务端触发,使用
代码:
TriggerClientEvent
函数。

服务器脚本(server.lua):

lua:
-- 触发特定玩家的客户端事件
TriggerClientEvent('myClientEvent', source, 'Hello Client!')

注:
代码:
source
变量代表触发该服务端事件的玩家的玩家 ID。

[a name=section4][/a]
4. 客户端与服务端之间的数据传递

通过事件,我们可以在客户端和服务端之间传递数据。数据可以是字符串、数字、表格(Lua 的 table),甚至是复杂的嵌套数据结构。

4.1 从客户端发送数据到服务端

客户端脚本:

lua:
local playerData = {
    name = 'PlayerOne',
    score = 100
}
TriggerServerEvent('playerDataEvent', playerData)

服务器脚本:

lua:
RegisterNetEvent('playerDataEvent')
AddEventHandler('playerDataEvent', function(data)
    print('Player Name: ' .. data.name)
    print('Player Score: ' .. data.score)
end)

4.2 从服务端发送数据到客户端

服务器脚本:

lua:
local serverData = {
    message = 'Welcome to the server!',
    time = os.time()
}
TriggerClientEvent('serverDataEvent', source, serverData)

客户端脚本:

lua:
RegisterNetEvent('serverDataEvent')
AddEventHandler('serverDataEvent', function(data)
    print('Server Message: ' .. data.message)
    print('Server Time: ' .. data.time)
end)

[a name=section5][/a]
5. 回调函数的用法

回调函数(Callback)是一种通过函数参数传递的函数,当某个操作完成后调用。在 FiveM 中,虽然没有直接的原生回调机制,但我们可以通过事件系统模拟回调,实现客户端和服务端之间的同步通信。

5.1 自定义回调机制

我们可以在客户端和服务端之间建立一个自定义的回调系统。下面是一个简单的实现。

服务器脚本(server.lua):

lua:
local Callbacks = {}

RegisterNetEvent('server:callback')
AddEventHandler('server:callback', function(name, requestId, ...)
    local src = source
    if Callbacks[name] then
        Callbacks[name](src, function(...)
            TriggerClientEvent('client:callbackResponse', src, requestId, ...)
        end, ...)
    else
        print('Callback "' .. name .. '" does not exist.')
    end
end)

function RegisterServerCallback(name, cb)
    Callbacks[name] = cb
end

-- 注册一个回调函数
RegisterServerCallback('getPlayerIdentifiers', function(source, cb)
    local identifiers = GetPlayerIdentifiers(source)
    cb(identifiers)
end)

客户端脚本(client.lua):

lua:
local Callbacks = {}
local CurrentRequestId = 0

function TriggerServerCallback(name, cb, ...)
    CurrentRequestId = CurrentRequestId + 1
    Callbacks[CurrentRequestId] = cb
    TriggerServerEvent('server:callback', name, CurrentRequestId, ...)
end

RegisterNetEvent('client:callbackResponse')
AddEventHandler('client:callbackResponse', function(requestId, ...)
    if Callbacks[requestId] then
        Callbacks[requestId](...)
        Callbacks[requestId] = nil
    end
end)

-- 使用回调函数
TriggerServerCallback('getPlayerIdentifiers', function(identifiers)
    print('Your Identifiers:')
    for _, id in ipairs(identifiers) do
        print(id)
    end
end)

5.2 代码解析

- **服务器端**

- `Callbacks` 表:用于存储注册的回调函数。
- `RegisterServerCallback` 函数:用于注册新的服务器回调。
- 当服务器接收到 `server:callback` 事件时,调用对应的回调函数,并将结果通过 `client:callbackResponse` 事件发送回客户端。

- **客户端**

- `Callbacks` 表:用于存储待处理的回调函数。
- `TriggerServerCallback` 函数:触发服务器回调,并生成唯一的 `requestId`。
- 当客户端接收到 `client:callbackResponse` 事件时,调用对应的回调函数。

[a name=section6][/a]
6. 实战示例

6.1 场景描述

我们将创建一个简单的系统,当玩家输入指令
代码:
/checkid
时,客户端会请求服务端获取玩家的标识符(如 Steam ID),然后在客户端显示。

6.2 实现步骤

客户端脚本(client.lua):

lua:
-- 自定义回调系统代码(参考上文)

RegisterCommand('checkid', function()
    TriggerServerCallback('getPlayerIdentifiers', function(identifiers)
        print('Your Identifiers:')
        for _, id in ipairs(identifiers) do
            print(id)
        end
    end)
end)

服务器脚本(server.lua):

lua:
-- 自定义回调系统代码(参考上文)

-- 注册回调函数
RegisterServerCallback('getPlayerIdentifiers', function(source, cb)
    local identifiers = GetPlayerIdentifiers(source)
    cb(identifiers)
end)

6.3 代码解析

-
代码:
RegisterCommand
:注册一个客户端指令
代码:
/checkid

-
代码:
TriggerServerCallback
:客户端请求服务端的回调函数
代码:
getPlayerIdentifiers
,并等待结果。
-
代码:
RegisterServerCallback
:服务端注册一个回调函数,当收到客户端请求时执行。
-
代码:
cb(identifiers)
:服务端获取玩家的标识符后,通过回调函数返回给客户端。

[a name=section7][/a]
7. 总结

在本教程中,我们学习了:

- FiveM 中事件的概念和作用。
- 如何注册和触发服务端事件和客户端事件。
- 如何在客户端和服务端之间传递数据。
- 如何使用原生函数实现回调机制,实现同步通信。
- 实战示例,如何将这些知识应用于实际开发中。
 
顶部