Jump to content
模组网
icedream

【Creation Kit 学习指南 30】事件与属性

Recommended Posts

概述

本章将介绍Papyrus语言中的事件属性

你将学到:

  • 事件和触发事件的基本信息。
  • 属性和建立、设置、使用属性的基本信息。
  • 如何通过事件控制游戏。
  • 如何通过按照属性执行的动作控制游戏。
本章教程建立的事件将在Lokir的墓地中进行,它是我们在关卡设计教程中建立的样本地下城。如果没有完成这个教程,你可以下载最后一关插件。但是请你确保你已经熟练掌握关卡设计并掌握以下内容:
  • 基本导航编辑。
  • 诸如陷阱、激活、触发条件之类的概念。
计划

现在,当你进入Lokir的坟墓的最后一间房间,名叫尸鬼霸主将从棺材里跳出并攻击你。让我们用特别的脚本元素使这场战斗更为惊心动魄。我们将在房间里添加2个死亡尸鬼霸主,这样我们用勇气术咒文使尸鬼霸主从它的墓地中出现。

设定阶段

首先,让我们设定需要被复活的尸鬼。打开编辑器,打开LokirsTomb房间,然后将视角锁定在洞穴区域;这是BOSS的房间。在目标窗口点击Actors>Actor或者all-然后通过选项过滤器找出"LvlDraugrMissileMale""LvlDraugrWarlockMale"。并将它们拖放到房间里。

开始时,让角色(例如这些尸鬼)开始时“存活”,然后我们让它们死亡。依次双击每个角色并在选项框中勾选"Starts Dead"'

熟悉以前BGS的MOD制作者请注意-简单地设定基本角色的生命为0将不再导致角色开始就处于死亡状态。你必须在选项框中勾选"Starts Dead"。

保存你的插件并检查这些新特性 ,你将发现在房间的地面上有两个死亡尸鬼的骨骼贴图。这是我们想要的-但是让我们看Creation Kit的运行结果。

事件策划

gallery_1_72_111132.jpg

事件介绍

我们需要这些尸鬼复活并从坟墓中跳出。当然,我们希望这是通过触发事件产生。

"事件"是Papyrus脚本用以控制游戏的剧情和状态的东西。这里有众多不同的事件,例如:

  • 影响一个目标或人物(升级、开门、扒窃)。
  • 捡起物品,装备物品, 卸载装备, 或丢弃物品.
  • 进入或离开一个场所。
  • 进入或退出一场战斗, 战斗中受到攻击, 死亡.
简而言之-如果我们想影响游戏中的事物,事件是一个不错的选择。

触发活动事件

你也许不会意识到,我们的案例已用到Papyrus脚本中的事件。这是尸鬼总能在适当时机跳出棺材的原因。如果你已经完成陷阱教程,你会发现尸鬼通过脚步声大小来作为动作的触发条件。当主角的脚步发出声音,声音达到影响尸鬼的大小,尸鬼就会起来。

这里有一些脚本及它们的事件发生情况:
  • 玩家触发冲突而触发的事件。
  • 含有触发动态剧情的脚本产生的效果。
  • 尸鬼霸主处于待触发状态,因此也被激活。
  • 让尸鬼霸主跳出坟墓的脚本

我们可以使用相同触发条件来控制2个死亡尸鬼的活动。

对于每个尸鬼:

  • 双击尸鬼打开它的属性窗口。
  • 锁定并选择Activate Parents标签。
  • 右击列表空处并选择'New'。出现活动选择对话框。
  • 点击'Select Reference in Render Window'。
  • 当十字准线光标出现时,右击触发音量。
如果你没有看见触发条件,请记住使用"M"让标记可见。

现在当玩家达到触发条件时每个尸鬼将会有活动事件。实际上我们并不能用事件做所有事,然而接下来你将学习编写控制事件的脚本。

编写脚本

开始设计

现在开始脚本编写。打开你先前的文本编辑器。然后建立一个名为"LokirsDraugrReanimate.psc"新文件。

从以下两行开始:

