通过事件让部件着火

Time:10 分钟

在本教程中,我们将会学习如何通过事件和函数在游戏中创建可以点燃及熄火部件的区域。

Scripting5_Final.png

初始设置

让我们从向游戏中放入两个部件开始。第一个部件将被用来点燃所有与其触碰的部件;第二个部件将被用来熄灭已经点燃的火焰。请确保两个部件在 Explorer(管理器)中的名称分别为 FirePart(点燃用部件)和 WaterPart(熄灭用部件)。

Scripting5_Parts.png

接下来,我们需要在 ServerScriptService 中创建一个 Script(脚本)。右键单击 ServerScriptService,将鼠标悬停在 Insert Object(插入对象)上方,然后选择 Script(脚本)

点燃火焰

我们现在应该已经对函数的使用有了一定的经验:printwait 函数可以在任何 Roblox 脚本中运行,而 SetMinutesAfterMidnight 是 Lighting 服务的成员函数。虽然上述函数都是由 Roblox 事先定义好的,但开发者也可以根据需要在脚本中创建各种自定义函数。

首先,我们需要创建一个能够点燃部件的函数。就从下面的几行代码开始吧:

部件上玩家的触碰检测 - 点燃部件:代码示例 1 ```

function lightOnFire()
	print("着火了!")
end
创建函数时,我们需要确保包括几个重要的组成部分:第一行代码的开头必须使用关键字 **function**。紧跟其后的单词将会成为函数的名称。为函数命名的规则与为变量命名的规则相同(无空格、不得以数字开头等)。在函数名称的后面需要添加括号 ()。在下面一行中,我们将会添加当函数被调用时运行的代码。在上述示例中,调用 lightOnFire 函数后,代码 print(“着火了!”) 将会运行。当添加所有需要运行的代码后,使用关键字 **end** 来结束函数的编写。

目前我们的函数还远远没有完成,但让我们先对其进行调用,稍微测试一下吧。如果现在对游戏进行 **Run**(运行),你会发现什么都不会发生。我们之前所编写的 print 语句并不会显示在 Output(输出)中。这是因为虽然我们对函数调用后的操作进行了编写,但并没有对函数进行调用。自定义函数的调用方式与其他普通函数相同:使用函数名称,后跟括号。请参照下列示例:

部件上玩家的触碰检测 - 点燃部件:代码示例 2 ```    
    
    function lightOnFire()
    	print("着火了!")
    end
    
    lightOnFire()
    
    
    "Lighting on fire!"

如果我们现在运行游戏,*着火了!*将显示在 Output(输出)中。

当创建自定义函数时,请务必确保在使用函数前对其先进行定义。在上述示例中,我们先对函数进行了定义,然后才对其进行调用。如果反而行之,则函数将不会正确运行:

部件上玩家的触碰检测 - 点燃部件:代码示例 3 ```

lightOnFire()

function lightOnFire()
	print("着火了!")
end
上述代码示例将不会正常运行。我们在代码的第一行就调用了 _lightOnFire()_,但由于没有事先定义函数的内容,将会导致 Script(脚本)出错。

让我们继续编写函数吧。现在的函数只能打印至输出窗口,这离我们“点燃一切”的需求还差得很远!我们希望能够通过这个函数将特定部件点燃,那么接下来就需要确保函数知道需要点燃的是哪个部件。让我们通过向函数添加 _Parameter_(参数)来完成这一步骤吧。在函数定义中的括号内添加关键字 part,如下所示:

部件上玩家的触碰检测 - 点燃部件:代码示例 4 ```    
    
    function lightOnFire(part)
    	print("将要点燃这个部件:")
    	print(part.Name)
    end

上述代码中的关键字 part 是函数的参数。之前我们曾经在其他函数中使用过一些参数:使用 wait 函数时,需要提供一个数字作为参数;使用 print 函数时,需要提供一个字符串或数字作为参数。在这个代码示例中,我们需要提供的是希望点燃的 Part(部件)。在函数内部,我们将可以像普通变量一样使用 part。

接下来,让我们添加点燃后出现的火焰。添加火焰最为简单的方式就是在代码中创建新的 Fire 实例,并将其父项设置为传递进来的部件。创建火焰实例的方法与创建新部件的方法一致:只需将 Instance.new(“Part”) 修改为 Instance.new(“Fire”) 即可。同时,我们需要确保将火焰保存在变量中,以便设置其 Parent(父项)属性。

部件上玩家的触碰检测 - 点燃部件:代码示例 5 ```

function lightOnFire(part)
	print("将要点燃这个部件:")
	print(part.Name)
	
	fire = Instance.new("Fire")
	fire.Parent = part
end
最后,我们需要确保每当部件触碰我们在教程开头创建的 _FirePart_ 时,都会调用此函数。让我们通过使用 **Event**(事件)来达成这个目标。事件用于在游戏中出现指定状况时对函数进行调用。事件可以包括以下状况:部件碰撞、玩家加入游戏、玩家按下按钮等。当事件发生时,我们可以在多处调用自定义函数。本示例中使用的事件为 **Touched**,与部件相关联:

部件上玩家的触碰检测 - 点燃部件:代码示例 6 ```    
    
    function lightOnFire(part)
    	print("将要点燃这个部件:")
    	print(part.Name)
    	
    	fire = Instance.new("Fire")
    	fire.Parent = part
    end
    
    firePart = game.Workspace.FirePart
    firePart.Touched:Connect(lightOnFire)

