You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Roblox Studio服务端脚本访问玩家本地鼠标及工具使用时ClickDetector交互问题求助

Roblox Studio服务端脚本访问玩家本地鼠标及工具使用时ClickDetector交互问题求助

首先看你遇到的问题,输出Nil Nil以及ClickDetector交互失效,主要是当前代码里有几个关键逻辑问题,我来帮你拆解并修正:

问题分析

  • 服务端初始print时机错误:你在服务端开头直接执行print(plr, mouseTarget),这时候还没触发Tool RemoteEvent,两个变量还未赋值,自然输出nil,这个print应该放到事件回调里才能看到有效数据。
  • 客户端鼠标目标未实时更新:你在客户端仅初始化时赋值了一次mouseTarget = mouse.Target,之后循环里一直传的是初始值,不会跟着鼠标移动更新,得每次循环都重新获取最新的mouse.Target
  • 全局变量的安全隐患:服务端用全局的plrmouseTarget,如果多个玩家同时使用这个工具,会互相覆盖数据,这是很危险的,应该结合工具事件自带的玩家参数来单独处理每个用户的状态。
  • 工具事件获取玩家的正确方式:工具的EquippedUnequipped事件本身就会传入当前使用工具的玩家对象,根本不需要依赖RemoteEvent传过来的玩家,这才是最可靠的获取方式。

修正后的代码

服务端脚本(放置在Tool内部)

local tool = script.Parent
local toolRemote = game.ReplicatedStorage.Tool
local lanternEvents = game.ReplicatedStorage.LanternEvents
local paperEvents = game.ReplicatedStorage.PaperEvents
local keypadEvent = game.ReplicatedStorage.KeypadEvent

-- 用字典存储每个玩家的当前鼠标目标,避免多玩家数据冲突
local playerMouseTargets = {}

toolRemote.OnServerEvent:Connect(function(player, mouseTarget)
    playerMouseTargets[player] = mouseTarget
    -- 这里打印可以测试是否收到客户端传来的有效数据
    print(player.Name, mouseTarget and mouseTarget.Name or "无目标")
end)

tool.Equipped:Connect(function(player)
    lanternEvents.Equipped:FireClient(player)
end)

tool.Unequipped:Connect(function(player)
    lanternEvents.UnEquipped:FireClient(player)
    -- 玩家卸下工具后清空对应存储的鼠标目标
    playerMouseTargets[player] = nil
end)

tool.Activated:Connect(function(player)
    local mouseTarget = playerMouseTargets[player]
    if not mouseTarget then return end

    local clickDetector = mouseTarget:FindFirstChildWhichIsA("ClickDetector")
    if clickDetector then
        if mouseTarget.Name == "Paper" then
            paperEvents.PaperEvent1:FireClient(player)
            player.CameraMode = Enum.CameraMode.Classic
        elseif mouseTarget.Parent.Name == "Keypad" then
            keypadEvent:FireClient(player)
        elseif mouseTarget.Parent.Name == "Lighter" then
            game.Workspace.Values.CollectedLighter.Value = true
            mouseTarget:Destroy()
        else
            game.Workspace.Values.Collected.Value += 1
            mouseTarget:Destroy()
        end
    end
end)

客户端脚本(放置在Tool内部的LocalScript)

local player = game.Players.LocalPlayer
local mouse = player:GetMouse()
local toolRemote = game.ReplicatedStorage.Tool

-- 降低循环频率,减少不必要的网络请求,0.1秒间隔足够实时
while task.wait(0.1) do
    local currentTarget = mouse.Target
    toolRemote:FireServer(currentTarget)
end

额外优化建议

  • 把客户端循环间隔从wait(0.01)改成task.wait(0.1),过高的频率会导致大量无效网络请求,0.1秒的间隔完全能保证鼠标目标的实时性。
  • 服务端用playerMouseTargets字典管理每个玩家的鼠标状态,彻底避免多玩家场景下的数据覆盖问题。
  • 工具的Activated事件自带玩家参数,直接使用这个参数对应操作玩家,比依赖RemoteEvent传玩家更稳定可靠。

这样修改后,应该就能解决你当前的Nil输出问题,同时实现工具使用时与ClickDetector的正常交互功能了。

备注:内容来源于stack exchange,提问作者Programing_Good_Games

火山引擎 最新活动