射线投射:创建激光枪¶
Time:10 分钟
Roblox 中的射线投射功能可用于检测某个部件是否与某条线段相交。本教程介绍如何使用射线投射功能创建激光枪。
教程¶
设置¶
要创建激光枪,玩家需要手握一个工具。请前往工具箱,选择 Roblox Sets (Roblox 集合),然后选择 Weapons (武器)集合。单击彩弹枪,并在系统提示时将它放入 StarterPack 中。打开 StarterPack 并移除名为 Handle 的部件之外的所有内容。然后,将 LocalScript
插入工具。请确保它不是 Script
,否则当你在线开始游戏时,该函数将不起作用!可以随意对该工具进行重命名,但不要更改部件名称!
框架¶
既然我们已经完成设置,现在该开始对我们的枪进行脚本处理了。我们先从一些变量开始:
local tool = script.Parent
local player = game:GetService("Players").LocalPlayer
tool
变量用于引用工具,player
变量用于引用使用这把枪的玩家。现在,我们执行一些操作,通过连接至工具的 Tool/Equipped
事件来装备工具:
local tool = script.Parent
local player = game:GetService("Players").LocalPlayer
tool.Equipped:connect(function(mouse)
print("Tool equipped!")
end)
现在,每当工具装备完毕,它就可以将 Tool equipped! 打印至“Output(输出)”窗口。你可能会注意到该函数的鼠标参数;即可用于响应玩家鼠标单击操作的 Mouse
对象。连接至鼠标的 Mouse/Button1Down
事件,如下所示:
local tool = script.Parent
local player = game:GetService("Players").LocalPlayer
tool.Equipped:connect(function(mouse)
print("Tool equipped!")
mouse.Button1Down:connect(function()
print("Mouse pressed!")
end)
end)
现在,当你单击你的鼠标时,Mouse pressed! 将被打印至输出窗口。快试试吧!开始游戏、装备工具并按下几次鼠标,你应该会看到如下内容:
Mouse pressed!
Mouse pressed!
Mouse pressed!
Tool equipped!
Mouse pressed!
射线投射¶
既然我们已经完成框架设置,接下来我们开始投射射线。将此射线添加到鼠标下移函数:
local ray = Ray.new(tool.Handle.CFrame.p, (mouse.Hit.p - toolHandle.CFrame.p).unit * 300)
这将创建从工具手柄中央开始射出的射线 (tool.Handle.CFrame.p
),并朝鼠标的位置射出 300 格 ((mouse.Hit.p - tool.Handle.CFrame.p).unit * 300
)。但是就其自身而言,此操作不会检测是否有部件挡住射线,所以我们需要使用 Workspace
的 Workspace/FindPartOnRay
方法。FindPartOnRay 包含四个参数:检查部件时所用的射线、要忽略的对象、是否将所有地形单元格视为完整的立方体,以及是否忽略水。由于这是激光,我们希望忽略水,也希望玩家不要朝自己开枪,因此我们希望像下面这样调用激光:
local part, position = workspace:FindPartOnRay(ray, player.Character, false, true)
part
是指被击中的部件(或是 type|nil,如果没有部件挡道),position
是指射线击中部件的位置。让我们将此射线添加到函数中吧。在 Button1Down 连接中,添加之前的线。你的脚本现在应该如下所示:
local tool = script.Parent
local player = game:GetService("Players").LocalPlayer
tool.Equipped:connect(function(mouse)
print("Tool equipped!")
mouse.Button1Down:connect(function()
print("Mouse pressed!")
local ray = Ray.new(tool.Handle.CFrame.p, (mouse.Hit.p - tool.Handle.CFrame.p).unit * 300)
local part, position = workspace:FindPartOnRay(ray, player.Character, false, true)
end)
end)
完成该操作后,你就可以创建激光束了!
创建激光束¶
能够看到挡住鼠标的对象后,我们可以在射线的起点(工具手柄中央)与射线击中的位置之间创建激光束。现在我们按如下所示创建激光束:
要开始创建激光束,我们需要在 Button1Down 连接中创建一个部件,如下所示:
local beam = Instance.new("Part", workspace)
但是此部件只是青砖,不是光束。要使其与我们的示例类似,需要执行以下几项操作:
需要将其
BasePart/BrickColor
属性设置为“Bright red(亮红色)”。需要将其
FormFactorPart/FormFactor
属性设置为“Custom(自定义)”需要将其
BasePart/Material
属性设置为“Neon(氖气)”需要将其
BasePart/Transparency
属性设置为 0.25需要将其
BasePart/Anchored
和BasePart/Locked
属性设置为 true,并将BasePart/CanCollide
属性设置为 false。
让我们执行这些操作吧!创建部件后,设置激光束的属性:
beam.BrickColor = BrickColor.new("Bright red")
beam.FormFactor = "Custom"
beam.Material = "Neon"
beam.Transparency = 0.25
beam.Anchored = true
beam.Locked = true
beam.CanCollide = false
但是,如果将此激光束放在工作区中,它看起来就像一块红砖。我们需要修改其 BasePart/Size
和 BasePart/CFrame
属性,以便激光束在手柄和击中点之间延伸。为此,请使用以下脚本:
local distance = (tool.Handle.CFrame.p - position).magnitude
beam.Size = Vector3.new(0.3, 0.3, distance)
beam.CFrame = CFrame.new(tool.Handle.CFrame.p, position) * CFrame.new(0, 0, -distance / 2)
现在,激光枪可以正常使用 - 它会射出可击中部件的射线光束。你甚至可以朝天空发射,它会在天上射出光束(即使天空中没有部件)。但是存在一个问题:光束无法移除。要移除光束,我们应使用 Debris
服务的 Debris/AddItem
方法。请将此方法添加到 Button1Down 连接的底部:
game:GetService("Debris"):AddItem(beam, 0.1)
这意味着,在光束后添加了 0.1 (1/10) 秒,光束将被移除。你的脚本现在应如下所示:
local tool = script.Parent
local player = game:GetService("Players").LocalPlayer
tool.Equipped:connect(function(mouse)
print("Tool equipped!")
mouse.Button1Down:connect(function()
print("Mouse pressed!")
local ray = Ray.new(tool.Handle.CFrame.p, (mouse.Hit.p - tool.Handle.CFrame.p).unit * 300)
local part, position = workspace:FindPartOnRay(ray, player.Character, false, true)
local beam = Instance.new("Part", workspace)
beam.BrickColor = BrickColor.new("Bright red")
beam.FormFactor = "Custom"
beam.Material = "Neon"
beam.Transparency = 0.25
beam.Anchored = true
beam.Locked = true
beam.CanCollide = false
local distance = (tool.Handle.CFrame.p - position).magnitude
beam.Size = Vector3.new(0.3, 0.3, distance)
beam.CFrame = CFrame.new(tool.Handle.CFrame.p, position) * CFrame.new(0, 0, -distance / 2)
game:GetService("Debris"):AddItem(beam, 0.1)
end)
end)
伤害对象¶
画出光束后,现在需要使其伤害玩家和其他具有 Humanoid
对象的部位。首先,我们需要在创建光束后使用 if 语句,以检查部件是否存在:
if part then
end
有时,部位不存在,射线就找不到它,因此 part
将为零。我们需要将这种情况考虑在内,以免脚本出错。完成这些操作后,我们应查看两个位置以查找对象的人形:部位的父项(以防击中手臂或腿)和部位父项的父项(以防击中帽子或工具)。要查找该人形,请使用以下脚本:
if part then
local humanoid = part.Parent:FindFirstChild("Humanoid")
if not humanoid then
humanoid = part.Parent.Parent:FindFirstChild("Humanoid")
end
end
首先,我们检查部位的父项。如果未找到,则查看部位父项的父项。但愿我们能找到人形,但有时找不到,因此在尝试伤害它之前,我们需要确保存在人形。请将你的 if 语句更改为如下所示:
if part then
local humanoid = part.Parent:FindFirstChild("Humanoid")
if not humanoid then
humanoid = part.Parent.Parent:FindFirstChild("Humanoid")
end
if humanoid then
humanoid:TakeDamage(30)
end
end
现在我们将进行检查,以确保存在人形,然后使用 Humanoid/TakeDamage
方法对它造成 30 点伤害。TakeDamage 无法伤害受 ForceField
保护的人形。你的脚本现在应如下所示:
local tool = script.Parent
local player = game:GetService("Players").LocalPlayer
tool.Equipped:connect(function(mouse)
print("Tool equipped!")
mouse.Button1Down:connect(function()
print("Mouse pressed!")
local ray = Ray.new(tool.Handle.CFrame.p, (mouse.Hit.p - tool.Handle.CFrame.p).unit * 300)
local part, position = workspace:FindPartOnRay(ray, player.Character, false, true)
local beam = Instance.new("Part", workspace)
beam.BrickColor = BrickColor.new("Bright red")
beam.FormFactor = "Custom"
beam.Material = "Neon"
beam.Transparency = 0.25
beam.Anchored = true
beam.Locked = true
beam.CanCollide = false
local distance = (tool.Handle.CFrame.p - position).magnitude
beam.Size = Vector3.new(0.3, 0.3, distance)
beam.CFrame = CFrame.new(tool.Handle.CFrame.p, position) * CFrame.new(0, 0, -distance / 2)
game:GetService("Debris"):AddItem(beam, 0.1)
if part then
local humanoid = part.Parent:FindFirstChild("Humanoid")
if not humanoid then
humanoid = part.Parent.Parent:FindFirstChild("Humanoid")
end
if humanoid then
humanoid:TakeDamage(30)
end
end
end)
end)
所有操作均已完成!尽情享受你的新激光枪吧!
最终产品¶
制作一把射线投射激光枪 ```
local tool = script.Parent
local player = game:GetService("Players").LocalPlayer
tool.Equipped:Connect(function(mouse)
print("Tool equipped!")
mouse.Button1Down:Connect(function()
print("Mouse pressed!")
local ray = Ray.new(tool.Handle.CFrame.p, (mouse.Hit.p - tool.Handle.CFrame.p).unit * 300)
local part, position = workspace:FindPartOnRay(ray, player.Character, false, true)
local beam = Instance.new("Part", workspace)
beam.BrickColor = BrickColor.new("Bright red")
beam.FormFactor = "Custom"
beam.Material = "Neon"
beam.Transparency = 0.25
beam.Anchored = true
beam.Locked = true
beam.CanCollide = false
local distance = (tool.Handle.CFrame.p - position).magnitude
beam.Size = Vector3.new(0.3, 0.3, distance)
beam.CFrame = CFrame.new(tool.Handle.CFrame.p, position) * CFrame.new(0, 0, -distance / 2)
game:GetService("Debris"):AddItem(beam, 0.1)
if part then
local humanoid = part.Parent:FindFirstChild("Humanoid")
if not humanoid then
humanoid = part.Parent.Parent:FindFirstChild("Humanoid")
end
if humanoid then
humanoid:TakeDamage(30)
end
end
end)
end)
***__Roblox官方链接__:[射线投射:创建激光枪](https://developer.roblox.com/zh-cn/articles/Making-a-ray-casting-laser-gun-in-Roblox)