在 Lua Roblox API 中,如何对跑进盒子的玩家/角色进行去抖?

问题描述 投票:0回答:1

背景:

携带最少的物品。只是一个玩家和一个漂浮在空中并固定的部件(矩形棱柱)。

老实说,我不明白幕后发生了什么,所以很难弄清楚。如果没有去抖,在事件触发时,回调函数将由 connect() 或事件处理程序(不确定)调用,并且,如果没有去抖,当在输出框中重复打印语句时,该函数将被多次调用。因此,使用存储去抖标志的变量(布尔类型)就可以解决这个问题。然后,当玩家的模型超出盒子模型的范围时,我会尝试“取消反跳”。但是,我不知道如何正确地做到这一点。

这是我的代码尝试:

local box = game.Workspace.BoxModel;
local debounce = false;

local function onTouchedDebounced()
    if (debounce == false)
    then
        debounce = true;
        print("Hello! onTouchedDebounced() has run.");
        box.Touched:Connect(onTouchedDebounced));
    end
end

local function onTouchedUndebounced()
    if (debounce == true) 
    then
        print("Hello! onTouchedUndebounced() has run.");
        debounce = false;
    end 
end

box.Touched:Connect(onTouchedDebounced);
box.TouchEnded:Connect(onTouchedUndebounced);
c api lua roblox
1个回答
2
投票

您正在做的事情的核心是合理的:在第一个事件之后开始阻止,并在一段时间后解除阻止。如果这是通过按下按钮或单击鼠标来实现的,那么您的解决方案就可以正常工作。 Touched 事件使情况变得复杂,因为任何接触它的部分都会触发,并且玩家的角色可能有多个接触点。

TouchedTouchEndeded 事件为您提供对已触摸部件的实例的引用。

如果目标是每个玩家只触发一次盒子事件,或者在任何人触摸它时触发一次,您可以保存当前正在触摸盒子的部件的字典。当零件接触时,计数器就会增加。当某个部分停止时,您可以将其递减。只有在所有触摸点都被删除后,您才能删除去抖标志。

local Players = game:GetService("Players")

local box = game.Workspace.BoxModel
local playersTouching = {} --<string playerName, int totalParts>

local function onTouched(otherPart)
    -- check that the thing that touched is a player
    local player = Players:GetPlayerFromCharacter(otherPart.Parent)
    if not player then
        warn(otherPart.Name .. " isn't a child of a character. Exiting")
        return
    end

    -- check whether this player is already touching the box
    local playerName = player.Name
    local total = playersTouching[playerName]
    if total and total > 0 then
        warn(playerName .. " is already touching the box")
        playersTouching[playerName] = total + 1
        return
    end

    -- handle a new player touching the box
    playersTouching[playerName] = 1

    -- Do a thing here that you only want to happen once per event...
    print(string.format("%s has begun touching", playerName))    
end

local function onTouchEnded(otherPart)
    -- decrement the counter for this player
    local playerName = otherPart.Parent.Name
    if playersTouching[playerName] == nil then
        return
    end

    local newTotal = playersTouching[playerName] - 1
    playersTouching[playerName] = newTotal

    -- if the total is back down to zero, clear the debounce flag
    if newTotal == 0 then
        playersTouching[playerName] = nil
        print(string.format("%s has stopped touching", playerName))
    end
end


box.Touched:Connect(onTouched)
box.TouchEnded:Connect(onTouchEnded)
© www.soinside.com 2019 - 2024. All rights reserved.