第五章 游戏外包装
底层规则和单位代码的制作基本就算告一段落了,现在我们还剩下一个重要的事情要做,那就是要给自己的游戏做出一副足够受看的外包装,否则的话,难道你想让玩家去玩一个只有概念和规则,没有具体形状的骨架式游戏?
游戏外包装的工作量似乎是整个游戏里最大的一部分,分为模型代码、音效编辑、图像编辑、3D建模等等,那么我们就依次来探索这些东西的做法。
1、 模型代码。SAGE和TS一样,也有ART代码,通过对一些W3D模型的调用来表现一个物体的外观形状,但和TS不同的是,SAGE没有专门的ART.INI,而是把ART代码作为单位代码的一个模块来对待,并保存在这个单位的代码中,因此它的使用格式和第三章中提到过的所有功能模块相同,也是一个函数,拥有函数名,并占用一个模块编号。
SAGE里的外观模块函数有很多种,不同的函数带有一定的底层功能,虽然都能调用W3D来表现物体外观,但细节上略有差异,这个在遇到的时候再略加点评。
纵观外观模块的定义法,不难看出两个规律:一是通过不同的条件标签(ConditionState)来区分一个物体在不同状态下的外观,二是通过不同的过渡标签来创建物体在两个状态之间变形时的过程动画。因此在举例之前有必要先讲解一状态标签和过渡过程的作用原理。
条件标签的作用是用来标志一个物体在不同的条件下具有什么什么样的特征,而这个特征可以是第三章里提到过的武器系统、装甲系统、运动模式等,也可以是本章里将要介绍的外观摸样。因此可以这样来理解,一个单位在游戏中会受到自身动作或外界环境的影响(例如空闲动作、移动动作、开火动作、白天、夜晚、温和、雪地、健康、受伤、获得升级等等)以至于使自己处于不同的情况,因此SAGE用条件标签来作为判断物体处于不同情况的依据,每种情况都可以细分为多中条件标签的组合逻辑,因此我们可以借助对这些条件标签组合逻辑情况的判定来得知这个单位目前处于什么状态,应该显示成什么样的外观,好比一个坦克,初生的时候是正常的外观模样,而在战斗中受伤,变成红血时,外观则变成了破烂不堪的形象。
所有条件标签又分为多种类型,除了NONE表示“没有任何特别情况”(可以理解为默认情况)外,其余的标签分别如下:
(1)破损阶段
DAMAGED 轻伤(黄血),生命值介于35%到70%之间
REALLYDAMAGED 重伤(红血),生命值介于0%到35%之间
RUBBLE 尸体/残骸,生命值=0但死亡动作尚未进行完毕的时候,通常体现在有延迟死亡模块作用的情况下
(2)天气时段
NIGHT 夜晚,地图编辑器里指定的一个时段
SNOW 雪地,地图编辑器里指定的一个环境
(3)自身动作
MOVING 移动
ATTACKING 攻击,覆盖瞄准、开火、换弹夹等全套动作
USING_WEAPON_[X] 使用武器,[X]可以取A、B、C,分别对应主、副、第三武器,覆盖该武器的瞄准、开火、开火间隔、换弹夹等全套动作
PREATTACK_[X] 瞄准,[X]可以取A、B、C,分别对应主、副、第三武器
FIRING_[X] 开火,[X]可以取A、B、C,分别对应主、副、第三武器
BETWEEN_FIRING_SHOTS_[X] 开火间隔,[X]可以取A、B、C,分别对应主、副、第三武器
RELOADING_[X] 换弹夹,[X]可以取A、B、C,分别对应主、副、第三武器
RAPPELLING 下滑,借助空降绳下落,但尚未落地时(让我想起了魂斗罗)
CLIMBING 攀爬,用于贝顿越过山脊
UNPACKING 部署,用于黑客、红卫兵等开始施展技能,将工具摆设到地面上
PACKING 回收,相对上面的部署来说,是把刚才部署下的工具再收回到箱子里装起来
SPECIAL_CHEERING 欢呼,本参战方战胜时部队会挥手并呐喊助威,类似RA2里的C键效果
CARRYING 搬运,用于矿车,当车上装着箱子时
PANICKING 惊恐,用于平民受到惊吓后到处乱跑
DYING 死亡过程,好像是专门配合延迟死亡模块体现死亡动作
RAISING_FLAG 升旗,似乎特指红卫兵正在占领敌人建筑的过程,好像对类似动作的所有特殊能力都有效
PARACHUTING 空降,经降落伞空降,但尚未落地时
EXPLODED_BOUNCING 爆飞,被DeathType= EXPLODED的武器杀死后将被爆起来很高
EXPLODED_FLAILING 爆飞到最高点后开始下落的过程
TURRET_ROTATE 炮塔转动,似乎专用于坦克,但事实上很少有坦克用这个标签来体现状态
OVER_WATER 位于水面上时
FREEFALL 自由落体,不知道有啥特殊含义,似乎和空降以及爆飞后的下落都有关系
(4)级别、特殊升级
VETERAN 达到老兵级别
ELITE 达到精英级别
HERO 达到王牌级别
WEAPONSET_PLAYER_UPGRADE 获得武器升级,特指通过Upgrade项目来升级
WEAPONSET_CRATEUPGRADE_ONE 捡垃圾捡到武器第1阶升级,特指捡垃圾捡到武器升级项目时
WEAPONSET_CRATEUPGRADE_TWO 捡垃圾捡到武器第2阶升级,捡垃圾最多能将武器升级2层
WEAPONSET_VETERAN 级别提高到老兵,使武器得到强化时
WEAPONSET_ELITE 级别提高到精英,使武器得到强化时
WEAPONSET_HERO 级别提高到王牌,使武器得到强化时
ARMORSET_CRATEUPGRADE_ONE 捡垃圾捡到装甲第1阶升级,特指捡垃圾捡到装甲升级项目时
ARMORSET_CRATEUPGRADE_TWO 捡垃圾捡到装甲第1阶升级,特指捡垃圾捡到装甲升级项目时
POWER_PLANT_UPGRADING 电厂升级过程中,使用时需要有PowerPlantUpdate模块支持,否则的话会报错
POWER_PLANT_UPGRADED 电厂升级完成后,同样需要有PowerPlantUpdate模块支持
RADAR_EXTENDING 雷达升级过程中,使用时需要有RadarUpdate模块支持,否则的话会报错
RADAR_UPGRADED 雷达升级完成后,同样需要有PowerPlantUpdate模块支持
(5)摩托车乘员、工厂门
RIDERS_ATTACKING 乘员在其内部开火时
RIDER[X] 装入不同的乘员时,需要摩托车容器的支持,[X]可取1-8共8个整数,分别表示8种不同的乘员装载情况
DOOR_[X]_WAITING_OPEN 工厂门等待打开,通常是单位生产完成时,[X]可取1-4共4个整数,分别表示一个工厂的4个门,每个工厂最多可以有4个门
DOOR_[X]_OPENING 工厂门打开过程,通常是单位准备下线时
DOOR_[X]_WAITING_TO_CLOSE 工厂门等待关闭,通常是等待单位开出工厂
DOOR_[X]_CLOSING 工厂门关闭过程,通常是单位已经完全开出工厂
(6)建造、拆除过程
AWAITING_CONSTRUCTION 地基已经布置完毕,等待基地车前来建设时,完成度停滞在0%
ACTIVELY_CONSTRUCTING 基地车正在建设这个建筑时,完成度保持不断增长的过程中
PARTIALLY_CONSTRUCTED 部分建造完成,但基地车却半途撤离开时,完成度停滞在0%到100%之间的某个百分比上
ACTIVELY_BEING_CONSTRUCTED 建造进度已达到100%,但该建筑尚未正式交付使用的时候,这是个非常短暂的过程,似乎只有几帧时间
CONSTRUCTION_COMPLETE 建造完成的建筑正式交付使用之后
SOLD 拆除建筑过程中,即点下了拆除键,但尚未拆除完毕的这段时间
(7)其他
JAMMED 常用于导弹出膛后开始冲刺时
RIGHT_TO_CENTER 从右边向中间跑
CENTER_TO_RIGHT 从中间向右边跑
LEFT_TO_CENTER 从左边向中间跑
CENTER_TO_LEFT 从中间向左边跑,这4个标签不知道有啥具体作用,原版将之用在了摩托车上
GARRISONED 被人驻扎之后,需要驻守容器的支持
SECOND_LIFE 第二次生命时??不明白啥意思,难道原版还有重生概念?
PREORDER 预定,似乎是指给工厂类建筑预定生产计划并开始生产时,需要PreorderCreate模块的支持
CAPTURED 被捕获之后,可以是通过外部占领或心灵控制的方式来捕获,原版似乎只用在了一些中立科技建筑上
JETEXHAUST 平飞过程中,似乎专用于机场型战斗机在空中平飞时
JETAFTERBURNER 弹射起飞时,似乎也只用于机场型战斗机借助弹射板起飞,但尚未进入最大平飞状态时的中间过程
LOADED 装有货物时,似乎只用于矿车不空(即装有箱子,哪怕只有一个)时
POST_COLLAPSE 倒塌过程中,原版只用于一些高塔在死亡后倒塌下来的过程
ENEMYNEAR 当有敌人靠近时,需要EnemyNearUpdate模块的支持
SPECIAL_DAMAGED 受到特殊伤害时,没搞懂这个特殊伤害是啥意思
BACKCRUSHED 当背后受到撞击导致死亡时
FRONTCRUSHED 当正面受到撞击导致死亡时,似乎需要CrushDie模块的支持
USER_1 用户自定义1
USER_2 用户自定义2
过渡过程的作用是连接两个不同情况的中间过程,也就是说,可以理解为变形金刚那样的“变形”,即从机甲状态过渡到车辆状态,或从车辆状态过渡到机甲状态。从这里可以看出,过渡过程是一个可双向的的过渡,而它也需要使用一定的标签来标示前后两个状态,但它所使用的标签最特殊,是玩家自行命名的,你可以给它命任何名称,只要调用得成功都行,如果调用失败,不会报错,但却会丢失过渡过程(就成了瞬间切换)。过渡标签是在ConditionState函数里用一个语句来定义并命名的,就像下面这个例子:
ConditionState = SNOW
Model = UARADR
Animation = UARADR.UARADR
AnimationMode = LOOP
TransitionKey = Amakeup 给这个状态定义一个过渡标签,并将之命名为Amakeup,供后面编写过渡过程时使用
End
ConditionState = SNOW SOLD
Model = None
TransitionKey = Abackout 定义另一个过渡标签,并将之命名为Abackout,供后面编写过渡过程时使用
End
TransitionState = Abackout Amakeup 从Abackout过渡到Amakeup的过程,即从SNOW状态过渡到SNOW SOLD状态的过程
Model = UARADRMK 过渡过程也调用一个W3D模型
Animation = UARADRMK.UARADRMK 并播放这个W3D模型里所包含的3D动画,点号前面表示W3D内部名称,后面表示3D动画名称
AnimationMode = ONCE 动画播放模式,ONCE表示只一次,此外还有其他模式,如无限循环、反向一次等等,这个后面遇到了再说
End
TransitionState = Amakeup Abackout 从Amakeup过渡到Abackout的过程,相对于上面一个过渡来说,这是它的反向过渡,这意味着3D动画有可能需要反过来播放
Model = UARADRMK
Animation = UARADRMK.UARADRMK 模型还是这个模型,动画也还是这个动画
AnimationMode = ONCE_BACKWARDS 唯独不同的是,ONCE_BACKWARDS表示反向一次,即把整个3D动画反过来播放
Flags = START_FRAME_LAST 当使用ONCE_BACKWARDS时,需要加上一句播放说明,START_FRAME_LAST表示将最后一帧作为开头来反向播放
End
所有动画控制如下:
AnimationMode = [播放模式] 所有播放模式默认的播放说明都是START_FRAME_FIRST,因此需要改变的话就要自己用Flags语句来申明
ONCE 正向一次
ONCE_BACKWARDS 反向一次,需要搭配Flags = START_FRAME_LAST语句使用
LOOP 正向无限循环
LOOP_BACKWARDS 反向无限循环,需要搭配Flags = START_FRAME_LAST语句使用
MANUAL 手动控制,实际上并非是让玩家自行控制,而是由游戏中特定的过程来控制
Flags = [播放说明]
START_FRAME_FIRST 以第一帧为起始帧进行播放
START_FRAME_LAST 以最后一帧为起始帧进行播放,事实上即便是正向播放,你也可以恶意地使用START_FRAME_FIRST来制造特定的反常效果
RANDOMSTART 随机选择一帧作为第一帧,剩下的按正常正向顺序播放
最简单的外观定义是基本式,也就是没有什么特别的定义,只需要写好基本定义的那几种情况即可发挥作用。它与运动模式没有任何关系,也就不会自动地反映出任何特殊运动表现,必须全靠人工根据不同的条件标签和过渡标签来区分状态,以做出微观定义,因此这种基本式往往被步兵、建筑或飞机采用。
Draw = W3DModelDraw ModuleTag_XX
OkToChangeModelColor = Yes
DefaultConditionState 默认状态,不仅包含了ConditionState = NONE时的外观定义,而且还作为缺省定义给其他情况时使用
Model = STARF 使用哪个W3D模型文件
Turret = Turret01 以哪个模型块作为第一炮塔
AltTurret = Turret02 以哪个模型块作为第二炮塔,一个单位最多有两个炮塔,每个炮塔都可以发射主、副、第三武器,恐怕只有战列舰才用双炮塔
TurretPitch = TurretEL01 以哪个模型块作为第一炮塔上所有炮管的俯仰控制关节点
AltTurretPitch = TurretEL02 以哪个模型块作为第一炮塔上所有炮管的俯仰控制关节点
WeaponFireFXBone = PRIMARY MuzzleP 用主武器开火时炮口FX的产生点对应哪个骨骼点,PRIMARY表示主武器,后一个是骨骼点名称的前缀,后面自动匹配数字序号
WeaponRecoilBone = PRIMARY BarrelP 用主武器开火时可退缩的炮管为哪个模型块,这个语句使炮管在开炮时沿其自身的X轴负方向退缩
WeaponMuzzleFlash = PRIMARY MuzzleP 用主武器开火时炮口闪光对应哪个骨骼点,原版经常做一些正交的平板放在炮口上充当闪光,不知道有啥意思
WeaponLaunchBone = PRIMARY MuzzleP 用主武器开火时开火点位置对应哪个骨骼点
WeaponFireFXBone = SECONDARY MuzzleS 用副武器开火时炮口FX的产生点对应哪个骨骼点,SECONDARY表示副武器
WeaponRecoilBone = SECONDARY BarrelS 用副武器开火时可退缩的炮管为哪个模型块
WeaponMuzzleFlash = SECONDARY MuzzleS 用副武器开火时炮口闪光对应哪个骨骼点
WeaponLaunchBone = SECONDARY MuzzleS 用副武器开火时开火点位置对应哪个骨骼点
WeaponFireFXBone = TERTIARY MuzzleT 用第三武器开火时炮口FX的产生点对应哪个骨骼点,SECONDARY表示副武器
WeaponRecoilBone = TERTIARY BarrelT 用第三武器开火时可退缩的炮管为哪个模型块
WeaponMuzzleFlash = TERTIARY MuzzleT 用第三武器开火时炮口闪光对应哪个骨骼点
WeaponLaunchBone = TERTIARY MuzzleT 用第三武器开火时开火点位置对应哪个骨骼点
End
ConditionState = DAMAGED 轻伤时的状态,由于上面用DefaultConditionState定义了缺省值,因此后面就不必全部重新定义,凡是没有定义的语句
Model = STARF_D 都将自动借用上面的缺省语句,相反,定义了的语句则会覆盖缺省值并发挥作用
End
ConditionState = REALLYDAMAGED 重伤时的状态
Model = STARF_E
End
ConditionState = RUBBLE 残骸/尸体时的状态
Model = STARF_R
End
End
特别需要注意的是,任何外观模块的函数中,至少必须有DefaultConditionState(默认状态),或者ConditionState = NONE(空状态),总之两者必须有一个,而且只能有一个。从表面上看,这两个子函数的效果差不多,因为默认状态实际上在很多时候都表示“初始状态”,也就是“不具备任何标签的状态”,而这种状态正好就是空状态,所以一般情况下,你把它们混淆是没什么问题的。但是它们的作用依然有差异,因为“空”也是一个特定的状态,与其他诸如轻伤、重伤等状态的级别是平等的,自己的定义只对自己有效,而默认状态则是涵盖所有状态的最高级别,它的定义可以覆盖其他状态,因此默认状态可以给整个外观模块提供一些缺省值,以至于其他状态不需要重复地定义一些相同的语句,这样可以省不少手笔。
此外SAGE还提供一个更加省手笔的写法,称为借用法,通常用在含有组合逻辑的状态中,例如下面这个段落:
ConditionState = REALLYDAMAGED 首先用正常的方法定义重伤时的外观
Model = UGRADR_D
Animation = UGRADR_D.UGRADR_D
AnimationMode = LOOP
TransitionKey = Gmakeup
End
AliasConditionState = NIGHT REALLYDAMAGED
这里跟一个AliasConditionState语句来让NIGHT REALLYDAMAGED状态借用REALLYDAMAGED状态外观。像这种多个标签并列的参数就是我所谓的组合逻辑状态,并列的标签表示同时具备这些标签时的状态,例如这个例子里的REALLYDAMAGED表示白天+重伤,而NIGHT REALLYDAMAGED则表示夜晚+重伤。而这样的一段语句,展开之后实际上就等效于下面这个样子:
ConditionState = REALLYDAMAGED
Model = UGRADR_D
Animation = UGRADR_D.UGRADR_D
AnimationMode = LOOP
TransitionKey = Gmakeup
End
ConditionState = NIGHT REALLYDAMAGED
Model = UGRADR_D
Animation = UGRADR_D.UGRADR_D
AnimationMode = LOOP
TransitionKey = Gmakeup
End
这就是分开写的写法,两个状态使用完全相同的语句及参数。由此可见AliasConditionState能让你节约不少篇幅。
像这样借用外观的情况,在建筑和步兵里非常常用。
SAGE在基本式的基础上又增加了一些具有特殊定义的进阶式,这些进阶式的基本定义和基本式一样,也是用不同的ConditionState和TransitionState子函数来定义,我就全部简写以表达意思,仅仅用蓝色文字来表示这种进阶式函数的特殊功能语句。
坦克通常使用W3DtankDraw函数,它的特色是可以定义履带的转动,以及当坦克处于移动过程中时,自动在车尾产生两道游戏平台默认的沙尘,目前尚不知道沙尘能否做成微观定义,让每个坦克的沙尘都不一样。
Draw = W3DTankDraw ModuleTag_XX
OkToChangeModelColor = Yes
DefaultConditionState
Model = STORM
End
ConditionState = DAMAGED
Model = STORM_D
End
ConditionState = REALLYDAMAGED
Model = STORM_E
End
ConditionState = RUBBLE
Model = STORM_R
End
TrackMarks = EXTnkTrack.tga 坦克开过之后在地面上留下一条履带痕迹,这条痕迹使用哪个TGA作为贴图
TreadAnimationRate = 2.0 履带贴图的移动速度,原来履带的转动是靠移动贴图来实现的,因此专门要为坦克做一个履带贴图,这个在W3D制作里再讲
TreadDriveSpeedFraction = 0.3 当本体的移动速度低于多少时,履带贴图将停止移动,不知道这里的0.3、0.6到底是个什么比率
TreadPivotSpeedFraction = 0.6 当本体的移动速度高于多少时,履带贴图将开始旋转
End
由于SAGE的物理引擎借鉴了NFS里很多运算,以至于SAGE能够做出一种TS里想都不敢想的多轮车辆,这可不仅仅是外观那么简单,而是直接体现运动方式,简直和NFS的感觉差不多,你可以让两轮或四轮后驱车辆急转弯并做出漂移动作,在地上用轮胎印记画出一个8字,同时还能看到后轮摩擦地面杨起的沙尘。因此多轮车辆一般使用W3DtruckDraw函数,它的特色是定义车轮的动作。
Draw = W3DTruckDraw ModuleTag_XX
OkToChangeModelColor = Yes
ConditionState = NONE
Model = AVAmbulance
End
ConditionState = REALLYDAMAGED
Model = AVAmbulance_D
End
ConditionState = RUBBLE
Model = AVAmbulance_D
End
TrackMarks = EXTireTrack.tga
Dust = RocketBuggyDust 车轮旋转时卷起的沙土,调用一个粒子系统
DirtSpray = RocketBuggyDirtSpray 似乎和上面一句的作用相似,不过貌似特指沙土飞扬时候调用哪个粒子系统(恐怕是指移动过程中)
PowerslideSpray = RocketBuggyDirtPowerSlide 还是和上面相似,不过特指刹车时摩擦出来的沙土
LeftFrontTireBone = Tire01 左前轮对应W3D里哪个模型块
RightFrontTireBone = Tire02 右前轮对应W3D里哪个模型块
LeftRearTireBone = Tire03 左后轮对应W3D里哪个模型块
RightRearTireBone = Tire04 右后轮对应W3D里哪个模型块
TireRotationMultiplier = 0.2 车轮旋转速度比率,以单位当前的移动速度为基准来决定车轮转速
PowerslideRotationAddition = 2.5 刹车时车轮转速的增量,搞不懂为什么是加2.5而不是减2.5
SAGE以上面3种外观式为基础又衍生出了下列近阶式,基本上可以说是组合了前击中方式的特殊定义。
W3DScienceModelDraw 证书式,用于一种需要获得了对应技能证书后才能看到的物体,例如原版的垃圾箱,特有RequiredScience语句
使之调用一些证书,没有获得这种证书的参战方无法看到它。
W3DDependencyModelDraw 加载式,用于定义类似炎黄盖特炮、炎黄广播塔之类需要加载在主体头顶上的物体,特有AttachToBoneInContainer语句
使之与主体上的某个骨骼点关联,确保其加载的位置
W3DTankTruckDraw 半轮半履带式,可以同时定义车轮和履带的转动
W3DOverlordAircraftDraw 炎黄飞机式,用于定义一些带有活动粒子系统骨骼点的物体,特有ParticlesAttachedToAnimatedBones = Yes语句
使这些粒子系统能够跟随骨骼点的3D动画而运动。
W3DOverlordTruckDraw 炎黄多轮车式,同上,同时也具备一般多轮车辆对车轮转动的定义
W3DOverlordTankDraw 炎黄坦克式,同上,同时也具备一般坦克对履带转动的定义
W3DpoliceCarDraw 警车式,我没看出它和一般的多轮车辆有啥区别
下面还有一些比较专用的方式,通常用于某种特殊物体的外观定义。
光束式,所有光束激光都用这种方法来产生视觉效果。需要LaserUpdate的支持。
Draw = W3DLaserDraw ModuleTag_XX
Texture = EXBinaryStream32.tga 光束上的贴图
NumBeams = 4 光束由多少个重叠的圆柱体构成,用于模拟激光的光晕效果
InnerBeamWidth = 0.4 内层光束(光束体)宽度
InnerColor = R:255 G:255 B:255 A:250 内层光束的染色效果,同样是RGB算法。最后的A似乎表示光束的透明度
OuterBeamWidth = 1.2 外层光束(光晕带)宽度
OuterColor = R:255 G:0 B:0 A:150 同内层光束染色效果,特别需要注意,由于内外两层是重叠的,因此相互的染色可能会发生影响
Tile = Yes 使用平铺贴图,反之则是将贴图拉伸以适合整条光束
ScrollRate = -0.25 使贴图在光束上移动的速度,以模拟激光的动作,正值表示发射出去,负值表示吸收回来
Segments = 20 将整条光束分割成相互独立的多少段,每段单独移动贴图,原话说,分割得越多,光束就越细腻
ArcHeight = 30.0 光束的弯曲程度,正值表示向上弯,负值表示向下弯,但通常不使用负值
SegmentOverlapRatio = 0.0000 似乎可以控制相邻分段接头处的贴图交叠效果,正值表示交叠,负值表示拉开
TilingScalar = 0.25 拉伸平铺情况,1表示不动,小于1表示收缩,大于1表示伸展
End
树木式,专用用树木式来体现树木的一些特征,所有树木都用这个方式来定义
Draw = W3DTreeDraw ModuleTag_XX
ModelName = PTDogwod01 调用哪个W3D作为树木的结构基础,仔细可以看出,树木其实是由很简单的4张正交平面加一根细圆柱体构成的
TextureName = PTDogwod01.tga 表面贴图,树木基本上就全靠这个贴图来体现形状,隔远了看起来倒也不错
DoTopple = Yes 被撞击后是否倒塌,怀疑No的话是表示竖直沉入地表,而非先倒塌然后横着沉入地表
DoShadow = Yes 是否在地面上投射阴影
ToppleFX = FX_ToppleTree 倒塌时的FX特效
BounceFX = FX_OptTreeBounce 倒塌时在地表面反弹起来的FX特效
KillWhenFinishedToppling = Yes 倒塌结束后是否判为死亡
SinkDistance = 10 下沉距离,也就是说将沉入地表以下10像素的地方然后消失
SinkTime = 5000 下沉持续时间
End
补给站式,专门定义补给站和补给堆的方式,可以体现出箱子不断不搬走,最后搬空的过程效果,需要SupplyWarehouseDockUpdate模块的支持。
Draw = W3DSupplyDraw ModuleTag_XX
ExtraPublicBone = SUP 特殊通用骨骼点,似乎是关联着补给站上那些箱子的位置
ConditionState = NONE
Model = CBToxRepos
End
SupplyBonePrefix = SUP 根据SupplyWarehouseDockUpdate里定义的箱子数量来决定隐藏一定比率箱子,若搬空则全部隐藏起来
End
尾气流式,专门定义射弹体尾气流用的方式,在毒素车的射弹体里出现过,似乎效果和光束差不多。我很怀疑这个是否能做成效果最好的粒子激光。
Draw = W3DProjectileStreamDraw ModuleTag_XX
Texture = EXToxinStream.tga 尾气流贴图
Width = 1.5 尾气流宽度
TileFactor = 2.0 贴图平铺倍数
ScrollRate = 6.0 贴图卷动速度,以模拟尾气流的喷射效果
MaxSegments = 14 每隔多少个分段显示一次贴图效果,似乎0可以表示显示所有分段
End
2、 音效编辑。好游戏总是需要优秀的听觉效果来刺激观众,因此有必要在音效方面下一定的功夫。
SAGE的音效比TS相对容易整理得多,因为不需要像TS那样用XCCMIXER注入AUDIO.BAG中,所以操作上来讲便宜了很多多余的步骤。
SAGE支持两种音效文件,一种是传统的8位或16位PCM,也可以使用压缩过的4位IMA-ADPCM,和TS一样,要求后缀名为WAV。另一种是大家求之不得的MP3,通常用于背景音乐,采样率可支持11000到44000之间的任意值,位速率可支持从64到256之间的一些特定值。从性价比的角度来讲,MP3肯定比WAV划算,但是我没测试过是否所有音效都能使用MP3。
SAGE的音效分为单位语音、武器/环境音效、EVA语音、背景音乐4类,代码的定义法和TS大同小异,我一样举一个例子,剩下的让你们自己去看ZH的代码。
单位语音代码,通常存放在Data\INI\Voice.ini里
AudioEvent RangerVoiceAttack
Sounds = iranata iranatb iranatc 调用哪些音源,通常是WAV文件
Control = random 播放方式,ramdom表示随机抽选一个来播放一次,单位语音通常只能random,用其他方式会显得很怪异
Volume = 90 一般音量倍率,以音源的音量为基准,100表示100%,小于100表示减小,反之则是增大
MinVolume = 45 最小音量倍率,同上,通常要比一般倍率的参数小
Priority = high 优先度,可选critical(实时)、high(高)和low(低),缺省时表示中等
Type = [类型] 播放类型,可在下面这么多种里选择搭配,当然,相互冲突的不能搭配,否则会出现怪异后果
ui 界面型,不知道有啥作用
voice 语音型,表示单位语音,似乎没啥作用
player 单方型,只能被本方玩家听到,因此和everyone相互冲突
world 全局型,该语音不会因为摄像机远离来源而衰减音量,因此全地图上任何位置都听得到
shrouded 强制型,该语音的来源被黑雾或灰雾笼罩时,照样能发出声音
everyone 公共型,可以被所有玩家听到,因此和player相互冲突
End
武器/环境音效代码,通常存放在Data\INI\ SoundEffects.ini里,定义法和单位语音一模一样,某些特别的语句和参数可以在这里使用而不会显得很怪异
AudioEvent HumveeMoveStart
Sounds = vhumstaa vhumstab vhumstac
Attack = vtoxlo1a 以哪个音源作为淡入阶段
Decay = vtoxlo3a 以哪个音源作为淡出阶段
Volume = 60
PitchShift = -5 5 音调浮动范围,从-5到+5之间升降调,缺省为0,即保持原调,这样可以使每次的音效都略有差异,显得很丰富
Delay = 0 500 发音延迟时间,从0到500毫秒之间随机取值
VolumeShift = -10 音量变化,-10表示从发音开始到发音结束,音量将衰减10个单位(不知道是不是分贝),正值则表示增强,缺省为0,即不变
Control = [播放方式] 播放方式,可在下面这么多种里选择搭配,当然,相互冲突的不能搭配,否则会出现怪异后果
random 随机抽选并播放一次
interrupt 强制中断然后播放第一个音源一次(会无视后面的音源)
loop 无至尽地循环播放第一个音源(会无视后面的音源)
all 必须将所有音源全部都播放至少一次,通常和loop搭配
Limit = 3 当Control的参数中存在loop时,表示播放一次最多有多少个循环
Priority = low
Type = world shrouded everyone
End
EVA语音代码,通常存放在Data\INI\Speech.ini里。定义非常简单,仅仅调用音源,最多再设置一下类型和音量倍率即可
DialogEvent Cinx_PlaneLandStereo
Filename = cplane03.wav 调用哪个音源,从参数来看貌似可以使用MP3格式
Volume = 100
Type = ui EVA语音似乎都最多使用ui类型,通常是缺省的,不知道缺省表示什么
End
背景音乐代码,通常存放在Data\INI\Music.ini里,和EVA的定义法大同小异。
MusicTrack Game_CHI_03
Filename = CHI_03.mp3
End
需要注意的是,SAGE的背景音乐播放方式和TS不同,TS是由平台底层的播放机功能来直接播放你定义好的这些曲目,而SAGE则需要在宏观AI里编写一系列很复杂的触发程序来播放它们,因此很多MODER发现,自己做的MOD只能替换原版音乐源,却不能自己添加。那么在后面的月光宝盒秘籍里,我将讲解如何编写宏观AI以及部分典型的任务流程。
音源的制作需要专业的音频编辑工具,MP3暂且不用考虑太多,因为一般都是直接从网上下载下来就能用,而WAV则需要处理,至少也需要转换一下格式。我推荐使用GOLDWAVE来编辑音效,这个工具使用非常简单,可以批量转换任何格式的音源,并能在转换过程中批量加入特效设置,例如批量改音量、批量增加滤波效果等等。还能完成精确的音频编辑工作,例如音效合成、剪辑。
对于使用381M决命时刻中文版为MOD基础的人来说,编辑好的音源,需要存放在\Data\Audio\Sounds\Chinese目录中。如果是以英文版为基础,则需要放到\Data\Audio\Sounds\English目录中。你也可以创建几个BIG包来分别保存它们,当然,在使用BIG保存资源的时候千万要注意路径,不能像以前使用MIX那样不管3721地随意塞进去。
3、 图像编辑。图像好不好,直接导致了玩家对这个游戏的第一映像好不好。要知道99 %的玩家都是小白,他们只知道看表面,根本不会去在意这个游戏的内涵到底有多深。因此你不能期望任何玩家都像资深的CNC爱好者那样来仔细品位你的作品,因此空有骨架而无外表的游戏在市场上是站不住脚的。
说到图像,我就想起了PhotoShop,没错,这是任何游戏都必须使用的图像编辑工具。什么,你说你做MOD就从来没用过?那不好意思,我只能说你还没入行。
以前在TS里,做一个图像都相当麻烦,因为首先需要用PhotoShop编辑PCX图片,完工之后还要用PaintShop Pro来加载调色板,然后还要用XCCMixer转换成SHP,如果是要制作多帧动画,还得用上AnimShop、ACDSee、FotoCanvas等等工具,累都累死人了。而现在则方便了很多,因为SAGE引擎直接就支持真彩色的图像,并支持Alpha蒙板,可以节约PhotoShop之后的所有工序。但SAGE的2D图像,包括3D模型上的贴图,都只能支持TGA和DDS格式。在上面的教程里我们可以注意到,所有调用贴图的语句参数,后缀名都是TGA,你绝对都看不到DDS这3个字,但事实上这些图像却多数是以DDS格式保存在游戏目录下,之所以还能被游戏识别,就是因为SAGE把DDS图片也视为TGA对待,因此你写代码尽管全部写成TGA好了。
有人一直找机会反对我,说SAGE还是有不如TS的地方,估计就在图像方面,不知道大家有没有注意到,任何3D游戏都无法支持多帧SHP那样的动画图片,因为现在的3D引擎还不能识别GIF动画,所以绝大多数时候,2D动画方面的表现甚至还不如TS引擎那么简单自如,往往需要借助3D动画来控制2D贴图产生视觉效果,而不能直接用一张动画SHP来表现。
SAGE的2D图像分为两种类型,一种是映射图像,另一种是贴图,前者经过申请并定义后能被其他INI调用,因此需要制作代码。后者则是图像资源,被INI和3D模型调用,甚至被影射图像的定义语句调用。
定义映射图像的代码通常在MappedImages\TextureSize_512目录下,有很多个INI,事实上你也可以随意新建一个INI来保存你自己定义的映射图像。被定义过的映射图像可以作为操作栏上的图标图像、单位头像,以及游戏宏观界面上的某些图像等等。一个典型的定义如下:
MappedImage Head122_UAPOWR 申请一个映射图像,并为之命名,之后就可以在其他INI里调用这个名称了
Texture = UAPOWRHead.tga 使用哪个TGA贴图作为其图像源
TextureWidth = 512 贴图宽度,单位为像素,这个参数必须和TGA图像源的尺寸一致,否则会发生拉伸导致变形甚至显示错误
TextureHeight = 512 贴图高度,同上
Coords = Left:0 Top:0 Right:122 Bottom:98 映射区域,从整张TGA的左上脚为原点开始计算,用上下左右4个顶点来选出一个小部分作为映射出来的实际图像
Status = NONE 状态,没搞懂有啥作用,似乎很多都是NONE
End
点评:映射图像是SAGE的特色之一,而且也比较难掌握,因为EA图方便,把几十个图标全部混杂地放在一张很大的TGA上,然后用Coords语句来“挖”出各个图标生成每个映射图像的实际图像。EA自己倒是有分割工具,自动生成代码,问题是玩家没有,只能靠人工计算,怎么办呢?我想到了一个无耻的办法,那就是分开定义各个图标。
MappedImage Head122_UAPOWR
Texture = UAPOWRHead.tga
TextureWidth = 122
TextureHeight = 98
Coords = Left:0 Top:0 Right:122 Bottom:98
Status = NONE
End
看看这样一改有啥后果。由于整张贴图的尺寸和挖的区域一样大,事实上也就是说,直接使用整张TGA的全部区域。那么你就可以把每个图标的图像资源像TS那样分开编辑了,如果图像尺寸有变化,只需要将TextureWidth、TextureHeight、Right、Bottom的值改到和TGA图像源尺寸一样大就行,根本不需要学EA那样混杂在一堆,还要慢慢地计算应该怎么挖,万一要改的话,动一张就要动全局。
关于TGA和DDS图像的编辑方法,我就不多说了,这个东西不是一两句话扯得清楚的,尤其是Alpha蒙板部分。所以我建议你最好是去买一本PhotoShop教程,先掌握了图像编辑基本方法了再说。最后做好的TGA和DDS图像源,需要保存到Art\Textures目录下。
4、 3D建模。这是3D游戏的灵魂所在,模型做得好不好,直接影响了整个游戏的大局,所以我事先建议某些急功近利的MODER,统统给我滚回去先把3DMAX学扎实了再回来看教程。
首先需要提的是,SAGE支持的W3D模型,是以3DMAX为基础的一种格式,具备3DMAX里的很多基本功能,但相比MAX来说并不完善,例如不支持凹凸贴图、不支持光线跟踪等等,使得做出来的模型在游戏里看起来很干瘪,像个玩具一样直白,没有任何华丽的表现。没办法,谁叫W3D是EA在3D游戏里的第一次尝试呢?后来EA使用了功能更近似于MAX的W3X,用在CNC3里,效果就华丽了不少。
那么要想把W3D做得不像玩具,关键就在于材质和贴图技巧。你们去看看《冲击波》、《Contra》等优秀MOD里的坦克模型就知道,优秀的模型,结构并不复杂,复杂的是贴图上包含丰富的迷彩底色和上层细节装饰,甚至精致得连螺丝钉、钢板缝都看得见。关于贴图技巧和材质通道的内容,我放到后面的进阶教程里再讲,其实看完本章,你如果能做出“玩具”来,已经很不错了。
关于建模的要点,前辈已经写过帖子来讲解,我就直接以附件的形式与教程一起打包,事实上我根本不知道这部分应该如何来讲解,因为3D建模本应该属于一个游戏开发基础技能,如果连3D建模都不会,我只好怀疑你是花钱买进游戏行业来混日子的人。所以我只讲解制作过程中的一些注意事项。
在讲解之前,我建议大家尽可能地提取原版的现成资源来观察,看看人家的标准是怎么做的,千万不要想当然地去自己钻研,否则一但走错方向,就会钻进牛角尖无法自拔。
(1) 坐标轴向
其实我也不知道该怎么说才够详细,但是说得太严谨的话,又好像是在讲CAD,没学过机械制图的菜鸟懂不起……不如直接给一副坦克模型图来说明如何摆放模型才是正确的方向:
3DMAX的默认视窗布局如上图所示,分别是顶视、前视、左视和透视,每个视角窗口的左下脚都有红绿蓝3个箭头,分别用来指示X、Y、Z的正方向(透视窗口中的3个箭头最容易识别)。
SAGE规定,在3DMAX的默认视窗里,顶=俯视视角,前=右侧视角,左=背后视角,同时又规定,X+为模型的正面朝向,Y+为模型的左手朝向,Z+为模型的顶面朝向。因此正确的放法,是如上图所示,将坦克的炮管口(正面)朝向X轴正方向,这和机械工业制图的习惯正好逆时针转了个90度,在实际制作模型时必须特别小心,否则做出来的坦克会像螃蟹一样“横行”霸道。
SAGE还有一些重要的微观轴向,尤其是对于一些可活动的模型块,如炮管的退缩、炮塔的转动,它们的微观轴向就显得尤为重要,如果胡乱设置的话,在游戏中会发生错误的动向或转向。必须注意的是,炮管的微观X+方向必须是从炮尾指向炮口的方向。炮塔的微观Z轴必须与世界坐标的Z轴一致。以上两点不太容易说清楚,请各位读者导入原版ZH的战神坦克模型去看看炮管和炮塔的微观轴向,自然就明了了。
(2) 模型的位置和尺寸
3DMAX里的XY平面相当于游戏里的“地面”,因此模型的底面必须正好落在XY平面上,否则在游戏里会出现“浮空”或“沉地”的怪现象。而模型的前后左右位置则需要从顶视图里来观察,通常坦克以底盘的前后左右4条边界线为标准,建筑以地基板的前后左右4条边界线为标准,人物以脊椎骨骼为基准来计算其中心点位置。以上图的灰熊坦克为例,炮管不属于底盘部件,虽然它长出那么多一截,但不应该参与中心点的计算,因此我们只使用车身来作为计算来源。正确的中心点可以确保车身在X和Y方向上满足,正向最远点的坐标与负向最远点的坐标值几乎相等。那么放到游戏中去的话,灰熊坦克基本上就在其血格范围之内,而不会偏离得太远。
中心点放好之后,还需要设置模型的尺寸,首先我们要在INI里定义一个单位的理论尺寸作为标准参考值,以它来调整模型的实际尺寸,使模型的实际尺寸尽可能接近理论尺寸但不要大于理论尺寸。而尺寸同样也是只使用底盘作为标准来进行计算,炮管是不参与计算的。假设我们定义灰熊坦克的主半径(X)为15,次半径(Y)为10的话,那么我们就要用整体缩放法在3DMAX里控制模型的底盘尺寸尽可能地逼近30X20,但不要超过30X20。
(3) 关节点
或许一提到关节点,有点经验的读者会立刻联想到士兵模型。其实不仅仅是士兵,坦克和建筑模型模型里照样存在关节点,上图中的左视图可以看到履带中央有两个绿色的小方格,这就是关节点,当坦克在移动时,它们将控制狼烟粒子系统的发射点位置。而透视图中的炮管口上也有一个绿色小方格,这个小方格的意义最重要,它控制着开火点的位置,其微观X+方向还同时决定了射弹体的出射方向。看到这里,或许很多人要开始高兴了——确实,SAGE不需要再像TS那样茫然而又麻烦地调整FireFLH值,你只需要在适当的地方放一个关节点就能直观地控制开火点位置和方向。
当然还不能高兴得太早。关节点不光要放置在模型里,还必须注意INI里对它的调用,前面在讲外观模块时明确提到WeaponLaunchBone等语句的含义,其最后一个参数就是关节点在3DMAX里的名称。返回外观模块定义去看,你还能发现有似乎调用并不是严格和关节点同名,例如:
WeaponLaunchBon = PRIMARY MuzzleP 主武器的开火点位置由一个名称为MuzzleP的关节点来控制
但在实际模型中,你却找不到MuzzleP这个关节点,只找得到MuzzleP01、MuzzleP02、MuzzleP03……等等带数字后缀的关节点。事实上,这也是一种特殊的、被游戏认可的“同名”规则,专业称呼为[BoneName]%02d,即INI里只调用前缀,实际关节点的命名可在前缀字段后加两位数字,那么凡是前缀和INI对应上的所有关节点都将作为开火点,于是会形成一种“每个开火点轮流开一炮”的现象。此现象在原版炎黄坦克里出现过,大家可以导入进来看看,和INI对照起来分析,看看我说得是不是如此。
要放置新的关节点,可以使用球体、方块和骨骼等实体,也可以使用点、灯光、辅助物等虚体,两者需要设置不同的输出方式。
选中一个实体或虚体,在W3D Tools脚本功能栏里可以察看它的输出方式,分为Export Transform(仅输出定位信息)和ExportGeometry(仅输出形体图像)两种方式。3DMAX的默认情况为,实体的两个选项都被钩上,表示既输出定位信息,又输出形体图像。而虚体则正好相反,两个选项都没钩,表示什么都不输出。因此如果使用实体作关节点,在输出W3D时不要忘了取消它的“Export Geometry”选项,使之不输出任何形体图像。而使用虚体作关节点时要记得钩上“Export Transform”选项,使之输出定位信息。
对于做坦克和建筑模型而言,如果你觉得这样设置很麻烦的话,我提供一个懒人专用方法:用虚体作关节点,模型做完后,全选整个模型的所有部件,统一把Export Geometry和Export Transform都钩上, Geometry Option选择Normal(直接输出),这样输出的话,相当于是让所有部件都同时输出形体图像和定位信息,由于虚体本身并不存在形体图像,因此即便钩上了Export Geometry也不会输出任何东西,在游戏里就不会有异常的显示情况。
特别注意,上述这个懒人方法只适合做坦克和建筑等“整合模型”(只输出一个W3D的模型)。而对于士兵模型这种“拆分模型”(拆分为SKN、SKL和动作的模型)而言,这个方法会导致巨大的定位信息冲突,会使步兵模型在游戏中显示为半静态的T字形。
(4) 所属色
所属色是RTS的一大特征,通常在模型的一些表面上染上不同的颜色用来表示该单位属于不同的玩家。具体做法很简单,把你希望染上所属色的部件名称改成HouseColor%02d,虽然在3DMAX里不会有任何变换,但该结构块在游戏中就会自动染上所属玩家的阵营颜色。此方法对坦克和建筑模型非常实用,但对步兵不实用,关于步兵的所属色制作,我在后面的人物制作要点里再提。
(5) 简模——RTS的本色
由于RTS的特殊性在于“大军团”和“多兵种”,因此一般情况下,同屏幕内容纳的多边形数必定是FPS游戏的几十到几千倍,所以我们在制作模型时,千万不能按照FPS的精模标准去制作每一个模型,经过我的实践证明,我的蓝宝1950XTX双256显卡运行SAGE引擎,在ZH里同屏幕内多边形数超过10W将使游戏直接崩溃,若在5W到10W之间,游戏速度会慢得不足25帧,所以你们看过原版ZH模型的话应该很清楚一个事实——通常每个模型只有几百个多边形,简陋得简直就像玩具。
与原版ZH的情况相反,历史上有一个非常著名的ZHMOD,叫《现代战争》,是我师傅QSN的杰作。这个MOD以精致和逼真著称,所有模型都是按照FPS的精模标准制作的,部分坦克模型的多边形数甚至超过了1W,这个游戏被我戏称为“只能看不能玩的军事教科书”,每一样东西你造一个出来看看外观,看看功能还可以,如果非要去玩这个游戏的话则简直是虐待自己的显卡,只要稍微多造几个坦克,直接就会要绝大多数NF系列显卡的命。
与崇尚精致和逼真的RW派作者(RealWar)相反,WC派作者(WorldCompetion)则是崇尚流畅和竞技体育,为了使游戏流畅,他们想方设法地简化模型的多边形数,很多时候为了追求流畅性,不得不干掉了一些模型上的细节表现,我个人的观点来看,这是值得的。
3DMAX有一个自带的脚本工具,多边形计数器,可以快速地计算出你的模型总共有多少个多边形。需要注意的是,3DMAX计算的多边形数,不是指物体的实际表面数,而是指三角形面数。例如长方体的一个侧面是由2个多边形组成的,而6棱柱的底面则是由6个多边形组成的,由此可以看出模型的多边形数和表面数没有固定的比例系数,但可以肯定的是,表面数越多,多边形数就必定越多。因此简化模型,实际上就是减少形体的表面数量。
如果决定要走简模路线,那么在建模的时候就要坚持一个建模原则:尽全力使用最少的表面数来表现形体。
A、 方体:通常用来表现建筑的地板等部件,需要注意的不多,因为3DMAX在创建方体时,长宽高的分段默认就是1,总多边形数为12。若无特别的精致要求,例如倒角、圆滑等,那么长宽高的分段数要尽可能保持全1。反之如果有特别的精致要求的话,分段数能少则少,若能用2分段将就体现效果的话,就坚决不使用3分段。
B、 柱体:通常用来表现炮管等长部件,可以通过锥化或编辑网格演变成台体。这是个比较害人的形体,分段数和多边形数基本按照平方比例增减,3DMAX在创建柱体时,默认的分段情况是端面1分段、高度5分段、底面18边。总共的多边形数就是216。因此要尽可能地减少底面边数,同时高度分段只能取1。在不需要特别精致的情况下,4棱柱足够用来表现炮管。反之如果非要表现成圆柱,则12棱柱已经足够精细了。
C、锥体:和柱体的处理基本相同,事实上柱体通过网格编辑也能演变成锥体,因此这里不再冗诉。
D、球体:这是个最害人的形体,由于球体的分段数与多边形数呈三次方比例增减。3DMAX在创建球体时,默认的分段数是32分段,总共的多边形数就是960!已经远大于原版一个坦克的总多边形数了。因此无论如何要尽可能减小分段,一般来说,10分段已经足够用了,不到万不得已,切记不要使用10以上的分段数。某些时候也可以使用几何球体来代替球体绘制模型,在相同的精致程度上,几何球体的多边形数往往比球体更少,但是在编辑网格时不太容易处理,大家根据实际情况来选用吧。
E、 环体:和柱体的情况比较类似,也是平方比例增减,默认分段情况为24分段、12边,总多边形数就是576。其中分段表示底面边数,因此12分段就足够表现出圆环。边数则表示环截面的边数,通常使用4边就足够光滑了,不到万不得已不使用5边或6边。
F、 管体:这个是必须严禁使用的基本形体。事实上我们完全可以将管体做成柱体,而在贴图上画出黑洞来模拟“管口”的特殊效果。
G、 比较复杂的形体:这是需要高级建模技术才做得出来的东西,需要在各种基本形体的基础上频繁地使用网格编辑,为了减少面数,高手往往会删除原有的面,而自己重新创建新面来代替。因此我无法在这里进行讲解,你们自己去买书学3DMAX高级建模吧。
H、输出W3D时的注意事项:除非你认为你的模型实在是简陋得比ZH的玩具级别还烂,否则尽量不要钩选“Smooth Vertex Normals”,这个功能会自动修正定点和法线的光滑程度,容易在一些无关紧要的细节上平白无故地增加很多多边形数,让原版已经简化完成的模型又变成了精致模型,那我们又何必去简化呢?
不要忘了随时察看模型的总多边形数,为了确保游戏运行最低速度不低于30帧/秒,我实测了3个级别的大致简化要求,根据运行该游戏的电脑配置分别表示如下:
A、6年前的古董电脑。即图拉丁赛阳1G或毒龙1G MX440双64显卡或R8500双64显卡 DDR266-256M内存。
多边形要求:ZH级别(玩具级别)。即坦克不超过300,建筑不超过600,士兵不超过200
B、3年前的淘汰配置。即P4HT2.4G或AMD2600+ FX5200双128显卡或R9550双128显卡 DDR400-512M内存
多边形要求:FK级别(仿真级别)。即坦克不超过1000,建筑不超过1500,士兵不超过400
C、主流甚至豪华配置。即CORE2.0或AMD3800+ NF8400单256显卡或1950XT双256显卡 DDR667-1G内存
多边形要求:CNC3级别(工艺品级别)。即坦克不超过2000,建筑不超过4000,士兵不超过1000
D、如果你的配置比上面的豪华配置还高出一大截,那么你可以承受RW级别(真实级别),即现代战争那种变态的精致程度。
(6) 无所不能的UVW展开
没贴过图的模型结构,通常称为“裸体”,你肯定会发现,一些高手制作的模型,只看裸体根本看不出有什么特别,甚至相当简陋,但贴上图之后却显得非常逼真。事实上这就是对游戏美工的一个最高难度要求——用最简陋的结构配上最细腻的贴图,来表现出足够精致的模型,因此专业的游戏美工有一个相同的认识,即3D游戏美工,最重要、且最有技术含量的是贴图,而非结构。
贴图是3DMAX的一大基本功,但光是看书还不足以学成高级美工,而是需要花费3、5年时间去反复训练和提高的。可以想像,要是随便买本书来看完就可以干游戏美工工作的话,那么那么多游戏美工高手就都该饿死了。
最牛的贴图方法是UVW展开,关于这个方法,几乎99%的3DMAX书本上都没有讲解,但它却是专业游戏开发中最实用的贴图方法。你可以将整个模型上各个面的图像用PS整合到一张图片上,然后贴给所有结构体,再将这些结构体的各个表面通过UVW展开,移动图片上各个合适的位置去“拼贴”,于是实际模型的表面上就会表现出具体的图像。关于UVW展开,在百度上能搜索到一些详细的教程,我收集到一个老外的金鱼视频教程作为附件,该教程详细地讲解了从0开始建模,到贴图、动画制作的全部操作过程,但由于体积巨大,因此我只能给出地址,你们自己去下载观看吧,我猜想你们在看完之后必定会汗颜——看一遍视频,胜读10年书。
http://www.086g.com/forum-cn/thread-107689-1-1.html
(7) 人物制作要点及W3D输出注意事项
人物是一种最特殊的模型,所有士兵模型都要用这种方式来制作。看过3DMAX动画书籍的人应该知道,人物模型中通常都含有蒙皮和骨骼这两个概念,蒙皮受到骨骼上的各个关节点的牵引而产生随动的形变,于是产生了肢体动画。这里不便于仔细讲解骨骼的制作过程,你们自己去看书。我只讲解几点制作中的注意事项。
A、 蒙皮:在制作蒙皮时,可以利用基本形体来进行网格编辑,分别制作出头、躯干、四肢、枪械武器等各个部件,然后将它们整合起来,转换成一个“可编辑网格”,作为蒙皮。当然一些3DMAX动画书籍上讲解的通常是专业方法,即建立一个长方体作基础,利用网格编辑通过复杂的手工分段、表面挤出、网格点焊接等逐步做成一个完整的人体。总之不管怎么样,能用尽量少的多边形表现出足够细腻的人体结构就行。
B、 贴图:尽可能地用PS将整个人体上所有用得到的图像都整合到一张TGA上,将它贴到蒙皮上去。贴好之后你会发现整个人体上的图像是混乱的。不要紧,只要我们对蒙皮进行UVW展开并拼贴各个表面的位置,就能将贴图和蒙皮表面对应好。
C、所属色:由于士兵的模型是蒙皮,它是一个整体,因此无法使用类似于坦克、建筑的HouseColor%02d的方法来表达所属色区域。而经常使用PS的话,不难发现32位TGA是存在ALPHA通道的,这个通道通常用来区分一个TGA图像上的正常显示部分和全透明部分,即处于通道内的图像为正常显示,反之则是全透明,而通道边缘上的羽化区域则显示为半透明。因此SAGE利用TGA的这个特定来表达所属色,使士兵蒙皮上凡是出现了通道外图像的表面,统统显示为全透明。因此我们在保存士兵贴图时,一定要记得保存成32位TGA,否则将不支持ALPHA通道。此外TGA的命名也有讲究,SAGE规定,只有当TGA的文件名以小写的“zhca_”开头时,贴有通道外图像的表面将显示为纯净的所属色,否则,就显示为不可见。你们去观察一下原版ZH的士兵贴图文件就明白了,所有TGA的文件名总是有个小写的zhca_开头。
D、输出潜规则:3DMAX有个不成文的规定,那就是凡是被隐藏和冻结的部件是不会产生任何输出的,因此在输出W3D时,不要忘了恢复所有部件的显示和解冻。
E、 蒙皮、骨骼、动作之间的关联:和坦克模型不同的是,士兵的蒙皮只由骨骼来控制,因此蒙皮需要和骨骼实现绑定。3DMAX可以提供两种空间扭曲用于绑定蒙皮和骨骼,分别是SKIN和WWSKIN,两者的用法大同小异,对于简模来说,后者更方便一些,附件里的骨骼动画制作教程里详细地讲解了如何绑定,这里就不再多说废话了。只需要严格注意以下几个要点:
(a) 蒙皮只能钩选Export Geometry,并设置Geometry Option为Normal,千万不能钩选Export Transform。因为我们只需要它的形体图像,不能让它输出定位信息,否则会和骨骼发生冲突,导致人物动作不正常
(b) 骨骼只能钩选Export Transform,千万不能钩选Export Geometry。因为我们只需要它的定位信息,不能让它输出形体图像,否则人物身上会出现一些不应该有的怪异部件
(c) 绑定时,通常可以使用Auto-Link,可以快速将蒙皮上所有定点都自动绑定到最近的关节点上,但有时候会出现一些意外,即把错误的定点绑定到错误的关节点上,导致动作怪异,因此自动绑定完之后,要手工检查一下那些最密集的定点区域,试着进入“自动关键点”模式,移动一下关节点看看是否绑定到了不该绑定的定点,如果有的话,就要进行人工处理,选择这些绑定错误的顶点,Unlink,然后Link to Bome by Name或Link to Bome Selected。
(d) 输出W3D时,一定要记得先输出SKL,然后才是输出SKN。
在输出SKL时,要选择Skeleton输出方式。
在输出SKN时,要选择Hierarichical Model方式输出,下面还要钩选“Export Using Existing”,并选取刚才输出的SKL。如果忘了的话,会丢失SKN和SKL之间的绑定,导致人物在游戏里呈现怪异动作或微动的T字形。
动作动画是比较难做的东西,因为官方那些动作多数都是用光点捕捉器或动作生成器获取到的,而我们是在手工制作,所以可以借用原版里的一些现成动作,将它们略加修改弄成新的动作。导入动作动画时,3DMAX会自动提醒你伴随导入关联的SKL,因此你需要把动作动画和SKL放到同一个路径下,一导入动作,SKL就自动进入3DMAX了。修改好之后,不要忘了给所有关节点都钩选Export Transform,输出时选择Hierarichical Animated方式输出,下面还要钩选“Export Using Existing”,并选取刚才输出的SKL。如果设置错误的话,会使SKL不受动作的控制,导致人物在游戏里发生该动作时呈现纯静态的T字形。
(e) 必须强调一点,动作动画的第0帧必须保存成基准帧,用来记录T字型基准姿势,并且不允许对它进行编辑,因此任何动作动画都只能从第1帧开始。这样我们可以在必要的时候把SKN导进来与关节点进行绑定,以检验我们做的新动作是否够自然。如果你没保留基准帧,那么绑定SKN的时候,你就找不到一个最合适的姿势,以至于容易出现绑定错误导致无法检验动作效果。
(f) 如果你实在受不了这么麻烦的输出注意事项,建议你把士兵模型当作坦克来制作,即每个动作都包含完整的蒙皮、骨骼和动作,并整合起来Hierarichical Animated方式输出成单一的W3D,不要像官方那样拆分成相互关联的SKN、SKL和动作。这样做的好处在于输出设置可以偷懒,彻底避免了动作怪异、静态T字形和微动T字形的情况发生,但缺点就是最后得到的W3D含有重复的内容而占据了一些不必要的磁盘空间。
F、 辅助体: ZH玩多了,可以发现一个现象,那就是我们在点选目标时,鼠标指针必须移动到有形体的部位时才能成功选中该目标。例如中国机场的跑道尽头有一个小缺口,如果你把鼠标移动到该缺口上时,是点不中机场的。这里要解释的是,SAGE规定,既输出形体图像,又输出定位信息的表面,才能被玩家选中。因此对于士兵模型来说,SKN和SKL都没有全钩Export Geometry和Export Transform,因此在游戏里是无法点选该士兵的。因此官方使用了一个隐形的辅助体带代替SKN被玩家点选,因此这个辅助体必须同时钩上Export Geometry和Export Transform,并且Geometry Option里要选择OBBox(辅助体),使之在游戏里不被渲染出任何图像。
G、 常见错误分析
(a) 纯静态T字形:一是忘了设置WWSKIN来绑定SKN和SKL;二是忘了给所有关节点钩上Export Transform。三是输出SKN时忘了钩选“Export Using Existing xxxx_SKL”;四是在输出动作动画时,输出方式选成了Hierarichical Model,五是在输出动作动画时忘了钩选“Export Using Existing xxxx_SKL”。
(b) 微动的T字形:肯定是忘了取消SKN的Export Transform,导致SKN的位置信息由自身的中心点来控制,而不受SKL的控制,因此整个SKL上只有最靠近SKN中心点的那个关节点能发挥控制作用。
(c) 怪异动作:主要是SKN的顶点和SKL的关节点关联错误。当然也可能是输出动作动画时钩选“Export Using Existing”时选用了另一个步兵的SKL。所以要处理好士兵模型很麻烦,要么就只换SKN,借用原版的SKL和动作,如果要更换SKL,就得把所有动作都重新导入,与新的SKL关联后再重新输出。
(d) 士兵不能点选:肯定是忘了放置辅助体,要不然就是把辅助体隐藏了忘了在输出W3D前恢复显示。
至此,基础阶段的教程就全部介绍完了,接下来留给各位作者有两条道路:
1、 知难而退:SAGE引擎太复杂了,相信大多数作者看了这么久的教程,依旧是恍恍惚惚不知所谓,也做不出什么东西来,当然这也是正常的,无论学什么东西,教程都只能给你指点方向,具体如何去领悟真谛,必须要你们自己去深入研究。所以你们如果没兴趣作深入研究的话,我建议你们还是回TS去算了。
2、 迎难而上:SAGE引擎确实复杂,但是未必就完全摸索不通,只要对自己有信心的人都应该明白为什么我发到818上的帖子叫“5个月的心血”了,要摸索透这样一个功能庞大的引擎,确实需要认真地花时间去进行走火入魔似的研究和测试,最后才能体会出各个功能模块、各条语句的作用,达到融会贯通,把教程上讲解的文字归纳为自己所能灵活运用的知识,从而制作出像《冲击波》、《五星之光》等那样有深度的好MOD。如果你准备好要迎接新的挑战,就请你继续向下面看,后面全都是高难度的进阶教程了。