接下来,让我们进行游戏测试!点击 **Play(开始游戏)**后,将会生成游戏角色。控制角色走向 FirePart。当角色触碰到该部件时,其双腿将会燃烧起来!

Scripting5_Final.png

熄灭火焰

让我们为玩家们提供一个熄灭火焰的方法:触碰 WaterPart。如点燃火焰时相同,我们将需要创建一个能够熄灭火焰的函数,并将其连接至 WaterPart 的 Touched 事件。

部件上玩家的触碰检测 - 点燃部件:代码示例 7 ```

function putOutFire(part)
	print("要灭掉这个部件上的火:")
	print(part.Name)
end

waterPart = game.Workspace.WaterPart
waterPart.Touched:Connect(putOutFire)
为了熄灭火焰,我们将会使用名为 _Destroy_ 的函数。对 Roblox 中的任何对象使用此函数后,都将导致该对象被移除。或许你会想要像下面这样编写熄灭火焰的代码:

部件上玩家的触碰检测 - 点燃部件:代码示例 8 ```    
    
    function putOutFire(part)
    	print("要灭掉这个部件上的火:")
    	print(part.Name)
    	
    	part.Fire:Destroy()
    end
    
    waterPart = game.Workspace.WaterPart
    waterPart.Touched:Connect(putOutFire)

虽然上面的代码可用于扑灭火焰,但当角色没有着火并触碰 WaterPart 时,又会发生什么情况呢?

Scripting5_Error.png

没错,在这种情况下,之前的代码将会导致错误。在为游戏进行代码编写时,最理想的状况是不出现任何错误。为了修正这个情况,我们首先需要检查试图进行灭火的部件中是否存在火焰实例。该操作可以通过名为 FindFirstChild 的函数轻松完成:该函数可以查看指定名称的部件是否存在于其他对象中。函数的结果甚至可以被储存在变量中。让我们立即执行这一操作吧:

部件上玩家的触碰检测 - 点燃部件:代码示例 9 ```

function putOutFire(part)
	print("将要灭掉这个部件上的火:")
	print(part.Name)
	
	fire = part:FindFirstChild("Fire")
	if fire then
		fire:Destroy()
	end
end

waterPart = game.Workspace.WaterPart
waterPart.Touched:Connect(putOutFire)
在刚刚创建的函数中,我们会在打印输出语句后创建名为 **fire** 的变量,并在该变量中存储 _FindFirstChild(“Fire”)_ 的结果。下一行 **if fire then** 是条件性检查,用于查看 fire 中是否已存储任何内容。如果 FindFirstChild 成功存储 fire 变量中的内容,则将调用下一行 _fire:Destroy()_。否则,在未找到任何内容时,函数将不会执行任何操作。如此一来,在调用函数时就不会产生任何错误。

下面,让我们使用 **Play(开始游戏)**对游戏进行测试。在游戏中,我们将可以通过触碰 FirePart 点燃角色,然后触碰 WaterPart 来熄灭火焰。

## 后续步骤

让我们将这段新的代码与地形结合使用吧!使用地形后,玩家踩到火山熔岩时将会着火,而跳入水中后就可以熄灭身上的火焰。这种体验将会比普通的砖块要有趣逼真得多。首先,我们将会使用 **Add(添加)**地形工具来添加地形:

![Scripting5_Terrain.png](https://developer.roblox.com/assets/blt9052bdb90d586afe/Scripting5_Terrain.png)



移动并缩放之前创建的火部件和水部件,使其与刚刚添加的地形完全重叠。确保这两个部件都处于 *Anchored(锚固)*状态,且其 _`BasePart/CanCollide`_ 属性处于关闭状态。另外,你还可以将其 _Transparency_ 属性将其设为半透明,以便更为精确地为部件定位。

![Scripting5_TerrainAndParts.png](https://developer.roblox.com/assets/blt71975783c3b1e88e/Scripting5_TerrainAndParts.png)



在脚本末尾,我们会将这两个部件设为完全透明,使其不显示在游戏成品中:
    
    
    firePart.Transparency = 1
    waterPart.Transparency = 1
    

这样一来,代码就完成了!在开始游戏时,玩家可以跳到熔岩上点燃自己,也可以跳到水中将火灭掉!

![Scripting5_TerrainFinished.png](https://developer.roblox.com/assets/bltf9123e3441e2ad23/Scripting5_TerrainFinished.png)



下面是我们刚刚编写的所有代码:

部件上玩家的触碰检测 - 点燃部件:代码示例 10 ```    
    
    function lightOnFire(part)
    	print("将要点燃这个部件:")
    	print(part.Name)
    	
    	fire = Instance.new("Fire")
    	fire.Parent = part
    end
    
    firePart = game.Workspace.FirePart
    
    firePart.Touched:Connect(lightOnFire)
    
    function putOutFire(part)
    	print("将要灭掉这个部件上的火:")
    	print(part.Name)
    	
    	fire = part:FindFirstChild("Fire")
    	if fire then
    		fire:Destroy()
    	end
    end
    
    waterPart = game.Workspace.WaterPart
    waterPart.Touched:Connect(putOutFire)
    
    firePart.Transparency = 1
    waterPart.Transparency = 1

***Roblox官方链接:通过事件让部件着火