Roblox Studio · 第 17 课

客户端与服务器:谁看见了变化

分别运行 Script 与 LocalScript,用两个玩家窗口观察共享场景和个人效果的区别。

10–15 岁 75 分钟 Client / Server 动手实践 测试与保存

Course overview

同一个游戏,为什么两个人看到的颜色可以不同?

把服务器想成保存共同规则的裁判,把客户端想成每个人自己的屏幕和输入设备。它们会互相传递信息,但并不是一个完全相同的电脑。

这一课是一场观察实验。你会先看到服务器建立的共享路标,再看到本地脚本添加的个人标签,最后比较两个玩家窗口。

01 · BEFORE

开始之前

知道 Script 与 LocalScript 的区别。新建 Lesson17,熟悉 Output。

02 · MAKE

你的作品

一块服务器改成绿色的 SharedBlock,以及每个客户端独有的名字界面。

03 · CHECK

完成标志

两个玩家都看见共享绿块,各自界面显示自己的名字;能分辨 Server 和 Client 输出。

Studio 客户端测试视角截图
图 17-1:官方客户端视角截图:客户端包含玩家个人的显示与操作状态。Roblox Creator Documentation · CC BY 4.0 · 原图未修改 · 许可说明

Learning route

先准备,再动手;看到结果后,记得保存。

每完成一小步,就测试一次。先说出你预计会看到什么,再用 Play 和 Output 检查,不用急着一次写完所有代码。

1

01 · 先画出两个运行位置

ServerScriptService 里的普通 Script 在服务器运行。StarterPlayerScripts 里的 LocalScript 会复制到每个玩家的 PlayerScripts,分别在各自客户端运行。

2

02 · 服务器改共享场景

服务器把共享方块变绿,客户端会接收到这项变化。正常网络复制需要时间,不应假设它和另一条消息严格同时到达。

3

03 · 每个客户端有自己的 LocalPlayer

Players.LocalPlayer 在客户端代表正在使用这块屏幕的玩家。服务器同时管理很多玩家,没有这个“唯一的我”。

4

04 · 开两个客户端做对照

在 Studio 测试模式中选择 Server & Clients,设置两个客户端后启动。不同版本的按钮位置可能不同,按功能名称寻找,而不是记死图标坐标。

5

05 · 决定一项功能应该住在哪里

金币发放、任务完成和最高纪录,应该由服务器决定。相机、提示卡、按钮反馈等个人表现,通常由客户端处理。

Step by step

01 · 先画出两个运行位置

ServerScriptService 里的普通 Script 在服务器运行。StarterPlayerScripts 里的 LocalScript 会复制到每个玩家的 PlayerScripts,分别在各自客户端运行。

本课把地图保持很小,使用默认的小型 Baseplate 测试。你不需要修改账号、发布权限或云端设置。

  1. 创建 Anchored 的 SharedBlock,Size=8, 4, 4,Position=0, 2, -12。
  2. 创建 ServerScriptService > SharedWorld(Script)。
  3. 展开 StarterPlayer > StarterPlayerScripts,创建 MyView(LocalScript)。

Step by step

02 · 服务器改共享场景

服务器把共享方块变绿,客户端会接收到这项变化。正常网络复制需要时间,不应假设它和另一条消息严格同时到达。

print 前面加 [Server] 只是我们自己的阅读标签,真正的执行来源还要看 Output 的上下文。

  1. 将代码放入 SharedWorld。
  2. Play 时观察方块变绿,Output 有一条服务器消息。
ServerScriptService > SharedWorld(Script)Luau
local block = workspace:WaitForChild("SharedBlock")
block.Color = Color3.fromRGB(70, 220, 150)
print("[Server] SharedBlock is green")

Step by step

03 · 每个客户端有自己的 LocalPlayer

Players.LocalPlayer 在客户端代表正在使用这块屏幕的玩家。服务器同时管理很多玩家,没有这个“唯一的我”。

下面用代码创建一个简单界面,不需要沿用第 15 课文件。它只是显示身份,不会在其他人的屏幕上复制同一段名字。

  1. 把代码放入 MyView。
  2. 注意 ScreenGui 的 Parent 是当前玩家的 PlayerGui。
  3. Play 后读左上角名字,并找到对应 Client 输出。
StarterPlayer > StarterPlayerScripts > MyView(LocalScript)Luau
local Players = game:GetService("Players")
local player = Players.LocalPlayer
local gui = Instance.new("ScreenGui")
gui.Name = "MyViewGui"
gui.ResetOnSpawn = false
local label = Instance.new("TextLabel")
label.Size = UDim2.fromOffset(300, 56)
label.Position = UDim2.fromOffset(16, 16)
label.TextSize = 20
label.Text = "我的屏幕:" .. player.Name
label.Parent = gui
gui.Parent = player:WaitForChild("PlayerGui")
print("[Client] This is", player.Name)

Step by step

04 · 开两个客户端做对照

在 Studio 测试模式中选择 Server & Clients,设置两个客户端后启动。不同版本的按钮位置可能不同,按功能名称寻找,而不是记死图标坐标。

分别查看两个客户端与服务器视角。不要把两个客户端窗口误认为两个服务器。游戏仍只有这一轮测试的共享服务器。

  1. 确认两名玩家都看到绿色 SharedBlock。
  2. 确认两个标签分别显示自己的玩家名。
  3. 在服务器 Explorer 查看玩家记录;客户端专属界面不应被当作服务器权威数据。
同一测试中的服务器视角截图
图 17-2:官方服务器视角截图:切换后观察共同场景,理解服务器与客户端并不是同一份运行状态。Roblox Creator Documentation · CC BY 4.0 · 原图未修改 · 许可说明

Step by step

05 · 决定一项功能应该住在哪里

金币发放、任务完成和最高纪录,应该由服务器决定。相机、提示卡、按钮反馈等个人表现,通常由客户端处理。

客户端想做一件会影响共同规则的事,就需要发出请求。下一课会用 RemoteEvent 把这个请求交给服务器检查。

  1. 给“开提示卡、获得金币、改变相机、领取宝箱”分别写上 Client 或 Server。
  2. 用 End Session 结束所有测试客户端。
  3. 保存项目与一张两名玩家对照截图,避免留下测试窗口占用资源。

Homework

轮到你来改一改,做出自己的版本。

1 画一张运行地图

把 Workspace、ServerScriptService、PlayerGui 放到你理解的服务器或客户端位置。

2 个人欢迎词

给本地标签加一句自己的欢迎语,但保持玩家名字动态读取。

3 选做:不同显示

在两个测试客户端查看各自 LocalPlayer.UserId,只在 Output 观察,不用于收集真实个人资料。

完成标准:先在 Playtest 中验证作品,再点击 Stop,保存为“姓名缩写_Lesson17”或对应 Homework 副本;不要覆盖上一课的可运行版本。

Exit questions

先自己回答,再展开看看。

服务器中的 LocalPlayer 是谁?

服务器没有唯一的本地玩家,LocalPlayer 只在客户端有意义。

为什么两个人的标签名字不同?

同一份 LocalScript 在各自客户端运行,各自读取自己的 LocalPlayer。

金币奖励应该由谁决定?

由服务器验证并更新,客户端只能提出请求或显示结果。

多人测试结束后做什么?

结束整个会话,关闭测试客户端,再保存编辑项目。

Explore further

需要查资料时,从这里出发。

正文代码可以直接复制。先确认脚本类型、放置位置,以及这段代码是完整版本还是小实验;不要把同一脚本的多个版本叠加运行。界面参考图已标注来源,图中的对象名可能与本课不同,请以操作步骤为准。