在本教程中,我们将创建一个使轮子在地形上跟随的脚本。此脚本将没有任何UI。并且仅适用于特定对象。
因此,第一步是创建一个新的脚本。打开侦听器窗口,然后在文件菜单下选择“新建脚本…”。
我们首先需要创建与场景中的对象相对应的3个变量。
terrainGeometry = $ground
rayCaster = $WheelGuide
wheel = $wheel
这三个变量表示或接地、车轮和车轮控制对象。轮子本身会应用很多动画,所以为了保持整洁,我们将把它作为控制对象的父对象。我们将在地形上设置轮子导向的动画,并让脚本使轮子几何体跟随地面。让我们看看相应的最大文件。
这个文件中有三个对象,它们对应于脚本中的三个变量。您将看到车轮是车轮导向器的父对象。车轮导向装置只是一个样条曲线对象。地形是一个添加了噪波的平面。车轮导向器上有一些动画。它在地形上以直线行驶。用于创建代码以使轮子跟随地形。
rayToTerrain = ray rayCaster.pos [0,0,-1]
Zposition = intersectRay terrainGeometry rayToTerrain
wheel.pos.z = Zposition.pos.z + rayCaster.radius
三行代码,我们已经掌握了。如果你将文本复制并粘贴到maxscipt中并进行评估,轮子将下降到地形上。让我们看看为什么这样做。
变量rayToTerrain是该代码的关键。我们在里面储存着一束光线。射线是三维空间中具有原点和方向的线。在数学术语中,它被称为向量。因此,为了让车轮与地面碰撞,我们从地形上方的一点直接向下发射光线。因此,我们使用车轮导轨作为起点,因为我们知道它在地面上。我们使用变量rayCaster,而不是键入$WheelGuide。我们这样做是为了方便地更改在定义变量的顶部拍摄光线的内容,而不必在代码的每个实例中都更改这个名称。因此,rayCaster.pos等于$WheelGuide的x,y,z位置。
数字[0,0,-1]表示一个point3值。这是矢量的方向。我们需要对值进行归一化,这意味着所有数字加起来就是一。因此,在point3变量中,这三个数字表示x、y和z。因此,如果你想将光线投射到墙上,你可以使用同一行代码,但将point3值更改为[1,0]
下一个变量Zposition使用另一个新的maxscript命令。intersectRay。此命令的格式为intersectRay节点射线。因此,节点是光线将相交的对象,而光线是我们之前设置的rayToTerrain变量。输出是一个point3值,该值给出光线击中节点几何体的3D点。
最后一行设置车轮位置。我们知道光线与地面相交的点,所以我们只需将轮子的z位置(wheel.posz)设置为等于我们存储在z位置中的相交值。然后我们加上轮子的半径,将其推离地面。一个有趣的尝试是调整圆的半径,并在重新运行脚本时看到结果。
让我们更改代码,以便在动画过程中设置轮子的动画。这是代码:
terrainGeometry = $ground
rayCaster = $WheelGuide
wheel = $wheel
disableSceneRedraw()
with animate on
(
for currentTime = animationRange.start to animationRange.end do
(
slidertime = currentTime
rayToTerrain = ray rayCaster.pos [0,0,-1]
Zposition = intersectRay terrainGeometry rayToTerrain
wheel.pos.z = Zposition.pos.z + rayCaster.radius
)
)
enableSceneRedraw()
我们在这里所做的只是禁用场景重绘(disableSceneRedaw)来加快脚本的速度。如果我们不这样做,Max将重新绘制每一个更改,并且速度会慢得多。完成后,我们必须记住启用场景绘制,否则Max将不会更新视口。然后,我们创建一个从第一帧到最后帧的循环,并按帧向下移动轮子。我们在这里介绍的另一个新命令是启用animate,这就像打开animate按钮一样。
因此,如果我们现在运行脚本,轮子将在地形上设置动画,并随地面的上升和下降进行跟随。