scriptName LokirsDraugrReanimate extends Actor
{Resurrects the two dead Draugr in Lokir's Tomb.}
  • scriptName LokirsDraugrReanimate -这是脚本的名称,名称必须包括"后缀名"。
  • extends Actor -这个脚本将发生在角色(尸鬼)身上,因此它能做角色能做的任何事。
  • {...} -大双括号{}中的内容是文件描述信息-如同注释一样。这些并非必须填写的,但是它能让脚本后期维护更为方便,

我们设定它为活动事件,需要其他实体(例如主角或NPC)触发才能发生。通过“使用”或“激活”目标,在这种情况下,陷阱触发的脚本将被激活。

scriptName LokirsDraugrResurrection extends Actor
{Resurrects the two dead Draugr in Lokir's Tomb.}

Event OnActivate(ObjectReference akActionRef)
; Cast a Reanimate spell on the Draugr
EndEvent
展示效果

接下来,当活动事件发生时你需要对尸鬼施放勇气术。做完这些,你需要创建一个"属性"。在这种情况下,这是我们将要用到的咒语的属性。也就是要告诉Creation Kit将要使用的特殊咒语。

如果谁曾在早期Bethesda工具用legacy语言编辑脚本,这是一个重要改变。在Papyrus语言中,我们不能简单地将目标ID写入--你必须用到属性。这样可以写出更灵活更易维护的脚本,因为脚本中的每个案例的属性都有不同的数值。

"声明"咒语属性,如下:

scriptName LokirsDraugrResurrection extends Actor
{Resurrects the two dead Draugr in Lokir's Tomb.}

Spell property reanimateSpell auto

EVENT OnActivate(ObjectReference akActionRef)
	; Cast a Reanimate spell on the Draugr
EndEVENT
  • Spell - 说明我们将用到的类型是Spell。
  • property - 是reserved word,这里是添加一个新的属性。
  • reanimateSpell - 这是我们给变量的名字,在游戏里,当我们查阅属性时,Papyrus将用到spell.
  • auto - 另一个关键字 - 它告诉Papyrus自动对这个函数调用或赋值.不用担心它,它一般也没有作用。
  • ; ... - 分号后的内容是注释,用来标明作用方便维护,在脚本运行中不起作用。

我们已经定义一个咒语,但是它并没有效果。咒语属性可用Cast函数确定,接下来我们将用到,在活动事件脚本中插入:

scriptName LokirsDraugrResurrection extends Actor
{Resurrects the two dead Draugr in Lokir's Tomb.}

Spell property reanimateSpell Auto

EVENT OnActivate(ObjectReference akActionRef)
	; Cast a Reanimate spell on the Draugr
	reanimateSpell.Cast(Self, Self)
EndEVENT
如同很多函数一样,我们需要加入很多注解让人们知道这个函数要做什么。在这种情况下,Cast需要资源和对象。例如,我们需要尸鬼对它自己"cast"(施放)咒语。保留字"Self"在这种情况下就显得尤为重要;在其它方面使用它,Papyrus自动知道我们想关联它本身。在这种情况下,"self"如同对将要复活的尸鬼创造一个新的属性-只是和原来的相同。(其实"self"就是自己,意味着受和攻是同一人)

保存并编译脚本,然后返回Creation Kit。

关联脚本

返回编辑器,双击其中一个尸鬼来打开属性窗口,然后点击Scripts标签(你也可以按键盘上的'End'键跳到最右方)我们将在这里关联脚本:

  • 点击 Add.
  • Add script... 窗口, 输入新脚本的名字 'LokirsDraugrResurrection'.
  • 双击脚本并把它添加到尸鬼.
这样将脚本与reference关联,但是我们仍然需要告诉Creation Kit要施放的咒语。我们将用到"dunReanimateSelf",一个不可用的特殊事件咒语。
  • Scripts标签下选择LokirsDraugrResurrection
  • 点击Properties
  • 只有单属性才能出现的列表 - reanimateSpell
  • 选择reanimateSpell并点击Edit Value
  • 注意:在这种情况下这个列表只出现一个正常的表格 - spells
  • 选择 dunReanimateSelf。点击 OK。
对另一个尸鬼重复相同的步骤。保存你的工作并在游戏中体验成果!

调试脚本

第一眼看到脚本,我们会认为所有结果都是意料之中。然而,当你进行游戏,你会注意到任何时候只要触发活动事件复活事件就会发生在尸鬼身上。在玩家搜刮其尸体时也会发生!这并不是严重的问题,而是逻辑上的疏漏导致意料之外的BUG。

这里有成百上千种解决之道,例如通过控制让复活只发生一次。也可以让脚本忽略玩家的行为,不过这样依然会导致NPC的活动触发事件。

取而代之的是,我们可以让复活行为只发生在触发条件发往活动事件时。我们将通过建立另一个属性 -目标引用 - 我们将把它分配给触发条件。

我们用新的属性和OnActivate()提供的参数"akActionRef"作比较。这个参数是一系列特殊变量,只在这个活动事件中可用,Papyrus自动只将复活函数用在这个活动事件。

scriptName LokirsDraugrResurrection extends Actor
{This Script lives on the dead minion draugr in Lokir's Tomb.
It handles their resurrection}

Spell property reanimateSpell Auto
; this is the special self-resurrection spell to use
objectReference property myTrigger auto
; This is the reference we are waiting on to send an activate

Event OnActivate(ObjectReference akActionRef)
	; I've been activated - see if was my trigger
	if (akActionRef == myTrigger)
		; Cast a Reanimate spell on the Draugr
		reanimateSpell.Cast(Self, Self)
	EndIf
EndEvent
  • objectReference 这是新属性的数据类型
  • myTrigger 这是新属性的名字
  • if 这是"if条件语句"的开始。如果if后面的状态是真实,接下来的脚本将运行,换句话说,如果为真,Papyrus就将运行接下来的脚本直到"endif"
  • (akActionRef == myTrigger)
  • "=="是一个逻辑运算符,它意味着相等。在这种情况下,如果akActionRefmyTrigger相等,将继续运行一下内容。
  • endIf
  • 这对于结束if条件语句十分重要,如果有多个if条件语句嵌套尤其需要注意endIf的对应关系,这对于逻辑的路线来说非常重要。

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×
×
  • Create New...