Roblox Guidebook知识库
简体中文 ⌄

开发 / ROBLOX

Roblox Studio检查点:独立练习障碍路线

制作两个检查点,为每位玩家设置独立重生位置,并检查死亡、重复接触、顺序和离开会话。

个人进度按固定顺序推进打开大图 ↗
原创教学示意图,不是游戏地图 — 重复或回到较早点不会改变已到达索引
更新日期:

先定义小机制的规则 #

建立一条短练习路线,包含Start、Checkpoint1和Checkpoint2。玩家依次到达各点。接受与下一检查点的接触后,死亡应让角色回到那里。走回较早平台不能降低进度。第二名玩家具有独立进度和重生目的地。先明确这个规则,才能把预测与观察比较,而不是只看场景是否运行。

这是全新的教学原型,不是Stone Trail或本站作者其他游戏的实现。下面的脚本为本课原创;我们分析逻辑,但本文没有在Roblox引擎中运行它。进度只存在于当前服务器内存中。这里不添加跨访问保存、奖励或对所有绕路手段的防护。先验证这个有限机制,再扩展它。教学示意图也不是实际游戏地图或Studio截图。

1. 用准确名称准备独立场景 #

保存一个新的小项目,不干扰正在使用的游戏。在Workspace中准备一个名为Start的SpawnLocation和一个名为Checkpoints的Folder。文件夹里放两个SpawnLocation,分别叫Checkpoint1与Checkpoint2。在ServerScriptService里添加普通Script,命名为CheckpointServer。最终路径是Workspace.Start、Workspace.Checkpoints.Checkpoint1、Workspace.Checkpoints.Checkpoint2以及ServerScriptService.CheckpointServer。名称必须一致;Checkpoint 1多一个空格就不同。

其他路面可用普通锚定Part,但检查点必须真正是SpawnLocation,而非颜色相似的Part。在这个新练习场景中移除无关出生点。无需插入带未知脚本的模型包:自己的平台和一个服务器脚本就够了。加代码前确认三点都看得见且互不重叠,路线短而清楚。

2. 配置接触与安全重生空间 #

沿短而安全的路依次放Start、Checkpoint1、Checkpoint2。保持距离,以便单独触碰每个点。在SpawnLocation上方留出空间,避免角色出现在墙内、低天花板下或悬崖边。颜色和标签用于识别,不会自动记录进度。第一次测试不需要困难陷阱;障碍难度与检查点逻辑是两个问题。

下表列出本练习配置,脚本启动时会再次设置必要值。各点允许不依赖队伍的重生,关闭接触换队。CanTouch允许接触事件,Anchored固定平台。以后添加队伍或collision groups时,必须重新检查重生资格和物理接触。暂时保持默认自动加载角色启用;自定义加载不在这个原型范围内。

属性值本练习用途
ClassSpawnLocation出生及重生平台
Anchoredtrue固定平台
CanCollidetrue角色可站在平台上
CanTouchtrue允许检测物理接触
Enabledtrue允许出现
Neutraltrue不限制队伍
AllowTeamChangeOnTouchfalse接触不改变队伍

3. 将完整脚本放在服务器 #

打开ServerScriptService里的CheckpointServer,用下面完整示例替换内容。不要只复制Touched处理器;准备和初始化也必须存在。checkpoints表明确两个对象顺序,不依赖GetChildren的返回排列。configure核对对象类型并设置属性。缺少名称时WaitForChild会等待,类型错误时assert会报错。先修复结构,再测试路线,不要用延迟掩盖拼写错误。

服务器设置Player.RespawnLocation,并以Player为键保存progress。StarterPlayerScripts里的LocalScript不是等价放置方式。测试时不要同时运行另一个修改RespawnLocation的脚本。准备完场景后启动新的测试。如果在已经运行的测试里插入代码,设置未来重生点不会把活着的角色立即移到Start;这里没有传送命令。

local Players = game:GetService("Players")
local start = workspace:WaitForChild("Start")
local folder = workspace:WaitForChild("Checkpoints")
local checkpoints = {
    folder:WaitForChild("Checkpoint1"),
    folder:WaitForChild("Checkpoint2"),
}
local progress = {}

