允许体验将用户输入绑定到上下文行动或仅在某些条件或时间段启用的行动
上下文和行动
一个 上下文 是在玩家执行某些操动作时的条件。一些例子包括持有一个 Tool ,在汽车上坐下或站在门附近。无论是什么
在此上下文中,操作
在上下文中绑定动作
在大多数情况下,您都会首先使用 BindAction 来调用 UserInputService.InputBegan ,然后再使用 UserInputService.InputBegan 来调用 2> Class.UserInputService:UnbindAction()|UnbindAction2> 。
检查边界动作
要查看列表的动作和其他输入的绑定,您可以在开发者控制台(F9 在游戏中)查看“行动绑定”选项卡。这将显示所有绑定,包括 Roblox
无键输入
此服务特别有用于支持游戏手柄和触摸输入。 对于游戏手柄输入,您可能选择将 B 按钮绑定到返回用户到另一个菜单时将他们返回上一个菜单的行动。 对于触摸,
代码示例
This example properly shows how to use ContextActionService in binding user input to a contextual action. The context is the tool being equipped; the action is reloading some weapon. Test this code sample by placing it in a LocalScript parented to a Tool. When the Tool is equipped, a "Reload" action is bound, and when the Tool is unequipped the "Reload" action is unbound. When the player presses R with the Tool equipped, the message "Reloading!" will appear.
local ContextActionService = game:GetService("ContextActionService")
local ACTION_RELOAD = "Reload"
local tool = script.Parent
local function handleAction(actionName, inputState, _inputObject)
if actionName == ACTION_RELOAD and inputState == Enum.UserInputState.Begin then
print("Reloading!")
end
end
tool.Equipped:Connect(function()
ContextActionService:BindAction(ACTION_RELOAD, handleAction, true, Enum.KeyCode.R)
end)
tool.Unequipped:Connect(function()
ContextActionService:UnbindAction(ACTION_RELOAD)
end)
概要
方法
- BindAction(actionName : string,functionToBind : function,createTouchButton : bool,inputTypes : Tuple):void
将用户输入绑定到给予动作处理函数的动作。
行为像 BindAction 但还允许优先级被分配到覆盖输入类型的边界动作(从高到低)。
使用特定 Enum.UserInputType 与 Tool.Activation 和 1> Class.ClickDetector1> 事件触发。
获取有关所有绑定操作的信息表(键是通过 BindAction 传递的名称,值是由 GetBoundActionInfo 调用时的表)。
获取有关命名为 BindAction 的界定操作的信息表。
返回 BackpackItem.TextureId 的一个 Tool 当前 equipped 通过 2>Class.Player2> 。
给予一个带有触摸按钮的关联动作的名称,设置动作的描述。
如果 actionName 键包含一个绑定操动作,那么 image 将作为触摸按钮的图像设置。
给予一个带有触摸按钮的关联动作的名称,将按钮的位置设置在 ContextButtonFrame 中。
根据具有触摸按钮的关联动作的名称,设置显示在按钮上的文本。
从输入中解除输入的命名。
- UnbindActivate(userInputTypeForActivation : Enum.UserInputType,keyCodeForActivation : Enum.KeyCode):void
使用特定 Enum.UserInputType 从触发 Tool.Activation 时使用 1> Class.KeyCode1> 。
移除所有绑定的函数。所有的操作名将不再存在。所有的触摸按钮将被移除。
调用一个 ImageButton 的 Class.ContextActionService:BindAction()|bound 操作,该操作有一个触摸输入按钮。
活动
属性
方法
BindAction
在给予用户输入处理功能时,为其输入表示一个操作。当匹配的输
下面的代码示例显示了一个 Sound 可以被 played 而键 ( H ) 游戏手柄按钮或触摸屏幕按钮是按下。
local ContextActionService = game:GetService("ContextActionService")
-- 汽车喇叭声
local honkSound = Instance.new("Sound", workspace)
honkSound.Looped = true
honkSound.SoundId = "rbxassetid://9120386436"
local function handleAction(actionName, inputState, inputObject)
if actionName == "HonkHorn" then
if inputState == Enum.UserInputState.Begin then
honkSound:Play()
else
honkSound:Pause()
end
end
end
-- 当玩家坐在车辆上时:
ContextActionService:BindAction("HonkHorn", handleAction, true, Enum.KeyCode.H, Enum.KeyCode.ButtonY)
-- 当玩家离开时:
ContextActionService:UnbindAction("HonkHorn")
动作处理器参数
动作处理器使用以下参数调用:
<tr><td>1</td><td><code>字符串</code></td><td>与 BindAction 传入的同一个字符串</td></tr><tr><td>2</td><td><code>枚列.UserInputState</code></td><td>输入状态(开始、更改、结束或取消)\*</td></tr><tr><td>3</td><td><code>输入对象</code></td><td>一个包含输入信息的对象(根据输入类型不同)</td></tr>
# | 类型 | 描述 |
※这允许一个函数同时处理多个操作,如有需要。*取消是发生在有进行中的输入和另一个操作的边界,或是在进行中边界发生的操作的后,或是在进行中边界发生的操作的后,或是在进行中边界发生的操作的后,或是在进行中边界发生的操作的后,或是在进行中边界发生的操作的后,或是在进行中边界发生的操作的后,或是在进行中边界发生的操作的后,或是在进行中
动作绑定堆
行为绑定
触摸按钮
除了输入类型外,此函数的第三个参数控制是否按钮作品建为 Class.UserInputService.TouchEnabled|TouchEnabled</
参数
代表要执行的操作的字符串(例如“HonkHorn”或“OpenDoor”)。
当触发边界输入时,调用以下参数调用函数:string (actionName)、Enum.UserInputState 和一个输入对象。
是否创建触摸输入设备上的动作按钮。
任意数量的 Enum.KeyCode 或 Enum.UserInputType 代表输入要绑定到操动作。
返回
代码示例
This example properly shows how to use ContextActionService in binding user input to a contextual action. The context is the tool being equipped; the action is reloading some weapon. Test this code sample by placing it in a LocalScript parented to a Tool. When the Tool is equipped, a "Reload" action is bound, and when the Tool is unequipped the "Reload" action is unbound. When the player presses R with the Tool equipped, the message "Reloading!" will appear.
local ContextActionService = game:GetService("ContextActionService")
local ACTION_RELOAD = "Reload"
local tool = script.Parent
local function handleAction(actionName, inputState, _inputObject)
if actionName == ACTION_RELOAD and inputState == Enum.UserInputState.Begin then
print("Reloading!")
end
end
tool.Equipped:Connect(function()
ContextActionService:BindAction(ACTION_RELOAD, handleAction, true, Enum.KeyCode.R)
end)
tool.Unequipped:Connect(function()
ContextActionService:UnbindAction(ACTION_RELOAD)
end)
This code sample uses ContextActionService to bind an action named "BoundAction" to a general action handler function on the F key. Place this in a LocalScript inside StarterPlayerScripts and press F to see the message "Handling action: BoundAction".
local ContextActionService = game:GetService("ContextActionService")
local function handleAction(actionName, inputState, inputObj)
if inputState == Enum.UserInputState.Begin then
print("Handling action: " .. actionName)
print(inputObj.UserInputType)
end
-- Since this function does not return anything, this handler will
-- "sink" the input and no other action handlers will be called after
-- this one.
end
ContextActionService:BindAction("BoundAction", handleAction, false, Enum.KeyCode.F)
This code sample demonstrates how BindAction acts like a stack. It binds two actions, FirstAction (Z, X, and C keys) and SecondAction (Z and X keys) to two action handling functions. The second one will pass on a certain input (the X key).
Both actions use the Z and X keys, however the second handler will pass input only if X is pressed. So, when X is pressed, the second handler is called and then the first. The first action is also bound to the C key, and can be triggered even though the other two inputs are "covered" by the second action.
Test this code out by pasting it into a LocalScript within StarterPlayerScripts, then pressing Z, X and C. Observe which action handlers are called with what actions.
local ContextActionService = game:GetService("ContextActionService")
-- Define an action handler for FirstAction
local function actionHandlerOne(actionName, inputState, _inputObj)
if inputState == Enum.UserInputState.Begin then
print("Action Handler One: " .. actionName)
end
-- This action handler returns nil, so it is assumed that
-- it properly handles the action.
end
-- Binding the action FirstAction (it's on the bottom of the stack)
ContextActionService:BindAction("FirstAction", actionHandlerOne, false, Enum.KeyCode.Z, Enum.KeyCode.X, Enum.KeyCode.C)
-- Define an action handler for SecondAction
local function actionHandlerTwo(actionName, inputState, inputObj)
if inputState == Enum.UserInputState.Begin then
print("Action Handler Two: " .. actionName)
end
if inputObj.KeyCode == Enum.KeyCode.X then
return Enum.ContextActionResult.Pass
else
-- Returning nil implicitly Sinks inputs
return Enum.ContextActionResult.Sink
end
end
-- Binding SecondAction over the first action (since it bound more recently, it is on the top of the stack)
-- Note that SecondAction uses the same keys as
ContextActionService:BindAction("SecondAction", actionHandlerTwo, false, Enum.KeyCode.Z, Enum.KeyCode.X)
BindActionAtPriority
BindActionAtPriority 像 BindAction 但还允许优先级被分配到边境操动作。如果多个操作被绑定到同一个输入,高级优先级函数仍然会在不同的操作顺序下调用。在其他 words, 此函数会覆盖 BindAction 的默认“堆叠”行为。
参数
代表要执行的操作的字符串(例如“HonkHorn”或“OpenDoor”)。
当触发边界输入时,调用以下参数调用函数:string (actionName)、Enum.UserInputState 和一个输入对象。
是否创建触摸输入设备上的动作按钮。
行动的优先级(高于低于)。
任意数量的 Enum.KeyCode 或 Enum.UserInputType 代表输入要绑定到操动作。
返回
代码示例
This code sample demonstrates how ContextActionService:BindActionAtPriority() can be used to bind actions out of order yet still have the same priority levels. Normally, BindAction() would operate on order (last bound action has highest priority), but priority levels override this. You can test this code by pasting it into a Script with RunContext = Client in ReplicatedStorage.
local ContextActionService = game:GetService("ContextActionService")
local INPUT_KEY1 = Enum.KeyCode.Q
local INPUT_KEY2 = Enum.KeyCode.E
local function handleThrow(actionName: string, inputState: Enum.UserInputState, inputObject: InputObject)
if inputState ~= Enum.UserInputState.Begin then
return Enum.ContextActionResult.Pass
end
print(`Action [{actionName}] occurred. KeyCode [{inputObject.KeyCode}] pressed.`)
return Enum.ContextActionResult.Sink
end
local function handlePunch(actionName: string, inputState: Enum.UserInputState, inputObject: InputObject)
if inputState ~= Enum.UserInputState.Begin then
return Enum.ContextActionResult.Pass
end
print(`Action [{actionName}] occurred. KeyCode [{inputObject.KeyCode}] pressed.`)
return Enum.ContextActionResult.Sink
end
-- Without specifying priority, the most recently bound action is called first,
-- so pressing INPUT_KEY1 prints "Punch" and then sinks the input.
ContextActionService:BindAction("DefaultThrow", handleThrow, false, INPUT_KEY1)
ContextActionService:BindAction("DefaultPunch", handlePunch, false, INPUT_KEY1)
-- Here we bind both functions in the same order as above, but with explicitly swapped priorities.
-- That is, we give "Throw" a higher priority of 2 so it will be called first,
-- despite "Punch" still being bound more recently.
-- Pressing INPUT_KEY2 prints "Throw" and then sinks the input.
ContextActionService:BindActionAtPriority("PriorityThrow", handleThrow, false, 2, INPUT_KEY2)
ContextActionService:BindActionAtPriority("PriorityPunch", handlePunch, false, 1, INPUT_KEY2)
BindActivate
注意,指定的 Enum.UserInputType 必须是 Keyboard 或 Gamepad1 通过 1>Gamepad81> 在 4>Gamepad84> 上有效。
参数
必须通过 Gamepad8 的键盘或游戏手柄 1 来进行。
返回
GetAllBoundActionInfo
GetAllBindActioninfo 返回一个包含所有操作名称 ( 由原来传送到 BindAction ) 到 GetBoundActionInfo 的表,当使用此函数时,您可以检查所有现有的边界操作。 使用此函数,您可以检查所有现有的边界操作。
返回
GetBoundActionInfo
GetBindActionInfo 返回一个包含以下键描述其名称的关联行动的表。要同时为所有行动获取相同的信息,请使用 GetAllBoundActionInfo 。
<tr><td><code>stackOrder</code></td><td>数</td><td>描述堆叠中的行动索引(增加)</td></tr><tr><td><code>优先级等级</code> \*</td><td>数</td><td>描述<code>Class.ContextActionService:BindActionAtPriority()|优先级</code>级动作</td></tr><tr><td><code>创建触摸按钮</code></td><td>boolean</td><td>描述是否在 <code>Class.UserInputService.TouchEnabled|TouchEnabled</code> 设备上创建触摸按钮</td></tr><tr><td><code>输入类型</code></td><td>表</td><td>输入类型通过 <code>Class.ContextActionService:BindAction()|BindAction</code> 传递给 Class.ContextActionService:BindAction() 触发</td></tr><tr><td><code>描述</code> ※</td><td>字符串</td><td>由 <code>Class.ContextActionService:SetDescription()|SetDescription</code> 设置的动作描述</td></tr><tr><td><code>标题</code> ^</td><td>字符串</td><td>通过 <code>Class.ContextActionService:SetTitle()|SetTitle</code> 设置动作集的标题</td></tr><tr><td><code>图像</code> ※</td><td>字符串</td><td>由 <code>Class.ContextActionService:SetImage()|SetImage</code> 设置的动作按钮图像</td></tr>
名称 | 类型 | 描述 |
即使 BindActionAtPriority 未使用,它仍然会包含优先级级别 - 默认为 2000。
※ 表示该方法不会调用,如果与该动作法关联的方法未调用。
参数
返回
GetCurrentLocalToolIcon
GetCurrentLocalToolIcon 将返回一个 BackpackItem.TextureId 的 Class.Tool 当前 Tool 通过 equipped 或 1> nil1> 如果没有此工具或玩家缺少一个 4> Class.Player.Character|Character
返回
从工具的 TextureId 中的内容字符串,或零,如果找不到。
SetDescription
将描述设置在 BindAction 下的操作。在可用的操作列表中,这将是描述给定操动作的文本。
虽然名称可能暗示这个方法与相关于创建它的触摸按钮的函数的家族( SetTitle , SetImage 和 SetPosition ),但此方法不会影响此按钮。此方
参数
原始上,动作的名称通过 BindAction 传递给 BindAction。
一段文本描述操动作,例如“鸣响汽车的horn”或“打开道具”。
返回
代码示例
This code sample demonstrates binding an "Inspect" action to a touch button created automatically by ContextActionService. The button is customized using SetImage(), SetTitle(), SetDescription() and SetPosition(). The button is further customized by using GetButton() to get a reference to the ImageButton itself and tinting it green by setting ImageButton.ImageColor3.
Paste this code into a LocalScript placed within StarterPlayerScripts to test it. In Studio, be sure to toggle the touch device emulator in order for the button to actually be created.
local ContextActionService = game:GetService("ContextActionService")
local ACTION_INSPECT = "Inspect"
local INPUT_INSPECT = Enum.KeyCode.E
local IMAGE_INSPECT = "rbxassetid://1826746856" -- Image of a speech bubble with ? in it
local function handleAction(actionName, inputState, _inputObject)
if actionName == ACTION_INSPECT and inputState == Enum.UserInputState.End then
print("Inspecting")
end
end
-- For touch devices, a button is created on-screen automatically via the 3rd parameter
ContextActionService:BindAction(ACTION_INSPECT, handleAction, true, INPUT_INSPECT)
-- We can use these functions to customize the button:
ContextActionService:SetImage(ACTION_INSPECT, IMAGE_INSPECT)
ContextActionService:SetTitle(ACTION_INSPECT, "Look")
ContextActionService:SetDescription(ACTION_INSPECT, "Inspect something.")
ContextActionService:SetPosition(ACTION_INSPECT, UDim2.new(0, 0, 0, 0))
-- We can manipulate the button directly using ContextActionService:GetButton
local imgButton = ContextActionService:GetButton(ACTION_INSPECT)
if imgButton then -- Remember: non-touch devices won't return anything!
imgButton.ImageColor3 = Color3.new(0.5, 1, 0.5) -- Tint the ImageButton green
end
SetImage
此方法将触摸按钮创建的图像显示在 BindAction() 内。 具体地,它将 ImageLabel.Image 属性的 ImageLabel 与在
此函数是自定义交互按动作的触摸按钮的一部分。其他在此家族中包括 SetPosition 和 SetTitle。
参数
返回
代码示例
This code sample demonstrates binding an "Inspect" action to a touch button created automatically by ContextActionService. The button is customized using SetImage(), SetTitle(), SetDescription() and SetPosition(). The button is further customized by using GetButton() to get a reference to the ImageButton itself and tinting it green by setting ImageButton.ImageColor3.
Paste this code into a LocalScript placed within StarterPlayerScripts to test it. In Studio, be sure to toggle the touch device emulator in order for the button to actually be created.
local ContextActionService = game:GetService("ContextActionService")
local ACTION_INSPECT = "Inspect"
local INPUT_INSPECT = Enum.KeyCode.E
local IMAGE_INSPECT = "rbxassetid://1826746856" -- Image of a speech bubble with ? in it
local function handleAction(actionName, inputState, _inputObject)
if actionName == ACTION_INSPECT and inputState == Enum.UserInputState.End then
print("Inspecting")
end
end
-- For touch devices, a button is created on-screen automatically via the 3rd parameter
ContextActionService:BindAction(ACTION_INSPECT, handleAction, true, INPUT_INSPECT)
-- We can use these functions to customize the button:
ContextActionService:SetImage(ACTION_INSPECT, IMAGE_INSPECT)
ContextActionService:SetTitle(ACTION_INSPECT, "Look")
ContextActionService:SetDescription(ACTION_INSPECT, "Inspect something.")
ContextActionService:SetPosition(ACTION_INSPECT, UDim2.new(0, 0, 0, 0))
-- We can manipulate the button directly using ContextActionService:GetButton
local imgButton = ContextActionService:GetButton(ACTION_INSPECT)
if imgButton then -- Remember: non-touch devices won't return anything!
imgButton.ImageColor3 = Color3.new(0.5, 1, 0.5) -- Tint the ImageButton green
end
SetPosition
此方法将触摸按钮创建者的位置设置为 BindAction() 。 具体地,它将 GuiObject.Position 属性设置为 ImageButton 将返回的 1> Class.ContextActionService:GetButton()|GetButton
此函数是自定义交互按钮的行动作的一部分。其他在此家族中包括 SetImage 和 SetTitle。
参数
返回
代码示例
This code sample demonstrates binding an "Inspect" action to a touch button created automatically by ContextActionService. The button is customized using SetImage(), SetTitle(), SetDescription() and SetPosition(). The button is further customized by using GetButton() to get a reference to the ImageButton itself and tinting it green by setting ImageButton.ImageColor3.
Paste this code into a LocalScript placed within StarterPlayerScripts to test it. In Studio, be sure to toggle the touch device emulator in order for the button to actually be created.
local ContextActionService = game:GetService("ContextActionService")
local ACTION_INSPECT = "Inspect"
local INPUT_INSPECT = Enum.KeyCode.E
local IMAGE_INSPECT = "rbxassetid://1826746856" -- Image of a speech bubble with ? in it
local function handleAction(actionName, inputState, _inputObject)
if actionName == ACTION_INSPECT and inputState == Enum.UserInputState.End then
print("Inspecting")
end
end
-- For touch devices, a button is created on-screen automatically via the 3rd parameter
ContextActionService:BindAction(ACTION_INSPECT, handleAction, true, INPUT_INSPECT)
-- We can use these functions to customize the button:
ContextActionService:SetImage(ACTION_INSPECT, IMAGE_INSPECT)
ContextActionService:SetTitle(ACTION_INSPECT, "Look")
ContextActionService:SetDescription(ACTION_INSPECT, "Inspect something.")
ContextActionService:SetPosition(ACTION_INSPECT, UDim2.new(0, 0, 0, 0))
-- We can manipulate the button directly using ContextActionService:GetButton
local imgButton = ContextActionService:GetButton(ACTION_INSPECT)
if imgButton then -- Remember: non-touch devices won't return anything!
imgButton.ImageColor3 = Color3.new(0.5, 1, 0.5) -- Tint the ImageButton green
end
SetTitle
设置称号将设置创建于 BindAction 下的触摸按钮上显示的文本。具体地,这将 TextLabel.Text 属性的一个 TextLabel
此函数是自定义交互按钮的行动作的一部分。其他在此家族中包括 SetImage 和 SetPosition。
参数
返回
代码示例
This code sample demonstrates binding an "Inspect" action to a touch button created automatically by ContextActionService. The button is customized using SetImage(), SetTitle(), SetDescription() and SetPosition(). The button is further customized by using GetButton() to get a reference to the ImageButton itself and tinting it green by setting ImageButton.ImageColor3.
Paste this code into a LocalScript placed within StarterPlayerScripts to test it. In Studio, be sure to toggle the touch device emulator in order for the button to actually be created.
local ContextActionService = game:GetService("ContextActionService")
local ACTION_INSPECT = "Inspect"
local INPUT_INSPECT = Enum.KeyCode.E
local IMAGE_INSPECT = "rbxassetid://1826746856" -- Image of a speech bubble with ? in it
local function handleAction(actionName, inputState, _inputObject)
if actionName == ACTION_INSPECT and inputState == Enum.UserInputState.End then
print("Inspecting")
end
end
-- For touch devices, a button is created on-screen automatically via the 3rd parameter
ContextActionService:BindAction(ACTION_INSPECT, handleAction, true, INPUT_INSPECT)
-- We can use these functions to customize the button:
ContextActionService:SetImage(ACTION_INSPECT, IMAGE_INSPECT)
ContextActionService:SetTitle(ACTION_INSPECT, "Look")
ContextActionService:SetDescription(ACTION_INSPECT, "Inspect something.")
ContextActionService:SetPosition(ACTION_INSPECT, UDim2.new(0, 0, 0, 0))
-- We can manipulate the button directly using ContextActionService:GetButton
local imgButton = ContextActionService:GetButton(ACTION_INSPECT)
if imgButton then -- Remember: non-touch devices won't return anything!
imgButton.ImageColor3 = Color3.new(0.5, 1, 0.5) -- Tint the ImageButton green
end
UnbindAction
UnbindAction 将从用户输入中的名称解除用户的动作的绑定,以便不再需要调用动作处理器功能。 调用此函数时,当某些动作上下文不再适用时,例如关闭用户界面、退出车辆或 unequipping 一个 Tool 。 请参阅
此函数 不会 抛出错误,如果没有与指定字符串关联的此操作。使用 GetAllBoundActionInfo 或开发者控制台的“操作绑定”选项卡,您可以查看现在有哪些操作正在绑定。
参数
返回
代码示例
This example properly shows how to use ContextActionService in binding user input to a contextual action. The context is the tool being equipped; the action is reloading some weapon. Test this code sample by placing it in a LocalScript parented to a Tool. When the Tool is equipped, a "Reload" action is bound, and when the Tool is unequipped the "Reload" action is unbound. When the player presses R with the Tool equipped, the message "Reloading!" will appear.
local ContextActionService = game:GetService("ContextActionService")
local ACTION_RELOAD = "Reload"
local tool = script.Parent
local function handleAction(actionName, inputState, _inputObject)
if actionName == ACTION_RELOAD and inputState == Enum.UserInputState.Begin then
print("Reloading!")
end
end
tool.Equipped:Connect(function()
ContextActionService:BindAction(ACTION_RELOAD, handleAction, true, Enum.KeyCode.R)
end)
tool.Unequipped:Connect(function()
ContextActionService:UnbindAction(ACTION_RELOAD)
end)
UnbindActivate
解除绑定使用 Enum.KeyCode (或 Enum.UserInputType ) 使用 Tool 来激活一个 1> Class.Tool1> (或 4> Class.HopperBin4> ) 使用 7> Class.ContextActionService:BindActivate()|BindActiv
参数
同一个 UserInputType 发送到 BindActivate。
同一个钥匙代码原始发送到 BindActivate。
返回
UnbindAllActions
移除所有绑定的函数。所有操作名称将不再存在。所有触摸按钮将被移除。如果按钮是手动操作的,那么将不会清洁。
返回
GetButton
GetButton 返回 ImageButton 由 BindAction 创建,如果其第三个参数是 true 并且设备是 TouchEnabled。 该函数的唯一参数必须与原始发送到 BindAction 的操作名称完全匹配。
如果没有此操作被绑定或者按钮未创建,此函数将返回 nil 。
参数
原始上,动作的名称通过 BindAction 传递给 BindAction。
返回
一个由 BindAction 创建的图像按钮。