原文地址 https://www.iddevnet.com/doom3/entitydefs.php
doom3实体定义
一个entityDef只不过是一个带有一个名字的键/值对的集合。
它们通常用于定义实体(因此名称),
但它们可以真正用于定义可以使用键/值对列表定义的任何内容。
键和值的含义完全取决于对象的类型,
但是有两个键/值对保持不变,不管类型如何。
“spawnclass”键定义了“生成”这个实体的C ++类。
项目使用 idItem,trigger_once使用idTrigger_Multiple,怪物使用idAI等。
如果你知道C ++,你可以添加新的spawn类到游戏代码,
如果现有的不适合你的需要。没有“spawnclass”键的实体无法产生。
“继承”键可以让游戏复制来自另一个entityDef的所有键/值对。
循环引用是不可能的,因为每个entityDef只解析一次(你会得到一个错误)。
这是一个非常有用的钥匙。你可以做一些事情,如创建一个所有怪物继承的默认怪物。
这不仅可以节省打字,而且可以让你在一个地方改变一些东西,
并影响一堆物体(这是一种祝福和诅咒)。
编辑器使用任何以editor_开头的键。它特别寻找的一些键是:
键 | 价值/描述 |
---|---|
editor_color | 3个浮点数,用于定义编辑器中实体的颜色 |
editor_mins editor_max | 3个浮动每个定义实体的边界框的大小。?可用于创建动态大小的实体(如触发器)。注意:编辑器中的大小并不总是游戏中的大小,因为碰撞几何可能在其他地方指定。 |
editor_usage | 描述实体是什么以及如何使用它的文本 |
editor_material | 适用于实体的材料 |
editor_var <key> | 描述spawnvar <key>的文本描述。这允许级别设计器覆盖entityDef中的值 |
editor_copy <key> | 当创建此类型的对象时,将密钥从实体def复制到实体 |
editor_rotatable | Bool如果实体可以自由旋转,设置为1 |
editor_showangle | Bool设置为1以显示角度箭头 |
editor_mover | Bool设置为1以使用“movedir”而不是“angle”作为角度 |
editor_env | Bool如果对象是某种环境布娃娃,则设置为1 |
editor_combatnode | Bool设置为1以绘制该实体的作战区域 |
editor_light | Bool设置为1以像光一样对待这个实体 |
我们来看一下霰弹枪的一个例子entityDef
(这不是在def文件中看到的方式,为了清楚起见我已经重新排列了一些东西)
entityDef weapon_shotgun {
//全球
“spawnclass”“idItem”
//编辑器使用
“editor_color”“.3 .3 1”
“editor_mins”“-16 -16 0”
“editor_maxs”“16 16 32”
“editor_usage”“霰弹枪”
“editor_rotatable”“1”
//由idItem使用
“def_dropItem”“moveable_item_shotgun”
“inv_name”“霰弹枪”
“inv_weapon”“weapon_shotgun”
“inv_ammo_shells”“4”
“inv_item”“5”
“snd_acquire”“sound_weapon_acquire”
“snd_respawn”“sound_weapon_respawn”
//由idEntity使用
“size”“32 32 32”
“型号”“型号/武器/霰弹枪/ w_shotgun2.lwo”
//由idWeapon使用
“model_view”“viewmodel_shotgun”
“model_world”“worldmodel_shotgun”
“joint_attach”“SHOTGUN_ATTACHER”
“icon”“guis / assets / hud / wpn_2”
“weapon_scriptobject”“weapon_shotgun”
“def_projectile”“projectile_bullet_shotgun”
“ammoType”“ammo_shells”
“ammoRequired”“1”
“clipSize”“8”
“lowAmmo”“2”
“mtr_flashShader”“muzzleflash”
“flashColor”“1 0.8 0.4”
“flashRadius”“120”
“silent_fire”“0”
“recoilTime”“325”
“recoilAngles”“-1 0 0”
“weaponAngleOffsetAverages”“15”
“weaponAngleOffsetScale”“.40”
“weaponAngleOffsetMax”“20”
“weaponsOffsetTime”“500”
“weaponOffsetScale”“0.005”
“hide_time”“0.3”
“hide_distance”“-15”
“smoke_muzzle”“shotgunmuzzlesmoke.prt”
“def_ejectBrass”“fragments_shotgunbrass”
“ejectBrassDelay”“650”
//由脚本使用
“传播”“22”
“skin_invisible”“皮肤/ shotgun_invis”
}
//全球
“spawnclass”“idItem”
//编辑器使用
“editor_color”“.3 .3 1”
“editor_mins”“-16 -16 0”
“editor_maxs”“16 16 32”
“editor_usage”“霰弹枪”
“editor_rotatable”“1”
//由idItem使用
“def_dropItem”“moveable_item_shotgun”
“inv_name”“霰弹枪”
“inv_weapon”“weapon_shotgun”
“inv_ammo_shells”“4”
“inv_item”“5”
“snd_acquire”“sound_weapon_acquire”
“snd_respawn”“sound_weapon_respawn”
//由idEntity使用
“size”“32 32 32”
“型号”“型号/武器/霰弹枪/ w_shotgun2.lwo”
//由idWeapon使用
“model_view”“viewmodel_shotgun”
“model_world”“worldmodel_shotgun”
“joint_attach”“SHOTGUN_ATTACHER”
“icon”“guis / assets / hud / wpn_2”
“weapon_scriptobject”“weapon_shotgun”
“def_projectile”“projectile_bullet_shotgun”
“ammoType”“ammo_shells”
“ammoRequired”“1”
“clipSize”“8”
“lowAmmo”“2”
“mtr_flashShader”“muzzleflash”
“flashColor”“1 0.8 0.4”
“flashRadius”“120”
“silent_fire”“0”
“recoilTime”“325”
“recoilAngles”“-1 0 0”
“weaponAngleOffsetAverages”“15”
“weaponAngleOffsetScale”“.40”
“weaponAngleOffsetMax”“20”
“weaponsOffsetTime”“500”
“weaponOffsetScale”“0.005”
“hide_time”“0.3”
“hide_distance”“-15”
“smoke_muzzle”“shotgunmuzzlesmoke.prt”
“def_ejectBrass”“fragments_shotgunbrass”
“ejectBrassDelay”“650”
//由脚本使用
“传播”“22”
“skin_invisible”“皮肤/ shotgun_invis”
}
看这个脚本,我们开始看到代码中有3个不同的部分都使用这个entityDef。
第一个是编辑器,我们几乎可以忽略。下一段代码是idItem。
这是有道理的,因为我们将'idItem'指定为spawnclass,
所以自然地,类将要窥视一些值来正确地产生对象。
idEntity关心这个实体的原因是idItem来自idEntity。
这意味着每个idItem 都是一个idEntity。
游戏代码中的几乎所有内容都是从idEntity派生的。
(它类似于我们如何使用'inherit'从另一个entityDef复制公共属性)。
令人困惑的部分是idWeapon适合图片的位置。
我们知道霰弹枪是一种武器,但似乎没有任何地方可以告诉我们的代码。
这里的魔术钥匙是inv_weapon。
该键告诉idItem该项是武器,并使用 weapon_shotgun entityDef 定义 idWeapon 的参数。
它只是发生在idItem的entityDef与idWeapon的entityDef相同。
重要的是要注意,虽然它们都设置为“武器枪”,但不一定是它们。
其实他们不是像背包这样的东西。
这是一个给你健康,护甲和弹药的物品。
背包entityDef定义了世界上的对象,但其他东西在其他地方定义。
为了测试这个,你可以添加“inv_weapon”“weapon_shotgun”到“item_medkit”entityDef,
并注意你每次拿起一个药盒时都会得到一个霰弹枪。
另一个真正重要的关键是“weapon_scriptobject”
这说明游戏代码运行哪个脚本来使霰弹枪工作。
在这种情况下,对象名称与实体名称相同,但是它不一定是必须的。
装备霰弹枪时,它告诉武器代码开始使用“weapon_shotgun”对象
(在weapon_shotgun.script中定义)。
有趣的是,只有一个武器脚本运行。
当您切换武器时,它不会破坏脚本对象并创建一个新的对象,
它只是告诉脚本对象变成一个新的类型。
我们难题的缺失部分是伤害。毕竟,没有损坏的猎枪只是一个玩具。
损伤的方式看起来很奇怪,但实际上效果非常好。
当您按下攻击按钮时,霰弹枪脚本会调用launchProjectiles(13),
该弹射器发射13枚射弹。
这些弹丸也是由“def_projectile”键定义为“projectile_bullet_shotgun”的实体。
如果我们看“projectile_bullet_shotgun”,我们看到它是一个idProjectile,
它具有一系列的属性,可以定义它的外观,它如何飞行,它如何爆炸,
当它碰到各种类型的曲面时它的声音,以及一个一堆其他的东西。
它定义的一个是“def_damage”,它是一个定义损害的entityDef。
原来,还有更多的伤害比伤害多少。
还有第一人看起来如何,第三人看起来如何,你如何敲你回来,以及它是否能够吸收身体。
看着“damage_shotgun”,
我们看到每颗球都有14点伤害。乘以13粒,你会痛苦很多。
entityDefs在级别加载时间中起着非常重要的作用。
级别加载的资产通过走在级别和代码中定义的entityDefs来确定。
在创建新的entityDefs时,遵循这些命名指南是非常重要的,
以便预备功能正常工作:
字首 | 类型 |
---|---|
SND | 声音消失 |
mtr | materials(材质 ) |
model | Models |
smoke | 烟雾系统 |
GUI | GUI文件 |
高清 | 另一个实体 |
皮肤 | 皮肤 |
pda_name | 掌上电脑 |
FX | FX |
视频 | 视频解析 |
音频 | 音频日志 |
inv_icon | 库存图标 |
还有其他一些你可以通过查看游戏代码找到,但它们几乎贬值,不应该被使用。
未使用这些前缀意味着并非所有资产都将在地图加载中加载。
它们在被引用时会被加载,从而在游戏中引起联机(这是
doom3 mapdef
doom3的地图定义,在脚本编辑器中来进行定义了
地图定义非常像Quake 3中的.arena文件。它定义了地图的名称,它支持哪些游戏模式,以及在每个质量模式下以多少(以字节为单位)。
以下是Alpha Labs 1的示例: | 和DM地图比较: |
这个decl中的字段应该很容易弄清楚,“devname”是我们指向地图的内部名称。
它主要被'takeViewNotes2'命令使用,
这可能不再起作用(内部使用它来帮助查找错误)。
即使mapDef没有列出游戏类型,
也可以通过在控制台中指定地图来为特定的游戏类型加载地图。
游戏类型仅用于在创建服务器中列出地图和投票菜单。
关于创建mapDef的唯一困难在于指定大小。
cvar“com_updateLoadSize”有很多帮助。
当cvar设置为1时,游戏将在地图加载后自动更新地图def中的大小信息
(不能将其设置为只读)。
制作完成后,我们将运行一个批处理文件,
该文件通过com_updateLoadSize设置启动游戏,加载地图,退出游戏,重复播放。
我们会为所有4种质量模式 (尽管size0和size1往往总是相同)。
以下是批处理文件的片段:
doom3.exe + com_updateLoadSize 1 + map game \ admin.map + quit
doom3.exe + com_updateLoadSize 1 + map game \ alphalabs1.map + quit
doom3.exe + com_updateLoadSize 1 + si_map game \ mp \ d3dm1.map + si_pure 0 + spawnserver + quit
doom3.exe + com_updateLoadSize 1 + si_map game \ mp \ d3dm2.map + si_pure 0 + spawnserver + quit
doom3.exe + com_updateLoadSize 1 + map game \ alphalabs1.map + quit
doom3.exe + com_updateLoadSize 1 + si_map game \ mp \ d3dm1.map + si_pure 0 + spawnserver + quit
doom3.exe + com_updateLoadSize 1 + si_map game \ mp \ d3dm2.map + si_pure 0 + spawnserver + quit
mapdef不必在def文件中。它可以在任何你想要的文件,甚至一个材料文件!
但是,我强烈建议,在defs文件夹中创建一个mapdef
(其中包含您可能使用的任何entityDefs或自定义模型)的<mymap> .def。