local function configure(spawn)
    assert(spawn:IsA("SpawnLocation"), "Expected SpawnLocation")
    spawn.Anchored = true
    spawn.CanCollide = true
    spawn.CanTouch = true
    spawn.Enabled = true
    spawn.Neutral = true
    spawn.AllowTeamChangeOnTouch = false
end

configure(start)
for _, checkpoint in ipairs(checkpoints) do
    configure(checkpoint)
end

local function initialize(player)
    if progress[player] ~= nil then return end
    progress[player] = 0
    player.RespawnLocation = start
end

Players.PlayerAdded:Connect(initialize)
Players.PlayerRemoving:Connect(function(player)
    progress[player] = nil
end)
for _, player in ipairs(Players:GetPlayers()) do
    initialize(player)
end

for index, checkpoint in ipairs(checkpoints) do
    checkpoint.Touched:Connect(function(hit)
        local character = hit:FindFirstAncestorOfClass("Model")
        if not character then return end
        local player = Players:GetPlayerFromCharacter(character)
        if not player or player.Character ~= character then return end
        local humanoid = character:FindFirstChildOfClass("Humanoid")
        if not humanoid or humanoid.Health <= 0 then return end
        local current = progress[player]
        if current == nil or index ~= current + 1 then return end
        player.RespawnLocation = checkpoint
        progress[player] = index
    end)
end

4. 从碰到的部件识别玩家 #

Touched提供另一个部件,可能属于角色、掉落方块或其他物体。处理器查找最近的Model,用GetPlayerFromCharacter判断是否对应玩家,再核对player.Character,并寻找Health大于零的Humanoid。不做这些检查,物体或已死亡角色可能错误改变进度。不合格接触在设置重生位置之前return。

示例针对Humanoid位于角色Model中的普通角色。自定义嵌套rig需要有意识地调整模型查找;不要为了消除症状直接删除玩家验证。服务器观察到接触也不证明整条路线被诚实完成。角色移动和物理仍需要单独安全分析。本课检查普通短路线的个人检查点,不声称完成了反作弊系统。

5. 保持顺序而不阻塞其他玩家 #

新玩家的progress为0。仅接受current + 1:先索引1,再2。确认第一点后,脚或其他身体部件再次接触该平台,不再符合下一个索引。到达第二点后,第一点同样被拒绝。规则既防回退,也防跳过第一点。这是本练习选择的合同;自由顺序路线需要不同规则。

这里没有一次接触后锁住所有人的全局debounce。每个Player都是独立表键,检查及两次赋值没有task.wait或其他等待,因此玩家独立推进。这是对短处理器的逻辑分析,不是对以后异步代码的保证。如果加入奖励、数据请求或延迟,必须重新分析重复调用及修改状态的时机。

6. 分清死亡、新测试与重新加入 #

接受接触后只更新该Player的RespawnLocation。活角色留在原地,在下一次正常重生时核对目的地。死亡创建新的角色Model,但Player仍留在会话中,因此progress记录保留。不要在CharacterAdded里把progress清零,否则每次死亡都丢掉检查点。

离开时PlayerRemoving删除内存记录。重新加入得到新的0并指向Start。停止Studio测试再启动,也开始新会话。示例没有游戏内完整重置按钮。以后添加时,应同时重置索引和RespawnLocation;只改界面文字不够。保存项目保存场景和代码,不保存运行中的玩家表。不能把“保存文件”和“永久保存玩家进度”混为一谈。

不同动作对应不同状态寿命打开大图 ↗
原创教学示意图,不是游戏地图 — 仅保存在内存,没有永久保存

7. 按步骤进行单人测试 #

在Studio测试下拉菜单中选择Test并启动。该模式插入角色;Run仅运行模拟而不插入化身,不适合首次走路检查。开始新会话并核对Start出生。正常走到Checkpoint1,停在平台上,然后在原型专门设计的坠落区域造成死亡。等正常重生并记录位置。

