Lua Roblox API:我如何去抖一个 player/character 碰到盒子
Lua Roblox API: How can I debounce a player/character that runs into a box
背景:
承载最小的物体。只是一个播放器和一个漂浮在空中并被锚定的部分(矩形棱柱)。
老实说,我不明白引擎盖下发生了什么,所以很难弄清楚。在没有去抖动的情况下,在事件触发时,回调函数由 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);
您正在做的事情的核心是合理的:在第一个事件之后开始阻塞,并在一段时间后解除阻塞。如果这是通过按下按钮或 mouse-clicks,您的解决方案就可以正常工作。 Touched 事件使这变得复杂,因为它会触发任何接触它的部分,并且玩家的角色可能有多个接触点。
Touched and TouchEndeded 事件为您提供了对已接触零件的实例的引用。
如果目标是只为每个玩家触发一次盒子事件或在任何人触摸它时触发一次,您可以保留当前触摸盒子的部分的字典。当一个部分接触时,你增加一个计数器。当一个部分停止时,您将其递减。只有在所有触摸点都被移除后,您才能移除 debounced 标志。
local box = game.Workspace.BoxModel
local playersTouching = {} --<string playerName, int totalParts>
local function onTouchedDebounced(otherPart)
-- check that the thing that touched is a player
local playerModel = otherPart.Parent
if not playerModel:IsA("Model") 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 = playerModel.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("Hello! onTouchedDebounced() has ran with %s and %s", playerName, otherPart.Name))
end
local function onTouchedUndebounced(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("Hello! onTouchedUndebounced() has ran and %s has no more touching parts", playerName))
end
end
box.Touched:Connect(onTouchedDebounced)
box.TouchEnded:Connect(onTouchedUndebounced)
背景: 承载最小的物体。只是一个播放器和一个漂浮在空中并被锚定的部分(矩形棱柱)。
老实说,我不明白引擎盖下发生了什么,所以很难弄清楚。在没有去抖动的情况下,在事件触发时,回调函数由 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);
您正在做的事情的核心是合理的:在第一个事件之后开始阻塞,并在一段时间后解除阻塞。如果这是通过按下按钮或 mouse-clicks,您的解决方案就可以正常工作。 Touched 事件使这变得复杂,因为它会触发任何接触它的部分,并且玩家的角色可能有多个接触点。
Touched and TouchEndeded 事件为您提供了对已接触零件的实例的引用。
如果目标是只为每个玩家触发一次盒子事件或在任何人触摸它时触发一次,您可以保留当前触摸盒子的部分的字典。当一个部分接触时,你增加一个计数器。当一个部分停止时,您将其递减。只有在所有触摸点都被移除后,您才能移除 debounced 标志。
local box = game.Workspace.BoxModel
local playersTouching = {} --<string playerName, int totalParts>
local function onTouchedDebounced(otherPart)
-- check that the thing that touched is a player
local playerModel = otherPart.Parent
if not playerModel:IsA("Model") 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 = playerModel.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("Hello! onTouchedDebounced() has ran with %s and %s", playerName, otherPart.Name))
end
local function onTouchedUndebounced(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("Hello! onTouchedUndebounced() has ran and %s has no more touching parts", playerName))
end
end
box.Touched:Connect(onTouchedDebounced)
box.TouchEnded:Connect(onTouchedUndebounced)