玩家工具¶
Time:15 分钟
Tool(工具)是用于在 Roblox 中实现武器、魔杖和其他交互式对象的特殊实例。在本文中您将学到如何创建工具、如何让玩家能够装备工具,以及如何赋予工具能力和技能。
创建一个新的工具¶
工具是一个容器示例,就像 Model(模型)一样。要创建一个新的工具,请在 Workspace(工作区)中右键单击,选择 Insert Object(插入对象),然后选择 Tool(工具)。
再次提醒您,工具只是一个容器,所以如果它是空的,就不会显示在 3D 视图中。右键单击该工具并插入新的部件。该工具现在将显示在 3D 视图中。为了能被拾取,工具里需要有一个叫做 Handle(手柄)的部件。将工具中的部件重命名为 “Handle”。现在,如果您运行游戏,您的角色将能够拿起该工具。
自定义工具几何¶
一个工具可以包含任意多个部件。但请记住,只有一个部件能被命名为 Handle,因为该部件是工具将附加到角色的手的位置。这里有几个构建工具的小贴士:
当您完成构建时,请确保所有部件都没有锚固。如果工具的任何部分被锚固,工具将无法移动,角色在拿起它时将被卡住。
只命名一个部件为 Handle。如果有多个称为 Handle 的部件,工具将随意选择其中一个作为与手的连接点。
在创建工具时,请不要使用 Surface(表面)接合,这一点非常重要。用表面接合构造的工具在装备时会散开。当您将具有兼容表面(例如 Smooth/Weld 或 Inlet/Stud)的两个部件合并在一起时,会创建表面接合。您应将连接行为更改为 Always(始终),并确保所有部件的表面是 Smooth 或 SmoothNoOutlines。
由多个部件构建的工具示例:
在上面的示例中,白色部分是 Handle,其他部件使用接合连接在一起。
无手柄工具¶
您可以制作没有手柄或任何几何体的工具。在这种情况下,该工具就成为玩家输入的接口,而没有 3D 视图中的任何视觉表示。要制作这样的工具,只需关闭该工具的 RequiresHandle 属性。例如一个魔法物品,当它被拥有时,会给玩家一个通过键盘输入激活的特殊能力。
装备工具¶
工具可以通过多种方式装备。最简单的方法是将该工具放在工作区中,并在玩家与其发生碰撞时装备该工具。当这种情况发生时,该工具会自动添加到玩家的背包中。如果玩家当前没有任何装备,该工具将自动装备自己。请注意,这仅在工具的 RequiresHandle 属性设置为 true 时才有效。
您也可以使用 StarterPack 给玩家工具。每当玩家出生时,StarterPack 的所有内容都会被复制到玩家的背包中。如果您想确保所有玩家都使用相同的装备开始游戏,StarterPack 是实现此目的的最佳方式。
您还可以使用 Script(脚本)将工具提供给某个玩家,该脚本可以将该工具(或该工具的副本)放入玩家的背包中。
local copy = game.Workspace.Tool:Clone()
copy.Parent = game.Players.Player1.Backpack
您还可以通过将工具设置为玩家角色的子对象来强制玩家装备工具。
local copy = game.Workspace.Tool:Clone()
copy.Parent = game.Players.Player1.Character
使用脚本将工具给予角色时要小心!如果一个玩家已经装备了一个工具,而你强迫他们装备另一个,则两个工具可能会同时被装备,或许会导致意想不到的行为。
动作栏外观¶
当一个工具在玩家的背包里时,同时会出现在玩家屏幕底部的动作栏中。您可以自定义此栏中工具的工具提示和图标。可以通过编辑工具的 Tooltip 属性来设置工具提示。
您可以使用 TextureId 属性设置该工具的图标,可以像为贴花设置图像一样设置此属性的图像。
工具脚本基础知识¶
技术层面上,工具的目的是为玩家输入提供接口,因此有许多与它们相关的函数和事件可供开发人员与之交互。工具也是独一无二的,因为它们既可以运行常规脚本,也可以运行本地脚本。但是,由于它们与脚本的复杂关系,了解如何使用工具编写脚本的基础知识非常重要。
Script 对 LocalScript¶
Script 和 LocalScript 都可以监听相同的事件并调用工具上的相同函数。那么什么时候该使用哪一种呢?以下是一些一般指导原则:
代码符合下列条件时,应该使用 Script:
导致游戏世界发生变化(例如更改玩家健康状况、创建部件等)
代码符合下列条件时,应该使用 LocalScript:
依赖玩家输入(如鼠标或触摸输入)
需要只向拿着工具的玩家展示一些东西
事件¶
脚本可以监听四个工具特有的事件:
Activated:当玩家开始激活工具时(单击、触摸或按游戏手柄上的 A 键)。
Deactivated:玩家释放激活输入时。
Equipped:玩家从背包中选择工具。
Unequipped:玩家丢弃或切换工具时。
请记住,Script 和 LocalScript 都可以监听这些事件。下面是两个脚本连接到这些事件的代码:
-- 此代码假定脚本直接位于工具内部。如果脚本位于其他位置,则必须更改下一个变量所指向的路径。
local tool = script.Parent
local function onEquip()
end
local function onUnequip()
end
local function onActivate()
end
local function onDeactivate()
end
tool.Equipped:connect(onEquip)
tool.Unequipped:connect(onUnequip)
tool.Activated:connect(onActivate)
tool.Deactivated:connect(onDeactivate)
创建魔杖工具¶
在本例中,我们将演示如何制作一个简单的工具,该工具在持有者单击鼠标时会创建部件。我们将同时使用 Script 和 LocalScript 来说明它们分别的职责。
获取鼠标输入¶
每当用户单击鼠标时,都会触发 Activated 事件,但它不包含有关鼠标的信息。我们希望工具在用户单击的地方创建一个部件,因此知道该单击发生在空间中的哪个位置对我们来说很重要。要获得鼠标位置,我们需要使用 LocalScript,因为常规 Script 在服务器上运行,而服务器不知道任何有关用户鼠标的信息。
-- 本地 Script
local tool = script.Parent
local player = game.Players.LocalPlayer
local mouse = player:GetMouse()
local function onActivate()
local clickLocation = mouse.Hit
end
tool.Activated:connect(onActivate)
我们先为工具、玩家和玩家的鼠标创建了变量,然后在 onActivate 函数中,我们将单击的位置存储在了一个变量中。
创建部件¶
现在我们知道了玩家单击的位置,我们需要创建一个部件。哪个脚本应该处理此问题?在获得 LocalScript 中的位置后立即创建部件似乎是最简单的,然而这样做的问题是,LocalScript 仅在玩家的机器上运行,如果游戏中的 Experimental Mode(实验模式)处于关闭状态(这是默认设置),则由该 LocalScript 创建的任何部件都不会复制到服务器,则其他人不会看到您创建的部件!我们希望所有其他玩家都能够看到这些新的部件并与之交互,因此我们必须使用 Script 在服务器上创建该部件。
-- 服务器端 Script
local function createPart(location)
local part = Instance.new("Part")
part.CFrame = location
part.Parent = workspace
end
在 Script 和 LocalScript 之间通信¶
我们现在可以获取鼠标单击的位置,也可以在任意位置创建新部件,但是这些是用不同的脚本写的!我们需要让Script 和 LocalScript 之间能互相通信,以便其协同工作。为此,我们将使用前面创建的 RemoteEvent。
RemoteEvent 是可用于在 Script 和 LocalScript 之间发送信息的特殊对象。每个脚本都有一个事件侦听器,注册后就可以在事件触发时调用函数。我们也有一些函数可用于触发事件。
让我们从服务器 Script 上的侦听器开始。
-- 服务器端 Script
local tool = script.Parent
local clickEvent = tool.ClickEvent
local clickEventConnection
local function createPart(location)
local part = Instance.new("Part")
part.CFrame = location
part.Parent = workspace
end
local function onClick(player, clickLocation)
createPart(clickLocation)
end
local function onEquip()
clickEventConnection = clickEvent.OnServerEvent:connect(onClick)
end
local function onUnequip()
clickEventConnection:disconnect()
end
tool.Equipped:connect(onEquip)
tool.Unequipped:connect(onUnequip)
我们已经添加了相当多的内容,下面将进行逐步分解。首先,我们为工具和 RemoteEvent 声明了变量。我们还创建了变量 clickEventConnection,将使用它来存储事件连接。
然后,我们声明了函数 onClick,当侦听器听到事件触发时将调用该函数。该函数有两个参数,触发事件的玩家和玩家单击的位置(稍后将从 LocalScript 传入)。
在 onEquip 函数中,我们将 onClick 函数连接到 RemoteEvent 的 OnServerEvent 事件。这样,每当 RemoteEvent 触发时,它都会调用 onclick。最后,我们在 onUnequip 函数中的 clickEventConnection 上调用 disconnect,这样当玩家没有拿出工具时就不会触发该事件。
您可能已经注意到,我们将玩家传入了 onClick 函数,但我们从未实际使用过该变量。当您将函数绑定到 OnServerEvent 时,总是首先传入玩家参数,因此我们需要确保为它准备一个变量。
现在我们已经设置了 Script,我们只需要稍微修改一下 LocalScript,让它触发 RemoteEvent 即可。
-- 本地 Script
local tool = script.Parent
local player = game.Players.LocalPlayer
local mouse = player:GetMouse()
local clickEvent = tool.ClickEvent
local function onActivate()
local clickLocation = mouse.Hit
clickEvent:FireServer(clickLocation)
end
tool.Activated:connect(onActivate)
为了让 LocalScript 触发 RemoteEvent,我们调用 FireServer
。此函数可以接受我们想要的任意数量的参数。在本例中,我们只想传递玩家单击的位置。
现在,当我们装备好工具时,就可以通过单击来创建部件了!
***Roblox官方链接:玩家工具