对Checkpoint2重复。之后实际走回第一点,再检查死亡:应继续选择第二点。不要与Stop后新Test混淆,因为新测试故意清空内存。实际结果与预测分开记录。如果所选坠落区域没有让角色死亡,还不能认定RespawnLocation测试失败。先确认死亡与新角色出现确实发生,再评价目标。

8. 检查物体、跳序和重复接触 #

另一次尝试先碰Checkpoint2,再碰Checkpoint1之前检查结果:顺序条件应保留Start。随后正常完成两点。物体测试可创建普通未锚定方块,让它物理落在检查点上。它不是Player,不应改变任何人的进度。通过服务器状态或对应玩家之后的重生进行比较,而非仅看平台颜色。

Touched依赖物理运动。修改CFrame使两块锚定部件重叠,不是同样的事件测试。没有接触时,检查双方CanTouch及collision groups规则。实验没执行之前不要写“方块已被拒绝”的虚构结果。后面的用例表列出预期,不是本脚本已在Roblox引擎测试的报告;自己的笔记也应保留这个区别。

9. 两名玩家分别验证进度 #

选择Server & Clients,设置两个客户端,按Play或F7启动。A到第一点,B留在Start。死亡后A应在Checkpoint1出现,B仍在Start。然后B到第一点、A到第二点,分别比较结果。还要试两个角色几乎同时接触第一点:共享锁不能导致一人没有自己的进度。

两台相机看到同样颜色的平台不能证明个人设置。Workspace物体颜色是共享的,RespawnLocation属于某个Player。记录哪个客户端执行动作、哪个角色重生。结束后使用End Session关闭整个多客户端会话。两个本地客户端能检查具体情况,不证明大服务器性能、嵌套角色兼容性或所有异常接触顺序。

10. 每次查一个失败条件 #

检查点无效时,从结构走到状态:准确路径、SpawnLocation类型、普通服务器Script、CanTouch、活Player、预期索引、允许重生。拼写错误和故意拒绝索引2是不同原因。执行错误可使用相关Output指南;此处不重复完整控制台课程。下表没有“通过”标记,把自己的观察写在预期旁。

尤其检查启动后Enabled是否关闭、Neutral是否改变。检查点应留在Workspace且对玩家有效。其他脚本可能后来修改属性或RespawnLocation。如果目的地错误,记录动作顺序与真实平台,而非只说“坏了”。每次修改用明确的新尝试复核。无止境加等待不能修复错误的顺序条件。

用例预期状态检查
新Test/加入0;Start真实首次出生
Checkpoint1后死亡1;Checkpoint1等待新角色
再次Checkpoint1不改变不同身体部件接触
第一点后Checkpoint22;Checkpoint2死亡返回第二点
第二点后回第一点2;Checkpoint2不回退
先第二点再第一点0;Start拒绝跳序
方块/非玩家模型不改变没有对应Player
死亡/旧角色不改变Health及当前Character
A推进,B未推进A/B目的地独立分别死亡后检查
离开/Stop后新测试新的0没有永久保存

11. 保存结果,再选一个扩展 #

结束测试,以可辨识名称保存原型。记录层级、脚本版本、自动加载角色假设、实际完成的单人与双客户端用例以及预期和真实重生位置。本文的逻辑分析不表示你的项目已经通过Studio测试。把机制移入现有游戏之前,在自己场景中比较所有重要用例。

下一步可以是个人确认消息或明确重置按钮。永久保存是独立任务,涉及加载、写入失败、数据版本和重置规则;此处不用DataStore。不要向玩家承诺永远保留进度。先保留清楚的当前规则:本次访问中死亡回到已到达的点,离开结束教学内存状态。小而验证过的机制比同时加多个未测试系统更容易扩展。

原始资料

Roblox Creator Hub
Roblox Creator Hub — Player.RespawnLocation
Roblox Creator Hub — BasePart.Touched and CanTouch
Roblox Creator Hub — Studio testing modes
Roblox Creator Hub — Players lifecycle
Roblox Creator Hub — ServerScriptService