【原创】【智库教程】原版风格座舱完!全!制!作!教!程!

引言
本教程将从零开始教授如何制作一个完整的指令舱,包含从建模到导入的全部过程。
本教程由智库鸽笼出品,感谢Icecovery Studio对本教程的大力支持!智库原创,未经许可,严禁任何组织和个人转载。
以下是部分完成品预览图
特性:IVA! 法线贴图!自发光!自发光!自发光!
本教程包含从建模到导入的全部过程
此座舱已经制作完成,期间产生了接近200张截图,将在数日之内陆续发完,请各位耐心等待
在阅读本教程前,您需确保你至少有少量的建模基础,少量的绘图技术(PS/Paint.net),少量的Unity操作水平,少量的英文阅读能力以及少量的智商
本教程使用到的工具以及软件:
3DSMAX2017,Paint.net(这是个软件,相当于精简版的PS),Unity 2017.1.0.f3,Chrome,Notepad++
第一章-建模
首先我们先打开3dsmax,新建一个max工程文件命名为CommandPod保存在文件夹Pod下,创建一个24边的(24边是原版的通用边数)圆柱体重命名为pod,设置其半径到0.625m,在绿色箭头处把此对象的颜色设置成黑色,并且打开精简材质编辑器在蓝色箭头处将材质ID设置成0,然后在红色箭头处将材质赋予给这个对象
添加一个编辑多边形修改器,选中顶面,打开缩放变换输入窗口,在偏移:世界底下的框框中输入50,这样子顶面的直径会变成0.625m
将顶面移动至一个合适的高度,构成基本形状,这里我使这玩意的高度为1m
选中24条边,连接边,使两条连接,如下图所示
选择面向前方的四个边,挤出一定数值
将上方的四个顶点目标焊接到另外四个顶点处,构成下图的模样
进行一定的调整
选中如下四个面,插入一定的值,这里将会是我们的窗口
进行插入-挤出-缩放的操作,做出下图所示的舱门
选中下图所示的一堆面,然后给予一个45度的自动平滑
将窗口分离为对象Window(需要注意的是,这里不分开也是可以的,我们后面将用一个材质球实现窗口反射和表面哑光的效果)
给予一个不同颜色的材质以便区分(需要注意的是,这里如果不分开它们,也可以选定面,然后给单独的面赋予材质)
将底面插入并拉下一定的值
重复上一步数次,得到一个隔热底的形状
给隔热底部分给予一个单独的平滑组
在顶部插入,挤出,插入,挤出以下形状
将不同的部分给予不同的平滑组后得到下图所示的几何体
至此,座舱外表已经建模完成
建立一个与座舱完全重合的几何体
底下做一个简单的形状,大致与隔热底重合
将这个几何体移到一边并给予原谅色,重命名为Collider,这个几何体将是我们用于生成碰撞网的mesh,此处可以使用16边圆柱更好,但是我们选择32边的
将几何体Pod复制一份,并重命名为IVA
将顶底多余的面删除后在边界模式选择封口
将舱门移动进去
给整体一个大约95%的缩放
选中全部的面后,点击翻转,将所有的面翻转向内
右键几何体,对象属性中勾选背面消隐
将窗户封口并连接好点后再次分离,此时分离为几何体IVAwindow,注意在此时选择多边形时应勾选忽略背面选项
新建一个Box并且拉成以下形状
另外一个box拉成以下形状
对第二个box挤出一条支撑臂,然后删去两个box不可见的面后,在几何体IVA附加两个box
把几何体IVA顶部拉下来一点后挤出一定的形状
此处类似与制作隔热底的步骤,制作出一个舱门并且给予平滑组
对每个不同的部分分别都给予平滑组
至此所有的建模工作已经完成了
我们现在有了如下五个几何体
第二章-分解UV
选中几何体Pod和几何体Window,对它们添加一个UVW展开修改器
按下"打开UV编辑器"按钮,弹出编辑UVW窗口,我使用两块屏幕来方便分解UV的流程
我们切换到边模式,然后选择右侧的剥模式,UV将自动剥开成如下的样子
我们在模型视图中一条一条的选择要切开的边,右边会相应的一点一点剥开模型的UV
将上面的环剥下以后
将顶部剥成如下图所示的样子
我们退出剥模式,选择面模式,选择整个隔热底
在如下所示的位置打开展开法线贴图窗口
选择顶/底贴图
点击确定后隔热底被铺平
我们将隔热底移动到一边,然后把模型侧边的两瓣移动到一起
缝合它们
切换到点模式,将底下无法缝合的顶点对其到一起
将窗户也缝合好
我们可以打开棋盘格贴图映射,然后摆放好所有拆开来的UV,尽量使每一个空隙都被用到,每一个位置的方格的差不多大小,使方格尽量不扭曲变形,摆放好以后如下图所示
将IVA和IVAwindow也拆好,如下图所示
选择工具-渲染UVW模板
此处我建议渲染两张,一张为默认设置,勾选可见边,接缝边为绿色,另外一张不勾选可见边,接缝边为黑色
之后点击渲染UV模板按钮,以以下配置保存
对于IVA的UV进行同样操作
之后我们便得到了如下图所示的四张图片,至此,UV分解的工作也结束了
第三章-绘制贴图
我们打开Paint.net,(如果你想用PS也可以,楼主的ps日常抽风故选用更加简单的方法,而且Paint.net也是一款非常好用的dds查看/编辑器,可以在getpaint.net免费下载到(强行安利一波
打开IVA_uv2.png
油漆桶,填充模式改成全局,容限50%,在边上多点几下(PS中可以直接用’描边’完成)
给中间的部分上色
给其余的部分也先暂时上纯色,之后保存,保存设置选择32位
拖动该png文件到max中的几何体Pod上,可以看到已经没毛病了
将Pod_uv1.png拖放至paint.net中,选择添加图层
这样子我们就可以看到模型的边了
我们新建一个图层,沿着pod下缘画一条线
对这个图层进行高斯模糊处理
时刻注意保证模糊后擦除影响到其它部分的地方,导出时注意隐藏最上方的线框图层,以后不再提醒
在max中可以立即看到效果
我们合并刚刚那个图层,并且在新图层用笔刷画上一些奇奇怪怪的东西
图层不透明度改一下
max中可看到的效果如下
在箭头所指的几个地方也加上效果
如图
这里用方块所示的渐变工具也加一点特技
这里同理,顺便搞上一个从原版Mark1-2的贴图上扒下来的舱门
在Max中
画几条这种东西在侧边和隔热底上
把这个图层单独导出
记得加上白色的底
前往http://cpetry.github.io/NormalMap-Online/这个网站
在最右边的框框中拖入刚刚保存的图片,以以下设置生成一张法线贴图
现在我们的贴图
给窗户加一点特技
Max中
选中这一堆
复制到一个黑底的新贴图上
处理成以下模样
现在我们有的贴图
加上两个RCS喷口
和上面一样的方法,画一点钉子什么的
一样生成一张贴图
把两张贴图融合一下
不要忘了漫反射贴图
用淡淡的刷子搞脏一点
把窗户部分单独拿出来,然后移动到另一个图层
将除了窗户外的所有图层透明的设成1%
Max中
以同样的道理,画好IVA的贴图
像这样
当然我们也是有自发光贴图的(自发光!自发光!自发光!
第四章-导出
我们回到max,选中五个对象,然后点击导出-导出选定对象(直接点导出也可以,不过这是个好习惯,防止导出一些不必要的辅助对象
导出设置如下,确定单位是m
第五章-导入
我们打开Unity,新建一个场景(我这里不是新建的
然后安装好Parttool(我在这里使用的是「智库神器™」,然而这个东西和Parttool在下面会讲到的功能上相差无几,故不特别讲述,以下我们简称它为pt
注意:任何求发「智库神器™」的行为是不会得到回答的,智库神器属于智库内部自行研发的保密产品,将不会外传
新建场景和安装Parttool的过程不再细说
拖入我们导出的fbx文件,和五张贴图
将fbx文件拖入场景,并且坐标归零
点击这里更改模型的材质
因为我们有自发光贴图,而且有反光效果,所以我们将模型的材质球切换至KSP-Emissive-Bumped Specular
把贴图拖到正确的位置上,记得fix法线贴图
讲箭头处的三个东西设置好
效果如图,可以看出材质的区别和法线贴图的效果了
IVA同理,只不过我们由于没有法线贴图,故选择KSP-Emissive-Diffuse,并将箭头处设置成默认白色
之前画在玻璃上的污渍是不透明的
我们在这新建一个材质
选择KSP-Alpha-Translucent
现在是透明的了
我们把之前的碰撞网模型移到原点处与模型重合
删除Mesh Renderer和Collider这两个东西,任何加一个Mesh Collider,点选Convex
路径
我们新建一个叫做CommandPodRoot的空对象,
移动到我们想要的重心处,然后把它移动到全部物体的父对象位置
创建一个空对象命名为RCSjet,移动到合适的位置,绿色箭头朝着推力方向
另一边也一样
创建一个空对象命名为Ladder,方向以及大小在图中显示了,记得选择is Trigger
然后添加两个Tag,分别叫Ladder和Airlock,一个大小写都不能错
顺便在User Layer 21 加上Part Triggers
然后将Ladder这样配置
创建一个空对象叫Airlock,位置以及信息如图所示
这就是我们目前有的东西了,CommandPodRoot的方向应该是与模型成这样子的关系但是整体绕绿轴旋转180度,这里是我的一个错误我在后面修复了这个问题。
在CommandPodRoot加一个KSP Part Tools
必须导出至GameData(以下简称GD)下的路径
这里我们导出了DDS,但是原版的pt是没有这个功能的,可以选择PNG导出方便修改
然后我们就有了如下几个东西——三张贴图(漫反射,自发光,法线),一个.mu文件——然后我们新建一个txt文件重命名为Part.cfg
第六章-CFG
然后呢我们就可以愉快的来写这个cfg文件了,
首先我们先写一个框架
(没错就是这样子熟悉的…)
是的。
(响指)
Duang!
写好了
好吧这一次我会贴出源代码
PART
{
// this is a sample config file, for determining a good file format for defining part parameters
// comment line - ignored by cfg parser
// empty lines, or lines without a ‘=’ sign are also ignored
// all other lines are split at the ‘=’ sign, and the left operand is used to know what parameter we are setting
// diferent parameters require data in different formats (see docs), and each module has it’s own parameters (again, see docs)
// each assignment must be in a single line. Lines without assignments will be ignored. (You CAN turn on word wrap, though)
// each keyword here relates to an existing variable in the assigned module. If the keyword isn’t found, it is ignored.
// conversely, if a keyword is left unassigned (as in not in the file), it will be initialized with it’s default value
// This is done automatically, so any public variable defined in the loaded module can be accessed this way (provided it’s value can be parsed)
// — general parameters —
name = TestCommandPod
module = Part
author = Icecovery
// — asset parameters —
mesh = model.mu
scale = 1
rescaleFactor = 1
// — node definitions —
// definition format is Position X, Position Y, Position Z, Up X, Up Y, Up Z, [node size], [crossfeed, def=1 i.e. true], [rigid attach, def=0 i.e. false]
node_stack_bottom = 0.0, -0.3, 0.0, 0.0, -1.0, 0.0, 1
node_stack_top = 0.0, 0.7, 0.0, 0.0, 1.0, 0.0, 0
bulkheadProfiles = size1, size0
CoPOffset = 0.0, 0.5, 0.0
CoLOffset = 0.0, -0.35, 0.0
CenterOfBuoyancy = 0.0, 0.5, 0.0
CenterOfDisplacement = 0.0, -0.3, 0.0
buoyancy = 1.5
buoyancyUseSine = False
// — editor parameters —
TechRequired = start
entryCost = 0
cost = 600
category = Pods
subcategory = 0
title = Test Command Pod
manufacturer = Icecovery Stuio
description = This is a test command pod.
// attachment rules: stack, srfAttach, allowStack, allowSrfAttach, allowCollision
attachRules = 1,0,1,1,0
bodyLiftOnlyUnattachedLift = True
bodyLiftOnlyAttachName = bottom
// — standard part parameters —
mass = 0.8
dragModelType = default
maximum_drag = 0.2
minimum_drag = 0.15
angularDrag = 2
crashTolerance = 14
maxTemp = 1200
skinMaxTemp = 2200
skinInternalConductionMult = 0.625
heatConductivity = 0.1 // 5/6ths default
vesselType = Ship
// — internal setup —
CrewCapacity = 1
INTERNAL
{
name = TestCommandPodIVA
}
MODULE
{
name = ModuleCommand
minimumCrew = 1
}
RESOURCE
{
name = ElectricCharge
amount = 200
maxAmount = 200
}
MODULE
{
name = ModuleReactionWheel
PitchTorque = 5
YawTorque = 5
RollTorque = 5
RESOURCE
{
name = ElectricCharge
rate = 0.24
}
}
MODULE
{
name = ModuleColorChanger
shaderProperty = _EmissiveColor
animRate = 0.8
animState = false
useRate = true
toggleInEditor = true
toggleInFlight = true
toggleInFlight = true
unfocusedRange = 5
toggleName = Toggle Lights
eventOnName = Lights On
eventOffName = Lights Off
toggleAction = True
defaultActionGroup = Light
redCurve
{
key = 0 0 0 3
key = 1 1 0 0
}
greenCurve
{
key = 0 0 0 1
key = 1 1 1 0
}
blueCurve
{
key = 0 0 0 0
key = 1 0.7 1.5 0
}
alphaCurve
{
key = 0 1
}
}
MODULE
{
name = ModuleScienceExperiment
experimentID = crewReport
experimentActionName = Crew Report
resetActionName = Discard Crew Report
reviewActionName = Review Report
useStaging = False
useActionGroups = True
hideUIwhenUnavailable = True
rerunnable = True
xmitDataScalar = 1.0
usageReqMaskInternal = 5
usageReqMaskExternal = -1
}
MODULE
{
name = ModuleScienceContainer
reviewActionName = Review Stored Data
storeActionName = Store Experiments
evaOnlyStorage = True
storageRange = 1.3
}
RESOURCE
{
name = MonoPropellant
amount = 10
maxAmount = 10
}
MODULE
{
name = ModuleConductionMultiplier
modifiedConductionFactor = 0.003
convectionFluxThreshold = 3000
}
MODULE
{
name = ModuleDataTransmitter
antennaType = INTERNAL
packetInterval = 1.0
packetSize = 2
packetResourceCost = 12.0
requiredResource = ElectricCharge
antennaPower = 5000
optimumRange = 2500
packetFloor = .1
packetCeiling = 5
}
MODULE
{
name = ModuleLiftingSurface
useInternalDragModel = False
deflectionLiftCoeff = 0.35
liftingSurfaceCurve = CapsuleBottom
disableBodyLift = False
omnidirectional = False
perpendicularOnly = True
transformDir = Y
transformSign = -1
nodeEnabled = True
attachNodeName = bottom
}
EFFECTS
{
running
{
AUDIO_MULTI_POOL
{
channel = Ship
transformName = RCSjet
clip = sound_rocket_mini
volume = 0.0 0.0
volume = 0.1 0.0
volume = 0.5 0.025
volume = 1.0 0.1
pitch = 0.0 0.75
pitch = 1.0 1.5
loop = true
}
MODEL_MULTI_PARTICLE
{
modelName = Squad/FX/Monoprop_small
transformName = RCSjet
emission = 0.0 0.0
emission = 0.1 0.0
emission = 1.0 1.0
speed = 0.0 0.8
speed = 1.0 1.0
localRotation = -90, 0, 0
}
}
}
MODULE
{
name = ModuleRCSFX
stagingEnabled = False
thrusterTransformName = RCSjet
thrusterPower = 1
resourceName = MonoPropellant
resourceFlowMode = STAGE_PRIORITY_FLOW
runningEffectName = running
atmosphereCurve
{
key = 0 240
key = 1 100
key = 4 0.001
}
}
}
(嗯洋洋洒洒258行
(具体就不详述了,自己去体会吧
然后接下来我们来把节点的位置搞好
如上两个数值用一个空对象在unity中测出
填好
这里我暂时留空,我们还没有做IVA
这三个地方填写RCSjet(希望你还记得为什么
差不多就这样了先
第七章-测试
这一章还用说什么?
打开游戏就是了
如果一切都正常你可以在Pod类找到这玩意
如果没找到就去找找哪里做错了
如果找不出来就再找一次
再找不出来就先洗把脸再找
再找不出来再来问
这是目前的效果
RCS工作正常,玻璃的反射也没毛病
自发光没毛病
没毛病
没毛病
还是没毛病
还是非常的原版风格的
对比
第八章-IVA
这里将会是比较神奇的一个章节了
首先我们先创建一个CommandIVARoot,方向是这样子的,然后把模型旋转成这样子
加一个光源我们做的自发光的灯的地方
以及其它两个灯
现在是这样子的
然后我们创建两个临时的碰撞网在这里,与这个板子的表面重合,它们将会帮助我们更快的定位等一下要弄的小道具们
加入一个摄像机,在如下的位置,切换到Game窗口可以查看,记得把右边方块中的值改成最小,将会更加接近于在游戏中的样子
这里也有一个,看向窗外的
创建两个碰撞网,记得标记为Trigger
在你想要点击然后切换到摄像机的地方
接下来我们创建一个空对象命名为Prop
然后我们打开pt,到Prop选项卡,然后这里就是我们所有的Prop了
需要注意的是,如果你没有安装RPM或者ASET或者NF的Prop包或者之类的Mod,这里将只会显示原版自带的Prop,装了以后重新扫描GD即可出现新的
这里我们首先先放一个导航球(NavBall)
搜索NavBall(我不确定原版pt有没有搜索功能,没有就顺着找吧
出来以后移动到仪表盘正上方,之前我们的碰撞网此时有了作用,我们点击一下图示的两个按键
它就会自动贴在正确的位置上,只需要稍稍移动就行了
然后我们放一个座位,这里我们接下来都会使用NF的 Prop包里的东西
房号以后在这个座位下创建一个空对象Seat,这里是我们的绿人要坐的地方,然后移动它到IVA下
如下图所示
然后我们以此类推布置好我们的仪表盘
然后加一点小东西来装饰,这些东西都可以在NF的Prop包里找到
还是很温馨的对吧
喝着摩卡咖啡玩着Thinkpad又一边开火箭,感觉非常好呢(
然后我们把这几个和相机有关的东西移动出来
给他们加上如下图所示地方新建的Layer 16,命名为Kerbals,同时在Layer 20 写上Internal Space
给所有IVA下的对象加上Internal Space这个Layer
这个时候它会一体式是否也要改变子对象的Layer,我们选择是
然后给给相机们加上Kerbals这个Layer,然后移动回去
然后我们把这玩意先记得移动出来
然后我们导出IVA下的东西们
到以下路径
新建一个叫做IVA的.cfg文件
内容如下
以下是代码
INTERNAL
{
name = TestCommandPodIVA
MODULE
{
name = InternalCameraTargetHelper
}
MODULE
{
name = InternalSeat
seatTransformName = Seat
allowCrewHelmet = false
}
MODULE
{
name = InternalCameraSwitch
colliderTransformName = CamTrigger1
cameraTransformName = Camera1
}
MODULE
{
name = InternalCameraSwitch
colliderTransformName = CamTrigger2
cameraTransformName = Camera2
}
}
接下来我们刷新一下pt
然后我们在IVA这个选项卡中搜索(它也许叫做Internal Space)TestCommandPodIVA 这个名称
然后我们就生成了一个合成的IVA部件
把Prop复制一份,放到这个部件下,然后坐标归零,然后这些东西应该就会像下图一样到正确的地方了
然后我我们选择这个合成的part,选择Save to Config
然后我们重新打开IVA.cfg就可以看到这些小道具的信息都已经被填写好了,非常方便省时
然后我们回到Part.cfg,在INTERNAL下写好IVA的名称
然后这里我们就修复了上面提到的我犯的错误,转了180度
第九章-装十三
接下来当然就是装13了啊,打开游戏爽就是了
以下是一大堆截图
几把蛋坐在新玩具里笑得很开心
第十章-进阶
好的这里的确还有一些神奇的东西属于进阶部分,这些东西很简单,但是可以实现很不错的效果
首先我们复制一个外模,也就是几何体Pod,与IVA重合,然后给它一个神奇的材质,这个材质叫做DepthMask, 值得注意的是这个材质不在KSP分类下。
然后我们就可以把该对象移动到IVA这个父级下,然后重新导出一次,这样子在游戏中就可以实现点开右下方绿人边上的小绿点以后,只有窗口可以看到里面,或者我们还可以在边上开几个洞什么的,甚至是门上也可以开洞。这个效果可以在原版的很多Pod上看到。
这里也就是为什么我说实际上我们不需要分开window但是我还是分开了的原因了。
更多进阶内容(比如过热动画之类的我会在以后慢慢的补上,敬请期待
后记
这样子整个教程就都结束了,现在在Word看有145页,5700多个字,11371个字符,也写了很久的。
希望对大家有帮助,喜欢的话点个喜欢点个赞,B站投点币Patreon捐点钱。
B站ID: Icecovery
Patreon页面:https://www.patreon.com/Icecovery
最后祝大家都可以做出自己满意又精致的MOD。
然后就没有了。